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(Box<Type<'a>>),
90 MultiRange(Box<Type<'a>>),
92 Array(Box<Type<'a>>),
93 Set(Arc<Vec<Cow<'a, str>>>),
94 U16,
95 U24,
96 U32,
97 U64,
98 U8,
99 #[doc(hidden)]
101 Null,
102}
103
104impl<'a> Display for Type<'a> {
105 fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
106 match self {
107 Type::Args(t, a) => {
108 write!(f, "args({t}")?;
109 for (a, _, _) in a.iter() {
110 write!(f, ", {a}")?;
111 }
112 f.write_char(')')
113 }
114 Type::Base(t) => t.fmt(f),
115 Type::F32 => f.write_str("f32"),
116 Type::F64 => f.write_str("f64"),
117 Type::I16 => f.write_str("i16"),
118 Type::I24 => f.write_str("i24"),
119 Type::I32 => f.write_str("i32"),
120 Type::I64 => f.write_str("i64"),
121 Type::I8 => f.write_str("i8"),
122 Type::Invalid => f.write_str("invalid"),
123 Type::JSON => f.write_str("json"),
124 Type::Geometry => f.write_str("geometry"),
125 Type::Range(inner) => write!(f, "range({inner})"),
126 Type::MultiRange(inner) => write!(f, "multirange({inner})"),
127 Type::Array(inner) => {
128 inner.fmt(f)?;
129 f.write_str("[]")
130 }
131 Type::U16 => f.write_str("u16"),
132 Type::U24 => f.write_str("u24"),
133 Type::U32 => f.write_str("u32"),
134 Type::U64 => f.write_str("u64"),
135 Type::U8 => f.write_str("u8"),
136 Type::Null => f.write_str("null"),
137 Type::Enum(v) => {
138 f.write_str("enum(")?;
139 for (i, v) in v.iter().enumerate() {
140 if i != 0 {
141 f.write_str(", ")?;
142 }
143 write!(f, "'{v}'")?
144 }
145 f.write_char(')')
146 }
147 Type::Set(v) => {
148 f.write_str("set(")?;
149 for (i, v) in v.iter().enumerate() {
150 if i != 0 {
151 f.write_str(", ")?;
152 }
153 write!(f, "'{v}'")?
154 }
155 f.write_char(')')
156 }
157 }
158 }
159}
160
161impl<'a> Type<'a> {
162 pub fn base(&self) -> BaseType {
164 match self {
165 Type::Args(t, _) => *t,
166 Type::Base(t) => *t,
167 Type::Enum(_) => BaseType::String,
168 Type::F32 => BaseType::Float,
169 Type::F64 => BaseType::Float,
170 Type::I16 => BaseType::Integer,
171 Type::I24 => BaseType::Integer,
172 Type::I32 => BaseType::Integer,
173 Type::I64 => BaseType::Integer,
174 Type::I8 => BaseType::Integer,
175 Type::Invalid => BaseType::Any,
176 Type::JSON => BaseType::Any,
177 Type::Geometry => BaseType::Any,
178 Type::Range(_) => BaseType::Any,
179 Type::MultiRange(_) => BaseType::Any,
180 Type::Array(_) => BaseType::Any,
181 Type::Null => BaseType::Any,
182 Type::Set(_) => BaseType::String,
183 Type::U16 => BaseType::Integer,
184 Type::U24 => BaseType::Integer,
185 Type::U32 => BaseType::Integer,
186 Type::U64 => BaseType::Integer,
187 Type::U8 => BaseType::Integer,
188 }
189 }
190}
191
192impl<'a> From<BaseType> for Type<'a> {
193 fn from(t: BaseType) -> Self {
194 Type::Base(t)
195 }
196}
197
198#[derive(Debug, Clone, PartialEq, Eq)]
200pub struct FullType<'a> {
201 pub t: Type<'a>,
202 pub not_null: bool,
203 pub list_hack: bool,
204}
205
206impl<'a> FullType<'a> {
207 pub(crate) fn new(t: impl Into<Type<'a>>, not_null: bool) -> Self {
208 Self {
209 t: t.into(),
210 not_null,
211 list_hack: false,
212 }
213 }
214
215 pub fn invalid() -> Self {
217 Self {
218 t: Type::Invalid,
219 not_null: false,
220 list_hack: false,
221 }
222 }
223}
224
225impl<'a> core::ops::Deref for FullType<'a> {
226 type Target = Type<'a>;
227
228 fn deref(&self) -> &Self::Target {
229 &self.t
230 }
231}
232
233impl<'a> Display for FullType<'a> {
234 fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
235 self.t.fmt(f)?;
236 if self.list_hack {
237 f.write_str(" list_hack")?;
238 }
239 if self.not_null {
240 f.write_str(" not null")?;
241 }
242 Ok(())
243 }
244}