nom_gcode/
parse_command.rs

1use nom::{
2    IResult,
3    combinator::*,
4    sequence::*,
5    character::complete::{self as character, *},
6    Err,
7    error::ErrorKind,
8};
9
10use super::{
11    GCode,
12    G,
13    M,
14    P,
15    T,
16    O,
17};
18
19// #[inline(always)]
20pub fn parse_command<'r>(input: &'r str) -> IResult<&'r str, GCode<'r>> {
21    map_res(
22        tuple((
23            // Line Number
24            opt(delimited(char('N'), character::u32, space1)),
25            // Mnemonic
26            one_of("GMPTO"),
27            // Major Version
28            character::u32,
29            opt(preceded(char('.'), character::u32))
30        )),
31        |values| {
32            let (line_number, mnemonic, major, minor) = values;
33
34            let mnemonic = match mnemonic.to_ascii_uppercase() {
35                'G' => G,
36                'M' => M,
37                'P' => P,
38                'T' => T,
39                'O' => O,
40                _ => {
41                    return Err(Err::Error(("Invalid Mnemonic", ErrorKind::MapRes)))
42                },
43            };
44
45            let gcode = GCode {
46                line_number,
47                mnemonic,
48                major,
49                minor: minor.unwrap_or(0),
50                args_or_comments: None,
51            };
52
53            Ok(gcode)
54        },
55    )(input)
56}