1use std::{
2 fmt,
3 hash::{Hash, Hasher},
4 slice::Iter,
5 str::FromStr,
6};
7
8use crate::{
9 mem::{Root, Trace},
10 parser::{Input, ParseError},
11};
12
13use super::{
14 parser::{binary, code, text, TypeCodeError},
15 ArrayType, LambdaType, OptionType, PairType, Parameters, TypeError, TypeVec, UnionType,
16};
17
18#[derive(Clone, Debug, Eq)]
50pub struct Type(TypeVec);
51
52impl Type {
53 #[inline]
59 pub fn new(code: impl AsRef<[u8]>) -> Result<Self, TypeCodeError> {
60 binary::parse(code.as_ref())
61 }
62
63 #[must_use]
70 #[inline]
71 pub unsafe fn new_unchecked(code: impl AsRef<[u8]>) -> Self {
72 Self(code.as_ref().into())
73 }
74
75 #[must_use]
78 #[inline]
79 pub fn into_inner(self) -> TypeVec {
80 self.0
81 }
82
83 #[allow(clippy::cast_possible_truncation)]
91 pub fn array(elem: Self, size: Option<usize>) -> Result<Self, TypeError> {
92 let mut code = TypeVec::default();
93 code.push(code::ARRAY);
94
95 if !(elem.is_filled() || elem.is_option()) {
96 return Err(TypeError::ArrayElemNotFilled);
97 }
98 code.extend(elem.0);
99
100 match size {
101 Some(size @ 0x0000_0000_0000..=0x0000_0000_000f) => {
102 code.push(code::FIXED0 | size as u8);
103 }
104 Some(size @ 0x0000_0000_0010..=0x0000_0000_0fff) => {
105 code.push(code::FIXED1 | (size >> 8) as u8);
106 code.push(size as u8);
107 }
108 Some(size @ 0x0000_0000_1000..=0x0000_000f_ffff) => {
109 code.push(code::FIXED2 | (size >> 16) as u8);
110 code.push((size >> 8) as u8);
111 code.push(size as u8);
112 }
113 Some(size @ 0x0000_0010_0000..=0x0000_0fff_ffff) => {
114 code.push(code::FIXED3 | (size >> 24) as u8);
115 code.push((size >> 16) as u8);
116 code.push((size >> 8) as u8);
117 code.push(size as u8);
118 }
119 Some(size @ 0x0000_1000_0000..=0x000f_ffff_ffff) => {
120 code.push(code::FIXED4 | (size >> 32) as u8);
121 code.push((size >> 24) as u8);
122 code.push((size >> 16) as u8);
123 code.push((size >> 8) as u8);
124 code.push(size as u8);
125 }
126 Some(size) => return Err(TypeError::ArraySizeTooLarge(size)),
127 None => {}
128 }
129 Ok(Self(code))
130 }
131
132 #[must_use]
134 #[inline]
135 pub fn is_array(&self) -> bool {
136 self.0.first() == Some(&code::ARRAY)
137 }
138
139 #[must_use]
146 pub fn as_array(&self) -> Option<ArrayType> {
147 if self.is_array() {
148 let input = &self.0.as_slice()[1..];
149 let (elem, cursor) = binary::parse_filled_option(input, 0).expect("array elem-type");
150 let (len, _) =
151 binary::parse_fixed(cursor, input.len() - cursor.len()).expect("array size");
152
153 Some(ArrayType { elem, len })
154 } else {
155 None
156 }
157 }
158
159 pub fn lambda<I>(params: I, variadic: Option<Self>, ret: Self) -> Result<Self, TypeError>
167 where
168 I: IntoIterator<Item = Self>,
169 {
170 let mut code = TypeVec::default();
171 code.push(code::LAMBDA);
172 for (i, arg) in params.into_iter().enumerate() {
173 if !(arg.is_filled() || arg.is_option()) {
174 return Err(TypeError::ParamNotFilled(i + 1));
175 }
176 code.extend(arg.0);
177 }
178 if let Some(variadic) = variadic {
179 if !(variadic.is_filled() || variadic.is_option()) {
180 return Err(TypeError::VariadicNotFilled);
181 }
182 code.push(code::VARIADIC);
183 code.extend(variadic.0);
184 }
185 code.push(code::RETURN);
186 code.extend(ret.0);
187 Ok(Self(code))
188 }
189
190 #[must_use]
192 #[inline]
193 pub fn is_lambda(&self) -> bool {
194 self.0.first() == Some(&code::LAMBDA)
195 }
196
197 #[must_use]
204 pub fn as_lambda(&self) -> Option<LambdaType> {
205 if self.is_lambda() {
206 let code = &self.0.as_slice()[1..];
207 let (params, code) = binary::parse_params(code, 0).expect("lambda parameter types");
208 let (variadic, code) = binary::parse_variadic(code, 0).expect("lambda variadic type");
209 let (ret, _) = binary::parse_return(code, 0).expect("lambda return type");
210
211 Some(LambdaType {
212 params,
213 variadic,
214 result: ret,
215 })
216 } else {
217 None
218 }
219 }
220
221 pub fn option(ty: Self) -> Result<Self, TypeError> {
228 let mut code = TypeVec::default();
229
230 if ty.is_option() {
231 return Err(TypeError::NestedOption);
232 }
233 if !ty.is_filled() {
234 return Err(TypeError::OptionNotFilled);
235 }
236 code.push(code::OPTION);
237 code.extend(ty.0);
238 Ok(Self(code))
239 }
240
241 #[must_use]
243 #[inline]
244 pub fn is_option(&self) -> bool {
245 self.0.first() == Some(&code::OPTION)
246 }
247
248 #[must_use]
255 pub fn as_option(&self) -> Option<OptionType> {
256 if self.is_option() {
257 let code = &self.0.as_slice()[1..];
258 let (some, _) = binary::parse_filled(code, 0).expect("option some-type");
259
260 Some(OptionType { some })
261 } else {
262 None
263 }
264 }
265
266 #[allow(clippy::similar_names)]
272 pub fn pair(car: Self, cdr: Self) -> Result<Self, TypeError> {
273 let mut code = TypeVec::default();
274 code.push(code::PAIR);
275 if !(car.is_filled() || car.is_option()) {
276 return Err(TypeError::PairCarNotFilled);
277 }
278 code.extend(car.0);
279 if !(cdr.is_filled() || cdr.is_option()) {
280 return Err(TypeError::PairCdrNotFilled);
281 }
282 code.extend(cdr.0);
283 Ok(Self(code))
284 }
285
286 #[must_use]
288 #[inline]
289 pub fn is_pair(&self) -> bool {
290 self.0.first() == Some(&code::PAIR)
291 }
292
293 #[allow(clippy::similar_names)]
300 #[must_use]
301 pub fn as_pair(&self) -> Option<PairType> {
302 if self.is_pair() {
303 let code = &self.0.as_slice()[1..];
304 let (car, code) = binary::parse_filled_option(code, 0).expect("pair car-type");
305 let (cdr, _) = binary::parse_filled_option(code, 0).expect("pair cdr-type");
306
307 Some(PairType {
308 head: car,
309 tail: cdr,
310 })
311 } else {
312 None
313 }
314 }
315
316 pub fn union<I>(types: I) -> Result<Self, TypeError>
324 where
325 I: IntoIterator<Item = Self>,
326 {
327 let mut code = TypeVec::default();
328 let mut count = 0;
329
330 code.push(code::UNION);
331 for ty in types {
332 if !ty.is_specific() {
333 return Err(TypeError::UnionNotSpecific(ty));
334 }
335 code.extend(ty.0);
336 count += 1;
337 }
338 if count < 2 {
339 return Err(TypeError::UnionTooFewMembers);
340 }
341 code.push(code::END);
342 Ok(Self(code))
343 }
344
345 #[allow(clippy::similar_names)]
347 #[must_use]
348 pub fn is_union(&self) -> bool {
349 self.0.first() == Some(&code::UNION)
350 }
351
352 #[must_use]
359 pub fn as_union(&self) -> Option<UnionType> {
360 if self.is_union() {
361 let mut code = &self.0.as_slice()[1..];
362 let mut types = Vec::new();
363 let mut offset = 1;
364
365 loop {
366 assert!(!code.is_empty(), "union not terminated");
367 if code.first() == Some(&code::END) {
368 break;
369 }
370 match binary::parse_specific(code, offset) {
371 Ok((ty, rest)) => {
372 types.push(ty);
373 offset += code.len() - rest.len();
374 code = rest;
375 }
376 Err(err) => panic!("{err}"),
377 }
378 }
379 assert!(types.len() >= 2, "union with less than 2 members");
380 Some(UnionType { types })
381 } else {
382 None
383 }
384 }
385
386 #[must_use]
388 pub fn is_specific(&self) -> bool {
389 matches!(
390 self.0.as_slice(),
391 [code::TYPE
392 | code::BOOL
393 | code::CHAR
394 | code::INT
395 | code::FLOAT
396 | code::BINARY
397 | code::SYMBOL]
398 | [code::ARRAY | code::PAIR | code::LAMBDA, ..]
399 )
400 }
401
402 #[must_use]
404 #[inline]
405 pub fn is_filled(&self) -> bool {
406 self.is_specific() || self.is_any() || self.is_union()
407 }
408
409 #[inline]
411 pub fn iter(&self) -> Iter<'_, u8> {
412 self.0.iter()
413 }
414
415 #[must_use]
417 #[inline]
418 pub fn as_slice(&self) -> &[u8] {
419 self.0.as_slice()
420 }
421}
422
423impl<'a> IntoIterator for &'a Type {
424 type IntoIter = std::slice::Iter<'a, u8>;
425 type Item = &'a u8;
426
427 fn into_iter(self) -> Self::IntoIter {
428 self.iter()
429 }
430}
431
432impl Hash for Type {
433 fn hash<H: Hasher>(&self, state: &mut H) {
434 self.0.as_slice().hash(state);
435 }
436}
437
438impl PartialEq<Self> for Type {
439 fn eq(&self, other: &Self) -> bool {
440 if self.0.as_slice() == other.0.as_slice() {
441 return true;
442 }
443
444 if let Some(lhs) = self.as_option() {
445 return &lhs == other;
446 }
447 if let Some(lhs) = self.as_array() {
448 return &lhs == other;
449 }
450 if let Some(lhs) = self.as_pair() {
451 return &lhs == other;
452 }
453 if let Some(lhs) = self.as_lambda() {
454 return &lhs == other;
455 }
456 false
457 }
458}
459
460impl fmt::Display for Type {
461 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
462 match self.0.first().copied() {
463 Some(code::NIL) => write!(f, "nil"),
464 Some(code::VOID) => write!(f, "void"),
465 Some(code::ANY) => write!(f, "any"),
466 Some(code::TYPE) => write!(f, "type"),
467 Some(code::BOOL) => write!(f, "bool"),
468 Some(code::CHAR) => write!(f, "char"),
469 Some(code::INT) => write!(f, "int"),
470 Some(code::FLOAT) => write!(f, "float"),
471 Some(code::SYMBOL) => write!(f, "symbol"),
472 Some(code::BINARY) => write!(f, "binary"),
473 Some(code::ARRAY) => self.as_array().expect("array type").fmt(f),
474 Some(code::PAIR) => self.as_pair().expect("pair type").fmt(f),
475 Some(code::LAMBDA) => self.as_lambda().expect("lambda type").fmt(f),
476 Some(code::OPTION) => self.as_option().expect("option type").fmt(f),
477 Some(code::UNION) => self.as_union().expect("union type").fmt(f),
478 Some(_) | None => Ok(()),
479 }
480 }
481}
482
483impl<'a> Trace<'a> for Type {
484 fn trace(&self, _: &mut Vec<Root<'a>>) {
485 }
487}
488
489macro_rules! impl_simple {
490 ($($name:ident => $value:expr),+ $(),*) => {
491 impl Type {
492 $(#[must_use] #[inline] pub fn $name() -> Self { $value.clone() })+
493 paste::paste! {
494 $(#[must_use] #[inline] pub fn [<is_ $name>](&self) -> bool { *self == $value })+
495 }
496 }
497 };
498}
499
500impl_simple! {
501 nil => *code::T_NIL, void => *code::T_VOID,
502 any => *code::T_ANY, typedef => *code::T_TYPE,
503 boolean => *code::T_BOOL, character => *code::T_CHAR,
504 integer => *code::T_INT, float => *code::T_FLOAT,
505 string => *code::T_STRING, symbol => *code::T_SYMBOL,
506 binary => *code::T_BINARY, vector => *code::T_VECTOR,
507 list => *code::T_LIST,
508}
509
510impl AsRef<Self> for Type {
511 #[inline]
512 fn as_ref(&self) -> &Self {
513 self
514 }
515}
516
517impl FromStr for Type {
518 type Err = ParseError;
519
520 fn from_str(s: &str) -> Result<Self, Self::Err> {
523 let input = Input::new(s);
524 let (ty, _) = text::parse::<0>(None)(input)?;
525
526 Ok(ty)
527 }
528}
529
530impl<'a> From<(&Parameters<'a>, &Self)> for Type {
531 fn from((params, ret): (&Parameters<'a>, &Self)) -> Self {
532 let fixed = params
533 .fixed
534 .iter()
535 .map(|arg| arg.1.clone())
536 .collect::<Vec<_>>();
537 let variadic = params.variadic.as_ref().map(|arg| arg.1.clone());
538 Self::lambda(fixed, variadic, ret.to_owned()).expect("lambda type")
539 }
540}
541
542#[cfg(test)]
543mod tests {
544 use super::*;
545
546 #[test]
547 fn type_create_success() {
548 assert_eq!(Type::new([code::NIL]), Ok(Type::nil()));
549 assert_eq!(Type::new([code::VOID]), Ok(Type::void()));
550 assert_eq!(Type::new([code::ANY]), Ok(Type::any()));
551 assert_eq!(Type::new([code::BOOL]), Ok(Type::boolean()));
552 assert_eq!(Type::new([code::CHAR]), Ok(Type::character()));
553 assert_eq!(Type::new([code::INT]), Ok(Type::integer()));
554 assert_eq!(Type::new([code::FLOAT]), Ok(Type::float()));
555 assert_eq!(Type::new([code::SYMBOL]), Ok(Type::symbol()));
556 assert_eq!(Type::new([code::BINARY]), Ok(Type::binary()));
557 assert_eq!(Type::new([code::ARRAY, code::CHAR]), Ok(Type::string()));
558 assert_eq!(Type::new([code::ARRAY, code::ANY]), Ok(Type::vector()));
559 assert_eq!(
560 Type::new([code::ARRAY, code::INT]),
561 Ok(Type::array(Type::integer(), None).unwrap())
562 );
563 assert_eq!(
564 Type::new([code::PAIR, code::ANY, code::ANY]),
565 Ok(Type::pair(Type::any(), Type::any()).unwrap())
566 );
567 assert_eq!(
568 Type::new([code::LAMBDA, code::ANY, code::ANY, code::RETURN, code::ANY]),
569 Ok(Type::lambda(vec![Type::any(), Type::any()], None, Type::any()).unwrap())
570 );
571 assert_eq!(
572 Type::new([
573 code::OPTION,
574 code::LAMBDA,
575 code::ANY,
576 code::ANY,
577 code::RETURN,
578 code::ANY
579 ]),
580 Ok(Type::option(
581 Type::lambda(vec![Type::any(), Type::any()], None, Type::any()).unwrap()
582 )
583 .unwrap())
584 );
585 assert_eq!(
586 Type::new([
587 code::LAMBDA,
588 code::ANY,
589 code::ANY,
590 code::VARIADIC,
591 code::ANY,
592 code::RETURN,
593 code::ANY
594 ]),
595 Ok(Type::lambda(
596 vec![Type::any(), Type::any()],
597 Some(Type::any()),
598 Type::any()
599 )
600 .unwrap())
601 );
602 assert_eq!(
603 Type::new([code::UNION, code::INT, code::ARRAY, code::CHAR, code::END]),
604 Ok(Type::union(vec![
605 Type::integer(),
606 Type::array(Type::character(), None).unwrap()
607 ])
608 .unwrap())
609 );
610 assert_eq!(
611 Type::new([
612 code::OPTION,
613 code::UNION,
614 code::INT,
615 code::ARRAY,
616 code::CHAR,
617 code::END
618 ]),
619 Ok(Type::option(
620 Type::union(vec![
621 Type::integer(),
622 Type::array(Type::character(), None).unwrap()
623 ])
624 .unwrap()
625 )
626 .unwrap())
627 );
628 assert_eq!(
629 Type::new([
630 code::UNION,
631 code::BOOL,
632 code::INT,
633 code::ARRAY,
634 code::CHAR,
635 code::END
636 ]),
637 Ok(Type::union(vec![
638 Type::boolean(),
639 Type::integer(),
640 Type::array(Type::character(), None).unwrap()
641 ])
642 .unwrap())
643 );
644 }
645
646 #[test]
647 fn type_create_failure() {
648 assert_eq!(
649 Type::new([code::ARRAY]),
650 Err(TypeCodeError::ExpectedTypeOrOption(1))
651 );
652 assert_eq!(
653 Type::new([code::ARRAY, code::ARRAY]),
654 Err(TypeCodeError::ExpectedTypeOrOption(2))
655 );
656 assert_eq!(
657 Type::new([code::ARRAY, code::ARRAY, code::ARRAY]),
658 Err(TypeCodeError::ExpectedTypeOrOption(3))
659 );
660 assert_eq!(
661 Type::new([code::PAIR]),
662 Err(TypeCodeError::ExpectedTypeOrOption(1))
663 );
664 assert_eq!(
665 Type::new([code::PAIR, code::ANY]),
666 Err(TypeCodeError::ExpectedTypeOrOption(3))
667 );
668 assert_eq!(
669 Type::new([code::PAIR, code::PAIR, code::ANY]),
670 Err(TypeCodeError::ExpectedTypeOrOption(4))
671 );
672 assert_eq!(
673 Type::new([code::LAMBDA]),
674 Err(TypeCodeError::ExpectedReturn(1))
675 );
676 assert_eq!(
677 Type::new([code::LAMBDA, code::ANY]),
678 Err(TypeCodeError::ExpectedReturn(2))
679 );
680 assert_eq!(
681 Type::new([code::LAMBDA, code::VARIADIC]),
682 Err(TypeCodeError::ExpectedTypeOrOption(2))
683 );
684 assert_eq!(
685 Type::new([code::LAMBDA, code::ANY, code::VARIADIC]),
686 Err(TypeCodeError::ExpectedTypeOrOption(3))
687 );
688 assert_eq!(
689 Type::new([code::UNION]),
690 Err(TypeCodeError::ExpectedSpecificTypeEof(1))
691 );
692 assert_eq!(
693 Type::new([code::UNION, code::END]),
694 Err(TypeCodeError::ExpectedSpecificType(1))
695 );
696 assert_eq!(
697 Type::new([code::UNION, code::OPTION, code::BOOL, code::END]),
698 Err(TypeCodeError::ExpectedSpecificType(1))
699 );
700 assert_eq!(
701 Type::new([code::UNION, code::BOOL, code::END]),
702 Err(TypeCodeError::ExpectedSpecificType(2))
703 );
704 assert_eq!(
705 Type::new([code::UNION, code::BOOL, code::CHAR]),
706 Err(TypeCodeError::ExpectedMemberOrEnd(3))
707 );
708 }
709
710 #[test]
711 fn type_is() {
712 assert!(Type::nil().is_nil());
713 assert!(Type::void().is_void());
714 assert!(Type::any().is_any());
715 assert!(Type::boolean().is_boolean());
716 assert!(Type::character().is_character());
717 assert!(Type::integer().is_integer());
718 assert!(Type::float().is_float());
719 assert!(Type::string().is_string());
720 assert!(Type::symbol().is_symbol());
721 assert!(Type::binary().is_binary());
722 assert!(Type::vector().is_vector());
723 assert!(Type::pair(Type::any(), Type::any()).unwrap().is_pair());
724 assert!(Type::array(Type::any(), None).unwrap().is_array());
725 assert!(Type::lambda(vec![], None, Type::any()).unwrap().is_lambda());
726 }
727
728 #[test]
729 fn type_as_array() {
730 assert_eq!(Type::nil().as_array(), None);
731 assert_eq!(Type::void().as_array(), None);
732 assert_eq!(Type::any().as_array(), None);
733 assert_eq!(Type::boolean().as_array(), None);
734 assert_eq!(Type::character().as_array(), None);
735 assert_eq!(Type::integer().as_array(), None);
736 assert_eq!(Type::float().as_array(), None);
737 assert_eq!(
738 Type::string().as_array(),
739 Some(ArrayType {
740 elem: Type::character(),
741 len: None
742 })
743 );
744 assert_eq!(Type::symbol().as_array(), None);
745 assert_eq!(Type::binary().as_array(), None);
746 assert_eq!(
747 Type::vector().as_array(),
748 Some(ArrayType {
749 elem: Type::any(),
750 len: None
751 })
752 );
753 assert_eq!(
754 Type::pair(Type::any(), Type::any()).unwrap().as_array(),
755 None
756 );
757 assert_eq!(
758 Type::lambda(vec![], None, Type::any()).unwrap().as_array(),
759 None
760 );
761 }
762
763 #[test]
764 fn type_as_pair() {
765 assert_eq!(Type::nil().as_pair(), None);
766 assert_eq!(Type::void().as_pair(), None);
767 assert_eq!(Type::any().as_pair(), None);
768 assert_eq!(Type::boolean().as_pair(), None);
769 assert_eq!(Type::character().as_pair(), None);
770 assert_eq!(Type::integer().as_pair(), None);
771 assert_eq!(Type::float().as_pair(), None);
772 assert_eq!(Type::string().as_pair(), None);
773 assert_eq!(Type::symbol().as_pair(), None);
774 assert_eq!(Type::binary().as_pair(), None);
775 assert_eq!(Type::vector().as_pair(), None);
776 assert_eq!(
777 Type::pair(Type::any(), Type::any()).unwrap().as_pair(),
778 Some(PairType {
779 head: Type::any(),
780 tail: Type::any()
781 })
782 );
783 assert_eq!(
784 Type::lambda(vec![], None, Type::any()).unwrap().as_pair(),
785 None
786 );
787 }
788
789 #[test]
790 fn type_as_lambda() {
791 assert_eq!(Type::nil().as_lambda(), None);
792 assert_eq!(Type::void().as_lambda(), None);
793 assert_eq!(Type::any().as_lambda(), None);
794 assert_eq!(Type::boolean().as_lambda(), None);
795 assert_eq!(Type::character().as_lambda(), None);
796 assert_eq!(Type::integer().as_lambda(), None);
797 assert_eq!(Type::float().as_lambda(), None);
798 assert_eq!(Type::string().as_lambda(), None);
799 assert_eq!(Type::symbol().as_lambda(), None);
800 assert_eq!(Type::binary().as_lambda(), None);
801 assert_eq!(Type::vector().as_lambda(), None);
802 assert_eq!(
803 Type::pair(Type::any(), Type::any()).unwrap().as_lambda(),
804 None
805 );
806 assert_eq!(
807 Type::lambda(vec![], None, Type::any()).unwrap().as_lambda(),
808 Some(LambdaType {
809 params: vec![],
810 variadic: None,
811 result: Type::any()
812 })
813 );
814 assert_eq!(
815 Type::lambda(vec![Type::any()], None, Type::any())
816 .unwrap()
817 .as_lambda(),
818 Some(LambdaType {
819 params: vec![Type::any()],
820 variadic: None,
821 result: Type::any()
822 })
823 );
824 assert_eq!(
825 Type::lambda(vec![Type::any()], Some(Type::any()), Type::any())
826 .unwrap()
827 .as_lambda(),
828 Some(LambdaType {
829 params: vec![Type::any()],
830 variadic: Some(Type::any()),
831 result: Type::any()
832 })
833 );
834 assert_eq!(
835 Type::lambda(vec![Type::any(), Type::any()], None, Type::any())
836 .unwrap()
837 .as_lambda(),
838 Some(LambdaType {
839 params: vec![Type::any(), Type::any()],
840 variadic: None,
841 result: Type::any()
842 })
843 );
844 assert_eq!(
845 Type::lambda(
846 vec![Type::any(), Type::any()],
847 Some(Type::any()),
848 Type::any()
849 )
850 .unwrap()
851 .as_lambda(),
852 Some(LambdaType {
853 params: vec![Type::any(), Type::any()],
854 variadic: Some(Type::any()),
855 result: Type::any()
856 })
857 );
858 }
859
860 #[test]
861 fn type_display() {
862 assert_eq!(format!("{}", Type::nil()), "nil");
863 assert_eq!(format!("{}", Type::void()), "void");
864 assert_eq!(format!("{}", Type::any()), "any");
865 assert_eq!(format!("{}", Type::boolean()), "bool");
866 assert_eq!(format!("{}", Type::character()), "char");
867 assert_eq!(format!("{}", Type::integer()), "int");
868 assert_eq!(format!("{}", Type::float()), "float");
869 assert_eq!(format!("{}", Type::string()), "[char]");
870 assert_eq!(format!("{}", Type::symbol()), "symbol");
871 assert_eq!(format!("{}", Type::binary()), "binary");
872 assert_eq!(format!("{}", Type::vector()), "[any]");
873 assert_eq!(
874 format!("{}", Type::pair(Type::any(), Type::any()).unwrap()),
875 "(any * any)"
876 );
877 assert_eq!(
878 format!("{}", Type::array(Type::any(), None).unwrap()),
879 "[any]"
880 );
881 assert_eq!(
882 format!("{}", Type::lambda(vec![], None, Type::void()).unwrap()),
883 "fn(void -> void)"
884 );
885 assert_eq!(
886 format!("{}", Type::lambda(vec![], None, Type::any()).unwrap()),
887 "fn(void -> any)"
888 );
889 assert_eq!(
890 format!(
891 "{}",
892 Type::lambda(vec![Type::any()], None, Type::any()).unwrap()
893 ),
894 "fn(any -> any)"
895 );
896 assert_eq!(
897 format!(
898 "{}",
899 Type::lambda(vec![Type::any()], Some(Type::any()), Type::any()).unwrap()
900 ),
901 "fn(any, ...any -> any)"
902 );
903 assert_eq!(
904 format!(
905 "{}",
906 Type::lambda(vec![Type::any(), Type::any()], None, Type::any()).unwrap()
907 ),
908 "fn(any, any -> any)"
909 );
910 assert_eq!(
911 format!(
912 "{}",
913 Type::lambda(
914 vec![Type::any(), Type::any()],
915 Some(Type::any()),
916 Type::any()
917 )
918 .unwrap()
919 ),
920 "fn(any, any, ...any -> any)"
921 );
922 assert_eq!(
923 format!(
924 "{}",
925 Type::lambda(
926 vec![Type::any(), Type::any(), Type::any()],
927 None,
928 Type::any()
929 )
930 .unwrap()
931 ),
932 "fn(any, any, any -> any)"
933 );
934 assert_eq!(
935 format!(
936 "{}",
937 Type::lambda(
938 vec![Type::any(), Type::any(), Type::any()],
939 Some(Type::any()),
940 Type::any()
941 )
942 .unwrap()
943 ),
944 "fn(any, any, any, ...any -> any)"
945 );
946 assert_eq!(
947 format!(
948 "{}",
949 Type::lambda(
950 vec![Type::any(), Type::any()],
951 None,
952 Type::lambda(vec![Type::any()], None, Type::any()).unwrap()
953 )
954 .unwrap()
955 ),
956 "fn(any, any -> fn(any -> any))"
957 );
958 }
959
960 lazy_static! {
961 static ref TYPES: [(&'static str, Type); 19] = [
962 ("nil", Type::nil()),
963 ("void", Type::void()),
964 ("any", Type::any()),
965 ("bool", Type::boolean()),
966 ("char", Type::character()),
967 ("binary", Type::binary()),
968 ("int", Type::integer()),
969 ("float", Type::float()),
970 ("symbol", Type::symbol()),
971 ("type", Type::typedef()),
972 (
974 "fn()",
975 Type::lambda(
976 vec![],
977 None,
978 Type::void()
979 )
980 .unwrap()
981 ),
982 (
983 "fn(void -> any)",
984 Type::lambda(
985 vec![],
986 None,
987 Type::any()
988 )
989 .unwrap()
990 ),
991 (
992 "fn(void -> void)",
993 Type::lambda(
994 vec![],
995 None,
996 Type::void()
997 )
998 .unwrap()
999 ),
1000 (
1001 "fn(void -> any)",
1002 Type::lambda(
1003 vec![],
1004 None,
1005 Type::any()
1006 )
1007 .unwrap()
1008 ),
1009 (
1010 "fn(any -> void)",
1011 Type::lambda(
1012 vec![Type::any()],
1013 None,
1014 Type::void()
1015 )
1016 .unwrap()
1017 ),
1018 (
1019 "fn(any -> any)",
1020 Type::lambda(
1021 vec![Type::any()],
1022 None,
1023 Type::any()
1024 )
1025 .unwrap()
1026 ),
1027 (
1028 "fn(...any -> any)",
1029 Type::lambda(
1030 vec![],
1031 Some(Type::any()),
1032 Type::any()
1033 )
1034 .unwrap()
1035 ),
1036 (
1037 "fn(any, any, any, ...any -> any)",
1038 Type::lambda(
1039 vec![Type::any(), Type::any(), Type::any()],
1040 Some(Type::any()),
1041 Type::any()
1042 )
1043 .unwrap()
1044 ),
1045 (
1046 "fn(any, any -> fn(any -> any))",
1047 Type::lambda(
1048 vec![Type::any(), Type::any()],
1049 None,
1050 Type::lambda(vec![Type::any()], None, Type::any()).unwrap()
1051 )
1052 .unwrap()
1053 ),
1054 ];
1055 }
1056
1057 #[test]
1058 fn type_parse() {
1059 for (i, (s, ty)) in TYPES.iter().enumerate() {
1060 assert_eq!(Type::from_str(s), Ok(ty.clone()), "type {} failed", i + 1);
1061 }
1062 }
1063
1064 lazy_static! {
1065 static ref EQUALS: [(&'static str, &'static str); 0] = [];
1066 }
1067
1068 #[test]
1069 fn type_equals() {
1070 for (i, (t1, t2)) in EQUALS.iter().enumerate() {
1071 let t1 = Type::from_str(t1).unwrap_or_else(|_| panic!("{}: type 1", i + 1));
1072 let t2 = Type::from_str(t2).unwrap_or_else(|_| panic!("{}: type 2", i + 1));
1073 assert!(t1 == t2, "type {} failed", i + 1);
1074 }
1075 }
1076}