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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! Field-attribute serde modules for ClickHouse column types, mirroring
//! the `clickhouse` crate's `clickhouse::serde::*` modules.
//!
//! A row struct written for the `clickhouse` crate's `Row` derive ports to
//! this sink by swapping the attribute path:
//!
//! ```text
//! #[serde(with = "clickhouse::serde::ipv4")] // clickhouse crate
//! #[serde(with = "spate_clickhouse::serde::ipv4")] // this crate
//! ```
//!
//! Every module provides `serialize`, `deserialize`, and a nested `option`
//! submodule for `Option<T>` fields against `Nullable(...)` columns:
//!
//! ```text
//! #[serde(with = "spate_clickhouse::serde::ipv4::option")]
//! addr: Option<std::net::Ipv4Addr>,
//! ```
//!
//! ## ⚠ Omitting these attributes is silent data corruption
//!
//! `uuid::Uuid`, `std::net::Ipv4Addr`, and the `chrono`/`time` date,
//! datetime and duration types all have *default* serde representations
//! that serialize **successfully into the wrong bytes** for their
//! ClickHouse columns. `Ipv4Addr` emits big-endian octets where `IPv4` is
//! a little-endian `UInt32`, and both date/time crates emit string forms
//! where every date and time column is a fixed-width integer. Omitting the
//! attribute is silent data corruption, not an error. The sink's opt-in
//! schema validation (`validate_schema: full`) catches the shape-level
//! cases; the docs table in [`crate::rowbinary`] is the authoritative
//! mapping.
//!
//! Wire semantics are rewritten from `clickhouse` 0.15.1's `src/serde.rs`,
//! which is `MIT OR Apache-2.0`; this crate takes the Apache-2.0 branch, the
//! same license it is itself distributed under. Compatibility is proven by
//! round-tripping through that crate's deserializer in the mock tests.
/// Generates the `option` submodule of a with-module: `Option<T>` support
/// for `Nullable(...)` columns, delegating to the parent module's
/// `serialize`/`deserialize` for the inner value.
pub use option_module;