alith_client/components/grammar/
mod.rs

1use thiserror::Error;
2pub mod basic_url;
3pub mod boolean;
4pub mod custom;
5pub mod exact_string;
6pub mod faux_url;
7pub mod integer;
8pub mod none;
9pub mod text;
10
11pub use basic_url::BasicUrlGrammar;
12pub use boolean::BooleanGrammar;
13pub use custom::CustomGrammar;
14pub use exact_string::ExactStringGrammar;
15pub use faux_url::FauxUrlGrammar;
16pub use integer::IntegerGrammar;
17pub use none::NoneGrammar;
18pub use text::sentences::SentencesGrammar;
19pub use text::text_grammar::TextGrammar;
20pub use text::text_list::TextListGrammar;
21pub use text::words::WordsGrammar;
22
23#[derive(Clone, PartialEq)]
24pub enum Grammar {
25    Boolean(BooleanGrammar),
26    Integer(IntegerGrammar),
27    Text(TextGrammar),
28    Sentences(SentencesGrammar),
29    Words(WordsGrammar),
30    TextList(TextListGrammar),
31    BasicUrl(BasicUrlGrammar),
32    ExactString(ExactStringGrammar),
33    FauxUrl(FauxUrlGrammar),
34    NoneGrammar(NoneGrammar),
35    Custom(CustomGrammar),
36}
37
38macro_rules! grammar_default {
39    ($enum_name:ident {
40        $($variant:ident => $fn_name:ident: $inner_type:ident),* $(,)?
41    }) => {
42        impl $enum_name {
43            $(
44                pub fn $fn_name() -> $inner_type {
45                    $inner_type::default()
46                }
47            )*
48
49            pub fn grammar_string(&self) -> String {
50                match self {
51                    $(
52                        $enum_name::$variant(grammar) => grammar.grammar_string(),
53                    )*
54                }
55            }
56
57            pub fn validate_clean(&self, content: &str) -> Result<String, GrammarError> {
58                match self {
59                    $(
60                        $enum_name::$variant(grammar) => grammar.validate_clean(content),
61                    )*
62                }
63            }
64
65            pub fn set_stop_word_done<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self {
66                match self {
67                    $(
68                        $enum_name::$variant(grammar) => {
69                           if grammar.stop_word_done.as_deref() != Some(stop_word.as_ref()) {
70                               grammar.stop_word_done = Some(stop_word.as_ref().to_owned());
71                            }
72                            self
73                        }
74                    )*
75                }
76            }
77
78            pub fn set_stop_word_no_result<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self {
79                match self {
80                    $(
81                        $enum_name::$variant(grammar) => {
82                           if grammar.stop_word_no_result.as_deref() != Some(stop_word.as_ref()) {
83                               grammar.stop_word_no_result = Some(stop_word.as_ref().to_owned());
84                            }
85                            self
86                        }
87                    )*
88                }
89            }
90        }
91    };
92}
93
94grammar_default! {
95    Grammar {
96        Boolean => boolean: BooleanGrammar,
97        Integer => integer: IntegerGrammar,
98        Text => text: TextGrammar,
99        Sentences => sentences: SentencesGrammar,
100        Words => words: WordsGrammar,
101        TextList => text_list: TextListGrammar,
102        BasicUrl => basic_url: BasicUrlGrammar,
103        ExactString => exact_string: ExactStringGrammar,
104        FauxUrl => faux_url: FauxUrlGrammar,
105        NoneGrammar => none: NoneGrammar,
106        Custom => custom: CustomGrammar,
107    }
108}
109
110impl Default for Grammar {
111    fn default() -> Self {
112        Grammar::Text(TextGrammar::default())
113    }
114}
115
116pub trait GrammarSetterTrait {
117    fn stop_word_done_mut(&mut self) -> &mut Option<String>;
118
119    fn stop_word_no_result_mut(&mut self) -> &mut Option<String>;
120
121    fn set_stop_word_done<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self
122    where
123        Self: Sized,
124    {
125        if self.stop_word_done_mut().as_deref() != Some(stop_word.as_ref()) {
126            *self.stop_word_done_mut() = Some(stop_word.as_ref().to_owned());
127        }
128        self
129    }
130
131    fn set_stop_word_no_result<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self
132    where
133        Self: Sized,
134    {
135        if self.stop_word_no_result_mut().as_deref() != Some(stop_word.as_ref()) {
136            *self.stop_word_no_result_mut() = Some(stop_word.as_ref().to_owned());
137        }
138        self
139    }
140}
141
142#[derive(Error, Debug, PartialEq)]
143pub enum GrammarError {
144    #[error("grammar not set")]
145    GrammarNotSet,
146    #[error("response ({response}) lacks the correct prefix for given grammar ({correct_prefix})")]
147    PrefixIncorrect {
148        correct_prefix: String,
149        response: String,
150    },
151    #[error("failed to parse response_content ({content}) as type ({parse_type})")]
152    ParseValueError { content: String, parse_type: String },
153    #[error("incorrect destructuring function ({function}) for grammar type ({grammar_type})")]
154    DestructuringIncorrect {
155        function: String,
156        grammar_type: String,
157    },
158}