use std::sync::Arc;
use crate::{transform_error, TransformResult};
use super::{
step::{Step, StepResult},
};
use mf_model::{schema::Schema, tree::Tree, types::NodeId};
use serde::{Deserialize, Serialize};
use serde_json::{Value};
use mf_model::rpds::HashTrieMapSync;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AttrStep {
pub id: NodeId,
pub values: HashTrieMapSync<String, Value>,
}
impl AttrStep {
pub fn new(
id: NodeId,
values: HashTrieMapSync<String, Value>,
) -> Self {
AttrStep { id, values }
}
}
impl Step for AttrStep {
fn name(&self) -> String {
"attr_step".to_string()
}
fn apply(
&self,
dart: &mut Tree,
schema: Arc<Schema>,
) -> TransformResult<StepResult> {
let factory = schema.factory();
match dart.get_node(&self.id) {
Some(node) => {
let node_type = match factory.node_definition(&node.r#type) {
Some(nt) => nt,
None => {
return Err(transform_error(format!(
"未知的节点类型: {}",
node.r#type
)));
},
};
let attr = &node_type.attrs;
let mut new_values = self.values.clone();
for (key, _) in self.values.iter() {
if !attr.contains_key(key) {
new_values.remove_mut(key);
}
}
let result = dart.attrs(&self.id) + new_values;
match result {
Ok(_) => Ok(StepResult::ok()),
Err(e) => Err(transform_error(e.to_string())),
}
},
None => Err(transform_error("节点不存在".to_string())),
}
}
fn serialize(&self) -> Option<Vec<u8>> {
serde_json::to_vec(self).ok()
}
fn invert(
&self,
dart: &Arc<Tree>,
) -> Option<Arc<dyn Step>> {
match dart.get_node(&self.id) {
Some(node) => {
let mut revert_values = HashTrieMapSync::new_sync();
for (changed_key, _) in self.values.iter() {
if let Some(old_val) = node.attrs.get_safe(changed_key) {
revert_values
.insert_mut(changed_key.clone(), old_val.clone());
}
}
if revert_values.is_empty() {
None
} else {
Some(Arc::new(AttrStep::new(
self.id.clone(),
revert_values,
)))
}
},
None => None,
}
}
}