-
Notifications
You must be signed in to change notification settings - Fork 627
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rust docs: have a macro to make link to the Slint doc
- Loading branch information
Showing
14 changed files
with
186 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,18 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 | ||
// Copyright © SixtyFPS GmbH <[email protected]> | ||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 | ||
|
||
// Copyright © SixtyFPS GmbH <[email protected]> | ||
|
||
#![doc = include_str!("README.md")] | ||
#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")] | ||
|
||
extern crate proc_macro; | ||
use proc_macro::TokenStream; | ||
use quote::quote; | ||
|
||
mod slint_doc; | ||
|
||
/// This derive macro is used with structures in the run-time library that are meant | ||
/// to be exposed to the language. The structure is introspected for properties and fields | ||
/// marked with the `rtti_field` attribute and generates run-time type information for use | ||
|
@@ -179,3 +184,26 @@ fn callback_arg(ty: &syn::Type) -> Option<(&syn::Type, Option<&syn::Type>)> { | |
pub fn identity(_attr: TokenStream, item: TokenStream) -> TokenStream { | ||
item | ||
} | ||
|
||
/// To be applied on any item that has documentation comment, it will convert link to `slint:Foo` to the link from the | ||
/// documentation map from link-data.json | ||
#[proc_macro_attribute] | ||
pub fn slint_doc(_attr: TokenStream, item: TokenStream) -> TokenStream { | ||
use syn::visit_mut::VisitMut; | ||
let mut visitor = slint_doc::Visitor::new(); | ||
let mut item = syn::parse_macro_input!(item as syn::Item); | ||
visitor.visit_item_mut(&mut item); | ||
assert!(visitor.1, "No slint link found"); | ||
quote!(#item).into() | ||
} | ||
|
||
/// Same as `slint_doc` but for string literals instead of doc coments (useful for crate level documentation that cannot have an attribute) | ||
#[proc_macro] | ||
pub fn slint_doc_str(input: TokenStream) -> TokenStream { | ||
let input = syn::parse_macro_input!(input as syn::LitStr); | ||
let mut doc = input.value(); | ||
let mut visitor = slint_doc::Visitor::new(); | ||
visitor.process_string(&mut doc); | ||
assert!(visitor.1, "No slint link found"); | ||
quote!(#doc).into() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 | ||
// Copyright © SixtyFPS GmbH <[email protected]> | ||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 | ||
|
||
// Copyright © SixtyFPS GmbH <[email protected]> | ||
|
||
pub struct Visitor(serde_json::Value, pub bool); | ||
|
||
impl syn::visit_mut::VisitMut for Visitor { | ||
fn visit_attribute_mut(&mut self, i: &mut syn::Attribute) { | ||
if i.meta.path().is_ident("doc") { | ||
if let syn::Meta::NameValue(syn::MetaNameValue { | ||
value: syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit), .. }), | ||
.. | ||
}) = &mut i.meta | ||
{ | ||
let mut doc = lit.value(); | ||
self.process_string(&mut doc); | ||
*lit = syn::LitStr::new(&doc, lit.span()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl Visitor { | ||
pub fn new() -> Self { | ||
let link_path = concat!(env!("CARGO_MANIFEST_DIR"), "/link-data.json"); | ||
let link_data = std::fs::read_to_string(link_path).expect("Failed to read link-data.json"); | ||
let link_data: serde_json::Value = | ||
serde_json::from_str(&link_data).expect("Failed to parse link-data.json"); | ||
Self(link_data, false) | ||
} | ||
|
||
pub fn process_string(&mut self, doc: &mut String) { | ||
const NEEDLE: &str = "slint:"; | ||
let mut begin = 0; | ||
// search for all occurrences of "slint:foo" and replace it with the link from link-data.json | ||
while let Some(pos) = doc[begin..].find(NEEDLE).map(|x| x + begin) { | ||
if doc[pos..].starts_with("slint::") { | ||
begin = pos + NEEDLE.len(); | ||
continue; | ||
} | ||
let end = doc[pos + NEEDLE.len()..] | ||
.find([' ', '\n', ']', ')']) | ||
.expect("Failed to find end of link"); | ||
let link = &doc[pos + NEEDLE.len()..][..end]; | ||
let dst = if let Some(rust_link) = link.strip_prefix("rust:") { | ||
format!( | ||
"https://releases.slint.dev/{}/docs/rust/{rust_link}", | ||
env!("CARGO_PKG_VERSION"), | ||
) | ||
} else if let Some(dst) = self.0.get(link) { | ||
let dst = dst | ||
.get("href") | ||
.expect("Missing href in link-data.json") | ||
.as_str() | ||
.expect("invalid string in link-data.json"); | ||
format!("https://releases.slint.dev/{}/docs/slint{dst}", env!("CARGO_PKG_VERSION"),) | ||
} else { | ||
panic!("Unknown link {}", link); | ||
}; | ||
doc.replace_range(pos..pos + NEEDLE.len() + link.len(), &dst); | ||
begin = pos + dst.len(); | ||
self.1 = true; | ||
} | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_slint_doc() { | ||
let mut visitor = Visitor::new(); | ||
|
||
let mut string = r" | ||
Test [SomeLink](slint:index) | ||
Not in a link: slint:index xxx | ||
slint::index is not a link | ||
slint:index is a link | ||
rust link: slint:rust:foobar | ||
" | ||
.to_owned(); | ||
|
||
visitor.process_string(&mut string); | ||
assert!(visitor.1); | ||
assert_eq!( | ||
string, | ||
format!( | ||
r" | ||
Test [SomeLink](https://releases.slint.dev/{0}/docs/slint/) | ||
Not in a link: https://releases.slint.dev/{0}/docs/slint/ xxx | ||
slint::index is not a link | ||
https://releases.slint.dev/{0}/docs/slint/ is a link | ||
rust link: https://releases.slint.dev/{0}/docs/rust/foobar | ||
", | ||
env!("CARGO_PKG_VERSION") | ||
) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters