use wasm_bindgen::prelude::*;
use crate::{SNode, SNodeRef, Store};
use super::{StofData, StofDoc};
#[wasm_bindgen]
pub struct StofNode {
id: String,
}
impl StofNode {
pub fn node_ref(&self) -> SNodeRef {
SNodeRef::from(&self.id)
}
pub fn node<'a>(&self, doc: &'a StofDoc) -> Option<&'a SNode> {
self.node_ref().node(&doc.doc().graph)
}
pub fn node_mut<'a>(&self, doc: &'a mut StofDoc) -> Option<&'a mut SNode> {
self.node_ref().node_mut(&mut doc.doc_mut().graph)
}
}
#[wasm_bindgen]
impl StofNode {
#[wasm_bindgen(constructor)]
pub fn new(id: &str) -> Self {
Self { id: id.to_owned() }
}
#[wasm_bindgen(js_name = fromPath)]
pub fn path_from(doc: &StofDoc, path: &str) -> Option<Self> {
if let Some(nref) = doc.doc().graph.node_ref(path, None) {
return Some(Self::new(&nref.id));
}
None
}
#[wasm_bindgen(js_name = fromPathStart)]
pub fn path_from_start(doc: &StofDoc, path: &str, start: &Self) -> Option<Self> {
if let Some(nref) = doc.doc().graph.node_ref(path, Some(&start.node_ref())) {
return Some(Self::new(&nref.id));
}
None
}
pub fn id(&self) -> String {
self.id.clone()
}
pub fn invalidate(&self, doc: &mut StofDoc, symbol: &str) -> bool {
if let Some(node) = self.node_mut(doc) {
node.invalidate(symbol);
return true;
}
false
}
#[wasm_bindgen(js_name = invalidateAll)]
pub fn invalidate_all(&self, doc: &mut StofDoc) -> bool {
if let Some(node) = self.node_mut(doc) {
node.invalidate_all();
return true;
}
false
}
pub fn dirty(&self, doc: &StofDoc, symbol: &str) -> bool {
if let Some(node) = self.node(doc) {
return node.dirty(symbol);
}
false
}
#[wasm_bindgen(js_name = anyDirty)]
pub fn any_dirty(&self, doc: &StofDoc) -> bool {
if let Some(node) = self.node(doc) {
return node.has_dirty();
}
false
}
pub fn validate(&self, doc: &mut StofDoc, symbol: &str) -> bool {
if let Some(node) = self.node_mut(doc) {
return node.validate(symbol);
}
false
}
pub fn validate_all(&self, doc: &mut StofDoc) -> bool {
if let Some(node) = self.node_mut(doc) {
return node.validate_all();
}
false
}
pub fn root(&self, doc: &StofDoc) -> Option<Self> {
if let Some(nref) = self.node_ref().root(&doc.doc().graph) {
return Some(Self::new(&nref.id));
}
None
}
pub fn exists(&self, doc: &StofDoc) -> bool {
self.node_ref().exists(&doc.doc().graph)
}
#[wasm_bindgen(js_name = isChildOf)]
pub fn is_child_of(&self, doc: &StofDoc, parent: &Self) -> bool {
self.node_ref().is_child_of(&doc.doc().graph, &parent.node_ref())
}
#[wasm_bindgen(js_name = isImmediateChildOf)]
pub fn is_immediate_child_of(&self, doc: &StofDoc, parent: &Self) -> bool {
if let Some(node) = parent.node(doc) {
return node.has_child(&self.node_ref());
}
false
}
pub fn path(&self, doc: &StofDoc) -> String {
self.node_ref().path(&doc.doc().graph)
}
#[wasm_bindgen(js_name = idPath)]
pub fn id_path(&self, doc: &StofDoc) -> Vec<String> {
self.node_ref().id_path(&doc.doc().graph)
}
#[wasm_bindgen(js_name = distanceTo)]
pub fn distance_to(&self, doc: &StofDoc, other: &Self) -> i32 {
self.node_ref().distance_to(&doc.doc().graph, &other.node_ref())
}
pub fn name(&self, doc: &StofDoc) -> Option<String> {
if let Some(node) = self.node(doc) {
return Some(node.name.clone());
}
None
}
pub fn parent(&self, doc: &StofDoc) -> Option<Self> {
if let Some(node) = self.node(doc) {
if let Some(parent) = &node.parent {
return Some(Self::new(&parent.id));
}
}
None
}
pub fn children(&self, doc: &StofDoc) -> Vec<Self> {
let mut children = Vec::new();
if let Some(node) = self.node(doc) {
for child in &node.children {
children.push(Self::new(&child.id));
}
}
children
}
pub fn data(&self, doc: &StofDoc) -> Vec<StofData> {
let mut data = Vec::new();
if let Some(node) = self.node(doc) {
for dref in &node.data {
data.push(StofData::new(&dref.id));
}
}
data
}
#[wasm_bindgen(js_name = hasData)]
pub fn has_data(&self, doc: &StofDoc, data: &StofData) -> bool {
if let Some(node) = self.node(doc) {
return node.has_data(&data.data_ref());
}
false
}
#[wasm_bindgen(js_name = createData)]
pub fn create_data(&self, doc: &mut StofDoc, value: JsValue) -> Result<StofData, String> {
StofData::construct(doc, self, value)
}
pub fn to_json(&self, doc: &StofDoc) -> JsValue {
if let Some(node) = self.node(doc) {
if let Ok(val) = serde_wasm_bindgen::to_value(node) {
return val;
}
}
JsValue::null()
}
pub fn from_json(doc: &mut StofDoc, json: JsValue) -> bool {
if let Ok(node) = serde_wasm_bindgen::from_value::<SNode>(json) {
doc.doc_mut().graph.nodes.set(&node.id.clone(), node);
return true;
}
false
}
}