fapprox/src/node/mod.rs
2025-11-09 13:31:55 +05:00

120 lines
3.2 KiB
Rust

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<Node>,
pub(crate) handler: NodeHandler,
pub(crate) max_children_count: Option<usize>,
}
impl Node {
pub fn new(
children: Option<Vec<Node>>,
handler: NodeHandler,
max_children_count: Option<usize>,
) -> 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>) -> f64,
max_children_count: Option<usize>,
) -> 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<f64> = 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(),
}
)
}
}