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
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
server/target/
|
||||||
184
server/Cargo.lock
generated
Normal file
184
server/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.103"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.145"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.110"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde_core",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_parser",
|
||||||
|
"toml_writer",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_parser"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
|
||||||
|
dependencies = [
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_writer"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wgu"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||||
10
server/Cargo.toml
Normal file
10
server/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "wgu"
|
||||||
|
authors = ["sel <sel@selstacker.space>"]
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "*", features = ["derive"] }
|
||||||
|
serde_json = "1.0.145"
|
||||||
|
toml = "0.9.8"
|
||||||
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