1use serde::Serialize;
2use serde_json::Value;
3use std::collections::HashMap;
4
5use crate::attrs::Attrs;
6
7use super::mark::Mark;
8use super::schema::{Attribute, AttributeSpec, compute_attrs};
9#[derive(Clone, PartialEq, Debug, Eq)]
10pub struct MarkType {
11 pub name: String,
12 pub rank: usize,
13 pub spec: MarkSpec,
14 pub attrs: HashMap<String, Attribute>,
15 pub excluded: Option<Vec<MarkType>>,
16}
17
18impl MarkType {
19 pub(crate) fn compile(
20 marks: HashMap<String, MarkSpec>
21 ) -> HashMap<String, MarkType> {
22 let mut result = HashMap::new();
23
24 for (rank, (name, spec)) in marks.into_iter().enumerate() {
25 result.insert(
26 name.clone(),
27 MarkType::new(name.clone(), rank, spec.clone()),
28 );
29 }
30
31 result
32 }
33
34 fn new(
35 name: String,
36 rank: usize,
37 spec: MarkSpec,
38 ) -> Self {
39 let attrs = spec.attrs.as_ref().map_or_else(HashMap::new, |attrs| {
40 attrs
41 .iter()
42 .map(|(name, spec)| {
43 (name.clone(), Attribute::new(spec.clone()))
44 })
45 .collect()
46 });
47
48 MarkType { name, rank, spec, attrs, excluded: None }
49 }
50
51 pub fn create(
52 &self,
53 attrs: Option<&HashMap<String, Value>>,
54 ) -> Mark {
55 Mark { r#type: self.name.clone(), attrs: self.compute_attrs(attrs) }
56 }
57 pub fn compute_attrs(
58 &self,
59 attrs: Option<&HashMap<String, Value>>,
60 ) -> Attrs {
61 match attrs {
62 Some(attr) => compute_attrs(&self.attrs, Some(attr)),
63 None => compute_attrs(&self.attrs, None),
64 }
65 }
66
67 }
69
70#[derive(Clone, PartialEq, Eq, Debug, Serialize, Default)]
71pub struct MarkSpec {
72 pub attrs: Option<HashMap<String, AttributeSpec>>,
73 pub excludes: Option<String>,
74 pub group: Option<String>,
75 pub spanning: Option<bool>,
76 pub desc: Option<String>,
77}