Updated field logic, fixed up some boilerplate for further testing.

This commit is contained in:
robotcritter 2022-07-23 22:16:24 -07:00
parent fe5c27e890
commit 9c2f58b114
1 changed files with 1 additions and 148 deletions

View File

@ -1,148 +1 @@
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);
}
}
pub mod fields;