pub struct TaggedEnumSchema<F>
where
F: Fn(&str) -> Option<&'static [&'static str]>,
{
pub tag_field: &'static str,
pub valid_tags: &'static [&'static str],
pub fields_for_tag: F,
pub enum_arrays: Vec<(&'static str, &'static [&'static str])>,
pub nested_objects: Vec<(&'static str, &'static [&'static str])>,
}
impl<F> TaggedEnumSchema<F>
where
F: Fn(&str) -> Option<&'static [&'static str]>,
{
pub fn new(
tag_field: &'static str,
valid_tags: &'static [&'static str],
fields_for_tag: F,
) -> Self {
Self {
tag_field,
valid_tags,
fields_for_tag,
enum_arrays: Vec::new(),
nested_objects: Vec::new(),
}
}
pub fn with_enum_array(
mut self,
field: &'static str,
valid_values: &'static [&'static str],
) -> Self {
self.enum_arrays.push((field, valid_values));
self
}
pub fn with_nested_object(
mut self,
field: &'static str,
valid_fields: &'static [&'static str],
) -> Self {
self.nested_objects.push((field, valid_fields));
self
}
pub fn is_valid_tag(&self, tag: &str) -> bool {
self.valid_tags.contains(&tag)
}
pub fn get_fields(&self, tag: &str) -> Option<&'static [&'static str]> {
(self.fields_for_tag)(tag)
}
pub fn get_enum_array_values(&self, field: &str) -> Option<&'static [&'static str]> {
self.enum_arrays
.iter()
.find(|(f, _)| *f == field)
.map(|(_, v)| *v)
}
pub fn get_nested_object_fields(&self, field: &str) -> Option<&'static [&'static str]> {
self.nested_objects
.iter()
.find(|(f, _)| *f == field)
.map(|(_, v)| *v)
}
}
pub struct ObjectSchema {
pub valid_fields: &'static [&'static str],
}
impl ObjectSchema {
pub const fn new(valid_fields: &'static [&'static str]) -> Self {
Self { valid_fields }
}
pub fn is_valid_field(&self, field: &str) -> bool {
self.valid_fields.contains(&field)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_tagged_enum_schema() {
let schema =
TaggedEnumSchema::new("type", &["AddDerive", "RemoveDerive"], |tag| match tag {
"AddDerive" => Some(&["target", "derives"][..]),
"RemoveDerive" => Some(&["target", "derives"][..]),
_ => None,
});
assert!(schema.is_valid_tag("AddDerive"));
assert!(!schema.is_valid_tag("InvalidType"));
assert_eq!(
schema.get_fields("AddDerive"),
Some(&["target", "derives"][..])
);
}
#[test]
fn test_object_schema() {
let schema = ObjectSchema::new(&["name", "value", "is_pub"]);
assert!(schema.is_valid_field("name"));
assert!(!schema.is_valid_field("invalid"));
}
}