1use std::iter::FusedIterator;
16use std::ops::{Deref, Index};
17use std::slice::ChunksExact;
18
19#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct SimpleUnary<'a> {
22 pub op: &'a str,
24 arg: Box<Simple<'a>>,
26}
27
28impl<'a> SimpleUnary<'a> {
29 pub fn new<S>(op: &'a str, arg: S) -> Self
31 where
32 S: Into<Simple<'a>>,
33 {
34 SimpleUnary {
35 op,
36 arg: Box::new(arg.into()),
37 }
38 }
39
40 #[must_use]
42 pub fn arg(&self) -> &Simple<'a> {
43 &self.arg
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct SimpleFunc<'a> {
53 pub func: &'a str,
55 arg: Box<Simple<'a>>,
57}
58
59impl<'a> SimpleFunc<'a> {
60 pub fn new<S>(func: &'a str, arg: S) -> Self
62 where
63 S: Into<Simple<'a>>,
64 {
65 SimpleFunc {
66 func,
67 arg: Box::new(arg.into()),
68 }
69 }
70
71 #[must_use]
73 pub fn arg(&self) -> &Simple<'a> {
74 &self.arg
75 }
76}
77
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub struct SimpleBinary<'a> {
81 pub op: &'a str,
83 first: Box<Simple<'a>>,
85 second: Box<Simple<'a>>,
87}
88
89impl<'a> SimpleBinary<'a> {
90 pub fn new<F, S>(op: &'a str, first: F, second: S) -> Self
92 where
93 F: Into<Simple<'a>>,
94 S: Into<Simple<'a>>,
95 {
96 SimpleBinary {
97 op,
98 first: Box::new(first.into()),
99 second: Box::new(second.into()),
100 }
101 }
102
103 #[must_use]
105 pub fn first(&self) -> &Simple<'a> {
106 &self.first
107 }
108
109 #[must_use]
111 pub fn second(&self) -> &Simple<'a> {
112 &self.second
113 }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
117pub struct Group<'a> {
122 pub left_bracket: &'a str,
124 pub expr: Expression<'a>,
126 pub right_bracket: &'a str,
128}
129
130impl<'a> Group<'a> {
131 pub fn new<E: Into<Expression<'a>>>(
133 left_bracket: &'a str,
134 expr: E,
135 right_bracket: &'a str,
136 ) -> Self {
137 Group {
138 left_bracket,
139 expr: expr.into(),
140 right_bracket,
141 }
142 }
143
144 pub fn from_iter<T, I>(left_bracket: &'a str, inters: T, right_bracket: &'a str) -> Self
146 where
147 T: IntoIterator<Item = I>,
148 I: Into<Intermediate<'a>>,
149 {
150 Group {
151 left_bracket,
152 expr: inters.into_iter().collect(),
153 right_bracket,
154 }
155 }
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
165pub struct Matrix<'a> {
166 pub left_bracket: &'a str,
168 cells: Box<[Expression<'a>]>,
170 num_cols: usize,
172 pub right_bracket: &'a str,
174}
175
176impl<'a> Matrix<'a> {
177 pub fn new<E>(left_bracket: &'a str, cells: E, num_cols: usize, right_bracket: &'a str) -> Self
185 where
186 E: Into<Box<[Expression<'a>]>>,
187 {
188 let cells = cells.into();
189 assert!(num_cols > 0, "num_cols must be positive");
190 assert_eq!(cells.len() / num_cols * num_cols, cells.len());
191 Matrix {
192 left_bracket,
193 cells,
194 num_cols,
195 right_bracket,
196 }
197 }
198
199 #[must_use]
201 pub fn num_cols(&self) -> usize {
202 self.num_cols
203 }
204
205 #[must_use]
207 pub fn num_rows(&self) -> usize {
208 self.cells.len() / self.num_cols
210 }
211
212 #[must_use]
214 pub fn num_cells(&self) -> usize {
215 self.cells.len()
216 }
217
218 #[must_use]
220 pub fn rows(&self) -> MatrixRows<'a, '_> {
221 MatrixRows(self.cells.chunks_exact(self.num_cols))
222 }
223
224 #[must_use]
226 pub fn iter(&self) -> MatrixRows<'a, '_> {
227 self.into_iter()
228 }
229}
230
231impl<'a, 'b> IntoIterator for &'b Matrix<'a> {
233 type IntoIter = MatrixRows<'a, 'b>;
234 type Item = &'b [Expression<'a>];
235
236 fn into_iter(self) -> Self::IntoIter {
237 self.rows()
238 }
239}
240
241impl<'a> Index<usize> for Matrix<'a> {
243 type Output = [Expression<'a>];
244
245 fn index(&self, row: usize) -> &Self::Output {
250 self.rows().nth(row).expect("index out of bounds")
251 }
252}
253
254impl<'a> Index<[usize; 2]> for Matrix<'a> {
256 type Output = Expression<'a>;
257
258 fn index(&self, idx: [usize; 2]) -> &Self::Output {
266 let [x, y] = idx;
267 assert!(x < self.num_cols, "index out of bounds");
268 &self.cells[x + self.num_cols * y]
269 }
270}
271
272#[derive(Debug, Clone)]
274pub struct MatrixRows<'a, 'b>(ChunksExact<'b, Expression<'a>>);
275
276impl<'a, 'b> Iterator for MatrixRows<'a, 'b> {
277 type Item = &'b [Expression<'a>];
278
279 fn next(&mut self) -> Option<Self::Item> {
280 self.0.next()
281 }
282
283 fn size_hint(&self) -> (usize, Option<usize>) {
284 self.0.size_hint()
285 }
286
287 fn count(self) -> usize {
288 self.len()
289 }
290
291 fn nth(&mut self, n: usize) -> Option<Self::Item> {
292 self.0.nth(n)
293 }
294
295 fn last(mut self) -> Option<Self::Item> {
296 self.next_back()
297 }
298}
299impl FusedIterator for MatrixRows<'_, '_> {}
300
301impl DoubleEndedIterator for MatrixRows<'_, '_> {
302 fn next_back(&mut self) -> Option<Self::Item> {
303 self.0.next_back()
304 }
305
306 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
307 self.0.nth_back(n)
308 }
309}
310
311impl ExactSizeIterator for MatrixRows<'_, '_> {}
312
313#[derive(Default, Debug, Clone, PartialEq, Eq)]
317pub enum Simple<'a> {
318 #[default]
323 Missing,
324 Number(&'a str),
326 Text(&'a str),
328 Ident(&'a str),
330 Symbol(&'a str),
332 Unary(SimpleUnary<'a>),
334 Func(SimpleFunc<'a>),
336 Binary(SimpleBinary<'a>),
338 Group(Group<'a>),
340 Matrix(Matrix<'a>),
342}
343
344impl Simple<'_> {
345 #[must_use]
347 pub fn as_option(&self) -> Option<&Self> {
348 match self {
349 Simple::Missing => None,
350 simple => Some(simple),
351 }
352 }
353}
354
355macro_rules! simple_from {
357 ($from:ty => $to:ident) => {
358 impl<'a> From<$from> for Simple<'a> {
359 fn from(inp: $from) -> Self {
360 Simple::$to(inp)
361 }
362 }
363 };
364}
365
366simple_from!(SimpleUnary<'a> => Unary);
367simple_from!(SimpleFunc<'a> => Func);
368simple_from!(SimpleBinary<'a> => Binary);
369simple_from!(Group<'a> => Group);
370simple_from!(Matrix<'a> => Matrix);
371
372#[derive(Default, Debug, Clone, PartialEq, Eq)]
378pub enum Script<'a> {
379 #[default]
381 None,
382 Sub(Simple<'a>),
384 Super(Simple<'a>),
386 Subsuper(Simple<'a>, Simple<'a>),
388}
389
390impl<'a> Script<'a> {
391 #[must_use]
393 pub fn sub(&self) -> Option<&Simple<'a>> {
394 match self {
395 Script::Sub(sub) | Script::Subsuper(sub, _) => Some(sub),
396 _ => None,
397 }
398 }
399
400 #[must_use]
402 pub fn sup(&self) -> Option<&Simple<'a>> {
403 match self {
404 Script::Super(sup) | Script::Subsuper(_, sup) => Some(sup),
405 _ => None,
406 }
407 }
408}
409
410#[derive(Default, Debug, Clone, PartialEq, Eq)]
412pub struct SimpleScript<'a> {
413 pub simple: Simple<'a>,
415 pub script: Script<'a>,
417}
418
419impl<'a> SimpleScript<'a> {
420 pub fn new<S>(simple: S, script: Script<'a>) -> Self
422 where
423 S: Into<Simple<'a>>,
424 {
425 SimpleScript {
426 simple: simple.into(),
427 script,
428 }
429 }
430
431 pub fn without_scripts<S>(simple: S) -> Self
433 where
434 S: Into<Simple<'a>>,
435 {
436 Self::new(simple, Script::None)
437 }
438
439 pub fn with_sub<S, Sub>(simple: S, sub: Sub) -> Self
441 where
442 S: Into<Simple<'a>>,
443 Sub: Into<Simple<'a>>,
444 {
445 Self::new(simple, Script::Sub(sub.into()))
446 }
447
448 pub fn with_super<S, Sup>(simple: S, sup: Sup) -> Self
450 where
451 S: Into<Simple<'a>>,
452 Sup: Into<Simple<'a>>,
453 {
454 Self::new(simple, Script::Super(sup.into()))
455 }
456
457 pub fn with_subsuper<S, Sub, Sup>(simple: S, sub: Sub, sup: Sup) -> Self
459 where
460 S: Into<Simple<'a>>,
461 Sub: Into<Simple<'a>>,
462 Sup: Into<Simple<'a>>,
463 {
464 Self::new(simple, Script::Subsuper(sub.into(), sup.into()))
465 }
466}
467
468impl<'a, S> From<S> for SimpleScript<'a>
469where
470 S: Into<Simple<'a>>,
471{
472 fn from(inp: S) -> Self {
473 SimpleScript::without_scripts(inp.into())
474 }
475}
476
477impl<'a> Deref for SimpleScript<'a> {
479 type Target = Script<'a>;
480
481 fn deref(&self) -> &Self::Target {
482 &self.script
483 }
484}
485
486#[derive(Debug, Clone, PartialEq, Eq)]
488pub struct Func<'a> {
489 pub func: &'a str,
491 pub script: Script<'a>,
493 arg: Box<ScriptFunc<'a>>,
495}
496
497impl<'a> Func<'a> {
498 pub fn new<Arg>(func: &'a str, script: Script<'a>, arg: Arg) -> Self
500 where
501 Arg: Into<ScriptFunc<'a>>,
502 {
503 Func {
504 func,
505 script,
506 arg: Box::new(arg.into()),
507 }
508 }
509
510 pub fn without_scripts<Arg>(func: &'a str, arg: Arg) -> Self
512 where
513 Arg: Into<ScriptFunc<'a>>,
514 {
515 Self::new(func, Script::None, arg)
516 }
517
518 pub fn with_sub<Sub, Arg>(func: &'a str, sub: Sub, arg: Arg) -> Self
520 where
521 Sub: Into<Simple<'a>>,
522 Arg: Into<ScriptFunc<'a>>,
523 {
524 Self::new(func, Script::Sub(sub.into()), arg)
525 }
526
527 pub fn with_super<Sup, Arg>(func: &'a str, sup: Sup, arg: Arg) -> Self
529 where
530 Sup: Into<Simple<'a>>,
531 Arg: Into<ScriptFunc<'a>>,
532 {
533 Self::new(func, Script::Super(sup.into()), arg)
534 }
535
536 pub fn with_subsuper<Sub, Sup, Arg>(func: &'a str, sub: Sub, sup: Sup, arg: Arg) -> Self
538 where
539 Sub: Into<Simple<'a>>,
540 Sup: Into<Simple<'a>>,
541 Arg: Into<ScriptFunc<'a>>,
542 {
543 Self::new(func, Script::Subsuper(sub.into(), sup.into()), arg)
544 }
545
546 #[must_use]
548 pub fn arg(&self) -> &ScriptFunc<'a> {
549 &self.arg
550 }
551}
552
553impl<'a> Deref for Func<'a> {
554 type Target = Script<'a>;
555
556 fn deref(&self) -> &Self::Target {
557 &self.script
558 }
559}
560
561#[derive(Debug, Clone, PartialEq, Eq)]
563pub enum ScriptFunc<'a> {
564 Simple(SimpleScript<'a>),
566 Func(Func<'a>),
568}
569
570impl Default for ScriptFunc<'_> {
571 fn default() -> Self {
572 ScriptFunc::Simple(SimpleScript::default())
573 }
574}
575
576impl<'a> From<Func<'a>> for ScriptFunc<'a> {
577 fn from(func: Func<'a>) -> Self {
578 ScriptFunc::Func(func)
579 }
580}
581
582impl<'a, S> From<S> for ScriptFunc<'a>
583where
584 S: Into<SimpleScript<'a>>,
585{
586 fn from(inp: S) -> Self {
587 ScriptFunc::Simple(inp.into())
588 }
589}
590
591#[derive(Debug, Clone, PartialEq, Eq)]
593pub struct Frac<'a> {
594 pub numer: ScriptFunc<'a>,
596 pub denom: ScriptFunc<'a>,
598}
599
600impl<'a> Frac<'a> {
601 pub fn new<N, D>(numer: N, denom: D) -> Self
603 where
604 N: Into<ScriptFunc<'a>>,
605 D: Into<ScriptFunc<'a>>,
606 {
607 Frac {
608 numer: numer.into(),
609 denom: denom.into(),
610 }
611 }
612}
613
614#[derive(Debug, Clone, PartialEq, Eq)]
616pub enum Intermediate<'a> {
617 ScriptFunc(ScriptFunc<'a>),
619 Frac(Frac<'a>),
621}
622
623impl Default for Intermediate<'_> {
624 fn default() -> Self {
625 Intermediate::ScriptFunc(ScriptFunc::default())
626 }
627}
628
629impl<'a> From<Frac<'a>> for Intermediate<'a> {
630 fn from(frac: Frac<'a>) -> Self {
631 Intermediate::Frac(frac)
632 }
633}
634
635impl<'a, S> From<S> for Intermediate<'a>
636where
637 S: Into<ScriptFunc<'a>>,
638{
639 fn from(inp: S) -> Self {
640 Intermediate::ScriptFunc(inp.into())
641 }
642}
643
644#[derive(Default, Debug, Clone, PartialEq, Eq)]
648pub struct Expression<'a>(Box<[Intermediate<'a>]>);
649
650impl<'a> Deref for Expression<'a> {
651 type Target = [Intermediate<'a>];
652
653 fn deref(&self) -> &Self::Target {
654 &self.0
655 }
656}
657
658impl<'a, I> FromIterator<I> for Expression<'a>
659where
660 I: Into<Intermediate<'a>>,
661{
662 fn from_iter<T>(iter: T) -> Self
663 where
664 T: IntoIterator<Item = I>,
665 {
666 Expression(iter.into_iter().map(std::convert::Into::into).collect())
667 }
668}
669
670impl<'a, B> From<B> for Expression<'a>
671where
672 B: Into<Box<[Intermediate<'a>]>>,
673{
674 fn from(inp: B) -> Self {
675 Expression(inp.into())
676 }
677}
678
679#[cfg(test)]
680mod tests {
681 use super::{
682 Expression, Frac, Func, Group, Intermediate, Matrix, Script, ScriptFunc, Simple,
683 SimpleBinary, SimpleFunc, SimpleScript, SimpleUnary,
684 };
685
686 #[test]
687 fn simple_unary() {
688 let unary = SimpleUnary::new("sqrt", Simple::Ident("x"));
689 assert_eq!(unary.op, "sqrt");
690 assert_eq!(unary.arg(), &Simple::Ident("x"));
691 assert_eq!(
692 Simple::from(unary),
693 Simple::Unary(SimpleUnary::new("sqrt", Simple::Ident("x")))
694 );
695 }
696
697 #[test]
698 fn simple_func() {
699 let func = SimpleFunc::new("sin", Simple::Ident("x"));
700 assert_eq!(func.func, "sin");
701 assert_eq!(func.arg(), &Simple::Ident("x"));
702 assert_eq!(
703 Simple::from(func),
704 Simple::Func(SimpleFunc::new("sin", Simple::Ident("x")))
705 );
706 }
707
708 #[test]
709 fn simple_binary() {
710 let binary = SimpleBinary::new("root", Simple::Number("3"), Simple::Ident("x"));
711 assert_eq!(binary.op, "root");
712 assert_eq!(binary.first(), &Simple::Number("3"));
713 assert_eq!(binary.second(), &Simple::Ident("x"));
714 assert_eq!(
715 Simple::from(binary),
716 Simple::Binary(SimpleBinary::new(
717 "root",
718 Simple::Number("3"),
719 Simple::Ident("x")
720 )),
721 );
722 }
723
724 #[test]
725 fn group() {
726 let from_expr = Group::new("(", Expression::from_iter([Simple::Ident("x")]), ")");
727 let from_inters = Group::from_iter("(", [Simple::Ident("x")], ")");
728 assert_eq!(from_expr, from_inters);
729 assert_eq!(from_expr.left_bracket, "(");
730 assert_eq!(from_expr.right_bracket, ")");
731 assert_eq!(from_expr.expr.len(), 1);
732 assert_eq!(Simple::from(from_expr.clone()), Simple::Group(from_expr));
733 }
734
735 fn cell(ident: &str) -> Expression<'_> {
736 Expression::from_iter([Simple::Ident(ident)])
737 }
738
739 #[test]
740 fn matrix() {
741 let matrix = Matrix::new("[", [cell("a"), cell("b"), cell("c"), cell("d")], 2, "]");
742 assert_eq!(matrix.left_bracket, "[");
743 assert_eq!(matrix.right_bracket, "]");
744 assert_eq!(matrix.num_cols(), 2);
745 assert_eq!(matrix.num_rows(), 2);
746 assert_eq!(matrix.num_cells(), 4);
747
748 let rows: Vec<_> = matrix.rows().collect();
749 assert_eq!(rows, [[cell("a"), cell("b")], [cell("c"), cell("d")]]);
750 assert_eq!(matrix.iter().count(), 2);
751 assert_eq!((&matrix).into_iter().count(), 2);
752
753 assert_eq!(matrix[0], [cell("a"), cell("b")]);
754 assert_eq!(matrix[1], [cell("c"), cell("d")]);
755 assert_eq!(matrix[[0, 0]], cell("a"));
756 assert_eq!(matrix[[1, 0]], cell("b"));
757 assert_eq!(matrix[[0, 1]], cell("c"));
758 assert_eq!(matrix[[1, 1]], cell("d"));
759
760 assert_eq!(Simple::from(matrix.clone()), Simple::Matrix(matrix));
761 }
762
763 #[test]
764 #[should_panic(expected = "index out of bounds")]
765 fn matrix_row_out_of_bounds() {
766 let matrix = Matrix::new("[", [cell("a"), cell("b")], 2, "]");
767 let _ = &matrix[1];
768 }
769
770 #[test]
771 #[should_panic(expected = "index out of bounds")]
772 fn matrix_col_out_of_bounds() {
773 let matrix = Matrix::new("[", [cell("a"), cell("b")], 2, "]");
774 let _ = &matrix[[2, 0]];
775 }
776
777 #[test]
778 #[should_panic(expected = "assertion")]
779 fn matrix_ragged() {
780 let _ = Matrix::new("[", [cell("a"), cell("b"), cell("c")], 2, "]");
781 }
782
783 #[test]
784 #[should_panic(expected = "num_cols must be positive")]
785 fn matrix_zero_cols() {
786 let _ = Matrix::new("[", [], 0, "]");
787 }
788
789 #[test]
790 fn matrix_rows_iterator() {
791 let matrix = Matrix::new("[", [cell("a"), cell("b"), cell("c"), cell("d")], 1, "]");
792 assert_eq!(matrix.rows().len(), 4);
793 assert_eq!(matrix.rows().size_hint(), (4, Some(4)));
794 assert_eq!(matrix.rows().nth(2), Some(&[cell("c")][..]));
795 assert_eq!(matrix.rows().last(), Some(&[cell("d")][..]));
796
797 let mut back = matrix.rows();
798 assert_eq!(back.next_back(), Some(&[cell("d")][..]));
799 assert_eq!(back.nth_back(1), Some(&[cell("b")][..]));
800 }
801
802 #[test]
803 fn simple_as_option() {
804 assert_eq!(Simple::Missing.as_option(), None);
805 assert_eq!(Simple::Ident("x").as_option(), Some(&Simple::Ident("x")));
806 assert_eq!(Simple::default(), Simple::Missing);
807 }
808
809 #[test]
810 fn script_accessors() {
811 assert_eq!(Script::default(), Script::None);
812 assert_eq!(Script::<'_>::None.sub(), None);
813 assert_eq!(Script::<'_>::None.sup(), None);
814
815 let sub = Script::Sub(Simple::Ident("i"));
816 assert_eq!(sub.sub(), Some(&Simple::Ident("i")));
817 assert_eq!(sub.sup(), None);
818
819 let sup = Script::Super(Simple::Number("2"));
820 assert_eq!(sup.sub(), None);
821 assert_eq!(sup.sup(), Some(&Simple::Number("2")));
822
823 let both = Script::Subsuper(Simple::Ident("i"), Simple::Number("2"));
824 assert_eq!(both.sub(), Some(&Simple::Ident("i")));
825 assert_eq!(both.sup(), Some(&Simple::Number("2")));
826 }
827
828 #[test]
829 fn simple_script() {
830 let none = SimpleScript::without_scripts(Simple::Ident("x"));
831 assert_eq!(none.simple, Simple::Ident("x"));
832 assert_eq!(none.sub(), None);
834 assert_eq!(none.sup(), None);
835 assert_eq!(SimpleScript::default().simple, Simple::Missing);
836
837 let sub = SimpleScript::with_sub(Simple::Ident("x"), Simple::Ident("i"));
838 assert_eq!(sub.sub(), Some(&Simple::Ident("i")));
839
840 let sup = SimpleScript::with_super(Simple::Ident("x"), Simple::Number("2"));
841 assert_eq!(sup.sup(), Some(&Simple::Number("2")));
842
843 let both = SimpleScript::with_subsuper(
844 Simple::Ident("x"),
845 Simple::Ident("i"),
846 Simple::Number("2"),
847 );
848 assert_eq!(both.sub(), Some(&Simple::Ident("i")));
849 assert_eq!(both.sup(), Some(&Simple::Number("2")));
850
851 assert_eq!(SimpleScript::from(Simple::Ident("x")), none);
853 }
854
855 #[test]
856 fn func() {
857 let none = Func::without_scripts("sum", Simple::Ident("x"));
858 assert_eq!(none.func, "sum");
859 assert_eq!(none.arg(), &ScriptFunc::from(Simple::Ident("x")));
860 assert_eq!(none.sub(), None);
862
863 let sub = Func::with_sub("sum", Simple::Ident("i"), Simple::Ident("x"));
864 assert_eq!(sub.sub(), Some(&Simple::Ident("i")));
865
866 let sup = Func::with_super("sum", Simple::Number("n"), Simple::Ident("x"));
867 assert_eq!(sup.sup(), Some(&Simple::Number("n")));
868
869 let both = Func::with_subsuper(
870 "sum",
871 Simple::Ident("i"),
872 Simple::Number("n"),
873 Simple::Ident("x"),
874 );
875 assert_eq!(both.sub(), Some(&Simple::Ident("i")));
876 assert_eq!(both.sup(), Some(&Simple::Number("n")));
877 }
878
879 #[test]
880 fn script_func() {
881 let from_func = ScriptFunc::from(Func::without_scripts("sum", Simple::Ident("x")));
882 assert!(matches!(from_func, ScriptFunc::Func(_)));
883 let from_simple = ScriptFunc::from(Simple::Ident("x"));
884 assert!(matches!(from_simple, ScriptFunc::Simple(_)));
885 assert_eq!(
886 ScriptFunc::default(),
887 ScriptFunc::Simple(SimpleScript::default())
888 );
889 }
890
891 #[test]
892 fn frac_and_intermediate() {
893 let frac = Frac::new(Simple::Number("1"), Simple::Number("2"));
894 assert_eq!(frac.numer, ScriptFunc::from(Simple::Number("1")));
895 assert_eq!(frac.denom, ScriptFunc::from(Simple::Number("2")));
896
897 assert_eq!(Intermediate::from(frac.clone()), Intermediate::Frac(frac));
898 assert!(matches!(
899 Intermediate::from(Simple::Ident("x")),
900 Intermediate::ScriptFunc(_)
901 ));
902 assert!(matches!(
903 Intermediate::default(),
904 Intermediate::ScriptFunc(_)
905 ));
906 }
907
908 #[test]
909 fn expression() {
910 let expr = Expression::from_iter([Simple::Ident("x"), Simple::Ident("y")]);
911 assert_eq!(expr.len(), 2);
913 assert_eq!(expr[0], Intermediate::from(Simple::Ident("x")));
914 assert_eq!(Expression::default().len(), 0);
915
916 let boxed: Box<[Intermediate<'_>]> = Box::new([Intermediate::from(Simple::Ident("x"))]);
917 assert_eq!(Expression::from(boxed).len(), 1);
918 }
919}