Skip to main content

ratex_parser/functions/
char_cmd.rs

1use std::collections::HashMap;
2
3use crate::error::{ParseError, ParseResult};
4use crate::functions::{define_function_full, FunctionContext, FunctionSpec};
5use crate::parse_node::ParseNode;
6
7pub fn register(map: &mut HashMap<&'static str, FunctionSpec>) {
8    define_function_full(
9        map,
10        &["\\@char"],
11        "textord",
12        1, 0, None,
13        false, true, true, false, false,
14        handle_at_char,
15    );
16}
17
18fn handle_at_char(
19    ctx: &mut FunctionContext,
20    args: Vec<ParseNode>,
21    _opt_args: Vec<Option<ParseNode>>,
22) -> ParseResult<ParseNode> {
23    let arg = args.into_iter().next().unwrap();
24    let body = ParseNode::ord_argument(arg);
25
26    let mut number_str = String::new();
27    for node in &body {
28        if let Some(text) = node.symbol_text() {
29            number_str.push_str(text);
30        }
31    }
32
33    let code: u32 = number_str
34        .parse()
35        .map_err(|_| ParseError::msg(format!("\\@char has non-numeric argument {}", number_str)))?;
36
37    let text = char::from_u32(code)
38        .ok_or_else(|| ParseError::msg(format!("\\@char with invalid code point {}", code)))?
39        .to_string();
40
41    Ok(ParseNode::TextOrd {
42        mode: ctx.parser.mode,
43        text,
44        loc: None,
45    })
46}