passgen-rs 0.1.0

Password generator with a regular-expression-like syntax
Documentation
/// Prepare a Pattern for generation.
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)
    }
}