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