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