kalosm_sample/structured_parser/
word.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::{CreateParserState, Parse, SendCreateParserState};
4use crate::{ParseStatus, Parser, StringParser};
5
6#[derive(Clone, Debug)]
7/// A single word.
8pub struct Word<const MIN_LENGTH: usize = 1, const MAX_LENGTH: usize = 20>(pub String);
9
10impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Word<MIN_LENGTH, MAX_LENGTH> {
11    /// Create a new word.
12    pub fn new(word: String) -> Self {
13        assert!(word.len() >= MIN_LENGTH);
14        assert!(word.len() <= MAX_LENGTH);
15        Self(word)
16    }
17}
18
19impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> From<Word<MIN_LENGTH, MAX_LENGTH>>
20    for String
21{
22    fn from(word: Word<MIN_LENGTH, MAX_LENGTH>) -> Self {
23        word.0
24    }
25}
26
27impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> From<String>
28    for Word<MIN_LENGTH, MAX_LENGTH>
29{
30    fn from(word: String) -> Self {
31        Self(word)
32    }
33}
34
35impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Deref for Word<MIN_LENGTH, MAX_LENGTH> {
36    type Target = String;
37
38    fn deref(&self) -> &Self::Target {
39        &self.0
40    }
41}
42
43impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> DerefMut for Word<MIN_LENGTH, MAX_LENGTH> {
44    fn deref_mut(&mut self) -> &mut Self::Target {
45        &mut self.0
46    }
47}
48
49/// A parser for a word.
50pub struct WordParser<const MIN_LENGTH: usize = 1, const MAX_LENGTH: usize = 20> {
51    parser: StringParser<fn(char) -> bool>,
52}
53
54impl WordParser {
55    /// Create a new default word parser
56    pub fn new() -> Self {
57        Self::default()
58    }
59}
60
61impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Default
62    for WordParser<MIN_LENGTH, MAX_LENGTH>
63{
64    fn default() -> Self {
65        Self {
66            parser: StringParser::new(MIN_LENGTH..=MAX_LENGTH)
67                .with_allowed_characters(|c| c.is_ascii_alphanumeric()),
68        }
69    }
70}
71
72impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> CreateParserState
73    for WordParser<MIN_LENGTH, MAX_LENGTH>
74{
75    fn create_parser_state(&self) -> <Self as Parser>::PartialState {
76        self.parser.create_parser_state()
77    }
78}
79
80impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Parser
81    for WordParser<MIN_LENGTH, MAX_LENGTH>
82{
83    type Output = Word<MIN_LENGTH, MAX_LENGTH>;
84    type PartialState = <StringParser<fn(char) -> bool> as Parser>::PartialState;
85
86    fn parse<'a>(
87        &self,
88        state: &Self::PartialState,
89        input: &'a [u8],
90    ) -> crate::ParseResult<ParseStatus<'a, Self::PartialState, Self::Output>> {
91        self.parser
92            .parse(state, input)
93            .map(|result| result.map(Into::into))
94    }
95}
96
97impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Parse for Word<MIN_LENGTH, MAX_LENGTH> {
98    fn new_parser() -> impl SendCreateParserState<Output = Self> {
99        WordParser::default()
100    }
101}