1use std::any::TypeId;
2use std::cell::RefCell;
3use std::iter::once;
4use std::ops::Deref;
5use std::ops::DerefMut;
6use std::path::Path;
7use std::rc::Rc;
8
9use rhai::CustomType;
10use rhai::{
11 packages::{CorePackage, Package},
12 plugin::*,
13 Dynamic, Engine, EvalAltResult, ImmutableString, Scope, Variant, FLOAT, INT,
14};
15
16use crate::internal::ToBe;
17
18#[export_module]
19mod script_format {
20 pub const NL: &str = "\n";
21}
22
23pub type ScriptResult<T> = Result<T, Box<EvalAltResult>>;
47
48pub struct FormattingEngine {
68 engine: Engine,
69 messages: Rc<RefCell<Vec<String>>>,
70}
71
72impl Deref for FormattingEngine {
73 type Target = Engine;
74
75 fn deref(&self) -> &Self::Target {
76 &self.engine
77 }
78}
79
80impl DerefMut for FormattingEngine {
81 fn deref_mut(&mut self) -> &mut Self::Target {
82 &mut self.engine
83 }
84}
85
86impl FormattingEngine {
87 fn register_value<T: Variant + Clone + std::fmt::Display>(&mut self) {
88 self.engine
89 .register_fn("++", move |a: T, b: serde_value::Value| {
90 vec![a.to_string(), serde_json::to_string(&b).unwrap()]
91 });
92 self.engine
93 .register_fn("++", move |a: serde_value::Value, b: T| {
94 vec![serde_json::to_string(&a).unwrap(), b.to_string()]
95 });
96 }
97
98 fn register_string_concat_void<T: Variant + Clone + std::fmt::Display>(&mut self) {
99 self.engine
100 .register_fn("++", move |a: T, _b: ()| vec![a.to_string()]);
101 self.engine
102 .register_fn("++", move |_a: (), b: T| vec![b.to_string()]);
103 }
104
105 fn register_string_concat<T: Variant + Clone + std::fmt::Display>(&mut self) {
106 self.engine.register_fn("++", move |a: T, b: &str| {
107 vec![a.to_string(), b.to_string()]
108 });
109 self.engine.register_fn("++", move |a: &str, b: T| {
110 vec![a.to_string(), b.to_string()]
111 });
112 self.engine
113 .register_fn("++", move |a: T, b: T| vec![a.to_string(), b.to_string()]);
114 }
115
116 fn register_string_concat_vec<T: Variant + Clone + std::fmt::Display>(&mut self) {
117 self.engine.register_fn("++", move |a: Vec<T>, b: &str| {
118 a.iter()
119 .map(ToString::to_string)
120 .chain(once(b.to_owned()))
121 .collect::<Vec<_>>()
122 });
123 self.engine.register_fn("++", move |a: &str, b: Vec<T>| {
124 b.iter()
125 .map(ToString::to_string)
126 .chain(once(a.to_owned()))
127 .collect::<Vec<_>>()
128 });
129 self.engine.register_fn("++", move |a: Vec<T>, b: Vec<T>| {
130 a.iter()
131 .map(ToString::to_string)
132 .chain(b.iter().map(ToString::to_string))
133 .collect::<Vec<_>>()
134 });
135 }
136
137 fn register_concat<T: Variant + Clone + std::fmt::Display>(&mut self) {
138 self.register_string_concat::<T>();
139 self.register_string_concat_vec::<T>();
140 self.register_string_concat_void::<T>();
141 }
142
143 fn register_msg<T: Variant + Clone + std::fmt::Display>(&mut self) {
144 self.register_msg_single::<T>();
145 self.register_msg_multi::<T, &str>();
146 self.register_msg_multi::<T, String>();
147 self.register_msg_multi::<T, bool>();
148 self.register_msg_multi::<T, i64>();
149 self.register_msg_multi::<T, u64>();
150 self.register_msg_multi::<T, i32>();
151 self.register_msg_multi::<T, u32>();
152 self.register_msg_multi::<T, i16>();
153 self.register_msg_multi::<T, u16>();
154 self.register_msg_multi::<T, i8>();
155 self.register_msg_multi::<T, u8>();
156 self.register_msg_multi::<T, usize>();
157 self.register_msg_multi::<T, isize>();
158 self.register_msg_multi::<T, i128>();
159 self.register_msg_multi::<T, u128>();
160 self.register_msg_multi::<T, f32>();
161 self.register_msg_multi::<T, f64>();
162 }
163
164 fn register_msg_multi<
165 A: Variant + Clone + std::fmt::Display,
166 B: Variant + Clone + std::fmt::Display,
167 >(
168 &mut self,
169 ) {
170 self.engine
171 .register_fn("++", move |a: A, b: B| vec![a.to_string(), b.to_string()]);
172
173 self.engine
174 .register_fn("++", move |b: B, a: A| vec![b.to_string(), a.to_string()]);
175
176 self.engine.register_fn("++", move |a: Option<A>, b: B| {
177 if let Some(a) = a {
178 vec![a.to_string(), b.to_string()]
179 } else {
180 vec![b.to_string()]
181 }
182 });
183
184 self.engine.register_fn("++", move |a: A, b: Option<B>| {
185 if let Some(b) = b {
186 vec![a.to_string(), b.to_string()]
187 } else {
188 vec![a.to_string()]
189 }
190 });
191
192 self.engine
193 .register_fn("++", move |a: Option<A>, b: Option<B>| match (a, b) {
194 (Some(a), Some(b)) => vec![a.to_string(), b.to_string()],
195 (Some(a), None) => vec![a.to_string()],
196 (None, Some(b)) => vec![b.to_string()],
197 (None, None) => vec![],
198 });
199 }
200
201 fn register_msg_single<T: Variant + Clone + std::fmt::Display>(&mut self) {
202 self.engine.register_fn("++", move |a: Option<T>, _: ()| {
203 if let Some(a) = a {
204 vec![a.to_string()]
205 } else {
206 vec![]
207 }
208 });
209
210 self.engine.register_fn("++", move |_: (), a: Option<T>| {
211 if let Some(a) = a {
212 vec![a.to_string()]
213 } else {
214 vec![]
215 }
216 });
217 }
218
219 fn register_vec<T: Variant + Clone>(&mut self) {
220 self.engine
221 .register_type::<Vec<T>>()
222 .register_fn("len", |v: Vec<T>| v.len())
223 .register_iterator::<Vec<T>>()
224 .register_iterator::<&Vec<&T>>()
225 .register_iterator::<Vec<T>>()
226 .register_iterator::<&Vec<&T>>()
227 .register_indexer_get(|v: &mut Vec<T>, i: i64| {
228 v[usize::try_from(i).unwrap()].to_owned()
229 });
230 }
231
232 fn register_vec_printable<T: Variant + Clone + std::fmt::Display>(&mut self) {
233 self.register_vec::<T>();
234 self.engine.register_fn("++", move |a: Vec<T>| {
235 a.iter().map(ToString::to_string).collect::<Vec<_>>()
236 });
237
238 self.register_vec_printable_single::<T, &str>();
239 self.register_vec_printable_single::<T, String>();
240 self.register_vec_printable_single::<T, bool>();
241 self.register_vec_printable_single::<T, i64>();
242 self.register_vec_printable_single::<T, u64>();
243 self.register_vec_printable_single::<T, i32>();
244 self.register_vec_printable_single::<T, u32>();
245 self.register_vec_printable_single::<T, i16>();
246 self.register_vec_printable_single::<T, u16>();
247 self.register_vec_printable_single::<T, i8>();
248 self.register_vec_printable_single::<T, u8>();
249 self.register_vec_printable_single::<T, usize>();
250 self.register_vec_printable_single::<T, isize>();
251 self.register_vec_printable_single::<T, i128>();
252 self.register_vec_printable_single::<T, u128>();
253 self.register_vec_printable_single::<T, f32>();
254 self.register_vec_printable_single::<T, f64>();
255
256 self.register_vec_printable_multi::<T, &str>();
257 self.register_vec_printable_multi::<T, String>();
258 self.register_vec_printable_multi::<T, bool>();
259 self.register_vec_printable_multi::<T, i64>();
260 self.register_vec_printable_multi::<T, u64>();
261 self.register_vec_printable_multi::<T, i32>();
262 self.register_vec_printable_multi::<T, u32>();
263 self.register_vec_printable_multi::<T, i16>();
264 self.register_vec_printable_multi::<T, u16>();
265 self.register_vec_printable_multi::<T, i8>();
266 self.register_vec_printable_multi::<T, u8>();
267 self.register_vec_printable_multi::<T, usize>();
268 self.register_vec_printable_multi::<T, isize>();
269 self.register_vec_printable_multi::<T, i128>();
270 self.register_vec_printable_multi::<T, u128>();
271 self.register_vec_printable_multi::<T, f32>();
272 self.register_vec_printable_multi::<T, f64>();
273
274 self.register_vec_printable_void::<&str>();
275 self.register_vec_printable_void::<String>();
276 self.register_vec_printable_void::<bool>();
277 self.register_vec_printable_void::<i64>();
278 self.register_vec_printable_void::<u64>();
279 self.register_vec_printable_void::<i32>();
280 self.register_vec_printable_void::<u32>();
281 self.register_vec_printable_void::<i16>();
282 self.register_vec_printable_void::<u16>();
283 self.register_vec_printable_void::<i8>();
284 self.register_vec_printable_void::<u8>();
285 self.register_vec_printable_void::<usize>();
286 self.register_vec_printable_void::<isize>();
287 self.register_vec_printable_void::<i128>();
288 self.register_vec_printable_void::<u128>();
289 self.register_vec_printable_void::<f32>();
290 self.register_vec_printable_void::<f64>();
291 }
292
293 fn register_vec_printable_void<T: Variant + Clone + std::fmt::Display>(&mut self) {
294 self.engine.register_fn("++", move |a: Vec<T>, _b: ()| {
295 a.iter().map(ToString::to_string).collect::<Vec<_>>()
296 });
297 self.engine.register_fn("++", move |_a: (), b: Vec<T>| {
298 b.iter().map(ToString::to_string).collect::<Vec<_>>()
299 });
300 self.engine
301 .register_fn("++", move |a: Option<Vec<T>>, _b: ()| {
302 a.unwrap_or_default()
303 .iter()
304 .map(ToString::to_string)
305 .collect::<Vec<_>>()
306 });
307 self.engine
308 .register_fn("++", move |_a: (), b: Option<Vec<T>>| {
309 b.unwrap_or_default()
310 .iter()
311 .map(ToString::to_string)
312 .collect::<Vec<_>>()
313 });
314 }
315
316 fn register_vec_printable_multi<
317 A: Variant + Clone + std::fmt::Display,
318 B: Variant + Clone + std::fmt::Display,
319 >(
320 &mut self,
321 ) {
322 self.engine.register_fn("++", move |a: Vec<A>, b: Vec<B>| {
323 a.iter()
324 .map(ToString::to_string)
325 .chain(b.iter().map(ToString::to_string))
326 .collect::<Vec<_>>()
327 });
328
329 self.engine
330 .register_fn("++", move |a: Option<Vec<A>>, b: Vec<B>| {
331 let a: Vec<A> = a.unwrap_or_default();
332 a.iter()
333 .map(ToString::to_string)
334 .chain(b.iter().map(ToString::to_string))
335 .collect::<Vec<_>>()
336 });
337 self.engine
338 .register_fn("++", move |a: Vec<A>, b: Option<Vec<B>>| {
339 let b: Vec<B> = b.unwrap_or_default();
340 a.iter()
341 .map(ToString::to_string)
342 .chain(b.iter().map(ToString::to_string))
343 .collect::<Vec<_>>()
344 });
345 }
346
347 fn register_vec_printable_single<
348 A: Variant + Clone + std::fmt::Display,
349 B: Variant + Clone + std::fmt::Display,
350 >(
351 &mut self,
352 ) {
353 self.engine.register_fn("++", move |a: Vec<A>, b: B| {
354 a.iter()
355 .map(ToString::to_string)
356 .chain(once(b.to_string()))
357 .collect::<Vec<_>>()
358 });
359 self.engine.register_fn("++", move |a: A, b: Vec<B>| {
360 once(a.to_string())
361 .chain(b.iter().map(ToString::to_string))
362 .collect::<Vec<_>>()
363 });
364
365 self.engine
366 .register_fn("++", move |a: Option<Vec<A>>, b: B| {
367 let a: Vec<A> = a.unwrap_or_default();
368 a.iter()
369 .map(ToString::to_string)
370 .chain(once(b.to_string()))
371 .collect::<Vec<_>>()
372 });
373 self.engine
374 .register_fn("++", move |a: A, b: Option<Vec<B>>| {
375 let b: Vec<B> = b.unwrap_or_default();
376 once(a.to_string())
377 .chain(b.iter().map(ToString::to_string))
378 .collect::<Vec<_>>()
379 });
380
381 self.engine
382 .register_fn("++", move |a: Vec<A>, b: Option<B>| {
383 let mut res = a.iter().map(ToString::to_string).collect::<Vec<_>>();
384 if let Some(b) = b {
385 res.push(b.to_string());
386 }
387 res
388 });
389 self.engine
390 .register_fn("++", move |a: Option<A>, b: Vec<B>| {
391 a.iter()
392 .map(ToString::to_string)
393 .chain(b.iter().map(ToString::to_string))
394 .collect::<Vec<_>>()
395 });
396 }
397
398 fn register_type_dynamic<T: Variant + Clone + 'static, C: From<T> + PartialEq + 'static>(
399 &mut self,
400 is_call: fn(&Dynamic) -> bool,
401 as_call: fn(&Dynamic) -> Result<C, &'static str>,
402 ) {
403 self.engine
404 .register_fn("any", move |arr: rhai::Array, v: T| {
405 let value: C = v.into();
406 arr.iter()
407 .filter(|a| is_call(a))
408 .map(|a| {
409 let a: C = as_call(&a).unwrap().into();
410 a
411 })
412 .filter(|a| *a == value)
413 .into_iter()
414 .count()
415 > 0
416 });
417 self.engine
418 .register_fn("all", move |arr: rhai::Array, v: T| {
419 let value: C = v.into();
420 let expected = arr.len();
421 arr.iter()
422 .filter(|a| is_call(a))
423 .map(|a| {
424 let a: C = as_call(&a).unwrap().into();
425 a
426 })
427 .filter(|a| *a == value)
428 .into_iter()
429 .count()
430 == expected
431 });
432 self.engine
433 .register_fn("none", move |arr: rhai::Array, v: T| {
434 let value: C = v.into();
435 arr.iter()
436 .filter(|a| is_call(a))
437 .map(|a| {
438 let a: C = as_call(&a).unwrap().into();
439 a
440 })
441 .filter(|a| *a == value)
442 .into_iter()
443 .count()
444 == 0
445 });
446 }
447
448 fn register_comparison<
449 A: Variant + Clone + AsCast<C>,
450 B: Variant + Clone + AsCast<C>,
451 C: PartialEq + PartialOrd,
452 >(
453 &mut self,
454 ) {
455 self.engine
456 .register_fn(">", |left: A, right: B| left.as_cast() > right.as_cast());
457 self.engine
458 .register_fn(">=", |left: A, right: B| left.as_cast() >= right.as_cast());
459 self.engine
460 .register_fn("<", |left: A, right: B| left.as_cast() < right.as_cast());
461 self.engine
462 .register_fn("<=", |left: A, right: B| left.as_cast() <= right.as_cast());
463 self.engine
464 .register_fn("!=", |left: A, right: B| left.as_cast() != right.as_cast());
465 self.engine
466 .register_fn("==", |left: A, right: B| left.as_cast() == right.as_cast());
467
468 self.engine
469 .register_fn(">", |left: B, right: A| left.as_cast() > right.as_cast());
470 self.engine
471 .register_fn(">=", |left: B, right: A| left.as_cast() >= right.as_cast());
472 self.engine
473 .register_fn("<", |left: B, right: A| left.as_cast() < right.as_cast());
474 self.engine
475 .register_fn("<=", |left: B, right: A| left.as_cast() <= right.as_cast());
476 self.engine
477 .register_fn("!=", |left: B, right: A| left.as_cast() != right.as_cast());
478 self.engine
479 .register_fn("==", |left: B, right: A| left.as_cast() == right.as_cast());
480 }
481
482 fn register_options<T: Variant + Clone>(&mut self) {
483 self.engine
484 .register_fn("is_some", crate::internal::script_is_some::<T>)
485 .register_fn("unwrap", crate::internal::script_unwrap::<T>)
486 .register_fn("unwrap_or", crate::internal::script_unwrap_or::<T>);
487 }
488}
489
490impl FormattingEngine {
491 #[must_use]
501 pub fn new(debug: bool) -> Self {
502 build_engine(debug)
503 }
504
505 pub fn register_type<T: Variant + Clone>(&mut self) -> &mut Self {
518 self.engine.register_type::<T>();
519 self.register_vec::<T>();
520 self.register_options::<T>();
521
522 self
523 }
524
525 pub fn make_comparable<T: Variant + PartialEq + Clone>(&mut self) -> &mut Self {
538 self.register_type::<T>();
539 self.register_options::<T>();
540 self.register_vec::<T>();
541 self.register_fn("any", crate::internal::script_any_type::<T>)
542 .register_fn("all", crate::internal::script_all_type::<T>)
543 .register_fn("none", crate::internal::script_none_type::<T>);
544 self
545 }
546
547 pub fn build_type<T: Variant + CustomType + Clone>(&mut self) -> &mut Self {
578 self.engine.build_type::<T>();
579 self.register_type::<T>();
580 self
581 }
582
583 pub fn format_with_scope(&mut self, scope: &mut Scope, script: &str) -> ScriptResult<String> {
601 self.messages.borrow_mut().clear();
602 self.engine.run_with_scope(scope, script)?;
603
604 Ok(self.messages.borrow().join(""))
605 }
606
607 #[cfg(not(feature = "web"))]
625 pub fn format_from_file_with_scope<P: AsRef<Path>>(
626 &mut self,
627 scope: &mut Scope,
628 script: P,
629 ) -> ScriptResult<String> {
630 match std::fs::read_to_string(script.as_ref()) {
631 Ok(script) => self.format_with_scope(scope, &script),
632 Err(e) => Err(e.to_string().into()),
633 }
634 }
635
636 pub fn clone_messages(&self) -> Rc<RefCell<Vec<String>>> {
644 self.messages.clone()
645 }
646
647 pub fn format<T: Variant + Clone>(
665 &mut self,
666 name: &str,
667 data: T,
668 script: &str,
669 ) -> ScriptResult<String> {
670 self.register_type::<T>();
671
672 let mut scope = Scope::new();
673 scope.push_constant(name, data);
674
675 self.format_with_scope(&mut scope, script)
676 }
677
678 #[cfg(not(feature = "web"))]
696 pub fn format_from_file<T: Variant + Clone, P: AsRef<Path>>(
697 &mut self,
698 name: &str,
699 data: T,
700 script: P,
701 ) -> ScriptResult<String> {
702 match std::fs::read_to_string(script.as_ref()) {
703 Ok(script) => self.format(name, data, &script),
704 Err(e) => Err(e.to_string().into()),
705 }
706 }
707}
708
709fn option_to_string<T: std::fmt::Display>(value: Option<T>) -> Option<String> {
710 if let Some(v) = value {
711 Some(format!("{v}"))
712 } else {
713 None
714 }
715}
716
717fn dynamic_to_string(v: Dynamic) -> ScriptResult<Option<String>> {
718 let t = v.type_id();
719 if t == TypeId::of::<()>() {
720 Ok(None)
721 } else if v.is_array() {
722 let flattened = flatten_dynamic(v)?;
723 if flattened.len() > 0 {
724 Ok(Some(flattened.join("")))
725 } else {
726 Ok(None)
727 }
728 } else if t == TypeId::of::<Option<&str>>() {
729 Ok(option_to_string::<&str>(v.cast()))
730 } else if t == TypeId::of::<Option<bool>>() {
731 Ok(option_to_string::<bool>(v.cast()))
732 } else if t == TypeId::of::<Option<i8>>() {
733 Ok(option_to_string::<i8>(v.cast()))
734 } else if t == TypeId::of::<Option<i16>>() {
735 Ok(option_to_string::<i16>(v.cast()))
736 } else if t == TypeId::of::<Option<i32>>() {
737 Ok(option_to_string::<i32>(v.cast()))
738 } else if t == TypeId::of::<Option<i64>>() {
739 Ok(option_to_string::<i64>(v.cast()))
740 } else if t == TypeId::of::<Option<i128>>() {
741 Ok(option_to_string::<i128>(v.cast()))
742 } else if t == TypeId::of::<Option<u8>>() {
743 Ok(option_to_string::<u8>(v.cast()))
744 } else if t == TypeId::of::<Option<u16>>() {
745 Ok(option_to_string::<u16>(v.cast()))
746 } else if t == TypeId::of::<Option<u32>>() {
747 Ok(option_to_string::<u32>(v.cast()))
748 } else if t == TypeId::of::<Option<u64>>() {
749 Ok(option_to_string::<u64>(v.cast()))
750 } else if t == TypeId::of::<Option<f32>>() {
751 Ok(option_to_string::<f32>(v.cast()))
752 } else if t == TypeId::of::<Option<f64>>() {
753 Ok(option_to_string::<f64>(v.cast()))
754 } else if t == TypeId::of::<Option<u128>>() {
755 Ok(option_to_string::<u128>(v.cast()))
756 } else if t == TypeId::of::<Option<char>>() {
757 Ok(option_to_string::<char>(v.cast()))
758 } else if t == TypeId::of::<Option<String>>() {
759 Ok(if let Some(v) = v.cast::<Option<String>>() {
760 Some(v)
761 } else {
762 None
763 })
764 } else if t == TypeId::of::<Option<Dynamic>>() {
765 Ok(if let Some(v) = v.cast::<Option<Dynamic>>() {
766 dynamic_to_string(v)?
767 } else {
768 None
769 })
770 } else if t == TypeId::of::<bool>() {
771 Ok(Some(v.as_bool()?.to_string()))
772 } else if t == TypeId::of::<ImmutableString>() {
773 Ok(Some(v.into_immutable_string()?.to_string()))
774 } else if t == TypeId::of::<char>() {
775 Ok(Some(v.as_char()?.to_string()))
776 } else if t == TypeId::of::<INT>() {
777 Ok(Some(v.as_int()?.to_string()))
778 } else if t == TypeId::of::<FLOAT>() {
779 Ok(Some(v.as_float()?.to_string()))
780 } else {
781 eprintln!("{}", v.type_name());
782 Err("unsupported type".into())
783 }
784}
785
786fn flatten_dynamic(vs: Dynamic) -> Result<Vec<String>, Box<EvalAltResult>> {
787 let mut res = Vec::new();
788 if vs.is_array() {
789 for v in vs.into_array()? {
790 if v.is_array() {
791 let mut values = flatten_dynamic(v)?;
792 res.append(&mut values);
793 } else {
794 if let Some(s) = dynamic_to_string(v)? {
795 res.push(s);
796 }
797 }
798 }
799 } else if vs.type_id() == TypeId::of::<Option<Vec<String>>>() {
800 if let Some(mut vs) = vs.cast::<Option<Vec<String>>>() {
801 res.append(&mut vs);
802 }
803 } else if vs.type_id() == TypeId::of::<Vec<String>>() {
804 let mut vs = vs.cast::<Vec<String>>();
805 res.append(&mut vs);
806 } else if let Some(s) = dynamic_to_string(vs)? {
807 res.push(s);
808 }
809 Ok(res)
810}
811
812#[allow(clippy::too_many_lines)]
813fn build_engine(debug: bool) -> FormattingEngine {
814 let mut engine = FormattingEngine {
815 engine: rhai::Engine::new(),
816 messages: Rc::new(RefCell::new(Vec::new())),
817 };
818 engine.set_max_expr_depths(128, 64);
819
820 let package = CorePackage::new();
821 engine.register_global_module(package.as_shared_module());
822
823 let module = exported_module!(script_format);
824 engine.register_global_module(module.into());
825
826 {
828 let messages = engine.clone_messages();
829 engine
830 .register_custom_syntax(
831 ["~", "$expr$"],
832 true,
833 move |context: &mut rhai::EvalContext,
834 inputs: &[rhai::Expression]|
835 -> ScriptResult<Dynamic> {
836 for e in inputs {
837 let result = context.eval_expression_tree(&e)?;
838 let mut m = flatten_dynamic(result)?;
839 messages.borrow_mut().append(&mut m);
840 }
841 Ok(Dynamic::UNIT)
842 },
843 )
844 .unwrap();
845 }
846
847 let indent = Rc::new(RefCell::new(" ".to_owned()));
848
849 {
850 let indent = indent.clone();
851
852 #[allow(deprecated)]
854 engine.on_var(move |name, _, _| match name {
855 "IND" => Ok(Some(indent.borrow().clone().into())),
856 _ => Ok(None),
857 });
858 }
859
860 {
861 let indent = indent.clone();
862 #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
863 engine.register_fn("IND", move |count: i64| {
864 indent.borrow().repeat(count as usize)
865 });
866 }
867
868 {
869 let indent = indent.clone();
870 #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
871 engine.register_fn("SET_INDENT", move |value: &str| {
872 value.clone_into(&mut indent.borrow_mut());
873 });
874 }
875
876 {
877 let indent = indent.clone();
878 #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
879 engine.register_fn("SET_INDENT", move |value: &str, count: i64| {
880 *indent.borrow_mut() = value.repeat(count as usize)
881 });
882 }
883
884 {
885 let indent = indent.clone();
886 #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
887 engine.register_fn("SET_INDENT", move |count: i64| {
888 *indent.borrow_mut() = " ".repeat(count as usize)
889 });
890 }
891
892 #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
893 engine.register_fn("NL", |count: i64| "\n".repeat(count as usize));
894
895 engine.register_iterator::<Vec<serde_value::Value>>();
896
897 engine.register_options::<&str>();
898 engine.register_options::<String>();
899 engine.register_options::<bool>();
900 engine.register_options::<i64>();
901 engine.register_options::<u64>();
902 engine.register_options::<i32>();
903 engine.register_options::<u32>();
904 engine.register_options::<i16>();
905 engine.register_options::<u16>();
906 engine.register_options::<i8>();
907 engine.register_options::<u8>();
908 engine.register_options::<usize>();
909 engine.register_options::<isize>();
910 engine.register_options::<i128>();
911 engine.register_options::<u128>();
912 engine.register_options::<f32>();
913 engine.register_options::<f64>();
914
915 engine.register_type_dynamic::<i8, i64>(Dynamic::is_int, Dynamic::as_int);
916 engine.register_type_dynamic::<i16, i64>(Dynamic::is_int, Dynamic::as_int);
917 engine.register_type_dynamic::<i32, i64>(Dynamic::is_int, Dynamic::as_int);
918 engine.register_type_dynamic::<i64, i64>(Dynamic::is_int, Dynamic::as_int);
919
920 engine.register_type_dynamic::<u8, i64>(Dynamic::is_int, Dynamic::as_int);
921 engine.register_type_dynamic::<u16, i64>(Dynamic::is_int, Dynamic::as_int);
922 engine.register_type_dynamic::<u32, i64>(Dynamic::is_int, Dynamic::as_int);
923
924 engine.register_type_dynamic::<f32, f64>(Dynamic::is_float, Dynamic::as_float);
925 engine.register_type_dynamic::<f64, f64>(Dynamic::is_float, Dynamic::as_float);
926
927 engine.register_type_dynamic::<bool, bool>(Dynamic::is_bool, Dynamic::as_bool);
928
929 fn dynamic_as_string(dynamic: &Dynamic) -> Result<String, &'static str> {
930 dynamic.to_owned().into_string()
931 }
932
933 engine.register_type_dynamic::<String, String>(Dynamic::is_string, dynamic_as_string);
934 engine.register_type_dynamic::<&str, String>(Dynamic::is_string, dynamic_as_string);
935
936 engine
937 .register_fn("join", crate::internal::script_join)
938 .register_fn("split", crate::internal::script_split)
939 .register_fn("splitn", crate::internal::script_splitn)
940 .register_fn("rsplitn", crate::internal::script_rsplitn)
941 .register_fn("is_empty", crate::internal::script_string_is_empty)
942 .register_fn("is_empty", crate::internal::script_array_is_empty)
943 .register_fn("starts_with", crate::internal::script_starts_with)
944 .register_fn("ends_with", crate::internal::script_ends_with)
945 .register_fn("trim", crate::internal::script_trim)
946 .register_fn("is_string", crate::internal::script_is_no_string)
947 .register_fn("is_string", crate::internal::script_is_string);
948
949 engine.build_type::<ToBe>();
951 engine
952 .register_custom_operator("zip", 65)
953 .unwrap()
954 .register_custom_operator("to_be", 60)
955 .unwrap()
956 .register_custom_operator("and", 60)
957 .unwrap()
958 .register_fn("and", |a: bool, b: bool| a && b)
959 .register_custom_operator("or", 30)
960 .unwrap()
961 .register_fn("or", |a: bool, b: bool| a || b)
962 .register_custom_operator("xor", 30)
963 .unwrap()
964 .register_fn("xor", |a: bool, b: bool| a ^ b)
965 .register_custom_operator("contains", 25)
966 .unwrap()
967 .register_custom_operator("equals", 25)
968 .unwrap()
969 .register_custom_operator("require", 25)
970 .unwrap()
971 .register_custom_operator("any", 25)
972 .unwrap()
973 .register_custom_operator("all", 25)
974 .unwrap()
975 .register_custom_operator("none", 25)
976 .unwrap()
977 .register_fn("contains", crate::internal::script_map_contains)
978 .register_fn("contains", crate::internal::script_string_contains)
979 .register_fn("equals", crate::internal::script_map_equals)
980 .register_fn("equals", crate::internal::script_value_equals)
981 .register_fn("equals", crate::internal::script_array_equals)
982 .register_fn("contains", crate::internal::script_array_contains)
983 .register_fn("require", crate::internal::script_require)
984 .register_fn("to_be", crate::internal::script_to_be)
985 .register_fn("any", crate::internal::script_any)
986 .register_fn("any", crate::internal::script_any_void)
987 .register_fn("all", crate::internal::script_all)
988 .register_fn("all", crate::internal::script_all_void)
989 .register_fn("none", crate::internal::script_none)
990 .register_fn("none", crate::internal::script_none_void);
991
992 engine.register_msg_single::<&str>();
993 engine.register_msg_single::<String>();
994 engine.register_msg_single::<bool>();
995 engine.register_msg_single::<i64>();
996 engine.register_msg_single::<u64>();
997 engine.register_msg_single::<i32>();
998 engine.register_msg_single::<u32>();
999 engine.register_msg_single::<i16>();
1000 engine.register_msg_single::<u16>();
1001 engine.register_msg_single::<i8>();
1002 engine.register_msg_single::<u8>();
1003 engine.register_msg_single::<usize>();
1004 engine.register_msg_single::<isize>();
1005 engine.register_msg_single::<i128>();
1006 engine.register_msg_single::<u128>();
1007 engine.register_msg_single::<f32>();
1008 engine.register_msg_single::<f64>();
1009
1010 engine.register_msg::<&str>();
1011 engine.register_msg::<String>();
1012 engine.register_msg::<bool>();
1013 engine.register_msg::<i64>();
1014 engine.register_msg::<u64>();
1015 engine.register_msg::<i32>();
1016 engine.register_msg::<u32>();
1017 engine.register_msg::<i16>();
1018 engine.register_msg::<u16>();
1019 engine.register_msg::<i8>();
1020 engine.register_msg::<u8>();
1021 engine.register_msg::<usize>();
1022 engine.register_msg::<isize>();
1023 engine.register_msg::<i128>();
1024 engine.register_msg::<u128>();
1025 engine.register_msg::<f32>();
1026 engine.register_msg::<f64>();
1027
1028 engine.register_comparison::<u8, u8, u8>();
1029 engine.register_comparison::<u8, u16, u16>();
1030 engine.register_comparison::<u8, u32, u32>();
1031 engine.register_comparison::<u8, u64, u64>();
1032 engine.register_comparison::<u8, usize, u128>();
1033 engine.register_comparison::<u8, u128, u128>();
1034
1035 engine.register_comparison::<u16, u16, u16>();
1036 engine.register_comparison::<u16, u32, u32>();
1037 engine.register_comparison::<u16, u64, u64>();
1038 engine.register_comparison::<u16, usize, u128>();
1039 engine.register_comparison::<u16, u128, u128>();
1040
1041 engine.register_comparison::<u32, u32, u32>();
1042 engine.register_comparison::<u32, u64, u64>();
1043 engine.register_comparison::<u32, usize, u128>();
1044 engine.register_comparison::<u32, u128, u128>();
1045
1046 engine.register_comparison::<u64, u64, u64>();
1047 engine.register_comparison::<u64, usize, u128>();
1048 engine.register_comparison::<u64, u128, u128>();
1049
1050 engine.register_comparison::<usize, usize, u128>();
1051 engine.register_comparison::<usize, u128, u128>();
1052
1053 engine.register_comparison::<u128, u128, u128>();
1054
1055 engine.register_comparison::<i8, i8, i8>();
1056 engine.register_comparison::<i8, i16, i16>();
1057 engine.register_comparison::<i8, i32, i32>();
1058 engine.register_comparison::<i8, i64, i64>();
1059 engine.register_comparison::<i8, isize, i128>();
1060 engine.register_comparison::<i8, i128, i128>();
1061
1062 engine.register_comparison::<i16, i16, i16>();
1063 engine.register_comparison::<i16, i32, i32>();
1064 engine.register_comparison::<i16, i64, i64>();
1065 engine.register_comparison::<i8, isize, i128>();
1066 engine.register_comparison::<i16, i128, i128>();
1067
1068 engine.register_comparison::<i32, i32, i32>();
1069 engine.register_comparison::<i32, i64, i64>();
1070 engine.register_comparison::<i32, isize, i128>();
1071 engine.register_comparison::<i32, i128, i128>();
1072
1073 engine.register_comparison::<i64, i64, i64>();
1074 engine.register_comparison::<i64, isize, i128>();
1075 engine.register_comparison::<i64, i128, i128>();
1076
1077 engine.register_comparison::<isize, isize, i128>();
1078 engine.register_comparison::<isize, i128, i128>();
1079
1080 engine.register_comparison::<i128, i128, i128>();
1081
1082 engine.register_comparison::<f32, f32, f32>();
1083 engine.register_comparison::<f32, f64, f64>();
1084
1085 engine.register_comparison::<u8, f32, f32>();
1086 engine.register_comparison::<u16, f32, f32>();
1087 engine.register_comparison::<u32, f64, f64>();
1088
1089 engine.register_comparison::<i8, f32, f32>();
1090 engine.register_comparison::<i16, f32, f32>();
1091 engine.register_comparison::<i32, f64, f64>();
1092
1093 engine.register_value::<&str>();
1094 engine.register_value::<String>();
1095 engine.register_value::<bool>();
1096 engine.register_value::<i64>();
1097 engine.register_value::<u64>();
1098 engine.register_value::<i32>();
1099 engine.register_value::<u32>();
1100 engine.register_value::<i16>();
1101 engine.register_value::<u16>();
1102 engine.register_value::<i8>();
1103 engine.register_value::<u8>();
1104 engine.register_value::<usize>();
1105 engine.register_value::<isize>();
1106 engine.register_value::<i128>();
1107 engine.register_value::<u128>();
1108 engine.register_value::<f32>();
1109 engine.register_value::<f64>();
1110
1111 engine.register_fn("++", move |a: serde_value::Value, b: serde_value::Value| {
1112 vec![
1113 serde_json::to_string(&a).unwrap(),
1114 serde_json::to_string(&b).unwrap(),
1115 ]
1116 });
1117
1118 engine.register_concat::<&str>();
1119 engine.register_concat::<String>();
1120 engine.register_concat::<bool>();
1121 engine.register_concat::<i64>();
1122 engine.register_concat::<u64>();
1123 engine.register_concat::<i32>();
1124 engine.register_concat::<u32>();
1125 engine.register_concat::<i16>();
1126 engine.register_concat::<u16>();
1127 engine.register_concat::<i8>();
1128 engine.register_concat::<u8>();
1129 engine.register_concat::<usize>();
1130 engine.register_concat::<isize>();
1131 engine.register_concat::<i128>();
1132 engine.register_concat::<u128>();
1133 engine.register_concat::<f32>();
1134 engine.register_concat::<f64>();
1135
1136 engine.register_vec_printable::<&str>();
1137 engine.register_vec_printable::<String>();
1138 engine.register_vec_printable::<bool>();
1139 engine.register_vec_printable::<i64>();
1140 engine.register_vec_printable::<u64>();
1141 engine.register_vec_printable::<i32>();
1142 engine.register_vec_printable::<u32>();
1143 engine.register_vec_printable::<i16>();
1144 engine.register_vec_printable::<u16>();
1145 engine.register_vec_printable::<i8>();
1146 engine.register_vec_printable::<u8>();
1147 engine.register_vec_printable::<usize>();
1148 engine.register_vec_printable::<isize>();
1149 engine.register_vec_printable::<i128>();
1150 engine.register_vec_printable::<u128>();
1151 engine.register_vec_printable::<f32>();
1152 engine.register_vec_printable::<f64>();
1153
1154 engine.register_vec::<()>();
1155
1156 engine
1157 .register_fn("any", crate::internal::script_any_type::<bool>)
1158 .register_fn("all", crate::internal::script_any_type::<bool>)
1159 .register_fn("none", crate::internal::script_any_type::<bool>)
1160 .register_fn("++", move |(): (), b: &str| vec![b.to_owned()])
1161 .register_fn("++", move |(): (), b: usize| vec![b.to_string()]);
1162 engine
1163 .register_custom_operator("++", 15)
1164 .unwrap()
1165 .register_custom_operator("then_emit", 20)
1166 .unwrap()
1167 .register_fn(
1168 "then_emit",
1169 move |a: bool, msg: &str| {
1170 if a {
1171 Some(msg.to_owned())
1172 } else {
1173 None
1174 }
1175 },
1176 )
1177 .register_fn(
1178 "then_emit",
1179 move |a: bool, msg: Vec<String>| {
1180 if a {
1181 msg
1182 } else {
1183 Vec::new()
1184 }
1185 },
1186 )
1187 .register_custom_operator("or_emit", 20)
1188 .unwrap()
1189 .register_fn(
1190 "or_emit",
1191 move |a: bool, msg: &str| {
1192 if !a {
1193 Some(msg.to_owned())
1194 } else {
1195 None
1196 }
1197 },
1198 )
1199 .register_fn(
1200 "or_emit",
1201 move |a: bool, msg: Vec<String>| {
1202 if a {
1203 msg
1204 } else {
1205 Vec::new()
1206 }
1207 },
1208 );
1209 if debug {
1212 engine.on_print(move |x| eprintln!("INFO => {x}"));
1213 engine.on_debug(move |x, _, pos| eprintln!("DEBUG({pos:?}) => {x}"));
1214 } else {
1215 engine.on_print(|_| ());
1216 engine.on_debug(|_, _, _| ());
1217 }
1218
1219 engine.disable_symbol("eval");
1220
1221 engine
1222}
1223
1224trait AsCast<T> {
1225 fn as_cast(self) -> T;
1226}
1227
1228impl AsCast<u8> for u8 {
1229 fn as_cast(self) -> u8 {
1230 self as u8
1231 }
1232}
1233impl AsCast<u16> for u8 {
1234 fn as_cast(self) -> u16 {
1235 self as u16
1236 }
1237}
1238impl AsCast<u32> for u8 {
1239 fn as_cast(self) -> u32 {
1240 self as u32
1241 }
1242}
1243impl AsCast<u64> for u8 {
1244 fn as_cast(self) -> u64 {
1245 self as u64
1246 }
1247}
1248impl AsCast<u128> for u8 {
1249 fn as_cast(self) -> u128 {
1250 self as u128
1251 }
1252}
1253impl AsCast<usize> for u8 {
1254 fn as_cast(self) -> usize {
1255 self as usize
1256 }
1257}
1258impl AsCast<i8> for i8 {
1259 fn as_cast(self) -> i8 {
1260 self as i8
1261 }
1262}
1263impl AsCast<i16> for i8 {
1264 fn as_cast(self) -> i16 {
1265 self as i16
1266 }
1267}
1268impl AsCast<i32> for i8 {
1269 fn as_cast(self) -> i32 {
1270 self as i32
1271 }
1272}
1273impl AsCast<i64> for i8 {
1274 fn as_cast(self) -> i64 {
1275 self as i64
1276 }
1277}
1278impl AsCast<i128> for i8 {
1279 fn as_cast(self) -> i128 {
1280 self as i128
1281 }
1282}
1283impl AsCast<isize> for i8 {
1284 fn as_cast(self) -> isize {
1285 self as isize
1286 }
1287}
1288
1289impl AsCast<u16> for u16 {
1290 fn as_cast(self) -> u16 {
1291 self as u16
1292 }
1293}
1294impl AsCast<u32> for u16 {
1295 fn as_cast(self) -> u32 {
1296 self as u32
1297 }
1298}
1299impl AsCast<u64> for u16 {
1300 fn as_cast(self) -> u64 {
1301 self as u64
1302 }
1303}
1304impl AsCast<u128> for u16 {
1305 fn as_cast(self) -> u128 {
1306 self as u128
1307 }
1308}
1309impl AsCast<usize> for u16 {
1310 fn as_cast(self) -> usize {
1311 self as usize
1312 }
1313}
1314impl AsCast<i16> for i16 {
1315 fn as_cast(self) -> i16 {
1316 self as i16
1317 }
1318}
1319impl AsCast<i32> for i16 {
1320 fn as_cast(self) -> i32 {
1321 self as i32
1322 }
1323}
1324impl AsCast<i64> for i16 {
1325 fn as_cast(self) -> i64 {
1326 self as i64
1327 }
1328}
1329impl AsCast<i128> for i16 {
1330 fn as_cast(self) -> i128 {
1331 self as i128
1332 }
1333}
1334impl AsCast<isize> for i16 {
1335 fn as_cast(self) -> isize {
1336 self as isize
1337 }
1338}
1339
1340impl AsCast<u32> for u32 {
1341 fn as_cast(self) -> u32 {
1342 self as u32
1343 }
1344}
1345impl AsCast<u64> for u32 {
1346 fn as_cast(self) -> u64 {
1347 self as u64
1348 }
1349}
1350impl AsCast<u128> for u32 {
1351 fn as_cast(self) -> u128 {
1352 self as u128
1353 }
1354}
1355impl AsCast<usize> for u32 {
1356 fn as_cast(self) -> usize {
1357 self as usize
1358 }
1359}
1360impl AsCast<i32> for i32 {
1361 fn as_cast(self) -> i32 {
1362 self as i32
1363 }
1364}
1365impl AsCast<i64> for i32 {
1366 fn as_cast(self) -> i64 {
1367 self as i64
1368 }
1369}
1370impl AsCast<i128> for i32 {
1371 fn as_cast(self) -> i128 {
1372 self as i128
1373 }
1374}
1375impl AsCast<isize> for i32 {
1376 fn as_cast(self) -> isize {
1377 self as isize
1378 }
1379}
1380
1381impl AsCast<u64> for u64 {
1382 fn as_cast(self) -> u64 {
1383 self as u64
1384 }
1385}
1386impl AsCast<u128> for u64 {
1387 fn as_cast(self) -> u128 {
1388 self as u128
1389 }
1390}
1391impl AsCast<i64> for i64 {
1392 fn as_cast(self) -> i64 {
1393 self as i64
1394 }
1395}
1396impl AsCast<i128> for i64 {
1397 fn as_cast(self) -> i128 {
1398 self as i128
1399 }
1400}
1401
1402impl AsCast<usize> for usize {
1403 fn as_cast(self) -> usize {
1404 self as usize
1405 }
1406}
1407impl AsCast<u128> for usize {
1408 fn as_cast(self) -> u128 {
1409 self as u128
1410 }
1411}
1412impl AsCast<isize> for isize {
1413 fn as_cast(self) -> isize {
1414 self as isize
1415 }
1416}
1417impl AsCast<i128> for isize {
1418 fn as_cast(self) -> i128 {
1419 self as i128
1420 }
1421}
1422
1423impl AsCast<u128> for u128 {
1424 fn as_cast(self) -> u128 {
1425 self as u128
1426 }
1427}
1428impl AsCast<i128> for i128 {
1429 fn as_cast(self) -> i128 {
1430 self as i128
1431 }
1432}
1433
1434impl AsCast<f32> for f32 {
1435 fn as_cast(self) -> f32 {
1436 self as f32
1437 }
1438}
1439impl AsCast<f64> for f32 {
1440 fn as_cast(self) -> f64 {
1441 self as f64
1442 }
1443}
1444impl AsCast<f64> for f64 {
1445 fn as_cast(self) -> f64 {
1446 self as f64
1447 }
1448}
1449
1450impl AsCast<f32> for u8 {
1451 fn as_cast(self) -> f32 {
1452 self as f32
1453 }
1454}
1455impl AsCast<f64> for u8 {
1456 fn as_cast(self) -> f64 {
1457 self as f64
1458 }
1459}
1460impl AsCast<f32> for u16 {
1461 fn as_cast(self) -> f32 {
1462 self as f32
1463 }
1464}
1465impl AsCast<f64> for u16 {
1466 fn as_cast(self) -> f64 {
1467 self as f64
1468 }
1469}
1470impl AsCast<f64> for u32 {
1471 fn as_cast(self) -> f64 {
1472 self as f64
1473 }
1474}
1475
1476impl AsCast<f32> for i8 {
1477 fn as_cast(self) -> f32 {
1478 self as f32
1479 }
1480}
1481impl AsCast<f64> for i8 {
1482 fn as_cast(self) -> f64 {
1483 self as f64
1484 }
1485}
1486impl AsCast<f32> for i16 {
1487 fn as_cast(self) -> f32 {
1488 self as f32
1489 }
1490}
1491impl AsCast<f64> for i16 {
1492 fn as_cast(self) -> f64 {
1493 self as f64
1494 }
1495}
1496impl AsCast<f64> for i32 {
1497 fn as_cast(self) -> f64 {
1498 self as f64
1499 }
1500}