1use geo_aid_derive::Parse;
5use num_traits::Zero;
6
7use crate::token::number::ProcNum;
8use crate::unroll::library;
9use std::fmt::Formatter;
10use std::ops::Deref;
11use std::{
12 fmt::{Debug, Display},
13 iter::Peekable,
14 marker::PhantomData,
15};
16
17use crate::span;
18
19use super::{
20 token::{
21 number::CompExponent, Ampersant, Asterisk, At, Caret, Colon, Comma, Dollar, Dot, Eq,
22 Exclamation, Gt, Gteq, Ident, LBrace, LParen, LSquare, Let, Lt, Lteq, Minus, NamedIdent,
23 NumberLit, Plus, Question, RBrace, RParen, RSquare, Semi, Slash, Span, StrLit, TokInteger,
24 Token,
25 },
26 unit, ComplexUnit, Error,
27};
28
29pub trait Parse {
31 type FirstToken: CheckParses;
33
34 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
39 input: &mut InputStream<'t, I>,
40 ) -> Result<Self, Error>
41 where
42 Self: Sized;
43
44 fn get_span(&self) -> Span;
46}
47
48pub trait CheckParses {
50 fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
52 input: &InputStream<'t, I>,
53 ) -> Option<bool>;
54}
55
56impl<T: Parse> CheckParses for T {
57 fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
58 input: &InputStream<'t, I>,
59 ) -> Option<bool> {
60 Some(input.clone().parse::<Self>().is_ok())
61 }
62}
63
64#[derive(Debug)]
66pub struct TokenOr<T, U> {
67 phantom_t: PhantomData<T>,
68 phantom_u: PhantomData<U>,
69}
70
71impl<T: CheckParses, U: CheckParses> CheckParses for TokenOr<T, U> {
72 fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
73 input: &InputStream<'t, I>,
74 ) -> Option<bool> {
75 T::check_parses(input).or_else(|| U::check_parses(input))
76 }
77}
78
79#[derive(Debug)]
81pub struct Maybe<T> {
82 phantom_t: PhantomData<T>,
83}
84
85impl<T: CheckParses> CheckParses for Maybe<T> {
86 fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
87 input: &InputStream<'t, I>,
88 ) -> Option<bool> {
89 T::check_parses(input).and_then(|x| if x { Some(x) } else { None })
90 }
91}
92
93impl<T: Parse> Parse for Vec<T> {
94 type FirstToken = Maybe<T::FirstToken>;
95
96 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
97 input: &mut InputStream<'t, I>,
98 ) -> Result<Self, Error>
99 where
100 Self: Sized,
101 {
102 let mut parsed = Self::new();
103
104 while let Ok(Some(v)) = input.parse() {
105 parsed.push(v);
106 }
107
108 Ok(parsed)
109 }
110
111 fn get_span(&self) -> Span {
112 self.first().map_or(Span::empty(), |x| {
113 x.get_span().join(self.last().unwrap().get_span())
114 })
115 }
116}
117
118pub struct AtLeastOne<T>(Vec<T>);
120
121impl<T: Debug> Debug for AtLeastOne<T> {
122 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123 write!(f, "{:?}", self.0)
124 }
125}
126
127impl<T> Deref for AtLeastOne<T> {
128 type Target = Vec<T>;
129
130 fn deref(&self) -> &Self::Target {
131 &self.0
132 }
133}
134
135impl<T: Parse> Parse for AtLeastOne<T> {
136 type FirstToken = T::FirstToken;
137
138 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
139 input: &mut InputStream<'t, I>,
140 ) -> Result<Self, Error>
141 where
142 Self: Sized,
143 {
144 let mut parsed = Vec::new();
145
146 if let Ok(v) = input.parse() {
148 parsed.push(v);
149 }
150
151 while let Ok(Some(v)) = input.parse() {
152 parsed.push(v);
153 }
154
155 Ok(Self(parsed))
156 }
157
158 fn get_span(&self) -> Span {
159 self.first().map_or(Span::empty(), |x| {
160 x.get_span().join(self.last().unwrap().get_span())
161 })
162 }
163}
164
165impl<T: Parse, U: Parse> Parse for (T, U) {
166 type FirstToken = T::FirstToken;
167
168 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
169 input: &mut InputStream<'t, I>,
170 ) -> Result<Self, Error>
171 where
172 Self: Sized,
173 {
174 Ok((input.parse()?, input.parse()?))
175 }
176
177 fn get_span(&self) -> Span {
178 self.0.get_span().join(self.1.get_span())
179 }
180}
181
182impl<T: Parse> Parse for Option<T> {
183 type FirstToken = Maybe<T::FirstToken>;
184
185 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
186 input: &mut InputStream<'t, I>,
187 ) -> Result<Self, Error>
188 where
189 Self: Sized,
190 {
191 let mut branch = input.clone();
192
193 if let Ok(v) = branch.parse() {
194 *input = branch;
195 Ok(Some(v))
196 } else {
197 Ok(None)
198 }
199 }
200
201 fn get_span(&self) -> Span {
202 match self {
203 Some(v) => v.get_span(),
204 None => span!(0, 0, 0, 0),
205 }
206 }
207}
208
209#[derive(Debug, Clone)]
211pub struct InputStream<'t, I: Iterator<Item = &'t Token> + Clone> {
212 it: Peekable<I>,
214}
215
216impl<'t, I: Iterator<Item = &'t Token> + Clone> InputStream<'t, I> {
217 #[must_use]
219 pub fn new<It: IntoIterator<IntoIter = I>>(it: It) -> Self {
220 Self {
221 it: it.into_iter().peekable(),
222 }
223 }
224
225 pub fn parse<P: Parse>(&mut self) -> Result<P, Error> {
230 P::parse(self)
231 }
232
233 pub fn get_token(&mut self) -> Result<&'t Token, Error> {
238 self.it.next().ok_or(Error::EndOfInput)
239 }
240
241 pub fn expect_token(&mut self) -> Result<(), Error> {
246 if self.eof() {
247 Err(Error::EndOfInput)
248 } else {
249 Ok(())
250 }
251 }
252
253 #[must_use]
255 pub fn eof(&mut self) -> bool {
256 self.it.peek().is_none()
257 }
258}
259
260#[derive(Debug, Parse)]
262pub enum BinaryOperator {
263 Add(Plus),
265 Sub(Minus),
267 Mul(Asterisk),
269 Div(Slash),
271}
272
273impl Display for BinaryOperator {
274 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
275 match self {
276 BinaryOperator::Add(_) => write!(f, "+"),
277 BinaryOperator::Sub(_) => write!(f, "-"),
278 BinaryOperator::Mul(_) => write!(f, "*"),
279 BinaryOperator::Div(_) => write!(f, "/"),
280 }
281 }
282}
283
284#[derive(Debug, Parse)]
287#[parse(first_token = Ampersant)]
288pub struct PointCollectionConstructor {
289 pub ampersant: Ampersant,
290 pub left_paren: LParen,
291 pub points: Punctuated<Expression<false>, Comma>,
292 pub right_paren: RParen,
293}
294
295#[derive(Debug)]
297pub struct ImplicitIterator<const ITER: bool> {
298 pub exprs: Punctuated<SimpleExpression, Comma>,
299}
300
301impl<const ITER: bool> ImplicitIterator<ITER> {
302 #[must_use]
304 pub fn get(&self, index: usize) -> Option<&SimpleExpression> {
305 if ITER {
306 self.exprs.get(index)
307 } else {
308 Some(&self.exprs.first)
309 }
310 }
311}
312
313impl<const ITER: bool> Parse for ImplicitIterator<ITER> {
314 type FirstToken = <SimpleExpression as Parse>::FirstToken;
315
316 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
317 input: &mut InputStream<'t, I>,
318 ) -> Result<Self, Error>
319 where
320 Self: Sized,
321 {
322 if ITER {
323 Ok(Self {
324 exprs: input.parse()?,
325 })
326 } else {
327 Ok(Self {
328 exprs: Punctuated {
329 first: input.parse()?,
330 collection: Vec::new(),
331 },
332 })
333 }
334 }
335
336 fn get_span(&self) -> Span {
337 self.exprs.get_span()
338 }
339}
340
341#[derive(Debug)]
343pub struct ExplicitIterator {
344 pub dollar: Dollar,
345 pub id_token: TokInteger,
346 pub id: u8,
347 pub left_paren: LParen,
348 pub exprs: Punctuated<Expression<false>, Comma>,
349 pub right_paren: RParen,
350}
351
352impl ExplicitIterator {
353 #[must_use]
355 pub fn get(&self, index: usize) -> Option<&Expression<false>> {
356 self.exprs.get(index)
357 }
358}
359
360impl Parse for ExplicitIterator {
361 type FirstToken = Dollar;
362
363 fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
364 input: &mut InputStream<'r, I>,
365 ) -> Result<Self, Error> {
366 let mut parsed = Self {
367 dollar: input.parse()?,
368 id_token: input.parse()?,
369 id: 0,
370 left_paren: input.parse()?,
371 exprs: input.parse()?,
372 right_paren: input.parse()?,
373 };
374
375 parsed.id = parsed
376 .id_token
377 .parsed
378 .parse()
379 .map_err(|_| Error::NumberTooLarge {
380 error_span: parsed.id_token.get_span(),
381 })?;
382
383 if parsed.exprs.len() == 1 {
384 return Err(Error::SingleVariantExplicitIterator {
385 error_span: parsed.dollar.span.join(parsed.right_paren.span),
386 });
387 }
388
389 Ok(parsed)
390 }
391
392 fn get_span(&self) -> Span {
393 self.dollar.span.join(self.right_paren.span)
394 }
395}
396
397#[derive(Debug)]
399pub enum Expression<const ITER: bool> {
400 ImplicitIterator(ImplicitIterator<ITER>),
402 Binop(ExprBinop<ITER>),
404}
405
406impl<const ITER: bool> Parse for Expression<ITER> {
407 type FirstToken = <SimpleExpression as Parse>::FirstToken;
408
409 fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
410 input: &mut InputStream<'r, I>,
411 ) -> Result<Self, Error> {
412 let mut expr = Expression::ImplicitIterator(input.parse()?);
413
414 while let Ok(Some(op)) = input.parse() {
415 let rhs = Expression::ImplicitIterator(input.parse()?);
416
417 expr = dispatch_order(expr, op, rhs);
418 }
419
420 Ok(expr)
421 }
422
423 fn get_span(&self) -> Span {
424 match self {
425 Expression::ImplicitIterator(it) => it.get_span(),
426 Expression::Binop(e) => e.lhs.get_span().join(e.rhs.get_span()),
427 }
428 }
429}
430
431#[derive(Debug)]
433pub struct RationalExponent {
434 pub lparen: LParen,
435 pub num: TokInteger,
436 pub slash: Slash,
437 pub denum: TokInteger,
438 pub rparen: RParen,
439}
440
441impl Parse for RationalExponent {
442 type FirstToken = LParen;
443
444 fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
445 input: &mut InputStream<'r, I>,
446 ) -> Result<Self, Error> {
447 let parsed = Self {
448 lparen: input.parse()?,
449 num: input.parse()?,
450 slash: input.parse()?,
451 denum: input.parse()?,
452 rparen: input.parse()?,
453 };
454
455 if parsed.denum.parsed.is_zero() {
456 return Err(Error::ZeroDenominator {
457 error_span: parsed.denum.span,
458 });
459 }
460
461 Ok(parsed)
462 }
463
464 fn get_span(&self) -> Span {
465 self.lparen.span.join(self.rparen.span)
466 }
467}
468
469#[derive(Debug, Parse)]
471pub enum Exponent {
472 Simple(TokInteger),
473 Parenthesized(RationalExponent),
474}
475
476impl Exponent {
477 pub fn as_comp(&self) -> Result<CompExponent, Error> {
482 match self {
483 Self::Simple(i) => Ok(CompExponent::new(
484 i.parsed
485 .parse()
486 .map_err(|_| Error::NumberTooLarge { error_span: i.span })?,
487 1,
488 )),
489 Self::Parenthesized(exp) => Ok(CompExponent::new(
490 exp.num.parsed.parse().map_err(|_| Error::NumberTooLarge {
491 error_span: exp.num.span,
492 })?,
493 exp.denum
494 .parsed
495 .parse()
496 .map_err(|_| Error::NumberTooLarge {
497 error_span: exp.denum.span,
498 })?,
499 )),
500 }
501 }
502}
503
504#[derive(Debug, Parse)]
506pub struct Exponentiation {
507 pub caret: Caret,
509 pub minus: Option<Minus>,
511 pub exponent: Exponent,
513}
514
515#[derive(Debug, Parse)]
517pub struct FieldIndex {
518 pub name: Box<Name>,
520 pub dot: Dot,
522 pub field: Ident,
524}
525
526#[derive(Debug)]
528pub enum Name {
529 Call(ExprCall),
532 FieldIndex(FieldIndex),
533 Ident(Ident),
534 Expression(ExprParenthesised),
535}
536
537impl Parse for Name {
538 type FirstToken = TokenOr<Maybe<Ident>, LParen>;
539
540 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
541 input: &mut InputStream<'t, I>,
542 ) -> Result<Self, Error>
543 where
544 Self: Sized,
545 {
546 let mut name = if let Some(expr) = input.parse()? {
547 Self::Expression(expr)
548 } else {
549 Self::Ident(input.parse()?)
550 };
551
552 loop {
553 name = if let Some(dot) = input.parse::<Option<Dot>>()? {
554 Self::FieldIndex(FieldIndex {
555 name: Box::new(name),
556 dot,
557 field: input.parse()?,
558 })
559 } else if let Some(lparen) = input.parse::<Option<LParen>>()? {
560 Self::Call(ExprCall {
561 name: Box::new(name),
562 lparen,
563 params: input.parse()?,
564 rparen: input.parse()?,
565 })
566 } else {
567 break Ok(name);
568 };
569 }
570 }
571
572 fn get_span(&self) -> Span {
573 match self {
574 Self::Call(v) => v.get_span(),
575 Self::FieldIndex(v) => v.get_span(),
576 Self::Expression(v) => v.get_span(),
577 Self::Ident(v) => v.get_span(),
578 }
579 }
580}
581
582#[derive(Debug, Parse)]
584pub struct SimpleExpression {
585 pub minus: Option<Minus>,
587 pub kind: SimpleExpressionKind,
589 pub exponent: Option<Exponentiation>,
591 pub display: Option<DisplayProperties>,
593}
594
595#[derive(Debug, Parse)]
597pub enum SimpleExpressionKind {
598 Name(Name),
600 Number(NumberLit),
602 ExplicitIterator(ExplicitIterator),
604 PointCollection(PointCollectionConstructor),
606}
607
608#[derive(Debug, Parse)]
610pub struct ExprCall {
611 pub name: Box<Name>,
613 pub lparen: LParen,
615 pub params: Option<Punctuated<Expression<false>, Comma>>,
617 pub rparen: RParen,
619}
620
621#[derive(Debug, Parse)]
623pub struct ExprParenthesised {
624 pub lparen: LParen,
626 pub content: Box<Expression<true>>,
628 pub rparen: RParen,
630}
631
632#[derive(Debug, Parse)]
634pub struct ExprBinop<const ITER: bool> {
635 pub lhs: Box<Expression<ITER>>,
637 pub operator: BinaryOperator,
639 pub rhs: Box<Expression<ITER>>,
641}
642
643impl BinaryOperator {
644 fn index(&self) -> u8 {
645 match self {
646 BinaryOperator::Add(_) | BinaryOperator::Sub(_) => 1,
647 BinaryOperator::Mul(_) | BinaryOperator::Div(_) => 2,
648 }
649 }
650}
651
652fn dispatch_order<const ITER: bool>(
654 lhs: Expression<ITER>,
655 op: BinaryOperator,
656 rhs: Expression<ITER>, ) -> Expression<ITER> {
658 match lhs {
659 lhs @ Expression::ImplicitIterator(_) => Expression::Binop(ExprBinop {
661 lhs: Box::new(lhs),
662 operator: op,
663 rhs: Box::new(rhs),
664 }),
665 Expression::Binop(lhs) => {
667 if op.index() > lhs.operator.index() {
668 Expression::Binop(ExprBinop {
669 lhs: lhs.lhs,
670 operator: lhs.operator,
671 rhs: Box::new(dispatch_order(*lhs.rhs, op, rhs)),
672 })
673 } else {
674 Expression::Binop(ExprBinop {
675 lhs: Box::new(Expression::Binop(lhs)),
676 operator: op,
677 rhs: Box::new(rhs),
678 })
679 }
680 }
681 }
682}
683
684#[derive(Debug, Parse)]
686pub enum PredefinedRuleOperator {
687 Eq(Eq),
689 Lt(Lt),
691 Gt(Gt),
693 Lteq(Lteq),
695 Gteq(Gteq),
697}
698
699#[derive(Debug, Parse)]
701pub enum RuleOperator {
702 Inverted(InvertedRuleOperator),
704 Predefined(PredefinedRuleOperator),
705 Defined(NamedIdent),
706}
707
708#[derive(Debug, Parse)]
710#[parse(first_token = Exclamation)]
711pub struct InvertedRuleOperator {
712 pub exclamation: Exclamation,
714 pub operator: Box<RuleOperator>,
716}
717
718#[derive(Debug, Parse)]
720pub struct FlagName {
721 pub at: At,
722 pub name: Punctuated<NamedIdent, Dot>,
723 pub colon: Colon,
724}
725
726#[derive(Debug, Parse)]
728#[parse(first_token = LBrace)]
729pub struct FlagSet {
730 pub lbrace: LBrace,
731 pub flags: Vec<FlagStatement>,
732 pub rbrace: RBrace,
733}
734
735#[derive(Debug, Parse)]
737pub enum FlagValue {
738 Ident(NamedIdent),
739 Set(FlagSet),
740 Number(NumberLit),
741}
742
743#[derive(Debug, Parse)]
745pub struct FlagStatement {
746 pub name: FlagName,
747 pub value: FlagValue,
748}
749
750#[derive(Debug, Clone, Parse)]
752pub struct VariableDefinition {
753 pub name: Ident,
755 pub display_properties: Option<DisplayProperties>,
757}
758
759#[derive(Debug, Parse)]
762pub struct LetStatement {
763 pub let_token: Let,
765 pub ident: Punctuated<VariableDefinition, Comma>,
767 pub eq: Eq,
769 pub expr: Expression<true>,
771 pub rule: Option<(RuleOperator, Expression<true>)>,
773 pub semi: Semi,
775}
776
777#[derive(Debug, Parse)]
780pub struct RuleStatement {
781 pub first: Expression<true>,
783 pub rules: AtLeastOne<(RuleOperator, Expression<true>)>,
785 pub semi: Semi,
787}
788
789#[derive(Debug, Parse)]
791pub struct RefStatement {
792 pub question: Question,
794 pub operand: Expression<true>,
796 pub semi: Semi,
798}
799
800#[derive(Debug)]
802pub enum Statement {
803 Noop(Semi),
805 Let(Displayed<LetStatement>),
807 Flag(FlagStatement),
809 Ref(Displayed<RefStatement>),
811 Rule(Displayed<RuleStatement>),
813}
814
815impl Parse for Statement {
816 type FirstToken = TokenOr<
817 LSquare,
818 TokenOr<
819 Semi,
820 TokenOr<At, TokenOr<Question, TokenOr<Let, <SimpleExpression as Parse>::FirstToken>>>,
821 >,
822 >;
823
824 fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
825 input: &mut InputStream<'t, I>,
826 ) -> Result<Self, Error>
827 where
828 Self: Sized,
829 {
830 let props = input.parse()?;
831 input.expect_token()?;
832
833 let tok = input.it.peek().cloned().unwrap();
834
835 match tok {
836 Token::Let(_) => Ok(Self::Let(Displayed {
837 properties: props,
838 statement: input.parse()?,
839 })),
840 Token::Semi(_) => {
841 if props.is_some() {
842 Err(Error::UnexpectedProperties {
843 error_span: props.get_span(),
844 })
845 } else {
846 Ok(Self::Noop(input.parse()?))
847 }
848 }
849 Token::At(_) => {
850 if props.is_some() {
851 Err(Error::UnexpectedProperties {
852 error_span: props.get_span(),
853 })
854 } else {
855 Ok(Self::Flag(input.parse()?))
856 }
857 }
858 Token::Question(_) => Ok(Self::Ref(Displayed {
859 properties: props,
860 statement: input.parse()?,
861 })),
862 _ => Ok(Self::Rule(Displayed {
863 properties: props,
864 statement: input.parse()?,
865 })),
866 }
867 }
868
869 fn get_span(&self) -> Span {
870 todo!()
871 }
872}
873
874impl Statement {
875 #[must_use]
876 pub fn as_flag(&self) -> Option<&FlagStatement> {
877 if let Self::Flag(v) = self {
878 Some(v)
879 } else {
880 None
881 }
882 }
883}
884
885#[derive(Debug, Parse)]
887pub struct Displayed<T: Parse> {
888 pub properties: Option<DisplayProperties>,
890 pub statement: T,
892}
893
894#[derive(Debug, Clone, Parse)]
896pub struct Punctuated<T: Parse, P: Parse> {
897 pub first: Box<T>,
899 pub collection: Vec<(P, T)>,
901}
902
903impl<T: Parse, P: Parse> Punctuated<T, P> {
904 #[must_use]
906 pub fn new(first: T) -> Punctuated<T, P> {
907 Self {
908 first: Box::new(first),
909 collection: Vec::new(),
910 }
911 }
912
913 pub fn iter(&self) -> impl Iterator<Item = &T> {
915 vec![self.first.as_ref()]
916 .into_iter()
917 .chain(self.collection.iter().map(|x| &x.1))
918 }
919
920 pub fn into_parsed_iter(self) -> impl Iterator<Item = T> {
922 vec![*self.first]
923 .into_iter()
924 .chain(self.collection.into_iter().map(|x| x.1))
925 }
926
927 #[must_use]
929 pub fn len(&self) -> usize {
930 self.collection.len() + 1
931 }
932
933 #[must_use]
935 pub fn is_empty(&self) -> bool {
936 false
937 }
938
939 #[must_use]
941 pub fn get(&self, index: usize) -> Option<&T> {
942 match index {
943 0 => Some(&self.first),
944 _ => self.collection.get(index - 1).map(|x| &x.1),
945 }
946 }
947}
948
949impl Parse for TokInteger {
950 type FirstToken = NumberLit;
951
952 fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
953 input: &mut InputStream<'r, I>,
954 ) -> Result<Self, Error> {
955 match input.get_token()? {
956 Token::NumberLit(NumberLit::Integer(tok)) => Ok(tok.clone()),
957 t => Err(Error::InvalidToken { token: t.clone() }),
958 }
959 }
960
961 fn get_span(&self) -> Span {
962 self.span
963 }
964}
965
966impl Parse for NamedIdent {
967 type FirstToken = Ident;
968
969 fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
970 input: &mut InputStream<'r, I>,
971 ) -> Result<Self, Error> {
972 match input.get_token()? {
973 Token::Ident(Ident::Named(named)) => Ok(named.clone()),
974 t => Err(Error::InvalidToken { token: t.clone() }),
975 }
976 }
977
978 fn get_span(&self) -> Span {
979 self.span
980 }
981}
982
983impl<T: Parse> Parse for Box<T> {
984 type FirstToken = T::FirstToken;
985
986 fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
987 input: &mut InputStream<'r, I>,
988 ) -> Result<Self, Error> {
989 Ok(Box::new(input.parse()?))
990 }
991
992 fn get_span(&self) -> Span {
993 (**self).get_span()
994 }
995}
996
997#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
999pub enum Type {
1000 Point,
1002 Line,
1004 Number(Option<ComplexUnit>),
1006 PointCollection(usize),
1008 Circle,
1010 Derived(&'static str),
1012 Unknown,
1014}
1015
1016impl Type {
1017 #[must_use]
1018 pub fn as_number(&self) -> Option<&Option<ComplexUnit>> {
1019 if let Self::Number(v) = self {
1020 Some(v)
1021 } else {
1022 None
1023 }
1024 }
1025}
1026
1027pub struct DefinedType {
1029 pub name: String,
1031}
1032
1033impl Display for Type {
1034 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1035 match self {
1036 Self::Point => write!(f, "Point"),
1037 Self::Line => write!(f, "Line"),
1038 Self::Number(unit) => match unit {
1039 Some(unit) => write!(f, "Number ({unit})"),
1040 None => write!(f, "Number (no unit)"),
1041 },
1042 Self::PointCollection(l) => write!(f, "Point collection ({l})"),
1043 Self::Circle => write!(f, "Circle"),
1044 Self::Derived(name) => write!(f, "{name}"),
1045 Type::Unknown => write!(f, "undefined"),
1046 }
1047 }
1048}
1049
1050impl Type {
1051 #[must_use]
1053 pub fn can_cast(&self, into: &Type) -> bool {
1054 match self {
1055 Type::Point => matches!(into, Type::Point | Type::PointCollection(1)),
1057 Type::Line => matches!(into, Type::Line),
1059 Type::Number(Some(unit1)) => {
1061 if let Type::Number(Some(unit2)) = into {
1062 unit1 == unit2
1063 } else {
1064 false
1065 }
1066 }
1067 Type::Number(None) => match into {
1069 Type::Number(unit) => match unit {
1070 Some(unit) => unit.0[1].is_zero(), None => true,
1072 },
1073 _ => false,
1074 },
1075 Type::PointCollection(l) => match into {
1076 Type::Point => *l == 1,
1077 Type::Line => *l == 2,
1078 Type::Number(Some(u)) => *u == unit::DISTANCE && *l == 2,
1079 Type::PointCollection(v) => v == l || *v == 0,
1080 _ => false,
1081 },
1082 Type::Circle => matches!(into, Type::Circle),
1083 Type::Derived(name) => {
1084 if into == self {
1085 true
1086 } else if let Type::PointCollection(count) = into {
1087 library::get_derived_pc(name) == *count
1088 } else {
1089 false
1090 }
1091 }
1092 Type::Unknown => true,
1093 }
1094 }
1095}
1096
1097#[derive(Debug, Clone, Parse)]
1099pub struct Property {
1100 pub name: NamedIdent,
1102 pub eq: Eq,
1104 pub value: PropertyValue,
1106}
1107
1108#[derive(Debug, Clone, Parse)]
1110pub enum PropertyValue {
1111 Number(NumberLit),
1112 Ident(Ident),
1113 RawString(RawString),
1114 String(StrLit),
1115}
1116
1117impl Display for PropertyValue {
1118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1119 match self {
1120 Self::Number(n) => write!(f, "{n}"),
1121 Self::Ident(i) => write!(f, "{i}"),
1122 Self::RawString(s) => write!(f, "!{}", s.lit),
1123 Self::String(s) => write!(f, "{s}"),
1124 }
1125 }
1126}
1127
1128#[derive(Debug, Clone, Parse)]
1130pub struct RawString {
1131 pub excl: Exclamation,
1132 pub lit: StrLit,
1134}
1135
1136pub trait FromProperty: Sized {
1138 fn from_property(property: PropertyValue) -> Result<Self, Error>;
1143}
1144
1145impl<T: FromProperty> FromProperty for Result<T, Error> {
1146 fn from_property(property: PropertyValue) -> Result<Self, Error> {
1147 Ok(T::from_property(property))
1148 }
1149}
1150
1151impl FromProperty for bool {
1152 fn from_property(property: PropertyValue) -> Result<Self, Error> {
1153 match property {
1154 PropertyValue::Ident(ident) => match ident {
1155 Ident::Named(ident) => match ident.ident.as_str() {
1156 "enabled" | "on" | "true" | "yes" => Ok(true),
1157 "disabled" | "off" | "false" | "no" => Ok(false),
1158 _ => Err(Error::BooleanExpected {
1159 error_span: ident.get_span(),
1160 }),
1161 },
1162 Ident::Collection(_) => Err(Error::BooleanExpected {
1163 error_span: ident.get_span(),
1164 }),
1165 },
1166 PropertyValue::Number(num) => match num {
1167 NumberLit::Integer(i) => match i.parsed.parse::<u8>() {
1168 Ok(0) => Ok(false),
1169 Ok(1) => Ok(true),
1170 _ => Err(Error::BooleanExpected { error_span: i.span }),
1171 },
1172 NumberLit::Float(f) => Err(Error::BooleanExpected { error_span: f.span }),
1173 },
1174 PropertyValue::String(s) => match s.content.as_str() {
1175 "enabled" | "on" | "true" | "yes" => Ok(true),
1176 "disabled" | "off" | "false" | "no" => Ok(false),
1177 _ => Err(Error::BooleanExpected {
1178 error_span: s.get_span(),
1179 }),
1180 },
1181 PropertyValue::RawString(s) => Err(Error::BooleanExpected {
1182 error_span: s.get_span(),
1183 }),
1184 }
1185 }
1186}
1187
1188impl FromProperty for String {
1189 fn from_property(property: PropertyValue) -> Result<String, Error> {
1190 match property {
1191 PropertyValue::Ident(ident) => Ok(ident.to_string()),
1192 PropertyValue::Number(num) => Err(Error::StringExpected {
1193 error_span: num.get_span(),
1194 }),
1195 PropertyValue::RawString(s) => Ok(s.lit.content),
1196 PropertyValue::String(s) => Ok(s.content),
1197 }
1198 }
1199}
1200
1201impl FromProperty for ProcNum {
1202 fn from_property(property: PropertyValue) -> Result<Self, Error> {
1203 match property {
1204 PropertyValue::Number(num) => Ok(ProcNum::from(&num)),
1205 PropertyValue::RawString(s) => Err(Error::NumberExpected {
1206 error_span: s.get_span(),
1207 }),
1208 PropertyValue::String(s) => Err(Error::NumberExpected {
1209 error_span: s.get_span(),
1210 }),
1211 PropertyValue::Ident(ident) => Err(Error::NumberExpected {
1212 error_span: ident.get_span(),
1213 }),
1214 }
1215 }
1216}
1217
1218#[derive(Debug, Clone, Parse)]
1220pub struct DisplayProperties {
1221 pub lsquare: LSquare,
1223 pub properties: Punctuated<Property, Semi>,
1225 pub rsquare: RSquare,
1227}