passgen-rs 0.1.0

Password generator with a regular-expression-like syntax
Documentation
use crate::pattern::Special;
use crate::{Config, Markov, Wordlist};
use std::collections::BTreeMap;
use std::sync::Arc;

pub trait Data {
    fn wordlist(&self, name: &str) -> Option<Arc<Wordlist>> {
        None
    }

    fn markov(&self, name: &str) -> Option<Arc<Markov>> {
        None
    }
}

impl Data for () {}

#[derive(Clone, Debug, Default)]
pub struct DataStore {
    wordlists: BTreeMap<String, Arc<Wordlist>>,
    markov: BTreeMap<String, Arc<Markov>>,
}

impl DataStore {
    pub fn resolve(&mut self, config: &Config, dependency: &Special) -> Result<(), ()> {
        match dependency {
            Special::Wordlist(name) => {
                if self.wordlist(name).is_none() {
                    let path = config.wordlist_path(name).unwrap();
                    let wordlist = Wordlist::load(path).unwrap();
                    self.wordlists.insert(name.clone(), Arc::new(wordlist));
                }
            }
            Special::Markov(name) => {
                if self.markov(name).is_none() {
                    let path = config.wordlist_path(name).unwrap();
                    let markov = Markov::load(path, 2).unwrap();
                    self.markov.insert(name.clone(), Arc::new(markov));
                }
            }
            _ => {}
        }
        Ok(())
    }
}

impl Data for DataStore {
    fn wordlist(&self, name: &str) -> Option<Arc<Wordlist>> {
        self.wordlists.get(name).cloned()
    }

    fn markov(&self, name: &str) -> Option<Arc<Markov>> {
        self.markov.get(name).cloned()
    }
}