From 9e789204974acc4da2a9a01a7bb5bcb4df6a8a78 Mon Sep 17 00:00:00 2001 From: sel Date: Thu, 27 Nov 2025 01:46:51 +0100 Subject: [PATCH] feat!: added transforms --- server/src/lib.rs | 74 +++++++++++++++++++++++++++++++++++++--------- server/src/main.rs | 13 ++++++++ 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/server/src/lib.rs b/server/src/lib.rs index 3130634..42e82ff 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -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 { + 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 { + 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::>(); + 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 { - let instance = ObjectInstance { - object_type: object_type.to_string(), - input: json!(input), - ..ObjectInstance::default() + pub fn transform(obj: &ObjectInstance, source: &str, destination: &str) -> Result { + 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)) + } } } diff --git a/server/src/main.rs b/server/src/main.rs index c782b90..61f177e 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -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(()) }