1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use tokio::io::AsyncReadExt;

use crate::{io::ClickhouseRead, values::Value, Result};

use super::{Deserializer, DeserializerState, Type};

pub struct ArrayDeserializer;

struct Array2Deserializer;

impl Array2Deserializer {
    async fn read<R: ClickhouseRead>(
        type_: &Type,
        reader: &mut R,
        n: u64,
        state: &mut DeserializerState,
    ) -> Result<Value> {
        Ok(match type_ {
            Type::Array(inner) => {
                let mut offsets = vec![];
                for _ in 0..n {
                    offsets.push(reader.read_u64_le().await?);
                }
                let mut out = Vec::with_capacity(n as usize);
                let mut read_offset = 0u64;
                for offset in offsets {
                    let len = offset - read_offset;
                    read_offset = offset;
                    let items = inner
                        .deserialize_column(reader, len as usize, state)
                        .await?;
                    out.push(Value::Array(items));
                }

                Value::Array(out)
            }
            _ => unimplemented!(),
        })
    }
}

#[async_trait::async_trait]
impl Deserializer for ArrayDeserializer {
    async fn read_prefix<R: ClickhouseRead>(
        type_: &Type,
        reader: &mut R,
        state: &mut DeserializerState,
    ) -> Result<()> {
        match type_ {
            Type::Array(inner) => {
                inner.deserialize_prefix(reader, state).await?;
            }
            _ => unimplemented!(),
        }
        Ok(())
    }

    async fn read<R: ClickhouseRead>(
        type_: &Type,
        reader: &mut R,
        state: &mut DeserializerState,
    ) -> Result<Value> {
        Ok(match type_ {
            Type::Array(inner) => {
                let len = reader.read_u64_le().await?;
                if let Type::Array(_) = &**inner {
                    return Array2Deserializer::read(&**inner, reader, len, state).await;
                }
                let items = inner
                    .deserialize_column(reader, len as usize, state)
                    .await?;
                Value::Array(items)
            }
            _ => unimplemented!(),
        })
    }
}