Skip to content

Instantly share code, notes, and snippets.

@elycruz
Created June 16, 2024 01:06
Show Gist options
  • Save elycruz/6ce26a5365042ee4a966f86dd4760709 to your computer and use it in GitHub Desktop.
Save elycruz/6ce26a5365042ee4a966f86dd4760709 to your computer and use it in GitHub Desktop.
Rust validators idea
/**
* Objective: Create constraint validation error reporting types, and/or, structs to
* be used by constraint validation types.
*/
use std::collections::{HashSet, HashMap};
use std::fmt;
use std::fmt::Debug;
use std::fmt::Display;
use std::error::Error;
type ViolationMessage = String;
#[derive(Debug)]
pub enum ViolationType {
CustomError,
PatternMismatch,
RangeOverflow,
RangeUnderflow,
StepMismatch,
TooLong,
TooShort,
NotEqual,
TypeMismatch,
ValueMissing,
}
#[derive(Debug)]
pub struct Violation (ViolationType, ViolationMessage);
/// Note: Provides `ToString` (`to_string()`) for free.
impl Display for Violation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.1)
}
}
pub enum ValidationErrType {
Struct(HashMap<Box<str>, ValidationErrType>),
Collection(HashMap<Box<str>, ValidationErrType>),
Field(Vec<Violation>),
Other(Box<dyn Error>),
}
pub type ValidationResult = Result<(), ValidationErrType>;
pub trait Validate<T: Copy> {
fn validate(x: T) -> ValidationResult;
}
pub trait ValidateOption<T: Copy> {
fn validate(x: Option<T>) -> ValidationResult;
}
pub trait ValidateRef<T: ?Sized> {
fn validate(x: &T) -> ValidationResult;
}
pub trait ValidateRefOption<T: ?Sized> {
fn validate(x: Option<&T>) -> ValidationResult;
}
pub trait Filter<T> {
fn filter(x: T) -> T;
}
pub trait Validator<T: Copy>: Fn(T) -> ValidationResult {}
pub trait ValidatorForRef<T: ?Sized>: Fn(&T) -> ValidationResult {}
#[cfg(test)]
mod test {
use super::*;
use super::ViolationType::{ValueMissing};
#[test]
fn test_violation_to_string() {
let v = Violation(ValueMissing, "value is missing.".to_string());
assert_eq!(&v.to_string(), "value is missing.");
}
#[test]
fn test_violation_debug() {
let v = Violation(ValueMissing, "value is missing.".to_string());
assert_eq!(format!("{:?}", v), "Violation(ValueMissing, \"value is missing.\")");
}
#[test]
fn test_violation_display() {
let v = Violation(ValueMissing, "value is missing.".to_string());
assert_eq!(format!("{:}", v), "value is missing.");
}
#[test]
fn test_validation_err_type() {
let mut struct_errs = HashMap::<Box<str>, ValidationErrType>::new();
struct_errs.insert("hello".into(), ValidationErrType::Field(vec![]));
let _ = ValidationErrType::Struct(struct_errs);
let _ = ValidationErrType::Collection(HashMap::new());
let _ = ValidationErrType::Field(vec![Violation(ValueMissing, "Value missing".to_string())]);
let _ = ValidationErrType::Other(Box::new(std::io::Error::new(std::io::ErrorKind::Other, "Some error occurred")));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment