use crate::pattern::*;
use crate::Data;
#[derive(thiserror::Error, Debug)]
pub enum Error {}
pub trait Prepare {
type Output;
fn prepare(self, env: &dyn Data) -> Result<Self::Output, Error>;
}
impl Pattern<Optimized> {
pub fn prepare(self, env: &dyn Data) -> Result<Pattern<Prepared>, Error> {
Prepare::prepare(self, env)
}
}
impl Prepare for Pattern<Optimized> {
type Output = Pattern<Prepared>;
fn prepare(self, env: &dyn Data) -> Result<Self::Output, Error> {
let output = match self {
Self::Literal(literal) => Self::Output::Literal(literal.prepare(env)?),
Self::Group(group) => Self::Output::Group(group.prepare(env)?),
Self::Set(set) => Self::Output::Set(set.prepare(env)?),
Self::Special(special) => Self::Output::Special(special.prepare(env)?),
};
Ok(output)
}
}
impl Prepare for Literal<Optimized> {
type Output = Literal<Prepared>;
fn prepare(self, env: &dyn Data) -> Result<Self::Output, Error> {
Ok(Self::Output { value: self.value })
}
}
impl Prepare for Set<Optimized> {
type Output = Set<Prepared>;
fn prepare(self, env: &dyn Data) -> Result<Self::Output, Error> {
Ok(self.into())
}
}
impl Prepare for Segment<Optimized> {
type Output = Segment<Prepared>;
fn prepare(self, env: &dyn Data) -> Result<Self::Output, Error> {
Ok(Self::Output {
items: self
.items
.into_iter()
.map(|i| i.prepare(env))
.collect::<Result<_, _>>()?,
})
}
}
impl Prepare for Item<Optimized> {
type Output = Item<Prepared>;
fn prepare(self, env: &dyn Data) -> Result<Self::Output, Error> {
Ok(Self::Output {
pattern: self.pattern.prepare(env)?,
repeat: self.repeat,
optional: self.optional,
})
}
}
impl Prepare for Group<Optimized> {
type Output = Group<Prepared>;
fn prepare(self, env: &dyn Data) -> Result<Self::Output, Error> {
Ok(Self::Output {
segments: self
.segments
.into_iter()
.map(|s| s.prepare(env))
.collect::<Result<_, _>>()?,
})
}
}
impl Prepare for Special<Optimized> {
type Output = Special<Prepared>;
fn prepare(self, data: &dyn Data) -> Result<Self::Output, Error> {
let result = match &self {
Self::Wordlist(name) => Self::Output::Wordlist(data.wordlist(name).unwrap()),
Self::Markov(name) => Self::Output::Markov(data.markov(name).unwrap()),
_ => todo!(),
};
Ok(result)
}
}