clickhouse_arrow/
formats.rs

1mod arrow;
2mod native;
3pub(crate) mod protocol_data;
4
5// Re-exports
6pub use arrow::ArrowFormat;
7pub use native::NativeFormat;
8
9use crate::ArrowOptions;
10
11/// Marker trait for various client formats.
12///
13/// Currently only two formats are in use: `ArrowFormat` and `NativeFormat`. This approach provides
14/// a simple mechanism to introduce new formats to work with `ClickHouse` data without a lot of
15/// overhead and a fullblown serde implementation.
16#[expect(private_bounds)]
17pub trait ClientFormat: sealed::ClientFormatImpl<Self::Data> + Send + Sync + 'static {
18    type Data: std::fmt::Debug + Clone + Send + Sync + 'static;
19
20    const FORMAT: &'static str;
21}
22
23pub(crate) mod sealed {
24    use super::{DeserializerState, SerializerState};
25    use crate::Type;
26    use crate::client::connection::ClientMetadata;
27    use crate::errors::Result;
28    use crate::io::{ClickHouseRead, ClickHouseWrite};
29    use crate::query::Qid;
30
31    pub(crate) trait ClientFormatImpl<T>: std::fmt::Debug
32    where
33        T: std::fmt::Debug + Clone + Send + Sync + 'static,
34    {
35        type Schema: std::fmt::Debug + Clone + Send + Sync + 'static;
36        type Deser: Default + Send + Sync + 'static;
37        type Ser: Default + Send + Sync + 'static;
38
39        #[expect(unused)]
40        fn finish_ser(_state: &mut SerializerState<Self::Ser>) {}
41
42        fn finish_deser(_state: &mut DeserializerState<Self::Deser>) {}
43
44        fn write<'a, W: ClickHouseWrite>(
45            writer: &'a mut W,
46            data: T,
47            qid: Qid,
48            header: Option<&'a [(String, Type)]>,
49            revision: u64,
50            metadata: ClientMetadata,
51        ) -> impl Future<Output = Result<()>> + Send + 'a;
52
53        fn read<'a, R: ClickHouseRead + 'static>(
54            reader: &'a mut R,
55            revision: u64,
56            metadata: ClientMetadata,
57            state: &'a mut DeserializerState<Self::Deser>,
58        ) -> impl Future<Output = Result<Option<T>>> + Send + 'a;
59    }
60}
61
62/// Context maintained during deserialization
63#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
64pub(crate) struct DeserializerState<T: Default = ()> {
65    pub(crate) options:      Option<ArrowOptions>,
66    pub(crate) deserializer: T,
67}
68
69impl<T: Default> DeserializerState<T> {
70    #[must_use]
71    pub(crate) fn with_arrow_options(mut self, options: ArrowOptions) -> Self {
72        self.options = Some(options);
73        self
74    }
75
76    #[must_use]
77    pub(crate) fn deserializer(&mut self) -> &mut T { &mut self.deserializer }
78}
79
80/// Context maintained during serialization
81#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
82pub(crate) struct SerializerState<T: Default = ()> {
83    pub(crate) options:    Option<ArrowOptions>,
84    pub(crate) serializer: T,
85}
86
87impl<T: Default> SerializerState<T> {
88    #[must_use]
89    pub(crate) fn with_arrow_options(mut self, options: ArrowOptions) -> Self {
90        self.options = Some(options);
91        self
92    }
93
94    #[expect(unused)]
95    #[must_use]
96    pub(crate) fn serializer(&mut self) -> &mut T { &mut self.serializer }
97}