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 pub fn arg(&self) -> &Simple<'a> {
42 &self.arg
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
51pub struct SimpleFunc<'a> {
52 pub func: &'a str,
54 arg: Box<Simple<'a>>,
56}
57
58impl<'a> SimpleFunc<'a> {
59 pub fn new<S>(func: &'a str, arg: S) -> Self
61 where
62 S: Into<Simple<'a>>,
63 {
64 SimpleFunc {
65 func,
66 arg: Box::new(arg.into()),
67 }
68 }
69
70 pub fn arg(&self) -> &Simple<'a> {
72 &self.arg
73 }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq)]
77pub struct SimpleBinary<'a> {
79 pub op: &'a str,
81 first: Box<Simple<'a>>,
83 second: Box<Simple<'a>>,
85}
86
87impl<'a> SimpleBinary<'a> {
88 pub fn new<F, S>(op: &'a str, first: F, second: S) -> Self
90 where
91 F: Into<Simple<'a>>,
92 S: Into<Simple<'a>>,
93 {
94 SimpleBinary {
95 op,
96 first: Box::new(first.into()),
97 second: Box::new(second.into()),
98 }
99 }
100
101 pub fn first(&self) -> &Simple<'a> {
103 &self.first
104 }
105
106 pub fn second(&self) -> &Simple<'a> {
108 &self.second
109 }
110}
111
112#[derive(Debug, Clone, PartialEq, Eq)]
113pub struct Group<'a> {
118 pub left_bracket: &'a str,
120 pub expr: Expression<'a>,
122 pub right_bracket: &'a str,
124}
125
126impl<'a> Group<'a> {
127 pub fn new<E: Into<Expression<'a>>>(
129 left_bracket: &'a str,
130 expr: E,
131 right_bracket: &'a str,
132 ) -> Self {
133 Group {
134 left_bracket,
135 expr: expr.into(),
136 right_bracket,
137 }
138 }
139
140 pub fn from_iter<T, I>(left_bracket: &'a str, inters: T, right_bracket: &'a str) -> Self
142 where
143 T: IntoIterator<Item = I>,
144 I: Into<Intermediate<'a>>,
145 {
146 Group {
147 left_bracket,
148 expr: inters.into_iter().collect(),
149 right_bracket,
150 }
151 }
152}
153
154#[derive(Debug, Clone, PartialEq, Eq)]
159pub struct Matrix<'a> {
160 pub left_bracket: &'a str,
162 cells: Box<[Expression<'a>]>,
164 num_cols: usize,
166 pub right_bracket: &'a str,
168}
169
170impl<'a> Matrix<'a> {
171 pub fn new<E>(left_bracket: &'a str, cells: E, num_cols: usize, right_bracket: &'a str) -> Self
179 where
180 E: Into<Box<[Expression<'a>]>>,
181 {
182 let cells = cells.into();
183 assert_eq!(cells.len() / num_cols * num_cols, cells.len());
184 Matrix {
185 left_bracket,
186 right_bracket,
187 cells,
188 num_cols,
189 }
190 }
191
192 pub fn num_cols(&self) -> usize {
194 self.num_cols
195 }
196
197 pub fn num_rows(&self) -> usize {
199 self.cells.len() / self.num_cols
200 }
201
202 pub fn num_cells(&self) -> usize {
204 self.cells.len()
205 }
206
207 pub fn rows(&self) -> MatrixRows<'a, '_> {
209 MatrixRows(self.cells.chunks_exact(self.num_cols))
210 }
211}
212
213impl<'a, 'b> IntoIterator for &'b Matrix<'a> {
215 type IntoIter = MatrixRows<'a, 'b>;
216 type Item = &'b [Expression<'a>];
217
218 fn into_iter(self) -> Self::IntoIter {
219 self.rows()
220 }
221}
222
223impl<'a> Index<usize> for Matrix<'a> {
225 type Output = [Expression<'a>];
226
227 fn index(&self, row: usize) -> &Self::Output {
232 self.rows().nth(row).expect("index out of bounds")
233 }
234}
235
236impl<'a> Index<[usize; 2]> for Matrix<'a> {
238 type Output = Expression<'a>;
239
240 fn index(&self, idx: [usize; 2]) -> &Self::Output {
245 let [x, y] = idx;
246 assert!(x < self.num_cols, "index out of bounds");
247 &self.cells[x + self.num_cols * y]
248 }
249}
250
251#[derive(Debug, Clone)]
253pub struct MatrixRows<'a, 'b>(ChunksExact<'b, Expression<'a>>);
254
255impl<'a, 'b> Iterator for MatrixRows<'a, 'b> {
256 type Item = &'b [Expression<'a>];
257
258 fn next(&mut self) -> Option<Self::Item> {
259 self.0.next()
260 }
261
262 fn size_hint(&self) -> (usize, Option<usize>) {
263 self.0.size_hint()
264 }
265
266 fn count(self) -> usize {
267 self.len()
268 }
269
270 fn nth(&mut self, n: usize) -> Option<Self::Item> {
271 self.0.nth(n)
272 }
273
274 fn last(mut self) -> Option<Self::Item> {
275 self.next_back()
276 }
277}
278impl<'a, 'b> FusedIterator for MatrixRows<'a, 'b> {}
279
280impl<'a, 'b> DoubleEndedIterator for MatrixRows<'a, 'b> {
281 fn next_back(&mut self) -> Option<Self::Item> {
282 self.0.next_back()
283 }
284
285 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
286 self.0.nth_back(n)
287 }
288}
289
290impl<'a, 'b> ExactSizeIterator for MatrixRows<'a, 'b> {}
291
292#[derive(Default, Debug, Clone, PartialEq, Eq)]
296pub enum Simple<'a> {
297 #[default]
302 Missing,
303 Number(&'a str),
305 Text(&'a str),
307 Ident(&'a str),
309 Symbol(&'a str),
311 Unary(SimpleUnary<'a>),
313 Func(SimpleFunc<'a>),
315 Binary(SimpleBinary<'a>),
317 Group(Group<'a>),
319 Matrix(Matrix<'a>),
321}
322
323impl<'a> Simple<'a> {
324 pub fn as_option(&self) -> Option<&Self> {
326 match self {
327 Simple::Missing => None,
328 simple => Some(simple),
329 }
330 }
331}
332
333macro_rules! simple_from {
335 ($from:ty => $to:ident) => {
336 impl<'a> From<$from> for Simple<'a> {
337 fn from(inp: $from) -> Self {
338 Simple::$to(inp)
339 }
340 }
341 };
342}
343
344simple_from!(SimpleUnary<'a> => Unary);
345simple_from!(SimpleFunc<'a> => Func);
346simple_from!(SimpleBinary<'a> => Binary);
347simple_from!(Group<'a> => Group);
348simple_from!(Matrix<'a> => Matrix);
349
350#[derive(Default, Debug, Clone, PartialEq, Eq)]
356pub enum Script<'a> {
357 #[default]
359 None,
360 Sub(Simple<'a>),
362 Super(Simple<'a>),
364 Subsuper(Simple<'a>, Simple<'a>),
366}
367
368impl<'a> Script<'a> {
369 pub fn sub(&self) -> Option<&Simple<'a>> {
371 match self {
372 Script::Sub(sub) => Some(sub),
373 Script::Subsuper(sub, _) => Some(sub),
374 _ => None,
375 }
376 }
377
378 pub fn sup(&self) -> Option<&Simple<'a>> {
380 match self {
381 Script::Super(sup) => Some(sup),
382 Script::Subsuper(_, sup) => Some(sup),
383 _ => None,
384 }
385 }
386}
387
388#[derive(Default, Debug, Clone, PartialEq, Eq)]
390pub struct SimpleScript<'a> {
391 pub simple: Simple<'a>,
393 pub script: Script<'a>,
395}
396
397impl<'a> SimpleScript<'a> {
398 pub fn new<S>(simple: S, script: Script<'a>) -> Self
400 where
401 S: Into<Simple<'a>>,
402 {
403 SimpleScript {
404 simple: simple.into(),
405 script,
406 }
407 }
408
409 pub fn without_scripts<S>(simple: S) -> Self
411 where
412 S: Into<Simple<'a>>,
413 {
414 Self::new(simple, Script::None)
415 }
416
417 pub fn with_sub<S, Sub>(simple: S, sub: Sub) -> Self
419 where
420 S: Into<Simple<'a>>,
421 Sub: Into<Simple<'a>>,
422 {
423 Self::new(simple, Script::Sub(sub.into()))
424 }
425
426 pub fn with_super<S, Sup>(simple: S, sup: Sup) -> Self
428 where
429 S: Into<Simple<'a>>,
430 Sup: Into<Simple<'a>>,
431 {
432 Self::new(simple, Script::Super(sup.into()))
433 }
434
435 pub fn with_subsuper<S, Sub, Sup>(simple: S, sub: Sub, sup: Sup) -> Self
437 where
438 S: Into<Simple<'a>>,
439 Sub: Into<Simple<'a>>,
440 Sup: Into<Simple<'a>>,
441 {
442 Self::new(simple, Script::Subsuper(sub.into(), sup.into()))
443 }
444}
445
446impl<'a, S> From<S> for SimpleScript<'a>
447where
448 S: Into<Simple<'a>>,
449{
450 fn from(inp: S) -> Self {
451 SimpleScript::without_scripts(inp.into())
452 }
453}
454
455impl<'a> Deref for SimpleScript<'a> {
457 type Target = Script<'a>;
458
459 fn deref(&self) -> &Self::Target {
460 &self.script
461 }
462}
463
464#[derive(Debug, Clone, PartialEq, Eq)]
466pub struct Func<'a> {
467 pub func: &'a str,
469 pub script: Script<'a>,
471 arg: Box<ScriptFunc<'a>>,
473}
474
475impl<'a> Func<'a> {
476 pub fn new<Arg>(func: &'a str, script: Script<'a>, arg: Arg) -> Self
478 where
479 Arg: Into<ScriptFunc<'a>>,
480 {
481 Func {
482 func,
483 script,
484 arg: Box::new(arg.into()),
485 }
486 }
487
488 pub fn without_scripts<Arg>(func: &'a str, arg: Arg) -> Self
490 where
491 Arg: Into<ScriptFunc<'a>>,
492 {
493 Self::new(func, Script::None, arg)
494 }
495
496 pub fn with_sub<Sub, Arg>(func: &'a str, sub: Sub, arg: Arg) -> Self
498 where
499 Sub: Into<Simple<'a>>,
500 Arg: Into<ScriptFunc<'a>>,
501 {
502 Self::new(func, Script::Sub(sub.into()), arg)
503 }
504
505 pub fn with_super<Sup, Arg>(func: &'a str, sup: Sup, arg: Arg) -> Self
507 where
508 Sup: Into<Simple<'a>>,
509 Arg: Into<ScriptFunc<'a>>,
510 {
511 Self::new(func, Script::Super(sup.into()), arg)
512 }
513
514 pub fn with_subsuper<Sub, Sup, Arg>(func: &'a str, sub: Sub, sup: Sup, arg: Arg) -> Self
516 where
517 Sub: Into<Simple<'a>>,
518 Sup: Into<Simple<'a>>,
519 Arg: Into<ScriptFunc<'a>>,
520 {
521 Self::new(func, Script::Subsuper(sub.into(), sup.into()), arg)
522 }
523
524 pub fn arg(&self) -> &ScriptFunc<'a> {
526 &self.arg
527 }
528}
529
530impl<'a> Deref for Func<'a> {
531 type Target = Script<'a>;
532
533 fn deref(&self) -> &Self::Target {
534 &self.script
535 }
536}
537
538#[derive(Debug, Clone, PartialEq, Eq)]
540pub enum ScriptFunc<'a> {
541 Simple(SimpleScript<'a>),
543 Func(Func<'a>),
545}
546
547impl<'a> Default for ScriptFunc<'a> {
548 fn default() -> Self {
549 ScriptFunc::Simple(SimpleScript::default())
550 }
551}
552
553impl<'a> From<Func<'a>> for ScriptFunc<'a> {
554 fn from(func: Func<'a>) -> Self {
555 ScriptFunc::Func(func)
556 }
557}
558
559impl<'a, S> From<S> for ScriptFunc<'a>
560where
561 S: Into<SimpleScript<'a>>,
562{
563 fn from(inp: S) -> Self {
564 ScriptFunc::Simple(inp.into())
565 }
566}
567
568#[derive(Debug, Clone, PartialEq, Eq)]
570pub struct Frac<'a> {
571 pub numer: ScriptFunc<'a>,
573 pub denom: ScriptFunc<'a>,
575}
576
577impl<'a> Frac<'a> {
578 pub fn new<N, D>(numer: N, denom: D) -> Self
580 where
581 N: Into<ScriptFunc<'a>>,
582 D: Into<ScriptFunc<'a>>,
583 {
584 Frac {
585 numer: numer.into(),
586 denom: denom.into(),
587 }
588 }
589}
590
591#[derive(Debug, Clone, PartialEq, Eq)]
593pub enum Intermediate<'a> {
594 ScriptFunc(ScriptFunc<'a>),
596 Frac(Frac<'a>),
598}
599
600impl<'a> Default for Intermediate<'a> {
601 fn default() -> Self {
602 Intermediate::ScriptFunc(ScriptFunc::default())
603 }
604}
605
606impl<'a> From<Frac<'a>> for Intermediate<'a> {
607 fn from(frac: Frac<'a>) -> Self {
608 Intermediate::Frac(frac)
609 }
610}
611
612impl<'a, S> From<S> for Intermediate<'a>
613where
614 S: Into<ScriptFunc<'a>>,
615{
616 fn from(inp: S) -> Self {
617 Intermediate::ScriptFunc(inp.into())
618 }
619}
620
621#[derive(Default, Debug, Clone, PartialEq, Eq)]
625pub struct Expression<'a>(Box<[Intermediate<'a>]>);
626
627impl<'a> Deref for Expression<'a> {
628 type Target = [Intermediate<'a>];
629
630 fn deref(&self) -> &Self::Target {
631 &self.0
632 }
633}
634
635impl<'a, I> FromIterator<I> for Expression<'a>
636where
637 I: Into<Intermediate<'a>>,
638{
639 fn from_iter<T>(iter: T) -> Self
640 where
641 T: IntoIterator<Item = I>,
642 {
643 Expression(iter.into_iter().map(|v| v.into()).collect())
644 }
645}
646
647impl<'a, B> From<B> for Expression<'a>
648where
649 B: Into<Box<[Intermediate<'a>]>>,
650{
651 fn from(inp: B) -> Self {
652 Expression(inp.into())
653 }
654}