use thiserror::Error;
pub mod basic_url;
pub mod boolean;
pub mod custom;
pub mod exact_string;
pub mod faux_url;
pub mod integer;
pub mod none;
pub mod text;
pub use basic_url::BasicUrlGrammar;
pub use boolean::BooleanGrammar;
pub use custom::CustomGrammar;
pub use exact_string::ExactStringGrammar;
pub use faux_url::FauxUrlGrammar;
pub use integer::IntegerGrammar;
pub use none::NoneGrammar;
pub use text::sentences::SentencesGrammar;
pub use text::text_grammar::TextGrammar;
pub use text::text_list::TextListGrammar;
pub use text::words::WordsGrammar;
#[derive(Clone, PartialEq)]
pub enum Grammar {
Boolean(BooleanGrammar),
Integer(IntegerGrammar),
Text(TextGrammar),
Sentences(SentencesGrammar),
Words(WordsGrammar),
TextList(TextListGrammar),
BasicUrl(BasicUrlGrammar),
ExactString(ExactStringGrammar),
FauxUrl(FauxUrlGrammar),
NoneGrammar(NoneGrammar),
Custom(CustomGrammar),
}
macro_rules! grammar_default {
($enum_name:ident {
$($variant:ident => $fn_name:ident: $inner_type:ident),* $(,)?
}) => {
impl $enum_name {
$(
pub fn $fn_name() -> $inner_type {
$inner_type::default()
}
)*
pub fn grammar_string(&self) -> String {
match self {
$(
$enum_name::$variant(grammar) => grammar.grammar_string(),
)*
}
}
pub fn validate_clean(&self, content: &str) -> Result<String, GrammarError> {
match self {
$(
$enum_name::$variant(grammar) => grammar.validate_clean(content),
)*
}
}
pub fn set_stop_word_done<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self {
match self {
$(
$enum_name::$variant(grammar) => {
if grammar.stop_word_done.as_deref() != Some(stop_word.as_ref()) {
grammar.stop_word_done = Some(stop_word.as_ref().to_owned());
}
self
}
)*
}
}
pub fn set_stop_word_no_result<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self {
match self {
$(
$enum_name::$variant(grammar) => {
if grammar.stop_word_no_result.as_deref() != Some(stop_word.as_ref()) {
grammar.stop_word_no_result = Some(stop_word.as_ref().to_owned());
}
self
}
)*
}
}
}
};
}
grammar_default! {
Grammar {
Boolean => boolean: BooleanGrammar,
Integer => integer: IntegerGrammar,
Text => text: TextGrammar,
Sentences => sentences: SentencesGrammar,
Words => words: WordsGrammar,
TextList => text_list: TextListGrammar,
BasicUrl => basic_url: BasicUrlGrammar,
ExactString => exact_string: ExactStringGrammar,
FauxUrl => faux_url: FauxUrlGrammar,
NoneGrammar => none: NoneGrammar,
Custom => custom: CustomGrammar,
}
}
impl Default for Grammar {
fn default() -> Self {
Grammar::Text(TextGrammar::default())
}
}
pub trait GrammarSetterTrait {
fn stop_word_done_mut(&mut self) -> &mut Option<String>;
fn stop_word_no_result_mut(&mut self) -> &mut Option<String>;
fn set_stop_word_done<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self
where
Self: Sized,
{
if self.stop_word_done_mut().as_deref() != Some(stop_word.as_ref()) {
*self.stop_word_done_mut() = Some(stop_word.as_ref().to_owned());
}
self
}
fn set_stop_word_no_result<T: AsRef<str>>(&mut self, stop_word: T) -> &mut Self
where
Self: Sized,
{
if self.stop_word_no_result_mut().as_deref() != Some(stop_word.as_ref()) {
*self.stop_word_no_result_mut() = Some(stop_word.as_ref().to_owned());
}
self
}
}
#[derive(Error, Debug, PartialEq)]
pub enum GrammarError {
#[error("grammar not set")]
GrammarNotSet,
#[error("response ({response}) lacks the correct prefix for given grammar ({correct_prefix})")]
PrefixIncorrect {
correct_prefix: String,
response: String,
},
#[error("failed to parse response_content ({content}) as type ({parse_type})")]
ParseValueError { content: String, parse_type: String },
#[error("incorrect destructuring function ({function}) for grammar type ({grammar_type})")]
DestructuringIncorrect {
function: String,
grammar_type: String,
},
}