1use std::fmt;
2
3#[derive(Debug, PartialEq, Clone)]
4pub struct Constituent<T> {
5 pub value: T,
6 pub span: (usize, usize),
7}
8
9impl<T> fmt::Display for Constituent<T>
10where
11 T: fmt::Display,
12{
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 write!(f, "{}..{}: {}", self.span.0, self.span.1, self.value)
15 }
16}
17
18#[derive(Debug, PartialEq, Clone)]
19pub struct Word<U> {
20 pub value: U,
21 pub span: (usize, usize),
22}
23
24impl<U> fmt::Display for Word<U>
25where
26 U: fmt::Display,
27{
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 write!(f, "{}..{}: {}", self.span.0, self.span.1, self.value)
30 }
31}
32
33#[derive(Debug, PartialEq, Clone)]
34pub enum SynTree<T, U> {
35 Branch(Constituent<T>, Vec<SynTree<T, U>>),
36 Leaf(Word<U>),
37}
38
39impl<T, U> SynTree<T, U> {
40 pub fn is_leaf(&self) -> bool {
41 match self {
42 Self::Leaf(_) => true,
43 _ => false,
44 }
45 }
46
47 pub fn is_branch(&self) -> bool {
48 match self {
49 Self::Branch(_, _) => true,
50 _ => false,
51 }
52 }
53
54 pub fn get_leaf(&self) -> Option<&Word<U>> {
55 match self {
56 Self::Leaf(w) => Some(w),
57 _ => None,
58 }
59 }
60
61 pub fn get_branch(&self) -> Option<(&Constituent<T>, &Vec<SynTree<T, U>>)> {
62 match self {
63 Self::Branch(c, cs) => Some((c, cs)),
64 _ => None,
65 }
66 }
67
68 pub fn into_branch(self) -> Option<(Constituent<T>, Vec<SynTree<T, U>>)> {
69 match self {
70 Self::Branch(c, cs) => Some((c, cs)),
71 _ => None,
72 }
73 }
74
75 pub fn map<V, W>(
76 &self,
77 map_branch: fn(&Constituent<T>) -> V,
78 map_leaf: fn(&Word<U>) -> W,
79 ) -> SynTree<V, W> {
80 match self {
81 Self::Branch(t, children) => {
82 let children = children
83 .iter()
84 .map(|c| c.map(map_branch, map_leaf))
85 .collect::<Vec<_>>();
86 SynTree::Branch(
87 Constituent {
88 span: t.span,
89 value: map_branch(&t),
90 },
91 children,
92 )
93 }
94 Self::Leaf(u) => SynTree::Leaf(Word {
95 span: u.span,
96 value: map_leaf(u),
97 }),
98 }
99 }
100}
101
102impl<T, U> fmt::Display for SynTree<T, U>
103where
104 T: fmt::Display,
105 U: fmt::Display,
106{
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match self {
109 Self::Leaf(t) => write!(f, "{}", t),
110 Self::Branch(t, ts) => {
111 write!(f, "({}", t)?;
112 if ts.len() == 1 {
113 write!(f, " ({}))", ts[0])
114 } else {
115 for t in ts.iter() {
116 let fmt = format!("{}", t);
118 for line in fmt.lines() {
119 write!(f, "\n {}", line)?;
120 }
121 }
122 write!(f, ")")
123 }
124 }
125 }
126 }
127}