texlang_stdlib/
chardef.rs

1//! The `\chardef` primitive.
2use texlang::prelude as txl;
3use texlang::traits::*;
4use texlang::*;
5
6/// Get the `\chardef` command.
7pub fn get_chardef<S: TexlangState>() -> command::BuiltIn<S> {
8    command::BuiltIn::new_execution(chardef_primitive_fn)
9}
10
11fn chardef_primitive_fn<S: TexlangState>(
12    _: token::Token,
13    input: &mut vm::ExecutionInput<S>,
14) -> txl::Result<()> {
15    let scope = TexlangState::variable_assignment_scope_hook(input.state_mut());
16    let (cmd_ref_or, _, c) =
17        <(Option<token::CommandRef>, parse::OptionalEquals, char)>::parse(input)?;
18    if let Some(cmd_ref) = cmd_ref_or {
19        input
20            .commands_map_mut()
21            .insert(cmd_ref, command::Command::Character(c), scope);
22    }
23    Ok(())
24}
25
26#[cfg(test)]
27mod test {
28    use super::*;
29    use crate::the;
30    use std::collections::HashMap;
31    use texlang_testing::*;
32
33    fn built_in_commands() -> HashMap<&'static str, command::BuiltIn<State>> {
34        HashMap::from([
35            ("chardef", get_chardef()),
36            ("the", the::get_the()),
37            ("i", TestingComponent::get_integer()),
38        ])
39    }
40
41    test_suite![
42        expansion_equality_tests(
43            (basic_case, r"\chardef\Hello = `\+ \Hello", "+"),
44            (
45                basic_case_with_the,
46                r"\chardef\Hello = 123 \the\Hello",
47                "123"
48            ),
49            (
50                parsable_as_number,
51                r"\chardef\Hello = 13 \i=\Hello x\the\i",
52                "x13"
53            ),
54            (
55                parsable_as_number_negative,
56                r"\chardef\Hello = 13 \i=-\Hello x\the\i",
57                "x-13"
58            ),
59        ),
60        serde_tests((basic_case, r"\chardef\Hello = `\+ ", r"\Hello"),),
61    ];
62}