galvan_ast/item/
type_item.rs

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// TODO: Add a marker trait to constrain this to only type decls
61#[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}