Skip to content

Commit

Permalink
feat(validatron): experimental support for collections in dsl
Browse files Browse the repository at this point in the history
  • Loading branch information
banditopazzo committed Jan 19, 2023
1 parent 93162a0 commit 60f071c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
4 changes: 4 additions & 0 deletions validatron/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ pub enum ValidatronError {
FieldValueParseError(String),
#[error("Operator {0} not allowed on type {1}")]
OperatorNotAllowedOnType(Operator, String),
#[error("Type not primitive, can't parse {0}")]
TypeNotPrimitive(String),
#[error("Collection field {0} is not primitive")]
CollectionFieldNotPrimitive(String),
}
36 changes: 26 additions & 10 deletions validatron/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,17 @@ pub enum ValidatronType<T: 'static> {
Collection(
Box<
dyn Fn(
&Field,
// &Field,
Operator,
&str,
) -> Result<compiler::ValidatedCondition<T>, ValidatronError>,
) -> Result<Box<dyn Fn(&T) -> bool + Send + Sync>, ValidatronError>,
>,
),
}

pub fn process_struct<F, T, S>(
field_compare: &Field,
field_access_fn: F,

op: Operator,
value: &str,
) -> Result<Box<dyn Fn(&S) -> bool + Send + Sync>, ValidatronError>
Expand Down Expand Up @@ -198,14 +197,31 @@ where
})))
}
},
crate::ValidatronType::Collection(..) => match field_compare {
Field::Simple(_) => {
// TODO:
todo!()
crate::ValidatronType::Collection(validate_fn) => match field_compare {
Field::Simple(field_compare_name) => {
if field_compare_name != field_name {
return None;
}
let validated_field_fn = match validate_fn(op, value) {
Ok(vcond) => vcond,
Err(ValidatronError::TypeNotPrimitive(_)) => {
return Some(Err(ValidatronError::CollectionFieldNotPrimitive(
field_name.to_string(),
)))
}
Err(err) => return Some(Err(err)),
};
Some(Ok(Box::new(move |s| {
field_access_fn(s)
.map(|f| validated_field_fn(f))
.unwrap_or(false)
})))
}
Field::Struct { .. } => {
// TODO:
todo!()
Field::Struct { name, .. } => {
if name != field_name {
return None;
}
Some(Err(ValidatronError::FieldNotStruct(field_name.to_string())))
}
},
}
Expand Down
24 changes: 20 additions & 4 deletions validatron/src/trait_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,27 @@ impl ValidatronTypeProvider for bool {
}
}

impl<T: ValidatronTypeProvider> ValidatronTypeProvider for Vec<T> {
impl<T> ValidatronTypeProvider for Vec<T>
where
T: ValidatronTypeProvider + PartialEq + Send + Sync,
{
fn field_type() -> ValidatronType<Self> {
ValidatronType::Collection(Box::new(move |_, _, _| {
// TODO:
todo!()
ValidatronType::Collection(Box::new(move |op, s| {
let ValidatronType::Primitive(p) = T::field_type() else {
return Err(ValidatronError::TypeNotPrimitive(s.to_string()))
};

let parsed = (p.parse_fn)(s)?;

match op {
Operator::Multi(op) => match op {
MultiOperator::Contains => Ok(Box::new(move |v| v.contains(&parsed))),
},
_ => Err(ValidatronError::OperatorNotAllowedOnType(
op,
"vec".to_string(),
)),
}
}))
}
}

0 comments on commit 60f071c

Please sign in to comment.