nativeclick 0.26.9

Nativeclick is a pure Rust SDK for working with Clickhouse with the native protocol in async environments with minimal boilerplate and maximal performance.
Documentation
use crate::{Result, io::ClickhouseRead, values::Value};

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

use crate::values;

pub struct PointDeserializer;

impl Deserializer for PointDeserializer {
    async fn read_prefix<R: ClickhouseRead>(
        _type_: &Type,
        reader: &mut R,
        state: &mut DeserializerState,
    ) -> Result<()> {
        for _ in 0..2 {
            Type::Float64.deserialize_prefix(reader, state).await?;
        }
        Ok(())
    }

    async fn read<R: ClickhouseRead>(
        _type_: &Type,
        reader: &mut R,
        rows: usize,
        state: &mut DeserializerState,
    ) -> Result<Vec<Value>> {
        let mut points = vec![Value::Point(Default::default()); rows];
        for col in 0..2 {
            for (row, value) in Type::Float64
                .deserialize_column(reader, rows, state)
                .await?
                .into_iter()
                .enumerate()
            {
                let Value::Float64(value) = value else {
                    unreachable!()
                };
                match &mut points[row] {
                    Value::Point(point) => point.0[col] = value,
                    _ => {
                        unreachable!()
                    }
                }
            }
        }
        Ok(points)
    }
}
macro_rules! array_deser {
    ($deserializer:ident, $name:ident, $item:ident) => {
        pub struct $deserializer;
        impl super::array::ArrayDeserializerGeneric for $deserializer {
            type Item = crate::values::$item;
            fn inner_type(_type_: &Type) -> &Type {
                &Type::$item
            }
            fn inner_value(items: Vec<Self::Item>) -> Value {
                Value::$name(values::$name(items))
            }
            fn item_mapping(value: Value) -> Self::Item {
                let Value::$item(point) = value else {
                    unreachable!()
                };
                point
            }
        }
    };
}

array_deser!(RingDeserializer, Ring, Point);
array_deser!(PolygonDeserializer, Polygon, Ring);
array_deser!(MultiPolygonDeserializer, MultiPolygon, Polygon);