Skip to content

Commit

Permalink
feat(validatron): add option field support
Browse files Browse the repository at this point in the history
  • Loading branch information
banditopazzo committed Feb 6, 2024
1 parent c75ab24 commit 1ab991d
Showing 1 changed file with 137 additions and 1 deletion.
138 changes: 137 additions & 1 deletion crates/validatron/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,19 @@ impl<T: Validatron + Send + Sync + 'static> Validatron for Option<T> {
fn get_class() -> ValidatronClass {
Self::class_builder()
.enum_class_builder()
.add_variant_field("Some", "0", Box::new(Option::as_ref))
.add_method0("is_some", Box::new(|c| c.is_some()))
.build()
}
}

#[cfg(test)]
mod test {
use crate::{validator::get_valid_unary_rule, Identifier, MethodCall};
use crate::{
validator::{get_valid_rule, get_valid_unary_rule},
AdtField, Field, Identifier, MethodCall, Operator, RValue, RelationalOperator, SimpleField,
Validatron,
};

#[test]
fn test_option_no_method() {
Expand Down Expand Up @@ -152,4 +157,135 @@ mod test {

assert!(!rule.is_match(&test));
}

#[test]
fn test_option_field_success() {
struct A {
a: i32,
}

impl Validatron for A {
fn get_class() -> crate::ValidatronClass {
Self::class_builder()
.struct_class_builder()
.add_field("a", Box::new(|t| &t.a))
.build()
}
}

let rule = get_valid_rule::<Option<A>>(
vec![
Identifier::Field(Field::Adt(AdtField {
variant_name: "Some".to_string(),
field_name: "0".to_string(),
})),
Identifier::Field(Field::Simple(SimpleField("a".to_string()))),
],
Operator::Relational(RelationalOperator::Equals),
RValue::Value("5".to_string()),
)
.unwrap();

let test = Some(A { a: 5 });

assert!(rule.is_match(&test));
}

#[test]
fn test_option_field_fail() {
struct A {
a: i32,
}

impl Validatron for A {
fn get_class() -> crate::ValidatronClass {
Self::class_builder()
.struct_class_builder()
.add_field("a", Box::new(|t| &t.a))
.build()
}
}

let rule = get_valid_rule::<Option<A>>(
vec![
Identifier::Field(Field::Adt(AdtField {
variant_name: "Some".to_string(),
field_name: "0".to_string(),
})),
Identifier::Field(Field::Simple(SimpleField("a".to_string()))),
],
Operator::Relational(RelationalOperator::Equals),
RValue::Value("5".to_string()),
)
.unwrap();

let test = None;

assert!(!rule.is_match(&test));
}

#[test]
fn test_option_field_nested_success() {
struct A {
b: Option<B>,
}

struct B {
c: C,
}

struct C {
inner: i32,
}

impl Validatron for A {
fn get_class() -> crate::ValidatronClass {
Self::class_builder()
.struct_class_builder()
.add_field("b", Box::new(|t| &t.b))
.build()
}
}

impl Validatron for B {
fn get_class() -> crate::ValidatronClass {
Self::class_builder()
.struct_class_builder()
.add_field("c", Box::new(|t| &t.c))
.build()
}
}

impl Validatron for C {
fn get_class() -> crate::ValidatronClass {
Self::class_builder()
.struct_class_builder()
.add_field("inner", Box::new(|t| &t.inner))
.build()
}
}

let rule = get_valid_rule::<A>(
vec![
Identifier::Field(Field::Simple(SimpleField("b".to_string()))),
Identifier::Field(Field::Adt(AdtField {
variant_name: "Some".to_string(),
field_name: "0".to_string(),
})),
Identifier::Field(Field::Simple(SimpleField("c".to_string()))),
Identifier::Field(Field::Simple(SimpleField("inner".to_string()))),
],
Operator::Relational(RelationalOperator::Equals),
RValue::Value("666".to_string()),
)
.unwrap();

let test = A {
b: Some(B {
c: C { inner: 666 },
}),
};

assert!(rule.is_match(&test));
}
}

0 comments on commit 1ab991d

Please sign in to comment.