はじめに

前回、SubsigのModifierをパースした。

Subsigには他にも、Special Subsignature Typesとして色々定義されてるので、一個ずつ見ていく。

Special Subsignature Types

Macro Subsignature

${min-max}MACROID$

というフォーマットです。非常にシンプルで助かる。

コードもこれで良さそう

use nom::{
    IResult,
    character::complete::{char, hex_digit1},
    sequence::{delimited, tuple},
    combinator::map_res,
};
use anyhow::{Result, anyhow};
use std::str::FromStr;

#[derive(Debug, Eq, PartialEq)]
pub struct MacroSubsignature {
    pub min: usize,
    pub max: usize,
    pub macroid: usize
}

impl MacroSubsignature {
    pub fn parse(input: &str) -> Result<MacroSubsignature> {
        match parse_macro(input) {
            Ok((_, (min, max, macroid))) => Ok(MacroSubsignature{min, max, macroid}),
            Err(e) => Err(anyhow!("Can't parse MacroSubsignature: {}", e)),
        }
    }
}

fn parse_usize(input: &str) -> IResult<&str, usize> {
    map_res(hex_digit1, FromStr::from_str)(input)
}

fn parse_macro(input: &str) -> IResult<&str, (usize, usize, usize)> {
    delimited(
        char('$'),
        tuple((
            delimited(char('{'), parse_usize, char('-')),
            parse_usize,
            delimited(char('}'), parse_usize, char('$'))
        )),
        nom::combinator::eof,
    )(input)
}

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

    #[test]
    fn parse_macro_example() {
        let sig = "${6-7}12$";
        let parsed = MacroSubsignature::parse(sig).unwrap();
        assert_eq!(MacroSubsignature{
            min: 6,
            max: 7,
            macroid: 12
        }, parsed);
    }
}

テストケースを増やそうかと思ったけど、main.ldbにもdaily.ldbにも無かった…

思ったより単純だったけど、今回はここまで。

終わりに

この記事はn01e0 Advent Calendar 2024の13日目の記事とします。