Add initial replicant crate
This commit is contained in:
parent
e8c6dd61f9
commit
fe5c27e890
|
@ -1,6 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"editor"
|
||||
"editor",
|
||||
"replicant"
|
||||
]
|
||||
|
||||
[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