1use std::fmt;
2
3use galvan_ast_macro::AstNode;
4use typeunion::type_union;
5
6use crate::{AstNode, Ident, PrintAst, Span, TypeIdent};
7
8type Array = Box<ArrayTypeItem>;
9type Dictionary = Box<DictionaryTypeItem>;
10type OrderedDictionary = Box<OrderedDictionaryTypeItem>;
11type Set = Box<SetTypeItem>;
12type Tuple = Box<TupleTypeItem>;
13type Optional = Box<OptionalTypeItem>;
14type Result = Box<ResultTypeItem>;
15type Plain = BasicTypeItem;
16type Generic = GenericTypeItem;
17type Void = VoidTypeItem;
18type Infer = InferTypeItem;
19type Never = NeverTypeItem;
20
21#[type_union]
22#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
23pub type TypeElement = Array
24 + Dictionary
25 + OrderedDictionary
26 + Set
27 + Tuple
28 + Optional
29 + Result
30 + Plain
31 + Generic
32 + Infer
33 + Void
34 + Never;
35
36impl TypeElement {
37 pub fn bool() -> Self {
38 BasicTypeItem {
39 ident: TypeIdent::new("Bool"),
40 span: Span::default(),
41 }
42 .into()
43 }
44
45 pub fn infer() -> Self {
46 InferTypeItem::default().into()
47 }
48
49 pub fn void() -> Self {
50 VoidTypeItem::default().into()
51 }
52}
53
54impl Default for TypeElement {
55 fn default() -> Self {
56 Self::infer()
57 }
58}
59
60#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
62pub struct ArrayTypeItem {
63 pub elements: TypeElement,
64 pub span: Span,
65}
66
67#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
68pub struct DictionaryTypeItem {
69 pub key: TypeElement,
70 pub value: TypeElement,
71 pub span: Span,
72}
73
74#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
75pub struct OrderedDictionaryTypeItem {
76 pub key: TypeElement,
77 pub value: TypeElement,
78 pub span: Span,
79}
80
81#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
82pub struct SetTypeItem {
83 pub elements: TypeElement,
84 pub span: Span,
85}
86
87#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
88pub struct TupleTypeItem {
89 pub elements: Vec<TypeElement>,
90 pub span: Span,
91}
92
93#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
94pub struct OptionalTypeItem {
95 pub inner: TypeElement,
96 pub span: Span,
97}
98
99#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
100pub struct ResultTypeItem {
101 pub success: TypeElement,
102 pub error: Option<TypeElement>,
103 pub span: Span,
104}
105
106#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
107pub struct BasicTypeItem {
108 pub ident: TypeIdent,
109 pub span: Span,
110}
111
112#[derive(Clone, Debug, PartialEq, Eq, Hash, AstNode)]
113pub struct GenericTypeItem {
114 pub ident: Ident,
115 pub span: Span,
116}
117
118#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, AstNode)]
119pub struct NeverTypeItem {
120 pub span: Span,
121}
122
123#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, AstNode)]
124pub struct VoidTypeItem {
125 pub span: Span,
126}
127
128#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, AstNode)]
129pub struct InferTypeItem {
130 pub span: Span,
131}
132
133impl fmt::Display for TypeElement {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 match self {
136 TypeElement::Array(arr) => write!(f, "[{}]", arr.elements),
137 TypeElement::Dictionary(dict) => write!(f, "[{}: {}]", dict.key, dict.value),
138 TypeElement::OrderedDictionary(dict) => write!(f, "[{}: {}]", dict.key, dict.value),
139 TypeElement::Set(set) => write!(f, "{{{}}}", set.elements),
140 TypeElement::Tuple(tuple) => {
141 write!(f, "(")?;
142 for (i, elem) in tuple.elements.iter().enumerate() {
143 if i > 0 { write!(f, ", ")?; }
144 write!(f, "{}", elem)?;
145 }
146 write!(f, ")")
147 },
148 TypeElement::Optional(opt) => write!(f, "{}?", opt.inner),
149 TypeElement::Result(res) => match &res.error {
150 Some(err) => write!(f, "Result<{}, {}>", res.success, err),
151 None => write!(f, "Result<{}>", res.success),
152 },
153 TypeElement::Plain(basic) => write!(f, "{}", basic.ident),
154 TypeElement::Generic(gen) => write!(f, "{}", gen.ident),
155 TypeElement::Void(_) => write!(f, "Void"),
156 TypeElement::Infer(_) => write!(f, "_"),
157 TypeElement::Never(_) => write!(f, "!"),
158 }
159 }
160}