1use super::attrs::Attrs;
2use super::content::ContentMatch;
3use super::id_generator::IdGenerator;
4use super::mark::Mark;
5use super::mark_definition::MarkDefinition;
6use super::node::Node;
7use super::schema::{compute_attrs, Attribute, AttributeSpec, Schema};
8use super::types::NodeId;
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use std::collections::HashMap;
12use std::fmt::{self, Debug};
13
14#[derive(Clone, Debug, Serialize, Deserialize)]
15pub struct NodeTree(pub Node, pub Vec<NodeTree>);
16
17impl NodeTree {
18 pub fn into_parts(self) -> (Node, Vec<NodeTree>) {
19 match self {
20 NodeTree(node, children) => (node, children),
21 }
22 }
23 pub fn from(
24 node: Node,
25 childs: Vec<Node>,
26 ) -> Self {
27 NodeTree(
28 node,
29 childs.into_iter().map(|n| NodeTree(n, vec![])).collect(),
30 )
31 }
32}
33#[derive(Clone, PartialEq, Eq)]
35pub struct NodeDefinition {
36 pub name: String,
38 pub spec: NodeSpec,
40 pub desc: String,
42 pub groups: Vec<String>,
44 pub attrs: HashMap<String, Attribute>,
46 pub default_attrs: HashMap<String, Value>,
48 pub content_match: Option<ContentMatch>,
50 pub mark_set: Option<Vec<MarkDefinition>>,
52}
53impl Debug for NodeDefinition {
54 fn fmt(
55 &self,
56 f: &mut fmt::Formatter<'_>,
57 ) -> fmt::Result {
58 f.debug_struct("NodeType")
59 .field("name", &self.name)
60 .field("spec", &self.spec)
61 .field("desc", &self.desc)
62 .field("groups", &self.groups)
63 .field("attrs", &self.attrs)
64 .field("default_attrs", &self.default_attrs)
65 .field("mark_set", &self.mark_set)
66 .finish()
67 }
68}
69
70impl NodeDefinition {
71 pub fn compile(
79 nodes: HashMap<String, NodeSpec>
80 ) -> HashMap<String, NodeDefinition> {
81 let mut result = HashMap::new();
82
83 for (name, spec) in &nodes {
85 result.insert(
86 name.clone(),
87 NodeDefinition::new(name.clone(), spec.clone()),
88 );
89 }
90
91 let result_clone = result.clone();
93 for (_, node_type) in result.iter_mut() {
94 if let Some(content) = &node_type.spec.content {
95 node_type.content_match =
96 Some(ContentMatch::parse(content.clone(), &result_clone));
97 }
98 }
99
100 result
101 }
102 pub fn new(
111 name: String,
112 spec: NodeSpec,
113 ) -> Self {
114 let attrs = spec.attrs.as_ref().map_or_else(HashMap::new, |attrs| {
115 attrs
116 .iter()
117 .map(|(name, spec)| {
118 (name.clone(), Attribute::new(spec.clone()))
119 })
120 .collect()
121 });
122
123 let default_attrs = attrs
124 .iter()
125 .filter_map(|(name, attr)| {
126 match (&attr.has_default, &attr.default) {
127 (true, Some(v)) => Some((name.clone(), v.clone())),
128 _ => None,
129 }
130 })
131 .collect();
132
133 NodeDefinition {
134 name,
135 spec,
136 desc: "".to_string(),
137 groups: vec![],
138 attrs,
139 default_attrs,
140 content_match: None,
141 mark_set: None,
142 }
143 }
144 pub fn check_content(
153 &self,
154 content: &[Node],
155 schema: &Schema,
156 ) -> bool {
157 if let Some(content_match) = &self.content_match {
158 if let Some(result) = content_match.match_fragment(content, schema)
159 {
160 if !result.valid_end {
161 return false;
162 }
163 }
164 }
165 true
166 }
167 pub fn check_attrs(
177 &self,
178 values: &Attrs,
179 ) {
180 for (key, _value) in values.attrs.iter() {
181 if !self.attrs.contains_key(key) {
182 panic!("节点 {} 属性 {}没有定义", self.name, key);
183 }
184 }
185 for (key, value) in &self.attrs {
186 if value.is_required() && !&values.contains_key(key) {
187 panic!("节点 {} 属性 {} 没有值,这个属性必填", self.name, key);
188 }
189 }
190 }
191
192 pub fn has_required_attrs(&self) -> bool {
194 self.attrs.values().any(|attr: &Attribute| attr.is_required())
195 }
196
197 pub fn create_and_fill(
199 &self,
200 id: Option<NodeId>,
201 attrs: Option<&HashMap<String, Value>>,
202 content: Vec<Node>,
203 marks: Option<Vec<Mark>>,
204 schema: &Schema,
205 ) -> NodeTree {
206 schema.factory()
207 .create_tree_with_type(self, id, attrs, content, marks)
208 .expect("NodeFactory::create_tree_with_type should succeed for compiled schema")
209 }
210
211 pub fn create(
213 &self,
214 id: Option<NodeId>,
215 attrs: Option<&HashMap<String, Value>>,
216 content: Vec<NodeId>,
217 marks: Option<Vec<Mark>>,
218 ) -> Node {
219 let id: NodeId = id.unwrap_or_else(IdGenerator::get_id);
220
221 Node::new(
222 &id,
223 self.name.clone(),
224 self.compute_attrs(attrs),
225 content,
226 self.compute_marks(marks),
227 )
228 }
229
230 pub(crate) fn compute_marks(
231 &self,
232 marks: Option<Vec<Mark>>,
233 ) -> Vec<Mark> {
234 match (&self.mark_set, marks) {
235 (Some(def), Some(marks)) => def
236 .iter()
237 .filter_map(|mark_type| {
238 marks.iter().find(|m| m.r#type == mark_type.name).cloned()
239 })
240 .collect(),
241 (None, Some(marks)) => marks,
242 _ => vec![],
243 }
244 }
245
246 pub(crate) fn compute_attrs(
247 &self,
248 attrs: Option<&HashMap<String, Value>>,
249 ) -> Attrs {
250 match attrs {
251 Some(attr) => compute_attrs(&self.attrs, Some(attr)),
252 None => compute_attrs(&self.attrs, Some(&self.default_attrs)),
253 }
254 }
255}
256
257#[derive(Clone, PartialEq, Debug, Eq, Default)]
261pub struct NodeSpec {
262 pub content: Option<String>,
264 pub marks: Option<String>,
266 pub group: Option<String>,
268 pub desc: Option<String>,
270 pub attrs: Option<HashMap<String, AttributeSpec>>,
272}
273
274
275
276
277