clickhouse_arrow/native/convert/
unit_value.rs1use std::borrow::Cow;
2
3use crate::{Error, FromSql, Result, Row, ToSql, Type, Value};
4
5#[derive(Clone, Debug, Default)]
7pub struct UnitValue<T: FromSql + ToSql>(pub T);
8
9impl<T: FromSql + ToSql> Row for UnitValue<T> {
10 const COLUMN_COUNT: Option<usize> = Some(1);
11
12 fn column_names() -> Option<Vec<Cow<'static, str>>> { None }
13
14 fn to_schema() -> Option<Vec<(String, Type, Option<Value>)>> { None }
15
16 fn deserialize_row(map: Vec<(&str, &Type, Value)>) -> Result<Self> {
17 if map.is_empty() {
18 return Err(Error::MissingField("<unit>"));
19 }
20 let item = map.into_iter().next().unwrap();
21 T::from_sql(item.1, item.2).map(UnitValue)
22 }
23
24 fn serialize_row(
25 self,
26 type_hints: &[(String, Type)],
27 ) -> Result<Vec<(Cow<'static, str>, Value)>> {
28 Ok(vec![(Cow::Borrowed("_"), self.0.to_sql(type_hints.iter().map(|(_, t)| t).next())?)])
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 #[test]
37 fn test_unit_value_creation() {
38 let unit = UnitValue(42i32);
39 assert_eq!(unit.0, 42);
40 }
41
42 #[test]
43 fn test_unit_value_default() {
44 let unit: UnitValue<i32> = UnitValue::default();
45 assert_eq!(unit.0, 0);
46 }
47
48 #[test]
49 fn test_unit_value_clone_debug() {
50 let unit = UnitValue(123i64);
51 let cloned = unit.clone();
52 assert_eq!(unit.0, cloned.0);
53
54 let debug_str = format!("{unit:?}");
56 assert!(debug_str.contains("UnitValue"));
57 assert!(debug_str.contains("123"));
58 }
59
60 #[test]
61 fn test_unit_value_deserialize_success() {
62 let map = vec![("col", &Type::Int32, Value::Int32(42))];
63 let unit: UnitValue<i32> = UnitValue::deserialize_row(map).unwrap();
64 assert_eq!(unit.0, 42);
65 }
66
67 #[test]
68 fn test_unit_value_deserialize_empty() {
69 let map = vec![];
70 let result: Result<UnitValue<i32>> = UnitValue::deserialize_row(map);
71 assert!(matches!(result, Err(Error::MissingField(_))));
72 }
73
74 #[test]
75 fn test_unit_value_serialize() {
76 let unit = UnitValue(123i32);
77 let type_hints = vec![("col".to_string(), Type::Int32)];
78 let result = unit.serialize_row(&type_hints).unwrap();
79
80 assert_eq!(result.len(), 1);
81 assert_eq!(result[0].0, "_");
82 assert_eq!(result[0].1, Value::Int32(123));
83 }
84
85 #[test]
86 fn test_unit_value_serialize_no_hints() {
87 let unit = UnitValue(456i64);
88 let result = unit.serialize_row(&[]).unwrap();
89
90 assert_eq!(result.len(), 1);
91 assert_eq!(result[0].0, "_");
92 assert_eq!(result[0].1, Value::Int64(456));
93 }
94
95 #[test]
96 fn test_unit_value_static_methods() {
97 assert_eq!(UnitValue::<i32>::COLUMN_COUNT, Some(1));
99 assert_eq!(UnitValue::<i32>::column_names(), None);
100 assert_eq!(UnitValue::<i32>::to_schema(), None);
101 }
102
103 #[test]
104 fn test_unit_value_string() {
105 let unit = UnitValue("hello".to_string());
106 let type_hints = vec![("col".to_string(), Type::String)];
107 let result = unit.serialize_row(&type_hints).unwrap();
108
109 assert_eq!(result.len(), 1);
110 assert_eq!(result[0].1, Value::String("hello".to_string().into_bytes()));
111 }
112
113 #[test]
114 fn test_unit_value_deserialize_string() {
115 let map = vec![("col", &Type::String, Value::String("test".to_string().into_bytes()))];
116 let unit: UnitValue<String> = UnitValue::deserialize_row(map).unwrap();
117 assert_eq!(unit.0, "test");
118 }
119}