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