1use enum_as_inner::EnumAsInner;
2use serde::{Deserialize, Serialize};
3use strum::AsRefStr;
4
5use super::{Ident, Literal};
6use crate::Span;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct Ty {
10 pub kind: TyKind,
11
12 pub span: Option<Span>,
13
14 pub name: Option<String>,
16}
17
18#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, EnumAsInner, AsRefStr)]
19pub enum TyKind {
20 Ident(Ident),
22
23 Primitive(PrimitiveSet),
25
26 Singleton(Literal),
28
29 Union(Vec<(Option<String>, Ty)>),
31
32 Tuple(Vec<TyTupleField>),
34
35 Array(Box<Ty>),
37
38 Function(Option<TyFunc>),
40
41 Any,
44
45 Difference { base: Box<Ty>, exclude: Box<Ty> },
47
48 GenericArg((usize, String)),
50}
51
52#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, EnumAsInner)]
53pub enum TyTupleField {
54 Single(Option<String>, Option<Ty>),
56
57 Wildcard(Option<Ty>),
60}
61
62#[derive(
64 Debug, Clone, Serialize, Deserialize, PartialEq, Eq, strum::EnumString, strum::Display,
65)]
66pub enum PrimitiveSet {
67 #[strum(to_string = "int")]
68 Int,
69 #[strum(to_string = "float")]
70 Float,
71 #[strum(to_string = "bool")]
72 Bool,
73 #[strum(to_string = "text")]
74 Text,
75 #[strum(to_string = "date")]
76 Date,
77 #[strum(to_string = "time")]
78 Time,
79 #[strum(to_string = "timestamp")]
80 Timestamp,
81}
82
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85pub struct TyFunc {
86 pub name_hint: Option<Ident>,
87 pub args: Vec<Option<Ty>>,
88 pub return_ty: Box<Option<Ty>>,
89}
90
91impl Ty {
92 pub fn new<K: Into<TyKind>>(kind: K) -> Ty {
93 Ty {
94 kind: kind.into(),
95 span: None,
96 name: None,
97 }
98 }
99
100 pub fn relation(tuple_fields: Vec<TyTupleField>) -> Self {
101 let tuple = Ty::new(TyKind::Tuple(tuple_fields));
102 Ty::new(TyKind::Array(Box::new(tuple)))
103 }
104
105 pub fn never() -> Self {
106 Ty::new(TyKind::Union(Vec::new()))
107 }
108
109 pub fn is_never(&self) -> bool {
110 self.kind.as_union().map_or(false, |x| x.is_empty())
111 }
112
113 pub fn as_relation(&self) -> Option<&Vec<TyTupleField>> {
114 self.kind.as_array()?.kind.as_tuple()
115 }
116
117 pub fn as_relation_mut(&mut self) -> Option<&mut Vec<TyTupleField>> {
118 self.kind.as_array_mut()?.kind.as_tuple_mut()
119 }
120
121 pub fn into_relation(self) -> Option<Vec<TyTupleField>> {
122 self.kind.into_array().ok()?.kind.into_tuple().ok()
123 }
124
125 pub fn is_relation(&self) -> bool {
126 match &self.kind {
127 TyKind::Array(elem) => {
128 matches!(elem.kind, TyKind::Tuple(_))
129 }
130 _ => false,
131 }
132 }
133}
134
135impl TyTupleField {
136 pub fn ty(&self) -> Option<&Ty> {
137 match self {
138 TyTupleField::Single(_, ty) => ty.as_ref(),
139 TyTupleField::Wildcard(ty) => ty.as_ref(),
140 }
141 }
142}
143
144impl From<PrimitiveSet> for TyKind {
145 fn from(value: PrimitiveSet) -> Self {
146 TyKind::Primitive(value)
147 }
148}
149
150impl From<TyFunc> for TyKind {
151 fn from(value: TyFunc) -> Self {
152 TyKind::Function(Some(value))
153 }
154}
155
156impl From<Literal> for TyKind {
157 fn from(value: Literal) -> Self {
158 TyKind::Singleton(value)
159 }
160}