diff options
| author | Sébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com> | 2023-11-27 11:37:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-27 11:37:30 +0100 |
| commit | 0fbb1aaaaa04d93ae478df6dc268ab8fb13e2bf2 (patch) | |
| tree | 81fca9a9e811fefba4763989766ddfc600302470 /crates/typst-macros | |
| parent | e36a18b99135a96bbddbaea33a2116977d04e318 (diff) | |
Optimize `Content::has`, `Introspector::query_label`, and `MetaElem` (#2759)
Diffstat (limited to 'crates/typst-macros')
| -rw-r--r-- | crates/typst-macros/src/elem.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/crates/typst-macros/src/elem.rs b/crates/typst-macros/src/elem.rs index acb73ba5..e0306b70 100644 --- a/crates/typst-macros/src/elem.rs +++ b/crates/typst-macros/src/elem.rs @@ -738,6 +738,27 @@ fn create_native_elem_impl(element: &Elem) -> TokenStream { } }); + // Fields that can be checked using the `has` method. + let field_has_matches = element.visible_fields().map(|field| { + let elem = &element.ident; + let name = &field.enum_ident; + let field_ident = &field.ident; + + if field.ghost { + quote! { + <#elem as #foundations::ElementFields>::Fields::#name => false, + } + } else if field.inherent() { + quote! { + <#elem as #foundations::ElementFields>::Fields::#name => true, + } + } else { + quote! { + <#elem as #foundations::ElementFields>::Fields::#name => self.#field_ident.is_some(), + } + } + }); + // Fields that can be set using the `set_field` method. let field_set_matches = element .visible_fields() @@ -888,6 +909,10 @@ fn create_native_elem_impl(element: &Elem) -> TokenStream { }) .unwrap_or_else(|| quote! { None }); + let label_has_field = element + .unless_capability("Unlabellable", || quote! { self.label().is_some() }) + .unwrap_or_else(|| quote! { false }); + let mark_prepared = element .unless_capability("Unlabellable", || quote! { self.prepared = true; }) .unwrap_or_else(|| quote! {}); @@ -1026,6 +1051,18 @@ fn create_native_elem_impl(element: &Elem) -> TokenStream { } } + fn has(&self, id: u8) -> bool { + let Ok(id) = <#ident as #foundations::ElementFields>::Fields::try_from(id) else { + return false; + }; + + match id { + <#ident as #foundations::ElementFields>::Fields::Label => #label_has_field, + #(#field_has_matches)* + _ => false, + } + } + fn fields(&self) -> #foundations::Dict { let mut fields = #foundations::Dict::new(); #(#field_dict)* |
