Skip to main content

live_data/
schema.rs

1//! Wire-shaped schema used in feed manifests and subscription acks.
2//!
3//! The intent is a serde-friendly minimal description that downstream
4//! consumers can render without taking a dependency on a specific
5//! columnar runtime. Publisher SDKs build these from their native
6//! schema types at manifest construction time.
7
8use serde::{Deserialize, Serialize};
9
10/// Ordered list of fields that make up a feed's schema.
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct WireSchema {
13    pub fields: Vec<FieldSpec>,
14}
15
16impl WireSchema {
17    pub fn new(fields: Vec<FieldSpec>) -> Self {
18        Self { fields }
19    }
20
21    pub fn field(&self, name: &str) -> Option<&FieldSpec> {
22        self.fields.iter().find(|f| f.name == name)
23    }
24}
25
26/// One field in a [`WireSchema`].
27///
28/// `dtype` is a free-form string for 0.1.0. Common values mirror Arrow
29/// logical types, for example: `i32`, `i64`, `u32`, `u64`, `f32`, `f64`,
30/// `bool`, `string`, `large_string`, `categorical32`, `datetime[ms]`.
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct FieldSpec {
33    pub name: String,
34    pub dtype: String,
35    #[serde(default)]
36    pub nullable: bool,
37}
38
39impl FieldSpec {
40    pub fn new(name: impl Into<String>, dtype: impl Into<String>) -> Self {
41        Self { name: name.into(), dtype: dtype.into(), nullable: false }
42    }
43
44    pub fn nullable(mut self, nullable: bool) -> Self {
45        self.nullable = nullable;
46        self
47    }
48}