#[macro_export]
macro_rules! schema {
{} => {
$crate::Schema::new()
};
($name:ident: $type:ident $(, $($rest:tt)*)?) => {
{
let mut builder = $crate::Schema::builder();
builder = builder.field(stringify!($name), schema!(@type $type));
$(
builder = schema!(@parse builder, $($rest)*);
)?
builder.build()
}
};
($name:ident ?: $type:ident $(, $($rest:tt)*)?) => {
{
let mut builder = $crate::Schema::builder();
builder = builder.optional(stringify!($name), schema!(@type $type));
$(
builder = schema!(@parse builder, $($rest)*);
)?
builder.build()
}
};
(@parse $builder:expr, $name:ident: $type:ident $(, $($rest:tt)*)?) => {
{
let mut builder = $builder.field(stringify!($name), schema!(@type $type));
$(
builder = schema!(@parse builder, $($rest)*);
)?
builder
}
};
(@parse $builder:expr, $name:ident ?: $type:ident $(, $($rest:tt)*)?) => {
{
let mut builder = $builder.optional(stringify!($name), schema!(@type $type));
$(
builder = schema!(@parse builder, $($rest)*);
)?
builder
}
};
(@type String) => { $crate::FieldType::String };
(@type Number) => { $crate::FieldType::Number };
(@type Boolean) => { $crate::FieldType::Boolean };
(@type Date) => { $crate::FieldType::Date };
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Schema, FieldType};
use serde_json::json;
#[test]
fn test_simple_schema_macro() {
let schema = schema! {
name: String,
age: Number,
active: Boolean
};
assert_eq!(schema.fields.len(), 3);
assert_eq!(schema.fields[0].key, "name");
assert_eq!(schema.fields[0].field_type, FieldType::String);
assert!(schema.fields[0].required);
assert_eq!(schema.fields[1].key, "age");
assert_eq!(schema.fields[1].field_type, FieldType::Number);
assert!(schema.fields[1].required);
}
#[test]
fn test_optional_fields_schema_macro() {
let schema = schema! {
name: String,
age?: Number,
email?: String
};
assert_eq!(schema.fields.len(), 3);
assert!(schema.fields[0].required);
assert!(!schema.fields[1].required);
assert!(!schema.fields[2].required);
}
#[test]
fn test_simple_validation_with_macro() {
let schema = schema! {
name: String,
age?: Number
};
let valid_data = json!({
"name": "John Doe",
"age": 30
});
assert!(schema.validate(&valid_data).is_ok());
let invalid_data = json!({
"age": 30
});
assert!(schema.validate(&invalid_data).is_err());
}
}