clickhouse_arrow/native/convert/
std_serialize.rs

1use std::any::TypeId;
2use std::collections::{BTreeMap, HashMap};
3
4use indexmap::IndexMap;
5
6use super::*;
7
8impl ToSql for u8 {
9    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::UInt8(self)) }
10}
11
12impl ToSql for bool {
13    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::UInt8(u8::from(self))) }
14}
15
16impl ToSql for u16 {
17    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::UInt16(self)) }
18}
19
20impl ToSql for u32 {
21    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::UInt32(self)) }
22}
23
24impl ToSql for u64 {
25    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::UInt64(self)) }
26}
27
28impl ToSql for u128 {
29    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::UInt128(self)) }
30}
31
32impl ToSql for i8 {
33    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::Int8(self)) }
34}
35
36impl ToSql for i16 {
37    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::Int16(self)) }
38}
39
40impl ToSql for i32 {
41    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::Int32(self)) }
42}
43
44impl ToSql for i64 {
45    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::Int64(self)) }
46}
47
48impl ToSql for i128 {
49    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::Int128(self)) }
50}
51
52impl ToSql for f32 {
53    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::Float32(self)) }
54}
55
56impl ToSql for f64 {
57    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> { Ok(Value::Float64(self)) }
58}
59
60impl ToSql for String {
61    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> {
62        Ok(Value::String(self.into_bytes()))
63    }
64}
65
66impl ToSql for &str {
67    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> {
68        Ok(Value::String(self.as_bytes().to_vec()))
69    }
70}
71
72impl<T: ToSql + 'static> ToSql for Vec<T> {
73    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> {
74        let type_hint = type_hint.and_then(|x| x.unarray());
75        if matches!(type_hint, Some(Type::String | Type::FixedSizedString(_))) {
76            let type_id = TypeId::of::<T>();
77            if type_id == TypeId::of::<u8>() || type_id == TypeId::of::<i8>() {
78                assert_eq!(size_of::<T>(), 1);
79                return Ok(Value::String(unsafe { std::mem::transmute::<Vec<T>, Vec<u8>>(self) }));
80            }
81        }
82        Ok(Value::Array(self.into_iter().map(|x| x.to_sql(type_hint)).collect::<Result<Vec<_>>>()?))
83    }
84}
85
86impl<T: ToSql, Y: ToSql, S: ::std::hash::BuildHasher> ToSql for HashMap<T, Y, S> {
87    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> {
88        let mut keys = Vec::with_capacity(self.len());
89        let mut values = Vec::with_capacity(self.len());
90        let type_hint = type_hint.and_then(|x| x.unmap());
91        for (key, value) in self {
92            keys.push(key.to_sql(type_hint.map(|x| x.0))?);
93            values.push(value.to_sql(type_hint.map(|x| x.1))?);
94        }
95        Ok(Value::Map(keys, values))
96    }
97}
98
99impl<T: ToSql, Y: ToSql> ToSql for BTreeMap<T, Y> {
100    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> {
101        let mut keys = Vec::with_capacity(self.len());
102        let mut values = Vec::with_capacity(self.len());
103        let type_hint = type_hint.and_then(|x| x.unmap());
104        for (key, value) in self {
105            keys.push(key.to_sql(type_hint.map(|x| x.0))?);
106            values.push(value.to_sql(type_hint.map(|x| x.1))?);
107        }
108        Ok(Value::Map(keys, values))
109    }
110}
111
112impl<T: ToSql, Y: ToSql, S: ::std::hash::BuildHasher> ToSql for IndexMap<T, Y, S> {
113    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> {
114        let mut keys = Vec::with_capacity(self.len());
115        let mut values = Vec::with_capacity(self.len());
116        let type_hint = type_hint.and_then(|x| x.unmap());
117        for (key, value) in self {
118            keys.push(key.to_sql(type_hint.map(|x| x.0))?);
119            values.push(value.to_sql(type_hint.map(|x| x.1))?);
120        }
121        Ok(Value::Map(keys, values))
122    }
123}
124
125#[cfg(feature = "serde")]
126impl ToSql for serde_json::Value {
127    fn to_sql(self, _type_hint: Option<&Type>) -> Result<Value> {
128        Ok(Value::Object(self.to_string().into_bytes()))
129    }
130}
131
132impl<T: ToSql> ToSql for Option<T> {
133    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> {
134        match self {
135            Some(x) => Ok(x.to_sql(type_hint.and_then(|x| x.unnull()))?),
136            None => Ok(Value::Null),
137        }
138    }
139}
140
141impl<T: ToSql, const N: usize> ToSql for [T; N] {
142    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> {
143        let type_hint = type_hint.and_then(|x| x.unarray());
144        Ok(Value::Array(
145            IntoIterator::into_iter(self)
146                .map(|x| x.to_sql(type_hint))
147                .collect::<Result<Vec<_>>>()?,
148        ))
149    }
150}
151
152impl<T: ToSql + Clone> ToSql for &T {
153    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> { self.clone().to_sql(type_hint) }
154}
155
156impl<T: ToSql + Clone> ToSql for &mut T {
157    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> { self.clone().to_sql(type_hint) }
158}
159
160impl<T: ToSql> ToSql for Box<T> {
161    fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> { (*self).to_sql(type_hint) }
162}
163
164macro_rules! tuple_impls {
165    ($($len:expr => ($($n:tt $name:ident)+))+) => {
166        $(
167            impl<$($name: ToSql),+> ToSql for ($($name,)+) {
168                fn to_sql(self, type_hint: Option<&Type>) -> Result<Value> {
169                    let type_hint = type_hint.and_then(|x| x.untuple());
170
171                    Ok(Value::Tuple(vec![
172                        $(
173                            self.$n.to_sql(type_hint.and_then(|x| x.get($n)))?,
174                        )+
175                    ]))
176                }
177            }
178        )+
179    }
180}
181
182tuple_impls! {
183    1 => (0 T0)
184    2 => (0 T0 1 T1)
185    3 => (0 T0 1 T1 2 T2)
186    4 => (0 T0 1 T1 2 T2 3 T3)
187    5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
188    6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
189    7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
190    8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
191    9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
192    10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
193    11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
194    12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
195    13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
196    14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
197    15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
198    16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
199}