use wasm_bindgen::prelude::*;
use crate::{SData, SDataRef, Store};
use super::{StofDoc, StofNode};
#[wasm_bindgen]
pub struct StofData {
id: String,
}
impl StofData {
pub fn data_ref(&self) -> SDataRef {
SDataRef::from(&self.id)
}
pub fn data<'a>(&self, doc: &'a StofDoc) -> Option<&'a SData> {
self.data_ref().data(&doc.doc().graph)
}
pub fn data_mut<'a>(&self, doc: &'a mut StofDoc) -> Option<&'a mut SData> {
self.data_ref().data_mut(&mut doc.doc_mut().graph)
}
}
#[wasm_bindgen]
impl StofData {
#[wasm_bindgen(constructor)]
pub fn construct(doc: &mut StofDoc, node: &StofNode, value: JsValue) -> Result<Self, String> {
if let Ok(value) = serde_wasm_bindgen::from_value::<serde_json::Value>(value) {
if let Ok(json) = serde_json::to_string(&value) {
let data = SData::new(Box::new(json));
if let Some(dref) = doc.doc_mut().graph.put_data(&node.node_ref(), data) {
return Ok(Self::new(&dref.id));
}
}
}
Err(format!("Could not create the Stof data"))
}
#[wasm_bindgen(js_name = newWithId)]
pub fn construct_with_id(doc: &mut StofDoc, node: &StofNode, id: &str, value: JsValue) -> Result<Self, String> {
if let Ok(value) = serde_wasm_bindgen::from_value::<serde_json::Value>(value) {
if let Ok(json) = serde_json::to_string(&value) {
let data = SData::new_id(id, Box::new(json));
if let Some(dref) = doc.doc_mut().graph.put_data(&node.node_ref(), data) {
return Ok(Self::new(&dref.id));
}
}
}
Err(format!("Could not create the Stof data"))
}
pub fn remove(&self, doc: &mut StofDoc) -> bool {
doc.doc_mut().graph.remove_data(&self.data_ref(), None)
}
#[wasm_bindgen(js_name = removeFrom)]
pub fn remove_from(&self, doc: &mut StofDoc, node: &StofNode) -> bool {
doc.doc_mut().graph.remove_data(&self.data_ref(), Some(&node.node_ref()))
}
pub fn new(id: &str) -> Self {
Self { id: id.to_owned() }
}
pub fn id(&self) -> String {
self.id.clone()
}
pub fn invalidate(&self, doc: &mut StofDoc, symbol: &str) -> bool {
if let Some(data) = self.data_mut(doc) {
data.invalidate(symbol);
return true;
}
false
}
#[wasm_bindgen(js_name = invalidateValue)]
pub fn invalidate_value(&self, doc: &mut StofDoc) -> bool {
if let Some(data) = self.data_mut(doc) {
data.invalidate_val();
return true;
}
false
}
pub fn dirty(&self, doc: &StofDoc, symbol: &str) -> bool {
if let Some(data) = self.data(doc) {
return data.dirty(symbol);
}
false
}
#[wasm_bindgen(js_name = anyDirty)]
pub fn any_dirty(&self, doc: &StofDoc) -> bool {
if let Some(data) = self.data(doc) {
return data.has_dirty();
}
false
}
pub fn validate(&self, doc: &mut StofDoc, symbol: &str) -> bool {
if let Some(data) = self.data_mut(doc) {
return data.validate(symbol);
}
false
}
pub fn validate_all(&self, doc: &mut StofDoc) -> bool {
if let Some(data) = self.data_mut(doc) {
return data.validate_val();
}
false
}
pub fn exists(&self, doc: &StofDoc) -> bool {
self.data_ref().exists(&doc.doc().graph)
}
pub fn nodes(&self, doc: &StofDoc) -> Vec<StofNode> {
let mut nodes = Vec::new();
if let Some(data) = self.data(doc) {
for nref in &data.nodes {
nodes.push(StofNode::new(&nref.id));
}
}
nodes
}
#[wasm_bindgen(js_name = getValue)]
pub fn get_value(&self, doc: &StofDoc) -> Result<JsValue, String> {
if let Some(data) = self.data(doc) {
if let Some(json) = data.get_data::<String>() {
if let Ok(value) = serde_json::from_str::<serde_json::Value>(&json) {
if let Ok(jsval) = serde_wasm_bindgen::to_value(&value) {
return Ok(jsval);
}
}
}
}
Err(format!("Could not get a JSON value for this data"))
}
#[wasm_bindgen(js_name = setValue)]
pub fn set_value(&self, doc: &mut StofDoc, value: JsValue) -> bool {
if let Some(data) = self.data_mut(doc) {
if let Ok(value) = serde_wasm_bindgen::from_value::<serde_json::Value>(value) {
if let Ok(json) = serde_json::to_string(&value) {
data.set_data(Box::new(json));
return true;
}
}
}
false
}
pub fn to_json(&self, doc: &StofDoc) -> JsValue {
if let Some(data) = self.data(doc) {
if let Ok(val) = serde_wasm_bindgen::to_value(data) {
return val;
}
}
JsValue::null()
}
pub fn from_json(doc: &mut StofDoc, json: JsValue) -> bool {
if let Ok(data) = serde_wasm_bindgen::from_value::<SData>(json) {
doc.doc_mut().graph.data.set(&data.id.clone(), data);
return true;
}
false
}
}