use std::fmt; use handler::*; use node_modifier::NodeModifier; pub(crate) mod handler; pub mod node_modifier; #[derive(Clone)] pub struct Node { pub(crate) children: Vec, pub(crate) handler: NodeHandler, pub(crate) max_children_count: Option, } impl Node { pub fn new( children: Option>, handler: NodeHandler, max_children_count: Option, ) -> Self { Self { children: children.unwrap_or(vec![]), handler: handler, max_children_count, } } pub fn empty() -> Self { Self { children: vec![], handler: NodeHandler::Empty, max_children_count: None, } } pub fn number(n: f64) -> Self { Self { children: vec![], handler: NodeHandler::Number { number: n }, max_children_count: Some(0), } } pub fn function( func_name: String, func: fn(Vec) -> f64, max_children_count: Option, ) -> Self { Self { children: vec![], handler: NodeHandler::Function { name: func_name, function: func, max_args: max_children_count, }, max_children_count, } } pub fn variable() -> Self { Self { children: vec![], handler: NodeHandler::Variable, max_children_count: Some(0), } } pub fn get_value(&self, passed_x: f64) -> f64 { if self.children.len() == 0 { return self.handler.run(vec![0f64], passed_x); } let mut inputs: Vec = vec![]; for node in &self.children { inputs.push(node.get_value(passed_x)); } return self.handler.run(inputs, passed_x); } pub fn modify_node(&mut self) -> NodeModifier { NodeModifier::from_random(self, None) } pub fn modify_tree(&mut self) -> NodeModifier { NodeModifier::from_node(self, None) } pub fn as_text(&self) -> String { let mut children_text = "".to_string(); if self.children.len() > 0 { for i in 0..self.children.len() { children_text += (&self.children[i]).as_text().as_str(); if i < self.children.len() - 1 { children_text += ","; } } } match &self.handler { NodeHandler::Function { name, function, max_args, } => name.clone() + "(" + children_text.as_str() + ")", NodeHandler::Empty => children_text, _ => self.to_string(), } } } impl fmt::Display for Node { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "{}", match &self.handler { NodeHandler::Number { number } => number.to_string(), NodeHandler::Function { function, name, max_args, } => name.clone(), NodeHandler::Variable => "X".to_string(), NodeHandler::Empty => "".to_string(), } ) } }