use serde::{Serialize, Deserialize};
use super::{MachGraph, MachNode};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Handle {
pub path: String,
pub index: Option<u32>
}
impl Handle {
pub fn has_index(&self) -> bool {
self.index.is_some()
}
pub fn get_index(&self, graph: &MachGraph) -> Option<u32> {
if self.has_index() { return self.index.clone(); }
Self::index(graph, &self.path)
}
pub fn set_index(&mut self, graph: &MachGraph) {
self.index = Self::index(graph, &self.path);
}
pub fn set_path(&mut self, graph: &MachGraph) {
if self.has_index() {
if let Some(path) = Self::path(graph, self.index.unwrap()) {
self.path = path;
}
}
}
pub fn path(graph: &MachGraph, index: u32) -> Option<String> {
let mut current_index = index as usize;
if current_index < graph.nodes.len() {
let mut current = &graph.nodes[current_index];
let mut result = current.name.clone();
while current.has_parent() {
current_index = current.parent as usize;
if current_index < graph.nodes.len() {
current = &graph.nodes[current_index];
result = format!("{}.{}", current.name.as_str(), result.as_str());
} else {
return None; }
}
return Some(result);
}
None
}
pub fn index(graph: &MachGraph, path: &String) -> Option<u32> {
let mut current: &MachNode = graph.get_root().expect("No root found on graph");
let mut set = false;
for name in path.split('.') {
if !set {
for node in &graph.nodes {
if node.name == name {
current = node;
set = true;
break;
}
}
if !set { return None; }
}
if name != current.name {
let mut found = false;
for child_index in ¤t.children {
let idx = *child_index as usize;
if idx < graph.nodes.len() {
let child = &graph.nodes[idx];
if child.name == name {
current = child;
found = true;
break;
}
}
}
if !found { return None; } }
}
Some(current.index)
}
}
impl From<String> for Handle {
fn from(path: String) -> Self {
Self {
path: path,
index: None
}
}
}
impl From<&str> for Handle {
fn from(path: &str) -> Self {
Self {
path: String::from(path),
index: None
}
}
}
impl From<u32> for Handle {
fn from(index: u32) -> Self {
Self {
path: String::from("undefined"),
index: Some(index)
}
}
}
impl From<(String, u32)> for Handle {
fn from((path, index): (String, u32)) -> Self {
Self {
path: path,
index: Some(index)
}
}
}
impl From<(&str, u32)> for Handle {
fn from((path, index): (&str, u32)) -> Self {
Self {
path: String::from(path),
index: Some(index)
}
}
}