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(()), 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}