diff options
| author | Laurenz <laurmaedje@gmail.com> | 2024-01-12 14:36:41 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2024-01-12 14:43:42 +0100 |
| commit | 37249c20f793689b523cbb379f30b37466ca51b9 (patch) | |
| tree | e1af42115de7685c43eee109d7f86ef0e69979e6 /crates/typst-macros/src | |
| parent | 1834ebc52918754dee51afffd8b55e82613eb687 (diff) | |
Autogenerate default cast in`#[ty]` unless `cast` is specified
Diffstat (limited to 'crates/typst-macros/src')
| -rw-r--r-- | crates/typst-macros/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/typst-macros/src/ty.rs | 34 | ||||
| -rw-r--r-- | crates/typst-macros/src/util.rs | 1 |
3 files changed, 20 insertions, 17 deletions
diff --git a/crates/typst-macros/src/lib.rs b/crates/typst-macros/src/lib.rs index 8ca7bcac..a9185a9b 100644 --- a/crates/typst-macros/src/lib.rs +++ b/crates/typst-macros/src/lib.rs @@ -116,6 +116,8 @@ pub fn func(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream { /// You can customize some properties of the resulting type: /// - `scope`: Indicates that the type has an associated scope defined by the /// `#[scope]` macro +/// - `cast`: Indicates that the type has a custom `cast!` implementation. +/// The macro will then not autogenerate one. /// - `name`: The type's normal name (e.g. `str`). Defaults to the Rust name in /// kebab-case. /// - `title`: The type's title case name (e.g. `String`). Defaults to the diff --git a/crates/typst-macros/src/ty.rs b/crates/typst-macros/src/ty.rs index 23f818bd..943bd453 100644 --- a/crates/typst-macros/src/ty.rs +++ b/crates/typst-macros/src/ty.rs @@ -28,18 +28,18 @@ pub fn ty(stream: TokenStream, item: syn::Item) -> Result<TokenStream> { /// Holds all relevant parsed data about a type. struct Type { + meta: Meta, ident: Ident, name: String, long: String, - scope: bool, title: String, docs: String, - keywords: Vec<String>, } /// The `..` in `#[ty(..)]`. struct Meta { scope: bool, + cast: bool, name: Option<String>, title: Option<String>, keywords: Vec<String>, @@ -49,6 +49,7 @@ impl Parse for Meta { fn parse(input: ParseStream) -> Result<Self> { Ok(Self { scope: parse_flag::<kw::scope>(input)?, + cast: parse_flag::<kw::cast>(input)?, name: parse_string::<kw::name>(input)?, title: parse_string::<kw::title>(input)?, keywords: parse_string_array::<kw::keywords>(input)?, @@ -59,37 +60,35 @@ impl Parse for Meta { /// Parse details about the type from its definition. fn parse(meta: Meta, ident: Ident, attrs: &[Attribute]) -> Result<Type> { let docs = documentation(attrs); - let (name, title) = determine_name_and_title(meta.name, meta.title, &ident, None)?; + let (name, title) = + determine_name_and_title(meta.name.clone(), meta.title.clone(), &ident, None)?; let long = title.to_lowercase(); - Ok(Type { - ident, - name, - long, - scope: meta.scope, - keywords: meta.keywords, - title, - docs, - }) + Ok(Type { meta, ident, name, long, title, docs }) } /// Produce the output of the macro. fn create(ty: &Type, item: Option<&syn::Item>) -> TokenStream { - let Type { - ident, name, long, title, docs, keywords, scope, .. - } = ty; + let Type { ident, name, long, title, docs, meta, .. } = ty; + let Meta { keywords, .. } = meta; - let constructor = if *scope { + let constructor = if meta.scope { quote! { <#ident as #foundations::NativeScope>::constructor() } } else { quote! { None } }; - let scope = if *scope { + let scope = if meta.scope { quote! { <#ident as #foundations::NativeScope>::scope() } } else { quote! { #foundations::Scope::new() } }; + let cast = (!meta.cast).then(|| { + quote! { + #foundations::cast! { type #ident, } + } + }); + let data = quote! { #foundations::NativeTypeData { name: #name, @@ -104,6 +103,7 @@ fn create(ty: &Type, item: Option<&syn::Item>) -> TokenStream { quote! { #item + #cast impl #foundations::NativeType for #ident { const NAME: &'static str = #name; diff --git a/crates/typst-macros/src/util.rs b/crates/typst-macros/src/util.rs index 4f7cc5fb..89880db1 100644 --- a/crates/typst-macros/src/util.rs +++ b/crates/typst-macros/src/util.rs @@ -255,6 +255,7 @@ pub mod kw { syn::custom_keyword!(span); syn::custom_keyword!(title); syn::custom_keyword!(scope); + syn::custom_keyword!(cast); syn::custom_keyword!(constructor); syn::custom_keyword!(keywords); syn::custom_keyword!(parent); |
