1#![allow(dead_code)]
17
18use crate::generated::gapic_dataplane::model::TypeAnnotationCode;
19use gaxi::prost::ConvertError;
20use std::sync::LazyLock;
21
22#[derive(Clone, Debug, PartialEq, Default)]
24#[repr(transparent)]
25pub struct Type(pub(crate) crate::generated::gapic_dataplane::model::Type);
26
27macro_rules! define_type_code {
28 ($($variant:ident = $val:expr),* $(,)?) => {
29 #[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Default)]
34 #[repr(i32)]
35 #[non_exhaustive]
36 pub enum TypeCode {
37 #[default]
39 Unspecified = 0,
40 $(
41 #[doc = concat!("Spanner `", stringify!($variant), "` data type.")]
42 $variant = $val
43 ),*,
44 Unknown(i32),
46 }
47
48 impl From<i32> for TypeCode {
49 fn from(value: i32) -> Self {
50 match value {
51 0 => TypeCode::Unspecified,
52 $($val => TypeCode::$variant),*,
53 v => TypeCode::Unknown(v),
54 }
55 }
56 }
57
58 impl From<TypeCode> for i32 {
59 fn from(value: TypeCode) -> Self {
60 match value {
61 TypeCode::Unspecified => 0,
62 $(TypeCode::$variant => $val),*,
63 TypeCode::Unknown(v) => v,
64 }
65 }
66 }
67
68 impl From<crate::generated::gapic_dataplane::model::TypeCode> for TypeCode {
69 fn from(value: crate::generated::gapic_dataplane::model::TypeCode) -> Self {
70 match value.value() {
71 Some(v) => v.into(),
72 None => TypeCode::Unspecified,
73 }
74 }
75 }
76
77 impl From<TypeCode> for crate::generated::gapic_dataplane::model::TypeCode {
78 fn from(value: TypeCode) -> Self {
79 let v: i32 = value.into();
80 v.into()
81 }
82 }
83 };
84}
85
86define_type_code!(
90 Bool = 1,
91 Int64 = 2,
92 Float64 = 3,
93 Float32 = 15,
94 Timestamp = 4,
95 Date = 5,
96 String = 6,
97 Bytes = 7,
98 Array = 8,
99 Struct = 9,
100 Numeric = 10,
101 Json = 11,
102 Proto = 13,
103 Enum = 14,
104 Interval = 16,
105 Uuid = 17,
106);
107
108impl From<crate::generated::gapic_dataplane::model::Type> for Type {
109 fn from(value: crate::generated::gapic_dataplane::model::Type) -> Self {
110 Type(value)
111 }
112}
113
114impl From<Type> for crate::generated::gapic_dataplane::model::Type {
115 fn from(value: Type) -> Self {
116 value.0
117 }
118}
119
120impl From<crate::google::spanner::v1::Type> for Type {
121 fn from(value: crate::google::spanner::v1::Type) -> Self {
122 use gaxi::prost::FromProto;
123 value.cnv().unwrap_or_default().into()
124 }
125}
126
127impl Type {
128 pub fn code(&self) -> TypeCode {
130 self.0.code.clone().into()
131 }
132
133 pub fn array_element_type(&self) -> Option<Type> {
135 self.0
136 .array_element_type
137 .as_deref()
138 .map(|t| Type(t.clone()))
139 }
140}
141
142impl gaxi::prost::ToProto<i32> for TypeCode {
143 type Output = i32;
144
145 fn to_proto(self) -> Result<i32, ConvertError> {
146 let internal: crate::generated::gapic_dataplane::model::TypeCode = self.into();
147
148 internal.to_proto()
149 }
150}
151
152impl gaxi::prost::ToProto<crate::generated::gapic_dataplane::model::Type> for Type {
153 type Output = crate::generated::gapic_dataplane::model::Type;
154
155 fn to_proto(self) -> Result<crate::generated::gapic_dataplane::model::Type, ConvertError> {
156 Ok(self.0)
157 }
158}
159
160static TYPE_INT64: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Int64));
161static TYPE_STRING: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::String));
162static TYPE_BOOL: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Bool));
163static TYPE_FLOAT32: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Float32));
164static TYPE_FLOAT64: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Float64));
165static TYPE_JSON: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Json));
166static TYPE_BYTES: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Bytes));
167static TYPE_TIMESTAMP: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Timestamp));
168static TYPE_DATE: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Date));
169static TYPE_NUMERIC: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Numeric));
170static TYPE_UUID: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Uuid));
171static TYPE_INTERVAL: LazyLock<Type> = LazyLock::new(|| create_type(TypeCode::Interval));
172static TYPE_PG_NUMERIC: LazyLock<Type> = LazyLock::new(|| {
173 let mut t = create_type(TypeCode::Numeric);
174 t.0.type_annotation = TypeAnnotationCode::PgNumeric;
175 t
176});
177static TYPE_PG_JSONB: LazyLock<Type> = LazyLock::new(|| {
178 let mut t = create_type(TypeCode::Json);
179 t.0.type_annotation = TypeAnnotationCode::PgJsonb;
180 t
181});
182static TYPE_PG_OID: LazyLock<Type> = LazyLock::new(|| {
183 let mut t = create_type(TypeCode::Int64);
184 t.0.type_annotation = TypeAnnotationCode::PgOid;
185 t
186});
187
188pub fn int64() -> Type {
190 TYPE_INT64.clone()
191}
192
193pub fn string() -> Type {
195 TYPE_STRING.clone()
196}
197
198pub fn bool() -> Type {
200 TYPE_BOOL.clone()
201}
202
203pub fn float32() -> Type {
205 TYPE_FLOAT32.clone()
206}
207
208pub fn float64() -> Type {
210 TYPE_FLOAT64.clone()
211}
212
213pub fn json() -> Type {
215 TYPE_JSON.clone()
216}
217
218pub fn bytes() -> Type {
220 TYPE_BYTES.clone()
221}
222
223pub fn timestamp() -> Type {
225 TYPE_TIMESTAMP.clone()
226}
227
228pub fn date() -> Type {
230 TYPE_DATE.clone()
231}
232
233pub fn numeric() -> Type {
235 TYPE_NUMERIC.clone()
236}
237
238pub fn uuid() -> Type {
240 TYPE_UUID.clone()
241}
242
243pub fn interval() -> Type {
245 TYPE_INTERVAL.clone()
246}
247
248pub fn pg_numeric() -> Type {
250 TYPE_PG_NUMERIC.clone()
251}
252
253pub fn pg_jsonb() -> Type {
255 TYPE_PG_JSONB.clone()
256}
257
258pub fn pg_oid() -> Type {
260 TYPE_PG_OID.clone()
261}
262
263pub fn array(element_type: Type) -> Type {
265 let mut t = create_type(TypeCode::Array);
266 t.0.array_element_type = Some(Box::new(element_type.0));
267 t
268}
269
270pub(crate) fn create_type(code: TypeCode) -> Type {
271 Type(crate::generated::gapic_dataplane::model::Type {
272 code: code.into(),
273 array_element_type: None,
274 struct_type: None,
275 type_annotation: TypeAnnotationCode::Unspecified,
276 proto_type_fqn: String::new(),
277 _unknown_fields: Default::default(),
278 })
279}
280
281#[cfg(test)]
282mod tests {
283 use super::*;
284 use std::hash::Hash;
285
286 #[test]
287 fn test_type_code_round_trip() {
288 let codes = vec![
289 TypeCode::Unspecified,
290 TypeCode::Bool,
291 TypeCode::Int64,
292 TypeCode::Float64,
293 TypeCode::Float32,
294 TypeCode::Timestamp,
295 TypeCode::Date,
296 TypeCode::String,
297 TypeCode::Bytes,
298 TypeCode::Array,
299 TypeCode::Struct,
300 TypeCode::Numeric,
301 TypeCode::Json,
302 TypeCode::Proto,
303 TypeCode::Enum,
304 TypeCode::Interval,
305 TypeCode::Uuid,
306 ];
307
308 for code in codes {
309 let i: i32 = code.into();
310 let c: TypeCode = i.into();
311 assert_eq!(code, c);
312
313 let generated: crate::generated::gapic_dataplane::model::TypeCode = code.into();
314 let back: TypeCode = generated.into();
315 assert_eq!(code, back);
316 }
317 }
318
319 #[test]
320 fn test_unknown_type_code() {
321 let i = 999;
322 let code: TypeCode = i.into();
323 assert_eq!(code, TypeCode::Unknown(i));
324 assert_eq!(i32::from(code), i);
325 }
326
327 #[test]
328 fn test_unknown_type_code_from_generated() {
329 use crate::generated::gapic_dataplane::model::type_code::UnknownValue;
330 use wkt::internal::UnknownEnumValue;
331
332 let i = 999;
333 let unknown = UnknownValue(UnknownEnumValue::Integer(i));
334 let generated = crate::generated::gapic_dataplane::model::TypeCode::UnknownValue(unknown);
335 let code: TypeCode = generated.into();
336 assert_eq!(code, TypeCode::Unknown(i));
337 }
338
339 #[test]
340 fn test_simple_types() {
341 assert_eq!(int64().code(), TypeCode::Int64);
342 assert_eq!(string().code(), TypeCode::String);
343 assert_eq!(bool().code(), TypeCode::Bool);
344 assert_eq!(float64().code(), TypeCode::Float64);
345 assert_eq!(bytes().code(), TypeCode::Bytes);
346 assert_eq!(timestamp().code(), TypeCode::Timestamp);
347 assert_eq!(date().code(), TypeCode::Date);
348 assert_eq!(numeric().code(), TypeCode::Numeric);
349 assert_eq!(json().code(), TypeCode::Json);
350 assert_eq!(float32().code(), TypeCode::Float32);
351 assert_eq!(uuid().code(), TypeCode::Uuid);
352 assert_eq!(interval().code(), TypeCode::Interval);
353 }
355
356 #[test]
357 fn test_default_type() {
358 let t = Type::default();
359 assert_eq!(t.code(), TypeCode::Unspecified);
360 assert_eq!(
361 t.0.code,
362 crate::generated::gapic_dataplane::model::TypeCode::Unspecified
363 );
364 }
365
366 #[test]
367 fn test_to_proto_traits() {
368 use gaxi::prost::ToProto;
369 let t = int64();
370 let proto: crate::generated::gapic_dataplane::model::Type = t.clone().to_proto().unwrap();
371 assert_eq!(
372 proto.code,
373 crate::generated::gapic_dataplane::model::TypeCode::Int64
374 );
375
376 let code = TypeCode::Int64;
377 let proto_code: i32 = code.to_proto().unwrap();
378 assert_eq!(proto_code, 2);
379 }
380
381 #[test]
382 fn test_from_type_traits() {
383 let internal_type = crate::generated::gapic_dataplane::model::Type {
384 code: crate::generated::gapic_dataplane::model::TypeCode::Bool,
385 ..Default::default()
386 };
387 let t: Type = internal_type.clone().into();
388 assert_eq!(t.code(), TypeCode::Bool);
389
390 let back: crate::generated::gapic_dataplane::model::Type = t.into();
391 assert_eq!(back.code, internal_type.code);
392 }
393
394 #[test]
395 fn test_array_type() {
396 let t = array(int64());
397 assert_eq!(t.code(), TypeCode::Array);
398 assert_eq!(
399 t.0.array_element_type.unwrap().code,
400 crate::generated::gapic_dataplane::model::TypeCode::Int64
401 );
402 }
403
404 #[test]
405 fn test_pg_types() {
406 assert_eq!(pg_numeric().code(), TypeCode::Numeric);
407 assert_eq!(
408 pg_numeric().0.type_annotation,
409 TypeAnnotationCode::PgNumeric
410 );
411
412 assert_eq!(pg_jsonb().code(), TypeCode::Json);
413 assert_eq!(pg_jsonb().0.type_annotation, TypeAnnotationCode::PgJsonb);
414
415 assert_eq!(pg_oid().code(), TypeCode::Int64);
416 assert_eq!(pg_oid().0.type_annotation, TypeAnnotationCode::PgOid);
417 }
418
419 #[test]
420 fn test_array_element_type() {
421 let arr = array(int64());
422 assert_eq!(arr.array_element_type(), Some(int64()));
423
424 assert_eq!(int64().array_element_type(), None);
426 assert_eq!(string().array_element_type(), None);
427 assert_eq!(Type::default().array_element_type(), None);
428 }
429
430 #[test]
431 fn test_auto_traits() {
432 static_assertions::assert_impl_all!(Type: Send, Sync, Clone, std::fmt::Debug);
433 static_assertions::assert_impl_all!(
434 TypeCode: Send,
435 Sync,
436 Clone,
437 Copy,
438 std::fmt::Debug,
439 PartialEq,
440 Eq,
441 Hash
442 );
443 }
444}