You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
inventory-app/src/util/form/field_value.rs

88 lines
2.4 KiB

use std::fmt::Debug;
use crate::util::form::field_error::FieldError;
/**
A sum type that contains a value and possibly an error. Used for form validation.
This isn't exactly like a sum type like Result as even in the error case, we want
to keep the value intact. It can't be just an either/or situation. For instance,
when doing form validation, in most cases, we would want to preserve the value
sent to us through the form, but inform the user of why it was rejected through an
error message.
*/
pub struct FieldValue<Value, Error> {
pub value: Value,
pub error: Option<Error>,
}
pub type StringField = FieldValue<String, FieldError>;
pub type BoolField = FieldValue<bool, FieldError>;
pub type FloatField = FieldValue<f64, FieldError>;
impl<Value, Error> FieldValue<Value, Error>
where Value: Default
{
pub fn new(value: Value) -> Self {
Self { value, error: None }
}
pub fn set_error(&mut self, error: Error) {
self.error = Some(error);
}
pub fn is_error(&self) -> bool {
self.error.is_some()
}
pub fn invalid_if<I>(mut self, is_invalid: I, err: Error ) -> Self
where I: FnOnce(&Value) -> bool {
if is_invalid(&self.value) {
self.set_error(err);
}
self
}
pub fn invalid_if_then<I, E>(mut self, is_invalid: I, err_if: E ) -> Self
where I: FnOnce(&Value) -> bool, E: FnOnce() -> Error {
if is_invalid(&self.value) {
self.set_error(err_if());
}
self
}
pub fn clear_value(mut self) -> Self {
self.value = Default::default();
self
}
pub fn clear_value_if_error(mut self) -> Self {
if self.is_error() { self.clear_value() } else { self }
}
pub fn map<F, V>(self, f: F) -> FieldValue<V, Error>
where F: FnOnce(Value) -> V {
FieldValue::<V, Error> {
value: f(self.value),
error: self.error,
}
}
}
impl<Value, Error> Default for FieldValue<Value, Error>
where Value: Default,
{
fn default() -> Self {
Self::new(Value::default())
}
}
impl<Value, Error> Debug for FieldValue<Value, Error>
where Value: Debug,
Error: Debug {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
fmt.debug_struct("FieldValue")
.field("value", &self.value)
.field("error", &self.error)
.finish()
}
}

Powered by TurnKey Linux.