klickhouse/types/deserialize/
array.rs

1use tokio::io::AsyncReadExt;
2
3use crate::{io::ClickhouseRead, values::Value, Result};
4
5use super::{Deserializer, DeserializerState, Type};
6
7/// Trait to allow reading `Item`s and packing them into a `Value::*`.
8pub trait ArrayDeserializerGeneric {
9    type Item;
10    /// The type of the items, e.g. [Value]
11    fn inner_type(type_: &Type) -> &Type;
12    /// Mapping from items to the return Value, e.g. simply `Vec<Value> -> Value::Array(items)`.
13    fn inner_value(items: Vec<Self::Item>) -> Value;
14    /// Conversion between the [Value] read and the items, e.g. simply the identity.
15    fn item_mapping(value: Value) -> Self::Item;
16}
17
18/// Simple case for reading into a [Value::Array].
19pub struct ArrayDeserializer;
20impl ArrayDeserializerGeneric for ArrayDeserializer {
21    type Item = Value;
22    fn inner_type(type_: &Type) -> &Type {
23        type_.unwrap_array()
24    }
25    fn inner_value(items: Vec<Self::Item>) -> Value {
26        Value::Array(items)
27    }
28    fn item_mapping(value: Value) -> Value {
29        value
30    }
31}
32
33impl<T: ArrayDeserializerGeneric + 'static> Deserializer for T {
34    async fn read_prefix<R: ClickhouseRead>(
35        type_: &Type,
36        reader: &mut R,
37        state: &mut DeserializerState,
38    ) -> Result<()> {
39        Self::inner_type(type_)
40            .deserialize_prefix(reader, state)
41            .await
42    }
43
44    async fn read<R: ClickhouseRead>(
45        type_: &Type,
46        reader: &mut R,
47        rows: usize,
48        state: &mut DeserializerState,
49    ) -> Result<Vec<Value>> {
50        if rows == 0 {
51            return Ok(vec![]);
52        }
53        let mut offsets = vec![];
54        for _ in 0..rows {
55            offsets.push(reader.read_u64_le().await?);
56        }
57        let mut items = Self::inner_type(type_)
58            .deserialize_column(reader, offsets[offsets.len() - 1] as usize, state)
59            .await?
60            .into_iter()
61            .map(Self::item_mapping);
62        let mut out = Vec::with_capacity(rows);
63        let mut read_offset = 0u64;
64        for offset in offsets {
65            let len = offset - read_offset;
66            read_offset = offset;
67            out.push(Self::inner_value((&mut items).take(len as usize).collect()));
68        }
69
70        Ok(out)
71    }
72}