ydb_unofficial/sqlx/
types.rs

1use sqlx_core::{types::Type, decode::Decode, encode::Encode};
2use ydb_grpc_bindings::generated::ydb::{self, value::Value, r#type::PrimitiveTypeId};
3use super::database::{Ydb, YdbArgumentBuffer};
4use super::entities::{YdbValue, YdbTypeInfo};
5
6#[derive(Debug)]
7struct AnotherType;
8impl std::fmt::Display for AnotherType {
9    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10        std::fmt::Debug::fmt(self, f)
11    }
12}
13impl std::error::Error for AnotherType {}
14
15macro_rules! ydb_type {
16    ($($t:ty = ($info:ident, $val:ident),)+) => {
17        $(
18        impl Type<Ydb> for $t {
19            fn type_info() -> YdbTypeInfo {
20                YdbTypeInfo::Primitive(PrimitiveTypeId::$info)
21            }
22        }
23        
24        impl Decode<'_, Ydb> for $t {
25            fn decode(value: &YdbValue) -> Result<Self, sqlx_core::error::BoxDynError> {
26                match value.value() {
27                    Value::$val(v) => Ok(v.clone().try_into().unwrap()),
28                    _ => Err(Box::new(AnotherType))
29                }
30            }
31        }
32
33        impl<S: ToString + Clone> Type<Ydb> for (S, $t) {
34            fn type_info() -> YdbTypeInfo {
35                YdbTypeInfo::Primitive(PrimitiveTypeId::$info)
36            }
37        }
38        
39        impl<'q, S: ToString + Clone> Encode<'q, Ydb> for (S, $t) {
40            fn encode_by_ref(&self, buf: &mut YdbArgumentBuffer) -> sqlx_core::encode::IsNull {
41                let value = ydb::Value {
42                    value: Some(ydb::value::Value::$val(self.1.clone().try_into().unwrap())),
43                    ..Default::default()
44                };
45                let value = ydb::TypedValue {
46                    r#type: Some(ydb::Type{r#type: Some(ydb::r#type::Type::TypeId(PrimitiveTypeId::$info.into()))}),
47                    value: Some(value),
48                };
49                buf.insert(self.0.to_string(), value);
50                sqlx_core::encode::IsNull::No
51            }
52        }
53    )+}
54}
55
56
57macro_rules! wrapper_primitive_types {
58    ($($t:ident ($inner:ty) $fun:ident ),+) => {$(
59        
60        #[derive(Debug, Clone, Copy)]
61        pub struct $t($inner);
62        impl Into<$inner> for $t { fn into(self) -> $inner {self.0} }
63        impl From<$inner> for $t { fn from(v: $inner) -> Self {Self(v)} }
64        impl $t {pub fn $fun(&self) -> $inner { self.0 }}
65    )+};
66}
67macro_rules! wrapper_types {
68    ($($t:ident ($inner:ty) $fun:ident ),+) => {$(
69        
70        #[derive(Debug, Clone)]
71        pub struct $t($inner);
72        impl Into<$inner> for $t { fn into(self) -> $inner {self.0} }
73        impl From<$inner> for $t { fn from(v: $inner) -> Self {Self(v)} }
74        impl $t {pub fn $fun(&self) -> $inner { self.0.clone() }}
75    )+};
76}
77
78wrapper_primitive_types! {
79    Date(u16) days, 
80    Datetime(u32) secs, 
81    Timestamp(u64) micros, 
82    Interval(i64) micros
83}
84
85wrapper_types! {
86    Json(String) text,
87    JsonDocument(String) text
88}
89impl Into<u32> for Date { fn into(self) -> u32 { self.0.into() }}
90impl From<u32> for Date { fn from(v: u32) -> Self {Self(v.try_into().unwrap())}}
91
92
93ydb_type! {
94    bool = (Bool, BoolValue),
95    i8  = (Int8, Int32Value),
96    u8  = (Uint8, Uint32Value),
97    i16 = (Int16, Int32Value),
98    u16 = (Uint16, Uint32Value),
99    i32 = (Int32, Int32Value),
100    u32 = (Uint32, Uint32Value),
101    i64 = (Int64, Int64Value),
102    u64 = (Uint64, Uint64Value),
103    f32 = (Float, FloatValue),
104    f64 = (Double, DoubleValue),
105    Vec<u8> = (String, BytesValue),
106    String = (Utf8, TextValue),
107    Date = (Date, Uint32Value),
108    Datetime = (Datetime, Uint32Value),
109    Timestamp = (Timestamp, Uint64Value),
110    Json = (Json, TextValue),
111    JsonDocument = (JsonDocument, TextValue),
112}
113