use crate::input::read_input;
use crate::validation::Validator;
use std::fmt::Debug;
use std::str::FromStr;
pub trait FieldTrait {
fn fill(&mut self) -> Result<(), String>;
fn as_any(&self) -> &dyn std::any::Any;
fn get_value(&self) -> Result<String, String>;
}
#[derive(Debug)]
pub struct Field<T> {
pub prompt: String,
pub validator: Option<Validator>,
pub value: Option<T>,
}
impl<T> FieldTrait for Field<T>
where
T: 'static + FromStr + Debug + Clone + Default,
T::Err: Debug,
{
fn fill(&mut self) -> Result<(), String> {
loop {
if let Ok(value) = read_input::<T>(&self.prompt, self.validator.as_ref()) {
self.value = Some(value);
break;
} else {
eprintln!("Invalid input. Please try again.");
}
}
Ok(())
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn get_value(&self) -> Result<String, String> {
self.value
.as_ref()
.ok_or_else(|| "Field has no value".to_string())
.map(|v| format!("{:?}", v))
}
}
impl<T> Field<T>
where
T: 'static + FromStr + Debug + Clone,
T::Err: Debug,
{
pub fn get_value(&self) -> Result<T, String> {
self.value
.as_ref()
.ok_or_else(|| "Field has no value".to_string())
.map(|v| v.clone())
}
}