1use std::mem;
2use std::rc::Rc;
3
4use serde_json::value::to_value;
5use serde_json::{Map, Value};
6
7use crate::entities::re::{
8 ApplyError, ApplyResponse, ApplyResult, ParseJsonError, PossibleBegin, ReType, State,
9};
10use crate::js_tools::{FieldGetter, UsizeFieldGetter, ValueFieldGetter};
11use crate::proto::builders::IJsonParser;
12use crate::proto::into_re::IntoRe;
13use crate::proto::re::{compile_if_required, IRe};
14
15const PRIMARY_KEY: &str = "repeat";
16const MIN_KEY: &str = "min";
17const MAX_KEY: &str = "max";
18
19pub struct Re {
20 re: Rc<dyn IRe>,
21 min: Option<usize>,
22 max: Option<usize>,
23 next_re: Option<Rc<dyn IRe>>,
24}
25
26struct LoopState {
27 begin: usize,
28 count: usize,
29 result: Option<ApplyResponse>,
30 stop_flag: bool,
31}
32
33impl Re {
34 pub fn one_or_more<T: IntoRe>(re: T) -> Re {
35 Re {
36 re: re.into_ire(),
37 min: Some(1),
38 max: None,
39 next_re: None,
40 }
41 }
42
43 pub fn zero_or_more<T: IntoRe>(re: T) -> Re {
44 Re {
45 re: re.into_ire(),
46 min: None,
47 max: None,
48 next_re: None,
49 }
50 }
51
52 pub fn custom<T: IntoRe>(re: T, min: Option<usize>, max: Option<usize>) -> Re {
53 Re {
54 re: re.into_ire(),
55 min,
56 max,
57 next_re: None,
58 }
59 }
60
61 pub fn parse_dict(
62 parser: &dyn IJsonParser,
63 dict: &Map<String, Value>,
64 ) -> Result<Option<Rc<dyn IRe>>, ParseJsonError> {
65 let opt_re = ValueFieldGetter::with_primary_field(dict, PRIMARY_KEY, &|val| {
66 parser.parse_json(val)
67 })?;
68 let re = match opt_re {
69 Some(val) => val,
70 _ => return Ok(None),
71 };
72 let min = UsizeFieldGetter::with_param_nullable_field(dict, MIN_KEY, &|val| {
73 Ok(val.cloned())
74 })?;
75 let max = UsizeFieldGetter::with_param_nullable_field(dict, MAX_KEY, &|val| {
76 Ok(val.cloned())
77 })?;
78 Ok(Some(
79 Re {
80 re,
81 min,
82 max,
83 next_re: None,
84 }
85 .into_ire(),
86 ))
87 }
88
89 fn try_finalize_seq(
90 &self,
91 accum: Option<ApplyResponse>,
92 count: usize,
93 ) -> Result<ApplyResponse, ApplyError> {
94 match self.min {
95 Some(ref val) if count < *val => return Err(ApplyError::NotMatched),
96 _ => (),
97 };
98 if count == 0 {
99 return Err(ApplyError::Empty);
100 }
101 Ok(accum.unwrap())
102 }
103
104 fn apply_iteration(
105 &self,
106 global_state: &mut State,
107 loop_state: &mut LoopState,
108 ) -> Result<(), ApplyError> {
109 match self.re.apply(global_state, loop_state.begin) {
110 Ok(applied) => {
111 let begin = applied.index;
112 let acc = mem::replace(&mut loop_state.result, None);
113 let joined = ApplyResponse::join_acc(acc, applied);
114 loop_state.result = Some(joined);
115 loop_state.count += 1;
116 loop_state.begin = begin;
117 Ok(())
118 }
119 Err(ApplyError::NotMatched) => {
120 let acc = mem::replace(&mut loop_state.result, None);
121 let result = self.try_finalize_seq(acc, loop_state.count)?;
122 loop_state.result = Some(result);
123 loop_state.stop_flag = true;
124 Ok(())
125 }
126 Err(err) => Err(err),
127 }
128 }
129
130 fn try_next_re(&self, state: &mut State, begin: usize) -> bool {
131 if let Some(ref re) = self.next_re {
132 re.apply(state, begin).is_ok()
133 } else {
134 false
135 }
136 }
137}
138
139impl IRe for Re {
140 fn get_type(&self) -> ReType {
141 ReType::Repeat
142 }
143
144 fn apply(&self, global_state: &mut State, begin: usize) -> ApplyResult {
145 let min_count = self.min.unwrap_or(0);
146 let mut loop_state = LoopState {
147 begin,
148 count: 0,
149 result: None,
150 stop_flag: false,
151 };
152 while Some(loop_state.count) != self.max {
153 if loop_state.count >= min_count
154 && self.next_re.is_some()
155 && self.try_next_re(global_state, loop_state.begin)
156 {
157 return self.try_finalize_seq(loop_state.result, loop_state.count);
158 }
159 self.apply_iteration(global_state, &mut loop_state)?;
160 if loop_state.stop_flag {
161 return Ok(loop_state.result.unwrap());
162 }
163 }
164 Ok(loop_state.result.unwrap())
165 }
166
167 fn show(&self) -> String {
168 format!(
169 "{}{},{}>{},{}{}",
170 '{',
171 self.re.show(),
172 self.min
173 .as_ref()
174 .map_or("_".to_string(), |x| { x.to_string() }),
175 self.max
176 .as_ref()
177 .map_or("_".to_string(), |x| { x.to_string() }),
178 self.next_re.is_some(),
179 '}'
180 )
181 }
182
183 fn to_json(&self) -> Value {
184 Value::Object(
185 vec![
186 ("repeat".to_string(), self.re.to_json()),
187 ("min".to_string(), to_value(self.min).unwrap()),
188 ("max".to_string(), to_value(self.max).unwrap()),
189 ]
190 .into_iter()
191 .collect(),
192 )
193 }
194
195 fn is_any(&self) -> bool {
196 self.re.is_any()
197 }
198
199 fn get_children(&self) -> Vec<Rc<dyn IRe>> {
200 vec![self.re.clone()]
201 }
202
203 fn compilation_required(&self) -> bool {
204 if matches!(self.re.get_type(), ReType::Repeat) {
205 panic!("Repeat is direct child of repeat")
206 }
207 self.re.compilation_required() || self.max.is_none()
208 }
209
210 fn possible_begin(&self) -> PossibleBegin {
211 if self.min.unwrap_or(0) > 0 {
212 self.re.possible_begin()
213 } else {
214 PossibleBegin::Any
215 }
216 }
217
218 fn compile(&self, mut next_re: Option<Rc<dyn IRe>>) -> Rc<dyn IRe> {
219 let re = compile_if_required(self.re.clone(), next_re.clone());
220 let probe_required = if let Some(ref next) = next_re {
221 re.possible_begin().has_intersection(&next.possible_begin())
222 } else {
223 false
224 };
225 if self.max.is_some() || !probe_required {
226 next_re = None;
227 }
228 Re {
229 re,
230 next_re,
231 min: self.min,
232 max: self.max,
233 }
234 .into_ire()
235 }
236}