feat!: added mostly foundational code, and a playground of sorts to interact with it
This commit is contained in:
parent
6c524b0741
commit
9a28c1a1dd
10 changed files with 417 additions and 0 deletions
58
server/src/lib.rs
Normal file
58
server/src/lib.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
pub mod modules;
|
||||
pub mod types;
|
||||
use crate::modules::{ModuleItem, item_registry};
|
||||
use crate::types::{ObjectInstance, ObjectTemplate};
|
||||
|
||||
use serde_json::{Value, json};
|
||||
|
||||
impl ObjectInstance {
|
||||
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))
|
||||
};
|
||||
|
||||
match modules.get(format!("{}:func:validator", object_type).as_str()) {
|
||||
Some(ModuleItem::Validator(validate)) => validate(&obj)?,
|
||||
Some(_) => panic!("{}:func:validator is not a ModuleItem::Validator", object_type),
|
||||
None => (),
|
||||
};
|
||||
|
||||
for (name, property) in template.input {
|
||||
for transform in property.transforms {
|
||||
let destination = transform.split(":").collect::<Vec<&str>>();
|
||||
|
||||
let temp_object = ObjectInstance {
|
||||
object_type: destination[0].to_string(),
|
||||
input: json!({
|
||||
destination[1]: obj.input.get(&name)
|
||||
}),
|
||||
..ObjectInstance::default()
|
||||
};
|
||||
|
||||
match modules.get(format!("{}:func:validator", &destination[0]).as_str()) {
|
||||
Some(ModuleItem::Validator(validate)) => validate(&temp_object)?,
|
||||
Some(_) => panic!("{}:func:validator is not a ModuleItem::Validator", object_type),
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
};
|
||||
|
||||
ObjectInstance::validate(&instance)?;
|
||||
Ok(instance)
|
||||
}
|
||||
}
|
||||
36
server/src/main.rs
Normal file
36
server/src/main.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
use serde_json::json;
|
||||
use wgu::types::ObjectInstance;
|
||||
use wgu::modules::{ModuleItem, item_registry};
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let modules = item_registry();
|
||||
|
||||
// change these!
|
||||
let object_type = "meta/text";
|
||||
let input = json!({
|
||||
"value": "owo"
|
||||
});
|
||||
let function = "local";
|
||||
|
||||
// this creates a new object instance
|
||||
let some_object = ObjectInstance::from_template(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 => {
|
||||
println!("the ModuleItem `{}:func:{}` doesn't exist. this is not necessarily bad in this example (if you changed `object_type`)", object_type, function);
|
||||
some_object.clone() // does nothing(?) i hope
|
||||
}
|
||||
};
|
||||
|
||||
println!("this is the same object with data:");
|
||||
println!("{:?}", some_object_with_data);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
20
server/src/modules.rs
Normal file
20
server/src/modules.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use crate::ObjectInstance;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub mod meta;
|
||||
|
||||
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>)
|
||||
}
|
||||
|
||||
pub fn item_registry() -> HashMap<&'static str, ModuleItem> {
|
||||
let mut map = HashMap::new();
|
||||
map.extend(meta::registry());
|
||||
map
|
||||
}
|
||||
14
server/src/modules/meta.rs
Normal file
14
server/src/modules/meta.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use crate::modules::ModuleItem;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub mod dummy;
|
||||
pub mod text;
|
||||
|
||||
pub fn registry() -> HashMap<&'static str, ModuleItem> {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("meta/dummy", ModuleItem::Template(dummy::TEMPLATE));
|
||||
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
|
||||
}
|
||||
5
server/src/modules/meta/dummy.rs
Normal file
5
server/src/modules/meta/dummy.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
pub const TEMPLATE: &str = r#"[input.value]
|
||||
transforms = ["meta/text:value"]
|
||||
subobjects = []
|
||||
duplicates = false
|
||||
"#;
|
||||
41
server/src/modules/meta/text.rs
Normal file
41
server/src/modules/meta/text.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
use serde_json::json;
|
||||
use crate::ObjectInstance;
|
||||
|
||||
pub const TEMPLATE: &str = r#"
|
||||
[input.value]
|
||||
transforms = []
|
||||
subobjects = []
|
||||
conditions = []
|
||||
duplicates = false
|
||||
|
||||
[local.length]
|
||||
transforms = ["meta/number:value"]
|
||||
subobjects = []
|
||||
conditions = []
|
||||
duplicates = false
|
||||
"#;
|
||||
|
||||
pub fn validate(obj: &ObjectInstance) -> Result<(), String> {
|
||||
let value = obj.input.get("value")
|
||||
.ok_or("input.value must exist")?;
|
||||
|
||||
let _value = value.as_str()
|
||||
.ok_or("input.value must be a string")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn local(obj: &ObjectInstance) -> Result<ObjectInstance, String> {
|
||||
let value = obj.input.get("value")
|
||||
.ok_or("input.value must exist")?;
|
||||
|
||||
let value = value.as_str()
|
||||
.ok_or("input.value must be a string")?;
|
||||
|
||||
let mut new = obj.clone();
|
||||
new.local = json!({
|
||||
"length": value.len()
|
||||
});
|
||||
|
||||
Ok(new)
|
||||
}
|
||||
48
server/src/types.rs
Normal file
48
server/src/types.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||
pub struct ObjectInstance {
|
||||
pub version: u32,
|
||||
pub variant: u32,
|
||||
pub plotted: bool,
|
||||
pub created: String,
|
||||
pub edited: String,
|
||||
pub hashed: String,
|
||||
pub input_sha256: String,
|
||||
pub full_sha256: String,
|
||||
pub object_type: String,
|
||||
pub logs: Vec<Log>,
|
||||
pub input: Value,
|
||||
pub local: Value,
|
||||
pub remote: Value
|
||||
}
|
||||
|
||||
// part of ObjectInstance
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Log {
|
||||
level: String,
|
||||
variant: String,
|
||||
timestamp: 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>,
|
||||
}
|
||||
|
||||
// part of ObjectTemplate
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
#[serde(default)]
|
||||
pub struct TemplateProperty {
|
||||
pub transforms: Vec<String>,
|
||||
pub subobjects: Vec<String>,
|
||||
pub conditions: Vec<[String; 2]>,
|
||||
pub duplicates: bool
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue