1use alloc::{
14 borrow::Cow,
15 boxed::Box,
16 fmt::{Display, Write},
17 sync::Arc,
18 vec::Vec,
19};
20use qusql_parse::Span;
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum BaseType {
25 Any,
27 Bool,
29 Bytes,
31 Date,
32 DateTime,
33 Float,
35 Integer,
37 String,
38 Time,
39 TimeStamp,
40 TimeInterval,
41 Uuid,
42}
43
44impl Display for BaseType {
45 fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
46 match self {
47 BaseType::Any => f.write_str("any"),
48 BaseType::Bool => f.write_str("bool"),
49 BaseType::Bytes => f.write_str("bytes"),
50 BaseType::Date => f.write_str("date"),
51 BaseType::DateTime => f.write_str("datetime"),
52 BaseType::Float => f.write_str("float"),
53 BaseType::Integer => f.write_str("integer"),
54 BaseType::String => f.write_str("string"),
55 BaseType::Time => f.write_str("time"),
56 BaseType::TimeStamp => f.write_str("timestamp"),
57 BaseType::TimeInterval => f.write_str("timeinterval"),
58 BaseType::Uuid => f.write_str("uuid"),
59 }
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
64pub enum ArgType {
65 Normal,
66 ListHack,
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
71pub enum Type<'a> {
72 #[doc(hidden)]
74 Args(BaseType, Arc<Vec<(usize, ArgType, Span)>>),
75 Base(BaseType),
76 Enum(Arc<Vec<Cow<'a, str>>>),
77 F32,
78 F64,
79 I16,
80 I24,
81 I32,
82 I64,
83 I8,
84 Invalid,
85 JSON,
86 Geometry,
87 Range(BaseType),
89 Array(Box<Type<'a>>),
90 Set(Arc<Vec<Cow<'a, str>>>),
91 U16,
92 U24,
93 U32,
94 U64,
95 U8,
96 #[doc(hidden)]
98 Null,
99}
100
101impl<'a> Display for Type<'a> {
102 fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
103 match self {
104 Type::Args(t, a) => {
105 write!(f, "args({t}")?;
106 for (a, _, _) in a.iter() {
107 write!(f, ", {a}")?;
108 }
109 f.write_char(')')
110 }
111 Type::Base(t) => t.fmt(f),
112 Type::F32 => f.write_str("f32"),
113 Type::F64 => f.write_str("f64"),
114 Type::I16 => f.write_str("i16"),
115 Type::I24 => f.write_str("i24"),
116 Type::I32 => f.write_str("i32"),
117 Type::I64 => f.write_str("i64"),
118 Type::I8 => f.write_str("i8"),
119 Type::Invalid => f.write_str("invalid"),
120 Type::JSON => f.write_str("json"),
121 Type::Geometry => f.write_str("geometry"),
122 Type::Range(inner) => write!(f, "range({inner})"),
123 Type::Array(inner) => {
124 inner.fmt(f)?;
125 f.write_str("[]")
126 }
127 Type::U16 => f.write_str("u16"),
128 Type::U24 => f.write_str("u24"),
129 Type::U32 => f.write_str("u32"),
130 Type::U64 => f.write_str("u64"),
131 Type::U8 => f.write_str("u8"),
132 Type::Null => f.write_str("null"),
133 Type::Enum(v) => {
134 f.write_str("enum(")?;
135 for (i, v) in v.iter().enumerate() {
136 if i != 0 {
137 f.write_str(", ")?;
138 }
139 write!(f, "'{v}'")?
140 }
141 f.write_char(')')
142 }
143 Type::Set(v) => {
144 f.write_str("set(")?;
145 for (i, v) in v.iter().enumerate() {
146 if i != 0 {
147 f.write_str(", ")?;
148 }
149 write!(f, "'{v}'")?
150 }
151 f.write_char(')')
152 }
153 }
154 }
155}
156
157impl<'a> Type<'a> {
158 pub fn base(&self) -> BaseType {
160 match self {
161 Type::Args(t, _) => *t,
162 Type::Base(t) => *t,
163 Type::Enum(_) => BaseType::String,
164 Type::F32 => BaseType::Float,
165 Type::F64 => BaseType::Float,
166 Type::I16 => BaseType::Integer,
167 Type::I24 => BaseType::Integer,
168 Type::I32 => BaseType::Integer,
169 Type::I64 => BaseType::Integer,
170 Type::I8 => BaseType::Integer,
171 Type::Invalid => BaseType::Any,
172 Type::JSON => BaseType::Any,
173 Type::Geometry => BaseType::Any,
174 Type::Range(_) => BaseType::Any,
175 Type::Array(_) => BaseType::Any,
176 Type::Null => BaseType::Any,
177 Type::Set(_) => BaseType::String,
178 Type::U16 => BaseType::Integer,
179 Type::U24 => BaseType::Integer,
180 Type::U32 => BaseType::Integer,
181 Type::U64 => BaseType::Integer,
182 Type::U8 => BaseType::Integer,
183 }
184 }
185}
186
187impl<'a> From<BaseType> for Type<'a> {
188 fn from(t: BaseType) -> Self {
189 Type::Base(t)
190 }
191}
192
193#[derive(Debug, Clone, PartialEq, Eq)]
195pub struct FullType<'a> {
196 pub t: Type<'a>,
197 pub not_null: bool,
198 pub list_hack: bool,
199}
200
201impl<'a> FullType<'a> {
202 pub(crate) fn new(t: impl Into<Type<'a>>, not_null: bool) -> Self {
203 Self {
204 t: t.into(),
205 not_null,
206 list_hack: false,
207 }
208 }
209
210 pub fn invalid() -> Self {
212 Self {
213 t: Type::Invalid,
214 not_null: false,
215 list_hack: false,
216 }
217 }
218}
219
220impl<'a> core::ops::Deref for FullType<'a> {
221 type Target = Type<'a>;
222
223 fn deref(&self) -> &Self::Target {
224 &self.t
225 }
226}
227
228impl<'a> Display for FullType<'a> {
229 fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
230 self.t.fmt(f)?;
231 if self.list_hack {
232 f.write_str(" list_hack")?;
233 }
234 if self.not_null {
235 f.write_str(" not null")?;
236 }
237 Ok(())
238 }
239}