feat!: added ability to run functions & more metadata to object instances
This commit is contained in:
parent
26309312e8
commit
7ae145be20
10 changed files with 323 additions and 68 deletions
91
server/Cargo.lock
generated
91
server/Cargo.lock
generated
|
|
@ -2,18 +2,78 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.12.0"
|
||||
|
|
@ -30,6 +90,12 @@ version = "1.0.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.178"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
|
|
@ -112,6 +178,17 @@ dependencies = [
|
|||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.110"
|
||||
|
|
@ -162,18 +239,32 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wgu"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"toml",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ version = "0.0.1"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
hex = "0.4.3"
|
||||
serde = { version = "*", features = ["derive"] }
|
||||
serde_json = "1.0.145"
|
||||
sha2 = "0.10.9"
|
||||
toml = "0.9.8"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
pub mod modules;
|
||||
pub mod types;
|
||||
|
||||
use crate::modules::{ModuleItem, item_registry};
|
||||
use crate::types::{ObjectInstance, ObjectTemplate};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::modules::{ModuleItem, FunctionItem, item_registry};
|
||||
use crate::types::{FunctionTemplate, FunctionTemplateObject, ObjectInstance, ObjectTemplate};
|
||||
|
||||
use serde_json::{Value, json};
|
||||
use sha2::{Sha256, Digest};
|
||||
use hex;
|
||||
|
||||
impl ObjectTemplate {
|
||||
fn from_object_type(object_type: &str) -> Result<ObjectTemplate, String> {
|
||||
|
|
@ -21,13 +26,50 @@ impl ObjectTemplate {
|
|||
}
|
||||
|
||||
impl ObjectInstance {
|
||||
pub fn from_template(object_type: &str, input: Value) -> Result<Self, String> {
|
||||
let instance = ObjectInstance {
|
||||
pub fn from_object_type(object_type: &str, input: Value) -> Result<Self, String> {
|
||||
let mut instance = ObjectInstance {
|
||||
object_type: object_type.to_string(),
|
||||
input: json!(input),
|
||||
..ObjectInstance::default()
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/questions/26593387/how-can-i-get-the-current-time-in-milliseconds
|
||||
instance.created = format!("{:?}", SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("time should go forward")
|
||||
.as_millis());
|
||||
|
||||
instance.edited = format!("{:?}", SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("time should go forward")
|
||||
.as_millis());
|
||||
|
||||
instance.hashed = format!("{:?}", SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("time should go forward")
|
||||
.as_millis());
|
||||
|
||||
let input_sha256_bytes = Sha256::digest(
|
||||
format!("{}+{}",
|
||||
instance.object_type,
|
||||
json!(instance.input)
|
||||
)
|
||||
);
|
||||
|
||||
instance.input_sha256 = hex::encode(input_sha256_bytes);
|
||||
|
||||
let full_sha256_bytes = Sha256::digest(
|
||||
format!("{}+{}+{}+{}+{}",
|
||||
instance.object_type,
|
||||
instance.hashed,
|
||||
json!(instance.input),
|
||||
json!(instance.local),
|
||||
json!(instance.remote)
|
||||
)
|
||||
);
|
||||
|
||||
instance.full_sha256 = hex::encode(full_sha256_bytes);
|
||||
|
||||
ObjectInstance::validate(&instance)?;
|
||||
Ok(instance)
|
||||
}
|
||||
|
|
@ -66,7 +108,13 @@ impl ObjectInstance {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn transform(obj: &ObjectInstance, source: &str, destination: &str) -> Result<Self, String> {
|
||||
pub fn run_transform(
|
||||
obj: &ObjectInstance,
|
||||
source: &str,
|
||||
destination: &str
|
||||
)
|
||||
-> Result<Self, String>
|
||||
{
|
||||
let object_type = &obj.object_type;
|
||||
let template = ObjectTemplate::from_object_type(object_type)?;
|
||||
|
||||
|
|
@ -100,13 +148,75 @@ impl ObjectInstance {
|
|||
};
|
||||
|
||||
if template_property.transforms.contains(&destination.to_string()) {
|
||||
let result = ObjectInstance::from_template(destination_parts[0], json!({
|
||||
let result = ObjectInstance::from_object_type(destination_parts[0], json!({
|
||||
destination_parts[1]: source_instance_category.get(source_parts[1])
|
||||
}))?;
|
||||
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(format!("invalid transform destination {}", destination))
|
||||
Err(format!("invalid destination {}", destination))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_function(
|
||||
function: &str,
|
||||
inputs: FunctionItem,
|
||||
params: Option<FunctionItem>
|
||||
)
|
||||
-> Result<FunctionItem, String>
|
||||
{
|
||||
let modules = item_registry();
|
||||
|
||||
// same thing as in ObjectTemplate::from_object_type
|
||||
let (template, function): (FunctionTemplate, _) = match modules.get(function) {
|
||||
Some(ModuleItem::Function((template_str, function))) => (toml::from_str(template_str).unwrap(), function),
|
||||
Some(_) => return Err(format!("the ModuleItem `{}` is not a ModuleItem::Function", function)),
|
||||
None => return Err(format!("the ModuleItem `{}` doesn't exist", function))
|
||||
};
|
||||
|
||||
validate_function_data(&inputs, &template.inputs, "input")?;
|
||||
|
||||
if let Some(params) = ¶ms {
|
||||
validate_function_data(params, &template.params, "parameter")?;
|
||||
}
|
||||
|
||||
let result = function(inputs.clone(), params.clone())?;
|
||||
validate_function_data(&result, &template.outputs, "output")?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
fn validate_function_data(data: &FunctionItem, template: &HashMap<String, FunctionTemplateObject>, category: &str) -> Result<(), String> {
|
||||
for (name, template_object) in template {
|
||||
if let None = data.get(name) && template_object.required {
|
||||
return Err(format!("required {} {} doesn't exist", category, name))
|
||||
}
|
||||
}
|
||||
|
||||
for (name, instances) in data {
|
||||
let template_object = match template.get(name) {
|
||||
Some(template_object) => template_object,
|
||||
None => return Err(format!("{} {} doesn't exist in the template", "input", name))
|
||||
};
|
||||
|
||||
let expected_count = &template_object.count;
|
||||
let expected_object_type = &template_object.object_type;
|
||||
|
||||
if instances.len() != *expected_count {
|
||||
return Err(format!("the amount of object instances in the {} {} ({}) doesn't match the expected amount ({})", category, name, instances.len(), expected_count));
|
||||
}
|
||||
|
||||
for instance in instances {
|
||||
if instance.object_type != *expected_object_type {
|
||||
return Err(format!("the object type of one or more object instances in the {} {} ({}) doesn't match the expected type ({})", category, name, instance.object_type, expected_object_type))
|
||||
}
|
||||
|
||||
ObjectInstance::validate(&instance)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +1,33 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use serde_json::json;
|
||||
use wgu::types::ObjectInstance;
|
||||
use wgu::modules::{ModuleItem, item_registry};
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let modules = item_registry();
|
||||
|
||||
// change these!
|
||||
// for step 1
|
||||
// 1 | creating a new object instance
|
||||
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_object_type(object_type, input)?;
|
||||
|
||||
println!("this is an object:");
|
||||
println!("{:#?}", some_object);
|
||||
println!("");
|
||||
|
||||
// this runs a function on it to calculate other properties
|
||||
let some_object_with_data = match modules.get(format!("{}:func:{}", object_type, function).as_str()) {
|
||||
Some(ModuleItem::Calculator(calc)) => calc(&some_object)?,
|
||||
Some(_) => return Err(format!("if you're trying to run a ModuleItem::Function and not a ModuleItem::Calculator, you'll have to add the match arm for that")),
|
||||
None => {
|
||||
return Err(format!("the ModuleItem `{}:func:{}` doesn't exist. this is not necessarily bad in this example (if you changed `object_type`)", object_type, function));
|
||||
}
|
||||
};
|
||||
// 2 | running a function on it
|
||||
let function = "meta/number:func:local";
|
||||
let mut function_input = HashMap::new();
|
||||
function_input.insert(format!("main"), vec![some_object.clone()]);
|
||||
|
||||
println!("this is the same object with data:");
|
||||
println!("{:#?}", some_object_with_data);
|
||||
println!("");
|
||||
println!("running function {}", function);
|
||||
println!("input: {:#?}", function_input);
|
||||
|
||||
let some_object_with_data = ObjectInstance::run_function(function, function_input, None)?;
|
||||
|
||||
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);
|
||||
println!("output: {:#?}", some_object_with_data);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@ use std::collections::HashMap;
|
|||
|
||||
pub mod meta;
|
||||
|
||||
pub type FunctionItem = HashMap<String, Vec<ObjectInstance>>;
|
||||
|
||||
pub enum ModuleItem {
|
||||
Template(&'static str),
|
||||
Validator(fn(&ObjectInstance) -> Result<(), String>),
|
||||
Calculator(fn(&ObjectInstance) -> Result<ObjectInstance, String>),
|
||||
Function(fn(
|
||||
inputs: HashMap<&str, &ObjectInstance>,
|
||||
params: Option<HashMap<&str, &ObjectInstance>>
|
||||
) -> Result<HashMap<String, ObjectInstance>, String>)
|
||||
Function((
|
||||
&'static str, // template
|
||||
fn(inputs: FunctionItem, params: Option<FunctionItem>) -> Result<FunctionItem, String>
|
||||
))
|
||||
}
|
||||
|
||||
pub fn item_registry() -> HashMap<&'static str, ModuleItem> {
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ pub fn registry() -> HashMap<&'static str, ModuleItem> {
|
|||
// meta/text
|
||||
map.insert("meta/text", ModuleItem::Template(text::TEMPLATE));
|
||||
map.insert("meta/text:func:validator", ModuleItem::Validator(text::validate));
|
||||
map.insert("meta/text:func:local", ModuleItem::Calculator(text::local));
|
||||
map.insert("meta/text:func:local", ModuleItem::Function((text::TEMPLATE_LOCAL, text::local)));
|
||||
|
||||
// meta/number
|
||||
map.insert("meta/number", ModuleItem::Template(number::TEMPLATE));
|
||||
map.insert("meta/number:func:validator", ModuleItem::Validator(number::validate));
|
||||
map.insert("meta/number:func:local", ModuleItem::Calculator(number::local));
|
||||
map.insert("meta/number:func:local", ModuleItem::Function((number::TEMPLATE_LOCAL, number::local)));
|
||||
|
||||
// meta/bool
|
||||
map.insert("meta/bool", ModuleItem::Template(bool::TEMPLATE));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
pub const TEMPLATE: &str = r#"[input.value]
|
||||
pub const TEMPLATE: &str = r#"
|
||||
[input.value]
|
||||
transforms = ["meta/text:value"]
|
||||
subobjects = []
|
||||
conditions = []
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use serde_json::json;
|
||||
use crate::ObjectInstance;
|
||||
|
||||
use crate::{modules::FunctionItem, types::ObjectInstance};
|
||||
|
||||
pub const TEMPLATE: &str = r#"
|
||||
[input.value]
|
||||
|
|
@ -15,6 +17,18 @@ conditions = []
|
|||
duplicates = false
|
||||
"#;
|
||||
|
||||
pub const TEMPLATE_LOCAL: &str = r#"
|
||||
[inputs.main]
|
||||
required = true
|
||||
object_type = "meta/number"
|
||||
count = 1
|
||||
|
||||
[outputs.main]
|
||||
required = true
|
||||
object_type = "meta/number"
|
||||
count = 1
|
||||
"#;
|
||||
|
||||
pub fn validate(obj: &ObjectInstance) -> Result<(), String> {
|
||||
let value = obj.input.get("value")
|
||||
.ok_or("input.value must exist")?;
|
||||
|
|
@ -25,18 +39,28 @@ pub fn validate(obj: &ObjectInstance) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn local(obj: &ObjectInstance) -> Result<ObjectInstance, String> {
|
||||
let _value = obj.input.get("value")
|
||||
.ok_or("input.value must exist")?;
|
||||
pub fn local(
|
||||
inputs: FunctionItem,
|
||||
_params: Option<FunctionItem>
|
||||
)
|
||||
-> Result<FunctionItem, String>
|
||||
{
|
||||
let Some(main) = inputs.get("main")
|
||||
else { unreachable!() };
|
||||
|
||||
let value = _value.as_number()
|
||||
.ok_or("input.value must be a number")?;
|
||||
let main_obj = &main[0];
|
||||
|
||||
let mut new = obj.clone();
|
||||
new.local = json!({
|
||||
let Some(value) = &main_obj.input.get("value")
|
||||
else { unreachable!() };
|
||||
|
||||
let mut result_obj = ObjectInstance::from_object_type("meta/number", main_obj.input.clone())?;
|
||||
|
||||
result_obj.local = json!({
|
||||
"length": value.to_string().len()
|
||||
});
|
||||
|
||||
Ok(new)
|
||||
}
|
||||
let mut result = HashMap::new();
|
||||
result.insert(format!("main"), vec![result_obj]);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use serde_json::json;
|
||||
use crate::ObjectInstance;
|
||||
|
||||
use crate::{modules::FunctionItem, types::ObjectInstance};
|
||||
|
||||
pub const TEMPLATE: &str = r#"
|
||||
[input.value]
|
||||
|
|
@ -15,6 +17,19 @@ conditions = []
|
|||
duplicates = false
|
||||
"#;
|
||||
|
||||
|
||||
pub const TEMPLATE_LOCAL: &str = r#"
|
||||
[inputs.main]
|
||||
required = true
|
||||
object_type = "meta/text"
|
||||
count = 1
|
||||
|
||||
[outputs.main]
|
||||
required = true
|
||||
object_type = "meta/text"
|
||||
count = 1
|
||||
"#;
|
||||
|
||||
pub fn validate(obj: &ObjectInstance) -> Result<(), String> {
|
||||
let value = obj.input.get("value")
|
||||
.ok_or("input.value must exist")?;
|
||||
|
|
@ -25,17 +40,28 @@ pub fn validate(obj: &ObjectInstance) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn local(obj: &ObjectInstance) -> Result<ObjectInstance, String> {
|
||||
let value = obj.input.get("value")
|
||||
.ok_or("input.value must exist")?;
|
||||
pub fn local(
|
||||
inputs: FunctionItem,
|
||||
_params: Option<FunctionItem>
|
||||
)
|
||||
-> Result<FunctionItem, String>
|
||||
{
|
||||
let Some(main) = inputs.get("main")
|
||||
else { unreachable!() };
|
||||
|
||||
let value = value.as_str()
|
||||
.ok_or("input.value must be a string")?;
|
||||
let main_obj = &main[0];
|
||||
|
||||
let mut new = obj.clone();
|
||||
new.local = json!({
|
||||
"length": value.len()
|
||||
let Some(value) = &main_obj.input.get("value")
|
||||
else { unreachable!() };
|
||||
|
||||
let mut result_obj = ObjectInstance::from_object_type("meta/text", main_obj.input.clone())?;
|
||||
|
||||
result_obj.local = json!({
|
||||
"length": value.to_string().len()
|
||||
});
|
||||
|
||||
Ok(new)
|
||||
let mut result = HashMap::new();
|
||||
result.insert(format!("main"), vec![result_obj]);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::collections::HashMap;
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||
pub struct ObjectInstance {
|
||||
pub variant: u32,
|
||||
pub variant: usize,
|
||||
pub plotted: bool,
|
||||
pub created: String,
|
||||
pub edited: String,
|
||||
|
|
@ -24,24 +24,39 @@ pub struct Log {
|
|||
level: String,
|
||||
variant: String,
|
||||
timestamp: String,
|
||||
message: String,
|
||||
message: String
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
#[serde(default)]
|
||||
pub struct ObjectTemplate {
|
||||
pub input: HashMap<String, TemplateProperty>,
|
||||
pub local: HashMap<String, TemplateProperty>,
|
||||
pub remote: HashMap<String, TemplateProperty>,
|
||||
pub input: HashMap<String, ObjectTemplateProperty>,
|
||||
pub local: HashMap<String, ObjectTemplateProperty>,
|
||||
pub remote: HashMap<String, ObjectTemplateProperty>
|
||||
}
|
||||
|
||||
// part of ObjectTemplate
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
#[serde(default)]
|
||||
pub struct TemplateProperty {
|
||||
pub struct ObjectTemplateProperty {
|
||||
pub transforms: Vec<String>,
|
||||
pub subobjects: Vec<String>,
|
||||
pub conditions: Vec<[String; 2]>,
|
||||
pub duplicates: bool
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
#[serde(default)]
|
||||
pub struct FunctionTemplate {
|
||||
pub inputs: HashMap<String, FunctionTemplateObject>,
|
||||
pub params: HashMap<String, FunctionTemplateObject>,
|
||||
pub outputs: HashMap<String, FunctionTemplateObject>
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
#[serde(default)]
|
||||
pub struct FunctionTemplateObject {
|
||||
pub required: bool,
|
||||
pub object_type: String,
|
||||
pub count: usize
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue