1use std::collections::HashMap;
2
3use serde_json::Value;
4
5use crate::{
6 error::{error_helpers::schema_error, PoolResult},
7 id_generator::IdGenerator,
8 mark::Mark,
9 mark_definition::MarkDefinition,
10 node::Node,
11 node_definition::{NodeDefinition, NodeTree},
12 schema::Schema,
13 types::NodeId,
14};
15
16#[derive(Clone)]
18pub struct NodeFactory<'schema> {
19 schema: &'schema Schema,
20}
21
22impl<'schema> NodeFactory<'schema> {
23 pub fn new(schema: &'schema Schema) -> Self {
25 Self { schema }
26 }
27
28 pub fn schema(&self) -> &'schema Schema {
30 self.schema
31 }
32
33 pub fn create_node(
35 &self,
36 type_name: &str,
37 id: Option<NodeId>,
38 attrs: Option<&HashMap<String, Value>>,
39 content: Vec<NodeId>,
40 marks: Option<Vec<Mark>>,
41 ) -> PoolResult<Node> {
42 let node_type = self.schema.nodes.get(type_name).ok_or_else(|| {
43 schema_error(&format!("无法在 schema 中找到节点类型: {type_name}"))
44 })?;
45
46 Ok(Self::instantiate_node(node_type, id, attrs, content, marks))
47 }
48
49 pub fn node_definition(
51 &self,
52 type_name: &str,
53 ) -> Option<&NodeDefinition> {
54 self.schema.nodes.get(type_name)
55 }
56
57 pub fn create_mark(
59 &self,
60 type_name: &str,
61 attrs: Option<&HashMap<String, Value>>,
62 ) -> PoolResult<Mark> {
63 let mark_def = self.schema.marks.get(type_name).ok_or_else(|| {
64 schema_error(&format!("无法在 schema 中找到标记类型: {type_name}"))
65 })?;
66
67 Ok(Self::instantiate_mark(mark_def, attrs))
68 }
69
70 pub fn mark_definition(
72 &self,
73 type_name: &str,
74 ) -> Option<&MarkDefinition> {
75 self.schema.marks.get(type_name)
76 }
77
78 pub fn create_top_node(
80 &self,
81 id: Option<NodeId>,
82 attrs: Option<&HashMap<String, Value>>,
83 content: Vec<Node>,
84 marks: Option<Vec<Mark>>,
85 ) -> PoolResult<NodeTree> {
86 let top_node_type = self
87 .schema
88 .top_node_type
89 .as_ref()
90 .ok_or_else(|| schema_error("未找到顶级节点类型定义"))?;
91
92 self.create_tree_with_type(top_node_type, id, attrs, content, marks)
93 }
94
95 pub fn create_tree(
97 &self,
98 type_name: &str,
99 id: Option<NodeId>,
100 attrs: Option<&HashMap<String, Value>>,
101 content: Vec<Node>,
102 marks: Option<Vec<Mark>>,
103 ) -> PoolResult<NodeTree> {
104 let node_type = self.schema.nodes.get(type_name).ok_or_else(|| {
105 schema_error(&format!("无法在 schema 中找到节点类型: {type_name}"))
106 })?;
107
108 self.create_tree_with_type(node_type, id, attrs, content, marks)
109 }
110
111 pub(crate) fn create_tree_with_type(
113 &self,
114 node_type: &NodeDefinition,
115 id: Option<NodeId>,
116 attrs: Option<&HashMap<String, Value>>,
117 content: Vec<Node>,
118 marks: Option<Vec<Mark>>,
119 ) -> PoolResult<NodeTree> {
120 let id: NodeId = id.unwrap_or_else(IdGenerator::get_id);
121 let computed_attrs = node_type.compute_attrs(attrs);
122 let computed_marks = node_type.compute_marks(marks);
123
124 let mut filled_nodes: Vec<NodeTree> = Vec::new();
125 let mut final_content_ids: Vec<NodeId> = Vec::new();
126
127 if let Some(content_match) = &node_type.content_match {
128 if let Some(matched) =
129 content_match.match_fragment(&content, self.schema)
130 {
131 if let Some(needed_type_names) =
132 matched.fill(&content, true, self.schema)
133 {
134 for type_name in needed_type_names {
135 if let Some(existing_node) =
136 content.iter().find(|n| n.r#type == type_name)
137 {
138 let attrs_map: HashMap<String, Value> =
139 existing_node
140 .attrs
141 .attrs
142 .iter()
143 .map(|(k, v)| (k.clone(), v.clone()))
144 .collect();
145 let marks_vec: Vec<Mark> =
146 existing_node.marks.iter().cloned().collect();
147 let child_type = self
148 .schema
149 .nodes
150 .get(&type_name)
151 .ok_or_else(|| {
152 schema_error(&format!(
153 "无法在 schema 中找到节点类型: {type_name}"
154 ))
155 })?;
156
157 let child_tree = self.create_tree_with_type(
158 child_type,
159 Some(existing_node.id.clone()),
160 Some(&attrs_map),
161 vec![],
162 Some(marks_vec),
163 )?;
164 let child_id = child_tree.0.id.clone();
165 final_content_ids.push(child_id);
166 filled_nodes.push(child_tree);
167 } else {
168 let child_type = self
169 .schema
170 .nodes
171 .get(&type_name)
172 .ok_or_else(|| {
173 schema_error(&format!(
174 "无法在 schema 中找到节点类型: {type_name}"
175 ))
176 })?;
177
178 let child_tree = self.create_tree_with_type(
179 child_type,
180 None,
181 None,
182 vec![],
183 None,
184 )?;
185 let child_id = child_tree.0.id.clone();
186 final_content_ids.push(child_id);
187 filled_nodes.push(child_tree);
188 }
189 }
190 }
191 }
192 }
193
194 let node = Node::new(
195 &id,
196 node_type.name.clone(),
197 computed_attrs,
198 final_content_ids,
199 computed_marks,
200 );
201
202 Ok(NodeTree(node, filled_nodes))
203 }
204
205 fn instantiate_node(
206 node_type: &NodeDefinition,
207 id: Option<NodeId>,
208 attrs: Option<&HashMap<String, Value>>,
209 content: Vec<NodeId>,
210 marks: Option<Vec<Mark>>,
211 ) -> Node {
212 let id: NodeId = id.unwrap_or_else(IdGenerator::get_id);
213 let attrs = node_type.compute_attrs(attrs);
214 let marks = node_type.compute_marks(marks);
215
216 Node::new(&id, node_type.name.clone(), attrs, content, marks)
217 }
218
219 pub(crate) fn instantiate_mark(
220 mark_def: &MarkDefinition,
221 attrs: Option<&HashMap<String, Value>>,
222 ) -> Mark {
223 Mark { r#type: mark_def.name.clone(), attrs: mark_def.compute_attrs(attrs) }
224 }
225}