Skip to content

Commit

Permalink
Ekr validate global properties (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekr-cfa authored Nov 26, 2024
1 parent df6eee0 commit c0869eb
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
48 changes: 46 additions & 2 deletions src/global_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ where
Arc::new(
|context: &mut Context, name, value| -> Result<(), IxaError> {
let val: T::Value = serde_json::from_value(value)?;
T::validate(&val)?;
if context.get_global_property_value(T::new()).is_some() {
return Err(IxaError::IxaError(format!("Duplicate property {name}")));
}
Expand All @@ -59,9 +60,10 @@ fn get_global_property(name: &String) -> Option<Arc<PropertySetterFn>> {
/// Defines a global property with the following parameters:
/// * `$global_property`: Name for the identifier type of the global property
/// * `$value`: The type of the property's value
/// * `$validate`: A function (or closure) that checks the validity of the property (optional)
#[macro_export]
macro_rules! define_global_property {
($global_property:ident, $value:ty) => {
($global_property:ident, $value:ty, $validate: expr) => {
#[derive(Copy, Clone)]
pub struct $global_property;

Expand All @@ -71,6 +73,10 @@ macro_rules! define_global_property {
fn new() -> Self {
$global_property
}

fn validate(val: &$value) -> Result<(), IxaError> {
$validate(val)
}
}

paste::paste! {
Expand All @@ -84,6 +90,10 @@ macro_rules! define_global_property {
}
}
};

($global_property: ident, $value: ty) => {
define_global_property!($global_property, $value, |_| { Ok(()) });
};
}

/// Global properties are not mutable and represent variables that are required
Expand All @@ -92,6 +102,8 @@ pub trait GlobalProperty: Any {
type Value: Any;

fn new() -> Self;
#[allow(clippy::missing_errors_doc)]
fn validate(value: &Self::Value) -> Result<(), IxaError>;
}

pub use define_global_property;
Expand Down Expand Up @@ -329,7 +341,7 @@ mod test {
.join("tests/data/global_properties_missing.json");
match context.load_global_properties(&path) {
Err(IxaError::IxaError(msg)) => {
assert_eq!(msg, "No global property: ixa.Property3");
assert_eq!(msg, "No global property: ixa.PropertyUnknown");
}
_ => panic!("Unexpected error type"),
}
Expand Down Expand Up @@ -360,4 +372,36 @@ mod test {
_ => panic!("Unexpected error type"),
}
}

#[derive(Deserialize)]
pub struct Property3Type {
field_int: u32,
}
define_global_property!(Property3, Property3Type, |v: &Property3Type| {
match v.field_int {
0 => Ok(()),
_ => Err(IxaError::IxaError(format!(
"Illegal value for `field_int`: {}",
v.field_int
))),
}
});
#[test]
fn validate_property_success() {
let mut context = Context::new();
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/data/global_properties_valid.json");
context.load_global_properties(&path).unwrap();
}

#[test]
fn validate_property_failure() {
let mut context = Context::new();
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/data/global_properties_invalid.json");
assert!(matches!(
context.load_global_properties(&path),
Err(IxaError::IxaError(_))
));
}
}
5 changes: 5 additions & 0 deletions tests/data/global_properties_invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"ixa.Property3": {
"field_int": 42
}
}
2 changes: 1 addition & 1 deletion tests/data/global_properties_missing.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"ixa.Property3": {
"ixa.PropertyUnknown": {
"field_int": 1,
"field_str": "test"
}
Expand Down
5 changes: 5 additions & 0 deletions tests/data/global_properties_valid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"ixa.Property3": {
"field_int": 0
}
}

0 comments on commit c0869eb

Please sign in to comment.