feat!: added transforms
This commit is contained in:
parent
999ef69453
commit
9e78920497
2 changed files with 73 additions and 14 deletions
|
|
@ -1,20 +1,39 @@
|
|||
pub mod modules;
|
||||
pub mod types;
|
||||
|
||||
use crate::modules::{ModuleItem, item_registry};
|
||||
use crate::types::{ObjectInstance, ObjectTemplate};
|
||||
|
||||
use serde_json::{Value, json};
|
||||
|
||||
fn get_template(object_type: &str) -> Result<ObjectTemplate, String> {
|
||||
let modules = item_registry();
|
||||
|
||||
let template: ObjectTemplate = match modules.get(object_type) {
|
||||
Some(ModuleItem::Template(template_str)) => toml::from_str(template_str).unwrap(),
|
||||
Some(_) => panic!("{} is not a ModuleItem::Template", object_type),
|
||||
None => return Err(format!("template {} doesn't exist", object_type))
|
||||
};
|
||||
|
||||
Ok(template)
|
||||
}
|
||||
|
||||
impl ObjectInstance {
|
||||
pub fn from_template(object_type: &str, input: Value) -> Result<Self, String> {
|
||||
let instance = ObjectInstance {
|
||||
object_type: object_type.to_string(),
|
||||
input: json!(input),
|
||||
..ObjectInstance::default()
|
||||
};
|
||||
|
||||
ObjectInstance::validate(&instance)?;
|
||||
Ok(instance)
|
||||
}
|
||||
|
||||
pub fn validate(obj: &ObjectInstance) -> Result<(), String> {
|
||||
let modules = item_registry();
|
||||
let object_type = &obj.object_type;
|
||||
|
||||
let template: ObjectTemplate = match modules.get(object_type.as_str()) {
|
||||
Some(ModuleItem::Template(template_str)) => toml::from_str(template_str).unwrap(),
|
||||
Some(_) => panic!("{} is not a ModuleItem::Template", object_type),
|
||||
None => return Err(format!("template {} doesn't exist", object_type))
|
||||
};
|
||||
let template = get_template(object_type)?;
|
||||
|
||||
match modules.get(format!("{}:func:validator", object_type).as_str()) {
|
||||
Some(ModuleItem::Validator(validate)) => validate(&obj)?,
|
||||
|
|
@ -24,7 +43,7 @@ impl ObjectInstance {
|
|||
|
||||
for (name, property) in template.input {
|
||||
for transform in property.transforms {
|
||||
let destination = transform.split(":").collect::<Vec<&str>>();
|
||||
let destination: Vec<&str> = transform.splitn(2, ":").collect();
|
||||
|
||||
let temp_object = ObjectInstance {
|
||||
object_type: destination[0].to_string(),
|
||||
|
|
@ -45,14 +64,41 @@ impl ObjectInstance {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_template(object_type: &str, input: Value) -> Result<Self, String> {
|
||||
let instance = ObjectInstance {
|
||||
object_type: object_type.to_string(),
|
||||
input: json!(input),
|
||||
..ObjectInstance::default()
|
||||
pub fn transform(obj: &ObjectInstance, source: &str, destination: &str) -> Result<Self, String> {
|
||||
let object_type = &obj.object_type;
|
||||
let template = get_template(object_type)?;
|
||||
|
||||
// assuming that the property to transform (source) is 'input.some.thing.nya',
|
||||
// source_parts[0] is the category (input)
|
||||
// source_parts[1] is the name (some.thing.nya)
|
||||
let source_parts: Vec<&str> = source.splitn(2, ".").collect();
|
||||
|
||||
// assuming that the transform destination is 'meta/text:value',
|
||||
// destination_parts[0] is the object type (meta/text)
|
||||
// destination_parts[1] is the property under `input` (value)
|
||||
let destination_parts: Vec<&str> = destination.splitn(2, ":").collect();
|
||||
|
||||
// first item of tuple is for the source object template, second is for the source object instance
|
||||
let source_category = match source_parts[0] {
|
||||
"input" => (template.input, &obj.input),
|
||||
"local" => (template.local, &obj.local),
|
||||
"remote" => (template.remote, &obj.remote),
|
||||
_ => return Err(format!("the category specified in the transformation source ({}) is invalid (must be input OR local OR remote)", source_parts[0]))
|
||||
};
|
||||
|
||||
ObjectInstance::validate(&instance)?;
|
||||
Ok(instance)
|
||||
let template_property = match source_category.0.get(source_parts[1]) {
|
||||
Some(template_property) => template_property,
|
||||
None => return Err(format!("the property specified as the transformation source ({}) doesn't exist in the template", source))
|
||||
};
|
||||
|
||||
if template_property.transforms.contains(&destination.to_string()) {
|
||||
let result = ObjectInstance::from_template(destination_parts[0], json!({
|
||||
destination_parts[1]: source_category.1.get(source_parts[1])
|
||||
}))?;
|
||||
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(format!("invalid transform destination {}", destination))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,18 @@ fn main() -> Result<(), String> {
|
|||
let modules = item_registry();
|
||||
|
||||
// change these!
|
||||
// for step 1
|
||||
let object_type = "meta/number";
|
||||
let input = json!({
|
||||
"value": 1312
|
||||
});
|
||||
|
||||
// for step 2
|
||||
let function = "local";
|
||||
|
||||
// for step 3
|
||||
let transform_source = "local.length";
|
||||
let transform_destination = "meta/number:value";
|
||||
|
||||
// this creates a new object instance
|
||||
let some_object = ObjectInstance::from_template(object_type, input)?;
|
||||
|
|
@ -30,6 +37,12 @@ fn main() -> Result<(), String> {
|
|||
|
||||
println!("this is the same object with data:");
|
||||
println!("{:?}", some_object_with_data);
|
||||
println!("");
|
||||
|
||||
let transformed = ObjectInstance::transform(&some_object_with_data, transform_source, transform_destination)?;
|
||||
|
||||
println!("this is what happens when we transform the {} property into a new {}:", transform_source, transform_destination);
|
||||
println!("{:?}", transformed);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue