finitio/schema/
type.rs

1use std::rc::Rc;
2use std::{cell::RefCell, rc::Weak};
3
4use snafu::Whatever;
5
6use crate::common::FilePosition;
7use crate::fio;
8
9use super::any::Any;
10use super::builtin::Builtin;
11use super::nil::Nil;
12use super::r#ref::Ref;
13use super::r#struct::Struct;
14use super::relation::Relation;
15use super::seq::Seq;
16use super::set::Set;
17use super::sub::Sub;
18use super::tuple::Tuple;
19use super::typedef::TypeDef;
20use super::union::Union;
21use super::{errors::ValidationError, typemap::TypeMap};
22
23pub trait TypeInclude<T> {
24    fn include(&self, _: &T) -> Result<(), Whatever>;
25}
26
27#[derive(Clone, Debug)]
28pub enum Type {
29    Nil(Nil),
30    Any(Any),
31    Builtin(Builtin),
32    Ref(TypeRef),
33    Seq(Seq),
34    Set(Set),
35    Union(Union),
36    Struct(Struct),
37    Sub(Sub),
38    Tuple(Tuple),
39    Relation(Relation),
40}
41
42#[derive(Clone, Debug)]
43pub enum TypeRef {
44    Any(AnyRef),
45    Nil(NilRef),
46    Builtin(BuiltinRef),
47    Ref(RefRef),
48    Seq(SeqRef),
49    Set(SetRef),
50    Union(UnionRef),
51    Struct(StructRef),
52    Sub(SubRef),
53    Tuple(TupleRef),
54    Relation(RelationRef),
55    Unresolved {
56        name: String,
57        position: FilePosition,
58    },
59}
60
61#[derive(Clone, Debug)]
62pub struct AnyRef {
63    pub any_: Weak<RefCell<Any>>,
64}
65
66#[derive(Clone, Debug)]
67pub struct NilRef {
68    pub nil_: Weak<RefCell<Nil>>,
69}
70
71#[derive(Clone, Debug)]
72pub struct BuiltinRef {
73    pub builtin_: Weak<RefCell<Builtin>>,
74}
75
76#[derive(Clone, Debug)]
77pub struct RefRef {
78    pub ref_: Weak<RefCell<Ref>>,
79}
80
81#[derive(Clone, Debug)]
82pub struct SeqRef {
83    pub seq_: Weak<RefCell<Seq>>,
84}
85
86#[derive(Clone, Debug)]
87pub struct SetRef {
88    pub set_: Weak<RefCell<Set>>,
89}
90#[derive(Clone, Debug)]
91pub struct UnionRef {
92    pub union_: Weak<RefCell<Union>>,
93}
94
95#[derive(Clone, Debug)]
96pub struct StructRef {
97    pub struct_: Weak<RefCell<Struct>>,
98}
99
100#[derive(Clone, Debug)]
101pub struct SubRef {
102    pub sub_: Weak<RefCell<Sub>>,
103}
104
105#[derive(Clone, Debug)]
106pub struct TupleRef {
107    pub tuple_: Weak<RefCell<Tuple>>,
108}
109
110#[derive(Clone, Debug)]
111pub struct RelationRef {
112    pub relation_: Weak<RefCell<Relation>>,
113}
114
115impl TypeRef {
116    pub fn position(&self) -> FilePosition {
117        match self {
118            Self::Any(r) => r.any_.upgrade().unwrap().borrow().position.clone(),
119            Self::Nil(r) => r.nil_.upgrade().unwrap().borrow().position.clone(),
120            Self::Builtin(r) => r.builtin_.upgrade().unwrap().borrow().position.clone(),
121            Self::Ref(r) => r.ref_.upgrade().unwrap().borrow().position.clone(),
122            Self::Seq(r) => r.seq_.upgrade().unwrap().borrow().position.clone(),
123            Self::Set(r) => r.set_.upgrade().unwrap().borrow().position.clone(),
124            Self::Union(r) => r.union_.upgrade().unwrap().borrow().position.clone(),
125            Self::Struct(r) => r.struct_.upgrade().unwrap().borrow().position.clone(),
126            Self::Sub(r) => r.sub_.upgrade().unwrap().borrow().position.clone(),
127            Self::Tuple(r) => r.tuple_.upgrade().unwrap().borrow().position.clone(),
128            Self::Relation(r) => r.relation_.upgrade().unwrap().borrow().position.clone(),
129            Self::Unresolved {
130                name: _name,
131                position,
132            } => position.clone(),
133        }
134    }
135    pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
136        if let Self::Unresolved {
137            name,
138            position: _position,
139        } = self
140        {
141            let ftype = type_map.get(name);
142            *self = match ftype {
143                Some(udtype) => match udtype {
144                    TypeDef::AnyType(any_) => TypeRef::Any(AnyRef {
145                        any_: Rc::downgrade(&any_.target),
146                    }),
147                    TypeDef::NilType(nil_) => TypeRef::Nil(NilRef {
148                        nil_: Rc::downgrade(&nil_.target),
149                    }),
150                    TypeDef::BuiltinType(builtin_) => TypeRef::Builtin(BuiltinRef {
151                        builtin_: Rc::downgrade(&builtin_.target),
152                    }),
153                    TypeDef::RefType(ref_) => TypeRef::Ref(RefRef {
154                        ref_: Rc::downgrade(&ref_.target),
155                    }),
156                    TypeDef::SeqType(seq_) => TypeRef::Seq(SeqRef {
157                        seq_: Rc::downgrade(&seq_.target),
158                    }),
159                    TypeDef::SetType(set_) => TypeRef::Set(SetRef {
160                        set_: Rc::downgrade(&set_.target),
161                    }),
162                    TypeDef::UnionType(union_) => TypeRef::Union(UnionRef {
163                        union_: Rc::downgrade(&union_.target),
164                    }),
165                    TypeDef::StructType(struct_) => TypeRef::Struct(StructRef {
166                        struct_: Rc::downgrade(&struct_.target),
167                    }),
168                    TypeDef::SubType(sub_) => TypeRef::Sub(SubRef {
169                        sub_: Rc::downgrade(&sub_.target),
170                    }),
171                    TypeDef::TupleType(tuple_) => TypeRef::Tuple(TupleRef {
172                        tuple_: Rc::downgrade(&tuple_.target),
173                    }),
174                    TypeDef::RelationType(relation_) => TypeRef::Relation(RelationRef {
175                        relation_: Rc::downgrade(&relation_.target),
176                    }),
177                },
178                None => {
179                    return Err(ValidationError::NoSuchType {
180                        name: name.clone(),
181                        position: self.position(),
182                    })
183                }
184            }
185        }
186        Ok(())
187    }
188}
189
190impl Type {
191    pub fn from_fio(ftype: &fio::Type) -> Self {
192        match ftype {
193            fio::Type::NilType(t) => Self::Nil(Nil::from_fio(t)),
194            fio::Type::AnyType(t) => Self::Any(Any::from_fio(t)),
195            fio::Type::BuiltinType(t) => Self::Builtin(Builtin::from_fio(t)),
196            fio::Type::RefType(t) => Self::Ref(TypeRef::Unresolved {
197                name: t.name.clone(),
198                position: t.position.clone(),
199            }),
200            fio::Type::SeqType(t) => Self::Seq(Seq::from_fio(t)),
201            fio::Type::SetType(t) => Self::Set(Set::from_fio(t)),
202            fio::Type::UnionType(t) => Self::Union(Union::from_fio(t)),
203            fio::Type::StructType(t) => Self::Struct(Struct::from_fio(t)),
204            fio::Type::SubType(t) => Self::Sub(Sub::from_fio(t)),
205            fio::Type::TupleType(t) => Self::Tuple(Tuple::from_fio(t)),
206            fio::Type::RelationType(t) => Self::Relation(Relation::from_fio(t)),
207        }
208    }
209
210    pub fn from_fio_ref(fref: &fio::RefType) -> Self {
211        Self::Ref(TypeRef::Unresolved {
212            name: fref.name.clone(),
213            position: fref.position.clone(),
214        })
215    }
216
217    pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
218        match self {
219            Self::Nil(_) | Self::Any(_) | Self::Builtin(_) => Ok(()), // Should probably not consider all Builtin ok here?
220
221            Self::Ref(tref) => tref.resolve(type_map),
222            Self::Seq(sref) => sref.resolve(type_map),
223            Self::Set(sref) => sref.resolve(type_map),
224            Self::Union(uref) => uref.resolve(type_map),
225            Self::Struct(sref) => sref.resolve(type_map),
226            Self::Sub(sref) => sref.resolve(type_map),
227            Self::Tuple(tref) => tref.resolve(type_map),
228            Self::Relation(rref) => rref.resolve(type_map),
229        }
230    }
231}