use crate::DEFAULT_INPUT_PATH;
use crate::DEFAULT_OUTPUT_PATH;
use std::io::{Cursor, Read, Write};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub(crate) enum PasswordFeedback {
#[default]
Hide,
Mask(char),
PartialMask(char, usize),
}
pub(crate) enum InputTarget {
FilePath(String),
Reader(Box<dyn std::io::Read>),
}
pub(crate) enum OutputTarget {
FilePath(String),
Writer(Box<dyn std::io::Write>),
Void,
}
pub struct Config {
pub(crate) password_feedback: PasswordFeedback,
pub(crate) input: InputTarget,
pub(crate) output: OutputTarget,
}
pub struct ConfigBuilder {
feedback: PasswordFeedback,
input: InputTarget,
output: OutputTarget,
}
impl Default for ConfigBuilder {
fn default() -> Self {
ConfigBuilder {
feedback: PasswordFeedback::default(),
input: InputTarget::FilePath(DEFAULT_INPUT_PATH.to_string()),
output: OutputTarget::FilePath(DEFAULT_OUTPUT_PATH.to_string()),
}
}
}
impl ConfigBuilder {
pub fn new() -> ConfigBuilder {
ConfigBuilder::default()
}
pub fn password_feedback_mask(self, mask: char) -> ConfigBuilder {
ConfigBuilder {
feedback: PasswordFeedback::Mask(mask),
..self
}
}
pub fn password_feedback_partial_mask(self, mask: char, length: usize) -> ConfigBuilder {
ConfigBuilder {
feedback: PasswordFeedback::PartialMask(mask, length),
..self
}
}
pub fn password_feedback_hide(self) -> ConfigBuilder {
ConfigBuilder {
feedback: PasswordFeedback::Hide,
..self
}
}
pub fn input_file_path(self, file_path: impl Into<String>) -> ConfigBuilder {
ConfigBuilder {
input: InputTarget::FilePath(file_path.into()),
..self
}
}
pub fn input_data(self, data: impl Into<Vec<u8>>) -> ConfigBuilder {
ConfigBuilder {
input: InputTarget::Reader(Box::new(Cursor::new(data.into()))),
..self
}
}
pub fn input_reader(self, reader: impl Read + 'static) -> ConfigBuilder {
ConfigBuilder {
input: InputTarget::Reader(Box::new(reader)),
..self
}
}
pub fn output_file_path(self, file_path: impl Into<String>) -> ConfigBuilder {
ConfigBuilder {
output: OutputTarget::FilePath(file_path.into()),
..self
}
}
pub fn output_writer(self, writer: impl Write + 'static) -> ConfigBuilder {
ConfigBuilder {
output: OutputTarget::Writer(Box::new(writer)),
..self
}
}
pub fn output_discard(self) -> ConfigBuilder {
ConfigBuilder {
output: OutputTarget::Void,
..self
}
}
pub fn build(self) -> Config {
Config {
password_feedback: self.feedback,
input: self.input,
output: self.output,
}
}
}