smt_scope/formatter/
defns_const.rs1use crate::NonMaxU32;
2
3use super::{defns::*, ConversionError, FormatterParseError};
4
5#[derive(Debug)]
6pub struct TermDisplayConst<'a> {
7 pub matcher: MatcherConst<'a>,
8 pub formatter: FormatterConst<'a>,
9}
10
11impl TryFrom<TermDisplayConst<'_>> for TermDisplay {
12 type Error = ConversionError;
13 fn try_from(t: TermDisplayConst) -> Result<Self, Self::Error> {
14 let matcher = Matcher::try_from(t.matcher)?;
15 let formatter = Formatter::try_from(t.formatter)?;
16 Self::new(matcher, formatter)
17 }
18}
19
20#[derive(Debug)]
21pub struct MatcherConst<'a> {
22 pub data: &'a str,
23 pub children: Option<NonMaxU32>,
24 pub kind: MatcherKindConst,
25}
26
27#[derive(Debug)]
28pub enum MatcherKindConst {
29 Exact,
30 Regex,
31}
32
33impl TryFrom<MatcherConst<'_>> for Matcher {
34 type Error = regex::Error;
35 fn try_from(m: MatcherConst<'_>) -> Result<Self, Self::Error> {
36 let kind = match m.kind {
37 MatcherKindConst::Exact => MatcherKind::Exact(m.data.to_string()),
38 MatcherKindConst::Regex => {
39 MatcherKind::Regex(RegexMatcher::new(format!("^(?:{})$", m.data))?)
40 }
41 };
42 Ok(Matcher {
43 children: m.children,
44 kind,
45 })
46 }
47}
48
49#[derive(Debug)]
50pub struct FormatterConst<'a> {
51 pub bind_power: BindPowerPair,
56
57 pub outputs: [Option<SubFormatterConst<'a>>; 64],
59}
60
61impl TryFrom<FormatterConst<'_>> for Formatter {
62 type Error = FormatterParseError;
63 fn try_from(f: FormatterConst<'_>) -> Result<Self, Self::Error> {
64 let outputs: Vec<_> = f
65 .outputs
66 .into_iter()
67 .map_while(|o| o)
68 .map(SubFormatter::try_from)
69 .collect::<Result<_, _>>()?;
70 let mut self_ = Self {
71 bind_power: f.bind_power,
72 outputs,
73 max_capture: None,
74 };
75 self_.calculate_max_capture();
76 Ok(self_)
77 }
78}
79
80impl<'a> FormatterConst<'a> {
81 pub const fn max_capture(&self) -> Option<NonMaxU32> {
83 let mut max_capture = None::<NonMaxU32>;
84 let mut idx = 0;
85 while idx < self.outputs.len() {
86 let Some(output) = &self.outputs[idx] else {
87 break;
88 };
89 if let SubFormatterConst::Capture(idx) = output {
90 max_capture = match max_capture {
91 Some(max) if max.get() >= idx.get() => Some(max),
92 _ => Some(*idx),
93 };
94 }
95 idx += 1;
96 }
97 max_capture
98 }
99}
100
101#[derive(Debug)]
102pub enum SubFormatterConst<'a> {
103 String(SubFormatterString<'a>),
105 Single(SubFormatterSingle),
106 Repeat(SubFormatterRepeatConst<'a>),
107 Capture(NonMaxU32),
108}
109
110impl TryFrom<SubFormatterConst<'_>> for SubFormatter {
111 type Error = FormatterParseError;
112 fn try_from(sub: SubFormatterConst<'_>) -> Result<Self, Self::Error> {
113 let sf = match sub {
114 SubFormatterConst::String(s) => {
115 let c = s.control_deduplicate.then_some(CONTROL_CHARACTER);
116 let data = deduplicate_character(s.data, c);
117 SubFormatter::String(data)
118 }
119 SubFormatterConst::Single(s) => SubFormatter::Single {
120 path: s.path.into(),
121 index: s.index,
122 bind_power: s.bind_power,
123 },
124 SubFormatterConst::Repeat(s) => SubFormatter::Repeat(s.try_into()?),
125 SubFormatterConst::Capture(idx) => SubFormatter::Capture(idx),
126 };
127 Ok(sf)
128 }
129}
130
131impl From<[Option<ChildIndex>; 8]> for ChildPath {
132 fn from(path: [Option<ChildIndex>; 8]) -> Self {
133 ChildPath(path.into_iter().flatten().collect())
134 }
135}
136
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138#[derive(Debug, Clone, PartialEq, Eq)]
139pub struct SubFormatterSingle {
140 pub path: [Option<ChildIndex>; 8],
141 pub index: ChildIndex,
142 pub bind_power: BindPowerPair,
144}
145
146#[derive(Debug)]
147pub struct SubFormatterString<'a> {
148 pub data: &'a str,
149 pub control_deduplicate: bool,
150}
151
152#[derive(Debug)]
153pub struct SubFormatterRepeatConst<'a> {
154 pub range: ChildRange,
155 pub left_sep: SubFormatterRepeatSeparator<'a>,
156 pub middle_sep: SubFormatterRepeatSeparator<'a>,
157 pub right_sep: SubFormatterRepeatSeparator<'a>,
158 pub left: BindPower,
159 pub middle: BindPowerPair,
160 pub right: BindPower,
161}
162
163impl TryFrom<SubFormatterRepeatConst<'_>> for SubFormatterRepeat {
164 type Error = FormatterParseError;
165 fn try_from(sub: SubFormatterRepeatConst<'_>) -> Result<Self, Self::Error> {
166 let left_sep = String::from(sub.left_sep);
167 let left_sep = left_sep.parse::<Formatter>()?;
168 let middle_sep = String::from(sub.middle_sep);
169 let middle_sep = middle_sep.parse::<Formatter>()?;
170 let right_sep = String::from(sub.right_sep);
171 let right_sep = right_sep.parse::<Formatter>()?;
172 Ok(Self {
173 path: sub.range.path.into(),
174 from: sub.range.from,
175 to: sub.range.to,
176 left_sep,
177 middle_sep,
178 right_sep,
179 left: sub.left,
180 middle: sub.middle,
181 right: sub.right,
182 })
183 }
184}
185
186#[derive(Debug)]
187pub struct SubFormatterRepeatSeparator<'a> {
188 pub separator_deduplicate: bool,
191 pub separator: &'a str,
192}
193
194impl From<SubFormatterRepeatSeparator<'_>> for String {
195 fn from(sep: SubFormatterRepeatSeparator<'_>) -> Self {
196 let c = sep.separator_deduplicate.then_some(SEPARATOR_CHARACTER);
197 deduplicate_character(sep.separator, c)
198 }
199}
200
201impl SubFormatterRepeatSeparator<'static> {
202 pub const fn default() -> Self {
203 Self {
204 separator_deduplicate: false,
205 separator: "",
206 }
207 }
208}
209
210#[derive(Debug)]
211pub struct ChildRange {
212 pub path: [Option<ChildIndex>; 8],
213 pub from: ChildIndex,
214 pub to: ChildIndex,
215}
216
217fn deduplicate_character(s: &str, c: Option<char>) -> String {
218 if let Some(c) = c {
219 let mut to: [u8; 4] = [0; 4];
220 let to = c.encode_utf8(&mut to);
221 s.replace([c, c], to)
222 } else {
223 s.to_string()
224 }
225}