Add initial replicant crate
This commit is contained in:
parent
e8c6dd61f9
commit
fe5c27e890
|
@ -1,6 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"editor"
|
"editor",
|
||||||
|
"replicant"
|
||||||
]
|
]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "replicant"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
glam = "0.21"
|
||||||
|
termtree = "0.4"
|
|
@ -0,0 +1,148 @@
|
||||||
|
use std::fmt;
|
||||||
|
use termtree;
|
||||||
|
|
||||||
|
#[non_exhaustive]
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum FieldOp {
|
||||||
|
Add,
|
||||||
|
Sub,
|
||||||
|
Mul,
|
||||||
|
Div,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for FieldOp {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let name = match self {
|
||||||
|
FieldOp::Add => "+",
|
||||||
|
FieldOp::Sub => "-",
|
||||||
|
FieldOp::Mul => "*",
|
||||||
|
FieldOp::Div => "/",
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(f, "{}", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Field: fmt::Debug + Clone {
|
||||||
|
fn op(&self, other: Self, op: FieldOp) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FieldNode<T: Field> {
|
||||||
|
field: T,
|
||||||
|
op: FieldOp,
|
||||||
|
children: Vec<FieldNode<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Field> FieldNode<T> {
|
||||||
|
pub fn evaluate(&self) -> T {
|
||||||
|
let mut result = self.field.clone();
|
||||||
|
|
||||||
|
for child in self.children.iter() {
|
||||||
|
let child_result = child.evaluate();
|
||||||
|
result = result.op(child_result, child.op);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_termtree(&self) -> termtree::Tree<String> {
|
||||||
|
let desc = format!("{} {:?} ({:?})", self.op, self.field, self.evaluate());
|
||||||
|
let mut tree = termtree::Tree::new(desc);
|
||||||
|
|
||||||
|
for child in self.children.iter() {
|
||||||
|
tree.push(child.to_termtree());
|
||||||
|
}
|
||||||
|
|
||||||
|
tree
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Field> fmt::Display for FieldNode<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.to_termtree())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Field for f32 {
|
||||||
|
fn op(&self, other: Self, op: FieldOp) -> Self {
|
||||||
|
match op {
|
||||||
|
FieldOp::Add => self + other,
|
||||||
|
FieldOp::Sub => self - other,
|
||||||
|
FieldOp::Mul => self * other,
|
||||||
|
FieldOp::Div => self / other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_nodes() {
|
||||||
|
use FieldOp::*;
|
||||||
|
|
||||||
|
let nodes: FieldNode<f32> = FieldNode {
|
||||||
|
field: 10.0,
|
||||||
|
op: Add,
|
||||||
|
children: vec![
|
||||||
|
FieldNode {
|
||||||
|
field: 4.0,
|
||||||
|
op: Add,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
FieldNode {
|
||||||
|
field: 2.0,
|
||||||
|
op: Sub,
|
||||||
|
children: vec![
|
||||||
|
FieldNode {
|
||||||
|
field: 0.0,
|
||||||
|
op: Add,
|
||||||
|
children: vec![
|
||||||
|
FieldNode {
|
||||||
|
field: 0.6,
|
||||||
|
op: Add,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
FieldNode {
|
||||||
|
field: 0.2,
|
||||||
|
op: Sub,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
FieldNode {
|
||||||
|
field: 3.0,
|
||||||
|
op: Div,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
FieldNode {
|
||||||
|
field: 7.0,
|
||||||
|
op: Mul,
|
||||||
|
children: vec![
|
||||||
|
FieldNode {
|
||||||
|
field: 0.75,
|
||||||
|
op: Add,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
FieldNode {
|
||||||
|
field: 0.5,
|
||||||
|
op: Sub,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
FieldNode {
|
||||||
|
field: 2.0,
|
||||||
|
op: Div,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("{}", nodes);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue