1use super::attrs::Attrs;
2use super::content::ContentMatch;
3use super::mark::Mark;
4use super::mark_definition::MarkDefinition;
5use super::node::Node;
6use super::schema::{compute_attrs, Attribute, AttributeSpec, Schema};
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use std::collections::HashMap;
10use std::fmt::{self, Debug};
11
12#[derive(Clone, Debug, Serialize, Deserialize)]
13pub struct NodeTree(pub Node, pub Vec<NodeTree>);
14
15impl NodeTree {
16 pub fn into_parts(self) -> (Node, Vec<NodeTree>) {
17 match self {
18 NodeTree(node, children) => (node, children),
19 }
20 }
21 pub fn from(
22 node: Node,
23 childs: Vec<Node>,
24 ) -> Self {
25 NodeTree(
26 node,
27 childs.into_iter().map(|n| NodeTree(n, vec![])).collect(),
28 )
29 }
30}
31#[derive(Clone, PartialEq, Eq)]
33pub struct NodeDefinition {
34 pub name: String,
36 pub spec: NodeSpec,
38 pub desc: String,
40 pub groups: Vec<String>,
42 pub attrs: HashMap<String, Attribute>,
44 pub default_attrs: HashMap<String, Value>,
46 pub content_match: Option<ContentMatch>,
48 pub mark_set: Option<Vec<MarkDefinition>>,
50}
51impl Debug for NodeDefinition {
52 fn fmt(
53 &self,
54 f: &mut fmt::Formatter<'_>,
55 ) -> fmt::Result {
56 f.debug_struct("NodeType")
57 .field("name", &self.name)
58 .field("spec", &self.spec)
59 .field("desc", &self.desc)
60 .field("groups", &self.groups)
61 .field("attrs", &self.attrs)
62 .field("default_attrs", &self.default_attrs)
63 .field("mark_set", &self.mark_set)
64 .finish()
65 }
66}
67
68impl NodeDefinition {
69 pub fn compile(
77 nodes: HashMap<String, NodeSpec>
78 ) -> HashMap<String, NodeDefinition> {
79 let mut result = HashMap::new();
80
81 for (name, spec) in &nodes {
83 result.insert(
84 name.clone(),
85 NodeDefinition::new(name.clone(), spec.clone()),
86 );
87 }
88
89 let result_clone = result.clone();
91 for (_, node_type) in result.iter_mut() {
92 if let Some(content) = &node_type.spec.content {
93 node_type.content_match =
94 Some(ContentMatch::parse(content.clone(), &result_clone));
95 }
96 }
97
98 result
99 }
100 pub fn new(
109 name: String,
110 spec: NodeSpec,
111 ) -> Self {
112 let attrs = spec.attrs.as_ref().map_or_else(HashMap::new, |attrs| {
113 attrs
114 .iter()
115 .map(|(name, spec)| {
116 (name.clone(), Attribute::new(spec.clone()))
117 })
118 .collect()
119 });
120
121 let default_attrs = attrs
122 .iter()
123 .filter_map(|(name, attr)| {
124 match (&attr.has_default, &attr.default) {
125 (true, Some(v)) => Some((name.clone(), v.clone())),
126 _ => None,
127 }
128 })
129 .collect();
130
131 NodeDefinition {
132 name,
133 spec,
134 desc: "".to_string(),
135 groups: vec![],
136 attrs,
137 default_attrs,
138 content_match: None,
139 mark_set: None,
140 }
141 }
142 pub fn check_content(
151 &self,
152 content: &[Node],
153 schema: &Schema,
154 ) -> bool {
155 if let Some(content_match) = &self.content_match {
156 if let Some(result) = content_match.match_fragment(content, schema)
157 {
158 if !result.valid_end {
159 return false;
160 }
161 }
162 }
163 true
164 }
165 pub fn check_attrs(
175 &self,
176 values: &Attrs,
177 ) {
178 for (key, _value) in values.attrs.iter() {
179 if !self.attrs.contains_key(key) {
180 panic!("节点 {} 属性 {}没有定义", self.name, key);
181 }
182 }
183 for (key, value) in &self.attrs {
184 if value.is_required() && !&values.contains_key(key) {
185 panic!("节点 {} 属性 {} 没有值,这个属性必填", self.name, key);
186 }
187 }
188 }
189
190 pub fn has_required_attrs(&self) -> bool {
192 self.attrs.values().any(|attr: &Attribute| attr.is_required())
193 }
194
195 pub(crate) fn compute_marks(
196 &self,
197 marks: Option<Vec<Mark>>,
198 ) -> Vec<Mark> {
199 match (&self.mark_set, marks) {
200 (Some(def), Some(marks)) => def
201 .iter()
202 .filter_map(|mark_type| {
203 marks.iter().find(|m| m.r#type == mark_type.name).cloned()
204 })
205 .collect(),
206 (None, Some(marks)) => marks,
207 _ => vec![],
208 }
209 }
210
211 pub(crate) fn compute_attrs(
212 &self,
213 attrs: Option<&HashMap<String, Value>>,
214 ) -> Attrs {
215 match attrs {
216 Some(attr) => compute_attrs(&self.attrs, Some(attr)),
217 None => compute_attrs(&self.attrs, Some(&self.default_attrs)),
218 }
219 }
220}
221
222#[derive(Clone, PartialEq, Debug, Eq, Default)]
226pub struct NodeSpec {
227 pub content: Option<String>,
229 pub marks: Option<String>,
231 pub group: Option<String>,
233 pub desc: Option<String>,
235 pub attrs: Option<HashMap<String, AttributeSpec>>,
237}