Repository: typst/typst
File: crates/typst-macros/src/scope.rs (Rust)

Code before:
        Some(ident_ext) => rewrite_primitive_base(&item, ident_ext),
    };

    Ok(quote! {
        #base

        impl #foundations::NativeScope for #self_ty {
            fn constructor() -> ::std::option::Option<&'static #foundations::NativeFuncData> {
                #constructor
            }

            #[allow(deprecated)]
            fn scope() -> #foundations::Scope {
                let mut scope = #foundations::Scope::deduplicating();
                #(#definitions;)*
                scope
            }
        }
    })
}

/// Process a const item and returns its definition.
fn handle_const(self_ty: &TokenStream, item: &syn::ImplItemConst) -> Result<TokenStream> {
    let ident = &item.ident;
    let name = ident.to_string().to_kebab_case();
    Ok(quote! { scope.define(#name, #self_ty::#ident) })
}

/// Process a type item.
fn handle_type_or_elem(item: &BareType) -> Result<TokenStream> {
    let ident = &item.ident;
    let define = if item.attrs.iter().any(|attr| attr.path().is_ident("elem")) {
        quote! { define_elem }
    } else {
        quote! { define_type }
    };
    Ok(quote! { scope.#define::<#ident>() })
}

/// Process a function, return its definition, and register it as a constructor
/// if applicable.
fn handle_fn(self_ty: &syn::Type, item: &mut syn::ImplItemFn) -> Result<FnKind> {
    let Some(attr) = item.attrs.iter_mut().find(|attr| attr.meta.path().is_ident("func"))
    else {
        bail!(item, "scope function is missing #[func] attribute");
    };

    let ident_data = quote::format_ident!("{}_data", item.sig.ident);

    match &mut attr.meta {
        syn::Meta::Path(_) => {

Review comment (suggestion):
```suggestion
    /// Whether this scope should be implemented through an extension
```

or

```suggestion
    /// Whether the scope should be implemented through an extension
```

Code after:
    let base = match &primitive_ident_ext {
        None => quote! { #item },
        Some(ident_ext) => rewrite_primitive_base(&item, ident_ext),
    };

    Ok(quote! {
        #base

        impl #foundations::NativeScope for #self_ty {
            fn constructor() -> ::std::option::Option<&'static #foundations::NativeFuncData> {
                #constructor
            }

            #[allow(deprecated)]
            fn scope() -> #foundations::Scope {
                let mut scope = #foundations::Scope::deduplicating();
                #(#definitions;)*
                scope
            }
        }
    })
}

/// The `..` in `#[scope(..)]`.
struct Meta {
    /// Whether this the scope should be implemented through an extension
    /// trait instead of an inherent impl.
    ext: bool,
}

impl Parse for Meta {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(Self { ext: parse_flag::<kw::ext>(input)? })
    }
}

/// Process a const item and returns its definition.
fn handle_const(self_ty: &TokenStream, item: &syn::ImplItemConst) -> Result<TokenStream> {
    let ident = &item.ident;
    let name = ident.to_string().to_kebab_case();
    Ok(quote! { scope.define(#name, #self_ty::#ident) })
}

/// Process a type item.
fn handle_type_or_elem(item: &BareType) -> Result<TokenStream> {
    let ident = &item.ident;
    let define = if item.attrs.iter().any(|attr| attr.path().is_ident("elem")) {
        quote! { define_elem }
    } else {
        quote! { define_type }
    };