1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! Parsing of relations (<, = and >)
//!
//! A relation is defined on p209 of the TeXBook to be a character token with
//! catcode 12 (other) and value <, = or >.

use crate::traits::*;
use crate::{error, token, types, vm};
use std::cmp::Ordering;

impl<S: TexlangState> Parsable<S> for Ordering {
    fn parse_impl(input: &mut vm::ExpandedStream<S>) -> Result<Self, Box<error::Error>> {
        get_required_element![
            input,
            "a relation",
            format!["a relation is a token with character code {} and one of the following values: <, =, >", types::CatCode::Other],
            token::Value::Other('<') => Ordering::Less,
            token::Value::Other('=') => Ordering::Equal,
            token::Value::Other('>') => Ordering::Greater,
        ]
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::parse::testing::*;

    parse_success_tests![
        (less_than, r"<a", Ordering::Less),
        (equals, r"=a", Ordering::Equal),
        (greater_than, r">a", Ordering::Greater),
    ];

    #[derive(Default)]
    struct State;

    impl TexlangState for State {
        fn cat_code(&self, c: char) -> types::CatCode {
            if c == '<' {
                return types::CatCode::Letter;
            }
            types::CatCode::PLAIN_TEX_DEFAULTS
                .get(c as usize)
                .copied()
                .unwrap_or_default()
        }
    }

    parse_failure_tests![
        Ordering,
        State,
        (empty_input, ""),
        (letter, "a"),
        (control_sequence, r"\A"),
        (incorrect_catcode, "<"),
    ];
}