Repository: typst/typst
File: crates/typst-library/src/math/lr.rs (Rust)

Code before:
    ("⌜", "⌝"),
    ("⌞", "⌟"),
];

/// Lazily created left/right wrapper functions.
static FUNCS: LazyLock<HashMap<&'static str, NativeFuncData>> = LazyLock::new(|| {
    let bump = Box::leak(Box::new(Bump::new()));
    DELIMS
        .iter()
        .copied()
        .map(|(l, r)| (l, create_lr_func_data(l.into(), r.into(), bump)))
        .collect()
});

/// Creates metadata for an accent wrapper function.
fn create_lr_func_data(
    left: EcoString,
    right: EcoString,
    bump: &'static Bump,
) -> NativeFuncData {
    NativeFuncData {
        function: NativeFuncPtr(bump.alloc(
            move |_: &mut Engine, _: Tracked<Context>, args: &mut Args| {
                let size = args.named("size")?;
                let body = args.expect("body")?;
                Ok(delimited(body, left.clone(), right.clone(), size).into_value())
            },
        )),
        name: "(..) => ..",
        title: "",
        docs: "",
        keywords: &[],
        contextual: false,
        scope: LazyLock::new(&|| Scope::new()),
        params: LazyLock::new(&|| create_lr_param_info()),
        returns: LazyLock::new(&|| CastInfo::Type(Type::of::<Content>())),
    }
}

/// Creates parameter signature metadata for an L/R function.
fn create_lr_param_info() -> Vec<ParamInfo> {
    vec![
        ParamInfo {
            name: "size",
            docs: "\
            The size of the brackets, relative to the height of the wrapped content.\n\
            \n\
            Default: The current value of [`lr.size`]($math.lr.size).",
            input: Rel::<Length>::input(),
            default: None,
            positional: false,

Review comment (refactor):
Oh I forgot to clean up the code I copied from the `#[func]` macro, sorry for that.

But do you not need the `args.take().finish()?` part here to prevent the user from passing too many arguments?

Code after:
    ('⧘', '⧙'),
    ('⧚', '⧛'),
    ('⟨', '⟩'),
    ('⧼', '⧽'),
    ('⦑', '⦒'),
    ('⦉', '⦊'),
    ('⟪', '⟫'),
    ('⌜', '⌝'),
    ('⌞', '⌟'),
    // Fences.
    ('|', '|'),
    ('‖', '‖'),
    ('⦀', '⦀'),
    ('⦙', '⦙'),
    ('⦚', '⦚'),
];

/// Lazily created left/right wrapper functions.
static FUNCS: LazyLock<HashMap<char, NativeFuncData>> = LazyLock::new(|| {
    let bump = Box::leak(Box::new(Bump::new()));
    DELIMS
        .iter()
        .copied()
        .map(|(l, r)| (l, create_lr_func_data(l, r, bump)))
        .collect()
});

/// Creates metadata for an L/R wrapper function.
fn create_lr_func_data(left: char, right: char, bump: &'static Bump) -> NativeFuncData {
    let title = bumpalo::format!(in bump, "{}{} Left/Right", left, right).into_bump_str();
    let docs = bumpalo::format!(in bump, "Wraps an expression in {}{}.", left, right)
        .into_bump_str();
    NativeFuncData {
        function: NativeFuncPtr(bump.alloc(
            move |_: &mut Engine, _: Tracked<Context>, args: &mut Args| {
                let size = args.named("size")?;
                let body = args.expect("body")?;
                Ok(delimited(body, left, right, size).into_value())
            },
        )),
        name: "(..) => ..",
        title,
        docs,
        keywords: &[],
        contextual: false,
        scope: LazyLock::new(&|| Scope::new()),
        params: LazyLock::new(&|| create_lr_param_info()),
        returns: LazyLock::new(&|| CastInfo::Type(Type::of::<Content>())),
    }
}