Skip to main content

sqlite_diff_rs/wire/
source.rs

1//! [`WireSource`]: sealed marker trait for CDC wire formats.
2
3use super::sealed::Sealed;
4use super::wire_type::WireType;
5
6/// Per-format marker naming a CDC wire source.
7///
8/// Implementors are unit structs owned by each format module
9/// (`PgWalstream`, `Wal2Json`, `Maxwell`). The associated payload type
10/// describes the format's per-column wire data.
11///
12/// Type identity is no longer source-native. Every payload carries a
13/// source-independent [`WireType`] that selects the decoder, so one
14/// semantic catalog drives every source without a per-source
15/// translation table.
16pub trait WireSource: Sealed {
17    /// Per-column payload the format hands to a decoder.
18    ///
19    /// Every payload struct carries a `column_name: &'a str` so decoder
20    /// errors are self-describing without an outer wrapping layer.
21    type Payload<'a>;
22
23    /// Semantic type of the column carried by the payload, used for
24    /// decoder dispatch.
25    fn wire_type(payload: &Self::Payload<'_>) -> WireType;
26
27    /// Extract the column name from a payload for diagnostic messages.
28    fn column_name<'a>(payload: &'a Self::Payload<'_>) -> &'a str;
29}
30
31/// Schema-side semantic type for one column of one table.
32pub trait WireColumnTypes {
33    /// Semantic [`WireType`] for the column at `column_index`.
34    fn column_type(&self, column_index: usize) -> WireType;
35}
36
37/// Table-name lookup for the [`DiffSetBuilder::digest`](crate::DiffSetBuilder::digest) entry point.
38pub trait WireSchema {
39    /// Concrete schema type for one table.
40    type Table: crate::schema::NamedColumns + WireColumnTypes;
41
42    /// Resolve a table name to its schema entry.
43    fn get(&self, table_name: &str) -> Option<&Self::Table>;
44}
45
46/// One CDC wire event digested via [`DiffSetBuilder::digest`](crate::DiffSetBuilder::digest).
47///
48/// Implemented in-crate for `pg_walstream::EventType`, `wal2json::MessageV2`,
49/// `wal2json::ChangeV1`, and `maxwell::Message` (each times both formats).
50pub trait Digestable<F, T, S, B>
51where
52    F: crate::builders::Format<S, B>,
53    T: crate::schema::NamedColumns + WireColumnTypes,
54{
55    /// Wire source this event came from.
56    type Src: WireSource;
57
58    /// Failure mode raised on schema lookup or decode failure.
59    type Error;
60
61    /// Fold this event into `builder`, resolving affected tables via `schema`
62    /// and decoding column payloads via `adapter`.
63    ///
64    /// # Errors
65    ///
66    /// Any per-source `ConversionError`.
67    fn digest_into<Sch, A>(
68        &self,
69        builder: crate::builders::DiffSetBuilder<F, T, S, B>,
70        schema: &Sch,
71        adapter: &A,
72    ) -> Result<crate::builders::DiffSetBuilder<F, T, S, B>, Self::Error>
73    where
74        Sch: WireSchema<Table = T>,
75        A: super::WireAdapter<Self::Src, S, B>;
76}