Skip to content

Commit

Permalink
feat(doc): inline doc links (#6626)
Browse files Browse the repository at this point in the history
* feat: infer hyperlinks

* feat: inline doc links

* rustfmt
  • Loading branch information
mattsse authored Dec 20, 2023
1 parent aaf1273 commit 8be2649
Show file tree
Hide file tree
Showing 8 changed files with 482 additions and 57 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/doc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ solang-parser.workspace = true
thiserror = "1"
toml.workspace = true
tracing.workspace = true
regex = "1.10.2"
2 changes: 1 addition & 1 deletion crates/doc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub struct DocBuilder {

// TODO: consider using `tfio`
impl DocBuilder {
const SRC: &'static str = "src";
pub(crate) const SRC: &'static str = "src";
const SOL_EXT: &'static str = "sol";
const README: &'static str = "README.md";
const SUMMARY: &'static str = "SUMMARY.md";
Expand Down
112 changes: 110 additions & 2 deletions crates/doc/src/document.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::{ParseItem, PreprocessorId, PreprocessorOutput};
use std::{collections::HashMap, path::PathBuf, sync::Mutex};
use crate::{DocBuilder, ParseItem, PreprocessorId, PreprocessorOutput};
use std::{
collections::HashMap,
path::{Path, PathBuf},
slice::IterMut,
sync::Mutex,
};

/// The wrapper around the [ParseItem] containing additional
/// information the original item and extra context for outputting it.
Expand Down Expand Up @@ -62,6 +67,15 @@ impl Document {
let context = self.context.lock().expect("failed to lock context");
context.get(&id).cloned()
}

fn try_relative_output_path(&self) -> Option<&Path> {
self.target_path.strip_prefix(&self.out_target_dir).ok()?.strip_prefix(DocBuilder::SRC).ok()
}

/// Returns the relative path of the document output.
pub fn relative_output_path(&self) -> &Path {
self.try_relative_output_path().unwrap_or(self.target_path.as_path())
}
}

/// The content of the document.
Expand All @@ -73,6 +87,100 @@ pub enum DocumentContent {
OverloadedFunctions(Vec<ParseItem>),
}

impl DocumentContent {
pub(crate) fn len(&self) -> usize {
match self {
DocumentContent::Empty => 0,
DocumentContent::Single(_) => 1,
DocumentContent::Constants(items) => items.len(),
DocumentContent::OverloadedFunctions(items) => items.len(),
}
}

pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut ParseItem> {
match self {
DocumentContent::Empty => None,
DocumentContent::Single(item) => {
if index == 0 {
Some(item)
} else {
None
}
}
DocumentContent::Constants(items) => items.get_mut(index),
DocumentContent::OverloadedFunctions(items) => items.get_mut(index),
}
}

pub fn iter_items(&self) -> ParseItemIter<'_> {
match self {
DocumentContent::Empty => ParseItemIter { next: None, other: None },
DocumentContent::Single(item) => ParseItemIter { next: Some(item), other: None },
DocumentContent::Constants(items) => {
ParseItemIter { next: None, other: Some(items.iter()) }
}
DocumentContent::OverloadedFunctions(items) => {
ParseItemIter { next: None, other: Some(items.iter()) }
}
}
}

pub fn iter_items_mut(&mut self) -> ParseItemIterMut<'_> {
match self {
DocumentContent::Empty => ParseItemIterMut { next: None, other: None },
DocumentContent::Single(item) => ParseItemIterMut { next: Some(item), other: None },
DocumentContent::Constants(items) => {
ParseItemIterMut { next: None, other: Some(items.iter_mut()) }
}
DocumentContent::OverloadedFunctions(items) => {
ParseItemIterMut { next: None, other: Some(items.iter_mut()) }
}
}
}
}

#[derive(Debug)]
pub struct ParseItemIter<'a> {
next: Option<&'a ParseItem>,
other: Option<std::slice::Iter<'a, ParseItem>>,
}

impl<'a> Iterator for ParseItemIter<'a> {
type Item = &'a ParseItem;

fn next(&mut self) -> Option<Self::Item> {
if let Some(next) = self.next.take() {
return Some(next)
}
if let Some(other) = self.other.as_mut() {
return other.next()
}

None
}
}

#[derive(Debug)]
pub struct ParseItemIterMut<'a> {
next: Option<&'a mut ParseItem>,
other: Option<IterMut<'a, ParseItem>>,
}

impl<'a> Iterator for ParseItemIterMut<'a> {
type Item = &'a mut ParseItem;

fn next(&mut self) -> Option<Self::Item> {
if let Some(next) = self.next.take() {
return Some(next)
}
if let Some(other) = self.other.as_mut() {
return other.next()
}

None
}
}

/// Read the preprocessor output variant from document context.
/// Returns [None] if there is no output.
macro_rules! read_context {
Expand Down
Loading

0 comments on commit 8be2649

Please sign in to comment.