use crate::entropy::Entropy;
use crate::prelude::*;
#[derive(Builder, Debug)]
#[builder(pattern = "owned")]
pub struct Scheme {
word_set_provider: Box<dyn WordSetProvider>,
word_stylers: Vec<Box<dyn WordStyler>>,
phrase_builder: Box<dyn PhraseBuilder>,
phrase_stylers: Vec<Box<dyn PhraseStyler>>,
}
impl Scheme {
pub fn new(
word_set_provider: Box<dyn WordSetProvider>,
word_stylers: Vec<Box<dyn WordStyler>>,
phrase_builder: Box<dyn PhraseBuilder>,
phrase_stylers: Vec<Box<dyn PhraseStyler>>,
) -> Self {
Self {
word_set_provider,
word_stylers,
phrase_builder,
phrase_stylers,
}
}
pub fn from<S: ToScheme>(config: &S) -> Self {
config.to_scheme()
}
pub fn build() -> SchemeBuilder {
SchemeBuilder::default()
}
pub fn generate(&self) -> String {
let mut words = self.word_set_provider.words();
for p in &self.word_stylers {
words = words.into_iter().map(|w| p.style_word(w)).collect();
}
let mut phrase = self.phrase_builder.build_phrase(words);
for p in &self.phrase_stylers {
phrase = p.style_phrase(phrase);
}
phrase
}
pub fn entropy(&self) -> Entropy {
self.word_set_provider.entropy()
+ self
.word_stylers
.iter()
.map(|p| p.entropy())
.sum::<Entropy>()
+ self.phrase_builder.entropy()
+ self
.phrase_stylers
.iter()
.map(|p| p.entropy())
.sum::<Entropy>()
}
}
impl Iterator for Scheme {
type Item = String;
fn next(&mut self) -> Option<String> {
Some(self.generate())
}
}
impl SchemeBuilder {
pub fn add_word_styler(mut self, styler: Box<dyn WordStyler>) -> Self {
match self.word_stylers {
Some(ref mut stylers) => stylers.push(styler),
None => self.word_stylers = Some(vec![styler]),
}
self
}
pub fn add_phrase_styler(mut self, styler: Box<dyn PhraseStyler>) -> Self {
match self.phrase_stylers {
Some(ref mut stylers) => stylers.push(styler),
None => self.phrase_stylers = Some(vec![styler]),
}
self
}
}
pub trait ToScheme {
fn to_scheme(&self) -> Scheme;
}