roussillon_type_system/types/
typedef.rs

1//! This module provides common constructions to create custom types.
2//!
3//! It lets the user identify algebraic types :
4//! - [Structure] is an [Identified] : [ProductType],
5//! - [Enumeration] is an [Identified] : [SumType],
6
7use std::rc::Rc;
8use crate::identity::{Identified, Identifier, Label, LabelBank, Labelled};
9use crate::types::algebraic::{ProductType, SumType};
10use crate::types::concept::{DataType, Type};
11use crate::value::concept::ValueCell;
12use crate::value::error::TypeResult;
13use crate::value::record::Record;
14
15/// A [Structure] is an identified [ProductType].
16#[derive(Clone, Debug)]
17pub struct Structure {
18    identifier: Identifier,
19    pub labels: LabelBank,
20    pub product_type: ProductType,
21}
22
23impl Structure {
24    pub fn new(identifier: &str, labels: LabelBank, fields: ProductType) -> Self {
25        Structure {
26            identifier: Identifier::new(identifier),
27            labels,
28            product_type: fields,
29        }
30    }
31
32    pub fn to_rc(self) -> Rc<Self> { Rc::new(self) }
33}
34
35impl DataType for Structure {
36    fn size(&self) -> usize { self.product_type.size() }
37
38    fn typename(&self) -> String { self.identifier.to_string() }
39
40    fn construct_from_raw(&self, raw: &[u8]) -> TypeResult<ValueCell> {
41        Ok(Record::from(self.clone().to_rc(), raw)?.to_cell())
42    }
43}
44
45impl Identified for Structure {
46    fn identifier(&self) -> Identifier {
47        self.identifier.clone()
48    }
49}
50
51impl Labelled<Type> for Structure {
52    fn labelled(&self, label: &Label) -> Option<Type> { self.product_type.field(self.labels.labelled(label)?) }
53}
54
55/// A [Enumeration] is an identified [SumType].
56#[derive(Clone, Debug)]
57pub struct Enumeration {
58    identifier: Identifier,
59    labels: LabelBank,
60    pub sum_type: SumType,
61}
62
63impl Enumeration {
64    pub fn new(identifier: &str, labels: LabelBank, sum_type: SumType) -> Self {
65        Enumeration {
66            identifier: Identifier::new(identifier),
67            labels,
68            sum_type,
69        }
70    }
71    pub fn variant(&self, tag: usize) -> Option<Type> { self.sum_type.variant(tag) }
72
73    pub fn to_rc(self) -> Rc<Self> { Rc::new(self) }
74}
75
76impl DataType for Enumeration {
77    fn size(&self) -> usize { self.sum_type.size() }
78
79    fn typename(&self) -> String { self.identifier.to_string() }
80
81    fn construct_from_raw(&self, raw: &[u8]) -> TypeResult<ValueCell> {
82        self.sum_type.construct_from_raw(raw)
83    }
84}
85
86impl Identified for Enumeration {
87    fn identifier(&self) -> Identifier {
88        self.identifier.clone()
89    }
90}
91
92impl Labelled<Type> for Enumeration {
93    fn labelled(&self, label: &Label) -> Option<Type> { self.variant(self.labels.labelled(label)?) }
94}