1pub mod fmt;
2pub mod map_notation;
3
4use crate::algebraic_value::de::{ValueDeserializeError, ValueDeserializer};
5use crate::algebraic_value::ser::value_serialize;
6use crate::de::Deserialize;
7use crate::meta_type::MetaType;
8use crate::product_type::{CONNECTION_ID_TAG, IDENTITY_TAG, TIMESTAMP_TAG, TIME_DURATION_TAG, UUID_TAG};
9use crate::sum_type::{OPTION_NONE_TAG, OPTION_SOME_TAG, RESULT_ERR_TAG, RESULT_OK_TAG};
10use crate::typespace::Typespace;
11use crate::{i256, u256};
12use crate::{AlgebraicTypeRef, AlgebraicValue, ArrayType, ProductType, SpacetimeType, SumType, SumTypeVariant};
13use derive_more::From;
14use enum_as_inner::EnumAsInner;
15
16#[derive(EnumAsInner, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, SpacetimeType, From)]
23#[sats(crate = crate)]
24pub enum AlgebraicType {
25 Ref(AlgebraicTypeRef),
31 Sum(SumType),
58 Product(ProductType),
84 Array(ArrayType),
87 String,
93 Bool,
95 I8,
97 U8,
99 I16,
101 U16,
103 I32,
105 U32,
107 I64,
109 U64,
111 I128,
113 U128,
115 I256,
117 U256,
119 F32,
121 F64,
123}
124
125impl MetaType for AlgebraicType {
126 fn meta_type() -> Self {
132 AlgebraicType::sum([
133 ("ref", AlgebraicTypeRef::meta_type()),
134 ("sum", SumType::meta_type()),
135 ("product", ProductType::meta_type()),
136 ("array", ArrayType::meta_type()),
137 ("string", AlgebraicType::unit()),
138 ("bool", AlgebraicType::unit()),
139 ("i8", AlgebraicType::unit()),
140 ("u8", AlgebraicType::unit()),
141 ("i16", AlgebraicType::unit()),
142 ("u16", AlgebraicType::unit()),
143 ("i32", AlgebraicType::unit()),
144 ("u32", AlgebraicType::unit()),
145 ("i64", AlgebraicType::unit()),
146 ("u64", AlgebraicType::unit()),
147 ("i128", AlgebraicType::unit()),
148 ("u128", AlgebraicType::unit()),
149 ("i256", AlgebraicType::unit()),
150 ("u256", AlgebraicType::unit()),
151 ("f32", AlgebraicType::unit()),
152 ("f64", AlgebraicType::unit()),
153 ])
154 }
155}
156
157impl Default for AlgebraicType {
159 fn default() -> Self {
160 Self::ZERO_REF
161 }
162}
163
164impl AlgebraicType {
165 pub const ZERO_REF: Self = Self::Ref(AlgebraicTypeRef(0));
167
168 pub fn is_connection_id(&self) -> bool {
172 matches!(self, Self::Product(p) if p.is_connection_id())
173 }
174
175 pub fn is_identity(&self) -> bool {
177 matches!(self, Self::Product(p) if p.is_identity())
178 }
179
180 pub fn is_timestamp(&self) -> bool {
182 matches!(self, Self::Product(p) if p.is_timestamp())
183 }
184
185 pub fn is_time_duration(&self) -> bool {
187 matches!(self, Self::Product(p) if p.is_time_duration())
188 }
189
190 pub fn is_uuid(&self) -> bool {
192 matches!(self, Self::Product(p) if p.is_uuid())
193 }
194
195 pub fn is_schedule_at(&self) -> bool {
197 matches!(self, Self::Sum(p) if p.is_schedule_at())
198 }
199
200 pub fn is_unit(&self) -> bool {
202 matches!(self, Self::Product(p) if p.is_unit())
203 }
204
205 pub fn is_never(&self) -> bool {
207 matches!(self, Self::Sum(p) if p.is_empty())
208 }
209
210 pub fn is_option(&self) -> bool {
212 matches!(self, Self::Sum(p) if p.is_option())
213 }
214
215 pub fn as_option(&self) -> Option<&AlgebraicType> {
218 self.as_sum()?.as_option()
219 }
220
221 pub fn is_result(&self) -> bool {
223 matches!(self, Self::Sum(p) if p.is_result())
224 }
225
226 pub fn as_result(&self) -> Option<(&AlgebraicType, &AlgebraicType)> {
229 self.as_sum()?.as_result()
230 }
231
232 pub fn is_scalar_or_string(&self) -> bool {
234 self.is_scalar() || self.is_string()
235 }
236
237 pub fn is_scalar(&self) -> bool {
244 self.is_bool() || self.is_integer() || self.is_float()
245 }
246
247 pub fn is_signed(&self) -> bool {
249 matches!(
250 self,
251 Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128 | Self::I256
252 )
253 }
254
255 pub fn is_unsigned(&self) -> bool {
257 matches!(
258 self,
259 Self::U8 | Self::U16 | Self::U32 | Self::U64 | Self::U128 | Self::U256
260 )
261 }
262
263 pub fn is_integer(&self) -> bool {
265 self.is_signed() || self.is_unsigned()
266 }
267
268 pub fn is_float(&self) -> bool {
270 matches!(self, Self::F32 | Self::F64)
271 }
272
273 pub fn unit() -> Self {
275 let fs: [AlgebraicType; 0] = [];
276 Self::product(fs)
277 }
278
279 pub fn never() -> Self {
281 let vs: [SumTypeVariant; 0] = [];
282 Self::sum(vs)
283 }
284
285 pub fn bytes() -> Self {
287 Self::array(Self::U8)
288 }
289
290 pub fn is_bytes(&self) -> bool {
292 self.as_array().is_some_and(|ty| ty.elem_ty.is_u8())
293 }
294
295 pub fn contains_refs(&self) -> bool {
297 match self {
298 AlgebraicType::Ref(_) => true,
299 AlgebraicType::Product(ProductType { elements }) => {
300 elements.iter().any(|elem| elem.algebraic_type.contains_refs())
301 }
302 AlgebraicType::Sum(SumType { variants }) => {
303 variants.iter().any(|variant| variant.algebraic_type.contains_refs())
304 }
305 AlgebraicType::Array(array) => array.elem_ty.contains_refs(),
306 _ => false,
307 }
308 }
309
310 pub fn sum<S: Into<SumType>>(sum: S) -> Self {
312 AlgebraicType::Sum(sum.into())
313 }
314
315 pub fn product<P: Into<ProductType>>(prod: P) -> Self {
317 AlgebraicType::Product(prod.into())
318 }
319
320 pub fn option(some_type: Self) -> Self {
322 Self::sum([(OPTION_SOME_TAG, some_type), (OPTION_NONE_TAG, AlgebraicType::unit())])
323 }
324
325 pub fn result(ok_type: Self, err_type: Self) -> Self {
328 Self::sum([(RESULT_OK_TAG, ok_type), (RESULT_ERR_TAG, err_type)])
329 }
330
331 pub fn array(ty: Self) -> Self {
333 ArrayType { elem_ty: Box::new(ty) }.into()
334 }
335
336 pub fn identity() -> Self {
338 AlgebraicType::product([(IDENTITY_TAG, AlgebraicType::U256)])
339 }
340
341 pub fn connection_id() -> Self {
343 AlgebraicType::product([(CONNECTION_ID_TAG, AlgebraicType::U128)])
344 }
345
346 pub fn timestamp() -> Self {
348 AlgebraicType::product([(TIMESTAMP_TAG, AlgebraicType::I64)])
349 }
350
351 pub fn time_duration() -> Self {
353 AlgebraicType::product([(TIME_DURATION_TAG, AlgebraicType::I64)])
354 }
355
356 pub fn uuid() -> Self {
358 AlgebraicType::product([(UUID_TAG, AlgebraicType::U128)])
359 }
360
361 pub fn simple_enum(var_names: impl Iterator<Item = &'static str>) -> Self {
363 Self::sum(var_names.into_iter().map(SumTypeVariant::unit).collect::<Box<[_]>>())
364 }
365
366 pub fn as_value(&self) -> AlgebraicValue {
367 value_serialize(self)
368 }
369
370 pub fn from_value(value: &AlgebraicValue) -> Result<Self, ValueDeserializeError> {
371 Self::deserialize(ValueDeserializer::from_ref(value))
372 }
373
374 pub fn saturating_value_from_i128(&self, value: i128) -> Option<AlgebraicValue> {
382 let signed = |min, max| value.clamp(min, max);
383 let unsigned = |max| value.clamp(0, max);
384
385 match self {
386 Self::I8 => Some((signed(i8::MIN as i128, i8::MAX as i128) as i8).into()),
387 Self::I16 => Some((signed(i16::MIN as i128, i16::MAX as i128) as i16).into()),
388 Self::I32 => Some((signed(i32::MIN as i128, i32::MAX as i128) as i32).into()),
389 Self::I64 => Some((signed(i64::MIN as i128, i64::MAX as i128) as i64).into()),
390 Self::I128 => Some(value.into()),
391 Self::I256 => Some(i256::from(value).into()),
392
393 Self::U8 => Some((unsigned(u8::MAX as i128) as u8).into()),
394 Self::U16 => Some((unsigned(u16::MAX as i128) as u16).into()),
395 Self::U32 => Some((unsigned(u32::MAX as i128) as u32).into()),
396 Self::U64 => Some((unsigned(u64::MAX as i128) as u64).into()),
397 Self::U128 => Some((value.max(0) as u128).into()),
398 Self::U256 => Some(u256::from(value.max(0) as u128).into()),
399 _ => None,
400 }
401 }
402
403 #[inline]
404 pub fn min_value(&self) -> Option<AlgebraicValue> {
406 match *self {
407 Self::I8 => Some(i8::MIN.into()),
408 Self::U8 => Some(u8::MIN.into()),
409 Self::I16 => Some(i16::MIN.into()),
410 Self::U16 => Some(u16::MIN.into()),
411 Self::I32 => Some(i32::MIN.into()),
412 Self::U32 => Some(u32::MIN.into()),
413 Self::I64 => Some(i64::MIN.into()),
414 Self::U64 => Some(u64::MIN.into()),
415 Self::I128 => Some(i128::MIN.into()),
416 Self::U128 => Some(u128::MIN.into()),
417 Self::I256 => Some(i256::MIN.into()),
418 Self::U256 => Some(u256::MIN.into()),
419 Self::F32 => Some(f32::MIN.into()),
420 Self::F64 => Some(f64::MIN.into()),
421 _ => None,
422 }
423 }
424
425 #[inline]
426 pub fn max_value(&self) -> Option<AlgebraicValue> {
428 match *self {
429 Self::I8 => Some(i8::MAX.into()),
430 Self::U8 => Some(u8::MAX.into()),
431 Self::I16 => Some(i16::MAX.into()),
432 Self::U16 => Some(u16::MAX.into()),
433 Self::I32 => Some(i32::MAX.into()),
434 Self::U32 => Some(u32::MAX.into()),
435 Self::I64 => Some(i64::MAX.into()),
436 Self::U64 => Some(u64::MAX.into()),
437 Self::I128 => Some(i128::MAX.into()),
438 Self::U128 => Some(u128::MAX.into()),
439 Self::I256 => Some(i256::MAX.into()),
440 Self::U256 => Some(u256::MAX.into()),
441 Self::F32 => Some(f32::MAX.into()),
442 Self::F64 => Some(f64::MAX.into()),
443 _ => None,
444 }
445 }
446
447 pub fn is_special(&self) -> bool {
451 match self {
452 AlgebraicType::Product(product) => product.is_special(),
453 AlgebraicType::Sum(sum) => sum.is_special(),
454 _ => false,
455 }
456 }
457
458 pub fn is_valid_for_client_type_definition(&self) -> bool {
467 if self.is_special() {
469 return false;
470 }
471 match self {
472 AlgebraicType::Sum(sum) => sum
473 .variants
474 .iter()
475 .all(|variant| variant.algebraic_type.is_valid_for_client_type_use()),
476 AlgebraicType::Product(product) => product
477 .elements
478 .iter()
479 .all(|elem| elem.algebraic_type.is_valid_for_client_type_use()),
480 _ => false,
481 }
482 }
483
484 pub fn is_valid_for_client_type_use(&self) -> bool {
496 match self {
497 AlgebraicType::Sum(sum) => {
498 if let Some(wrapped) = sum.as_option() {
499 wrapped.is_valid_for_client_type_use()
500 } else if let Some((ok_ty, err_ty)) = sum.as_result() {
501 ok_ty.is_valid_for_client_type_use() && err_ty.is_valid_for_client_type_use()
502 } else {
503 sum.is_special() || sum.is_empty()
504 }
505 }
506 AlgebraicType::Product(product) => product.is_special() || product.is_unit(),
507 AlgebraicType::Array(array) => array.elem_ty.is_valid_for_client_type_use(),
508 AlgebraicType::Ref(_) => true,
509 _ => true,
510 }
511 }
512
513 pub fn type_check(&self, value: &AlgebraicValue, typespace: &Typespace) -> bool {
514 match (self, value) {
515 (_, AlgebraicValue::Min | AlgebraicValue::Max) => true,
516 (AlgebraicType::Ref(r), _) => {
517 if let Some(resolved_ty) = typespace.get(*r) {
518 resolved_ty.type_check(value, typespace)
519 } else {
520 false
521 }
522 }
523 (AlgebraicType::Sum(sum_ty), AlgebraicValue::Sum(sv)) => sum_ty.type_check(sv, typespace),
524 (AlgebraicType::Product(product_ty), AlgebraicValue::Product(pv)) => product_ty.type_check(pv, typespace),
525 (AlgebraicType::Array(array_ty), AlgebraicValue::Array(arr)) => array_ty.type_check(arr, typespace),
526
527 (AlgebraicType::String, AlgebraicValue::String(_))
528 | (AlgebraicType::Bool, AlgebraicValue::Bool(_))
529 | (AlgebraicType::I8, AlgebraicValue::I8(_))
530 | (AlgebraicType::U8, AlgebraicValue::U8(_))
531 | (AlgebraicType::I16, AlgebraicValue::I16(_))
532 | (AlgebraicType::U16, AlgebraicValue::U16(_))
533 | (AlgebraicType::I32, AlgebraicValue::I32(_))
534 | (AlgebraicType::U32, AlgebraicValue::U32(_))
535 | (AlgebraicType::I64, AlgebraicValue::I64(_))
536 | (AlgebraicType::U64, AlgebraicValue::U64(_))
537 | (AlgebraicType::I128, AlgebraicValue::I128(_))
538 | (AlgebraicType::U128, AlgebraicValue::U128(_))
539 | (AlgebraicType::I256, AlgebraicValue::I256(_))
540 | (AlgebraicType::U256, AlgebraicValue::U256(_))
541 | (AlgebraicType::F32, AlgebraicValue::F32(_))
542 | (AlgebraicType::F64, AlgebraicValue::F64(_)) => true,
543 _ => false,
544 }
545 }
546}
547#[cfg(test)]
548mod tests {
549 use super::AlgebraicType;
550 use crate::meta_type::MetaType;
551 use crate::satn::Satn;
552 use crate::{
553 algebraic_type::fmt::fmt_algebraic_type, algebraic_type::map_notation::fmt_algebraic_type as fmt_map,
554 algebraic_type_ref::AlgebraicTypeRef, typespace::Typespace,
555 };
556 use crate::{product, AlgebraicValue, ValueWithType, WithTypespace};
557
558 #[test]
559 fn never() {
560 assert_eq!("(|)", fmt_algebraic_type(&AlgebraicType::never()).to_string());
561 }
562
563 #[test]
564 fn never_map() {
565 assert_eq!("{ ty_: Sum }", fmt_map(&AlgebraicType::never()).to_string());
566 }
567
568 #[test]
569 fn unit() {
570 assert_eq!("()", fmt_algebraic_type(&AlgebraicType::unit()).to_string());
571 }
572
573 #[test]
574 fn unit_map() {
575 assert_eq!("{ ty_: Product }", fmt_map(&AlgebraicType::unit()).to_string());
576 }
577
578 #[test]
579 fn primitive() {
580 assert_eq!("U8", fmt_algebraic_type(&AlgebraicType::U8).to_string());
581 }
582
583 #[test]
584 fn primitive_map() {
585 assert_eq!("{ ty_: U8 }", fmt_map(&AlgebraicType::U8).to_string());
586 }
587
588 #[test]
589 fn option() {
590 let option = AlgebraicType::option(AlgebraicType::never());
591 assert_eq!("(some: (|) | none: ())", fmt_algebraic_type(&option).to_string());
592 }
593
594 #[test]
595 fn option_map() {
596 let option = AlgebraicType::option(AlgebraicType::never());
597 assert_eq!(
598 "{ ty_: Sum, some: { ty_: Sum }, none: { ty_: Product } }",
599 fmt_map(&option).to_string()
600 );
601 }
602
603 #[test]
604 fn result() {
605 let result = AlgebraicType::result(AlgebraicType::U8, AlgebraicType::String);
606 assert_eq!("(ok: U8 | err: String)", fmt_algebraic_type(&result).to_string());
607 }
608
609 #[test]
610 fn result_map() {
611 let result = AlgebraicType::result(AlgebraicType::U8, AlgebraicType::String);
612 assert_eq!(
613 "{ ty_: Sum, ok: { ty_: U8 }, err: { ty_: String } }",
614 fmt_map(&result).to_string()
615 );
616 }
617
618 #[test]
619 fn algebraic_type() {
620 let algebraic_type = AlgebraicType::meta_type();
621 assert_eq!(
622 "(\
623 ref: U32 \
624 | sum: (variants: Array<(\
625 name: (some: String | none: ()), \
626 algebraic_type: &0\
627 )>) \
628 | product: (elements: Array<(\
629 name: (some: String | none: ()), \
630 algebraic_type: &0\
631 )>) \
632 | array: &0 \
633 | string: () \
634 | bool: () \
635 | i8: () | u8: () \
636 | i16: () | u16: () \
637 | i32: () | u32: () \
638 | i64: () | u64: () \
639 | i128: () | u128: () \
640 | i256: () | u256: () \
641 | f32: () | f64: ()\
642 )",
643 fmt_algebraic_type(&algebraic_type).to_string()
644 );
645 }
646
647 #[test]
648 fn algebraic_type_map() {
649 let algebraic_type = AlgebraicType::meta_type();
650 assert_eq!(
651 "{ \
652 ty_: Sum, \
653 ref: { ty_: U32 }, \
654 sum: { \
655 ty_: Product, \
656 variants: { \
657 ty_: Array, \
658 0: { \
659 ty_: Product, \
660 name: { ty_: Sum, some: { ty_: String }, none: { ty_: Product } }, \
661 algebraic_type: { ty_: Ref, 0: 0 } \
662 } \
663 } \
664 }, \
665 product: { \
666 ty_: Product, \
667 elements: { \
668 ty_: Array, \
669 0: { \
670 ty_: Product, \
671 name: { ty_: Sum, some: { ty_: String }, none: { ty_: Product } }, \
672 algebraic_type: { ty_: Ref, 0: 0 } \
673 } \
674 } \
675 }, \
676 array: { ty_: Ref, 0: 0 }, \
677 string: { ty_: Product }, \
678 bool: { ty_: Product }, \
679 i8: { ty_: Product }, u8: { ty_: Product }, \
680 i16: { ty_: Product }, u16: { ty_: Product }, \
681 i32: { ty_: Product }, u32: { ty_: Product }, \
682 i64: { ty_: Product }, u64: { ty_: Product }, \
683 i128: { ty_: Product }, u128: { ty_: Product }, \
684 i256: { ty_: Product }, u256: { ty_: Product }, \
685 f32: { ty_: Product }, f64: { ty_: Product } \
686 }",
687 fmt_map(&algebraic_type).to_string()
688 );
689 }
690
691 #[test]
692 fn nested_products_and_sums() {
693 let builtin = AlgebraicType::U8;
694 let product = AlgebraicType::product([("thing", AlgebraicType::U8)]);
695 let sum = AlgebraicType::sum([builtin.clone(), builtin.clone(), product]);
696 let next = AlgebraicType::product([
697 (Some("test"), builtin.clone()),
698 (None, sum),
699 (None, builtin),
700 (Some("never"), AlgebraicType::never()),
701 ]);
702 assert_eq!(
703 "(test: U8, 1: (U8 | U8 | (thing: U8)), 2: U8, never: (|))",
704 fmt_algebraic_type(&next).to_string()
705 );
706 }
707
708 fn in_space<'a, T: crate::Value>(ts: &'a Typespace, ty: &'a T::Type, val: &'a T) -> ValueWithType<'a, T> {
709 WithTypespace::new(ts, ty).with_value(val)
710 }
711
712 #[test]
713 fn option_as_value() {
714 let option = AlgebraicType::option(AlgebraicType::never());
715 let algebraic_type = AlgebraicType::meta_type();
716 let typespace = Typespace::new(vec![algebraic_type]);
717 let at_ref = AlgebraicType::Ref(AlgebraicTypeRef(0));
718 assert_eq!(
719 r#"(sum = (variants = [(name = (some = "some"), algebraic_type = (sum = (variants = []))), (name = (some = "none"), algebraic_type = (product = (elements = [])))]))"#,
720 in_space(&typespace, &at_ref, &option.as_value()).to_satn()
721 );
722 }
723
724 #[test]
725 fn result_as_value() {
726 let result = AlgebraicType::result(AlgebraicType::U8, AlgebraicType::String);
727 let algebraic_type = AlgebraicType::meta_type();
728 let typespace = Typespace::new(vec![algebraic_type]);
729 let at_ref = AlgebraicType::Ref(AlgebraicTypeRef(0));
730 assert_eq!(
731 r#"(sum = (variants = [(name = (some = "ok"), algebraic_type = (u8 = ())), (name = (some = "err"), algebraic_type = (string = ()))]))"#,
732 in_space(&typespace, &at_ref, &result.as_value()).to_satn()
733 );
734 }
735
736 #[test]
737 fn algebraic_type_as_value() {
738 let algebraic_type = AlgebraicType::meta_type();
739 let typespace = Typespace::new(vec![algebraic_type.clone()]);
740 let at_ref = AlgebraicType::Ref(AlgebraicTypeRef(0));
741
742 let ref0 = "algebraic_type = (ref = 0)";
743 let unit = "algebraic_type = (product = (elements = []))";
744 let aggr_elems_ty = format!(
745 "algebraic_type = (array = (product = (elements = [\
746 (\
747 name = (some = \"name\"), \
748 algebraic_type = (sum = (variants = [\
749 (name = (some = \"some\"), algebraic_type = (string = ())), \
750 (name = (some = \"none\"), {unit})\
751 ]))\
752 ), \
753 (name = (some = \"algebraic_type\"), {ref0})\
754 ])))"
755 );
756
757 assert_eq!(
758 format!(
759 "(\
760 sum = (\
761 variants = [\
762 (name = (some = \"ref\"), algebraic_type = (u32 = ())), \
763 (\
764 name = (some = \"sum\"), \
765 algebraic_type = (product = (elements = [\
766 (name = (some = \"variants\"), {aggr_elems_ty})\
767 ]))\
768 ), \
769 (\
770 name = (some = \"product\"), \
771 algebraic_type = (product = (elements = [\
772 (name = (some = \"elements\"), {aggr_elems_ty})\
773 ]))\
774 ), \
775 (name = (some = \"array\"), {ref0}), \
776 (name = (some = \"string\"), {unit}), \
777 (name = (some = \"bool\"), {unit}), \
778 (name = (some = \"i8\"), {unit}), \
779 (name = (some = \"u8\"), {unit}), \
780 (name = (some = \"i16\"), {unit}), \
781 (name = (some = \"u16\"), {unit}), \
782 (name = (some = \"i32\"), {unit}), \
783 (name = (some = \"u32\"), {unit}), \
784 (name = (some = \"i64\"), {unit}), \
785 (name = (some = \"u64\"), {unit}), \
786 (name = (some = \"i128\"), {unit}), \
787 (name = (some = \"u128\"), {unit}), \
788 (name = (some = \"i256\"), {unit}), \
789 (name = (some = \"u256\"), {unit}), \
790 (name = (some = \"f32\"), {unit}), \
791 (name = (some = \"f64\"), {unit})\
792 ]\
793 )\
794 )"
795 ),
796 in_space(&typespace, &at_ref, &algebraic_type.as_value()).to_satn()
797 );
798 }
799
800 #[test]
801 fn option_from_value() {
802 let option = AlgebraicType::option(AlgebraicType::never());
803 AlgebraicType::from_value(&option.as_value()).expect("No errors.");
804 }
805
806 #[test]
807 fn result_from_value() {
808 let result = AlgebraicType::result(AlgebraicType::U8, AlgebraicType::String);
809 AlgebraicType::from_value(&result.as_value()).expect("No errors.");
810 }
811
812 #[test]
813 fn builtin_from_value() {
814 let u8 = AlgebraicType::U8;
815 AlgebraicType::from_value(&u8.as_value()).expect("No errors.");
816 }
817
818 #[test]
819 fn algebraic_type_from_value() {
820 let algebraic_type = AlgebraicType::meta_type();
821 AlgebraicType::from_value(&algebraic_type.as_value()).expect("No errors.");
822 }
823
824 #[test]
825 fn special_types_are_special() {
826 assert!(AlgebraicType::identity().is_identity());
827 assert!(AlgebraicType::identity().is_special());
828 assert!(AlgebraicType::connection_id().is_connection_id());
829 assert!(AlgebraicType::connection_id().is_special());
830 assert!(AlgebraicType::timestamp().is_timestamp());
831 assert!(AlgebraicType::timestamp().is_special());
832 assert!(AlgebraicType::time_duration().is_special());
833 assert!(AlgebraicType::time_duration().is_time_duration());
834 assert!(AlgebraicType::uuid().is_uuid());
835 assert!(AlgebraicType::uuid().is_special());
836 }
837
838 #[test]
839 fn type_check() {
840 let av = AlgebraicValue::sum(1, AlgebraicValue::from(product![0u16, 1u32]));
841 let at = AlgebraicType::sum([
842 ("a", AlgebraicType::U8),
843 ("b", AlgebraicType::product([AlgebraicType::U16, AlgebraicType::U32])),
844 ]);
845
846 at.type_check(&av, Typespace::EMPTY);
847 }
848}