Repository: typst/typst
File: crates/typst-syntax/src/lexer.rs (Rust)

Code before:
            }
        } else {
            let len = self
                .s
                .get(start..self.s.string().len())
                .graphemes(true)
                .next()
                .map_or(0, str::len);
            self.s.jump(start + len);
        }
        SyntaxKind::Text
    }
}

/// Math argument list.
impl Lexer<'_> {
    fn math_args(&mut self, start: usize, c: char) -> (SyntaxKind, Option<SyntaxNode>) {
        match c {
            c if self.is_math_named_arg(start, c) => (SyntaxKind::Ident, None),
            '.' if self.is_math_spread_arg() => (SyntaxKind::Dots, None),
            _ => self.math(start, c),
        }
    }

    /// Handle named arguments in math function call.
    fn is_math_named_arg(&mut self, start: usize, c: char) -> bool {
        let cursor = self.s.cursor();
        if !is_id_start(c) {
            return false;
        }
        self.s.eat_while(is_id_continue);

        // Identifier is just `_`, and so invalid.
        if self.s.from(start) == "_" {
            return false;
        }

        // Check that a colon directly proceeds the identifier.
        if self.s.at(':') {
            true
        } else {
            self.s.jump(cursor);
            false
        }
    }

    /// Handle spread arguments in math function call.
    fn is_math_spread_arg(&mut self) -> bool {
        let cursor = self.s.cursor();
        if !self.s.eat_if('.') {
            return false;

Review comment (suggestion):
You can write this a lot shorterif you swap the boolean conditions  on the if-statements (e.g. `!is_id_start() -> is_id_start()`) and just `return true` in one spot.

Code after:
                .map_or(0, str::len);
            self.s.jump(start + len);
        }
        SyntaxKind::Text
    }

    /// Handle named arguments in math function call.
    pub fn maybe_math_named_arg(&mut self, start: usize) -> Option<SyntaxNode> {
        let cursor = self.s.cursor();
        self.s.jump(start);
        if self.s.eat_if(is_id_start) {
            self.s.eat_while(is_id_continue);
            // Check that a colon directly follows the identifier, and not the
            // `:=` or `::=` math shorthands.
            if self.s.at(':') && !self.s.at(":=") && !self.s.at("::=") {
                // Check that the identifier is not just `_`.
                let node = if self.s.from(start) != "_" {
                    SyntaxNode::leaf(SyntaxKind::Ident, self.s.from(start))
                } else {
                    let msg = SyntaxError::new("expected identifier, found underscore");
                    SyntaxNode::error(msg, self.s.from(start))
                };
                return Some(node);
            }
        }
        self.s.jump(cursor);
        None
    }

    /// Handle spread arguments in math function call.
    pub fn maybe_math_spread_arg(&mut self, start: usize) -> Option<SyntaxNode> {
        let cursor = self.s.cursor();
        self.s.jump(start);
        if self.s.eat_if("..") {
            // Check that neither a space nor a dot follows the spread syntax.
            // A dot would clash with the `...` math shorthand.
            if !self.space_or_end() && !self.s.at('.') {
                let node = SyntaxNode::leaf(SyntaxKind::Dots, self.s.from(start));
                return Some(node);
            }
        }
        self.s.jump(cursor);
        None
    }
}

/// Code.
impl Lexer<'_> {
    fn code(&mut self, start: usize, c: char) -> SyntaxKind {
        match c {
            '<' if self.s.at(is_id_continue) => self.label(),