ClamAVのシグネチャをヒューマンリーダブルな形にパースしたい part6
はじめに
前回、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日目の記事とします。
Comments