Updated field logic, fixed up some boilerplate for further testing.
This commit is contained in:
parent
fe5c27e890
commit
9c2f58b114
|
@ -1,148 +1 @@
|
||||||
use std::fmt;
|
pub mod fields;
|
||||||
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