live-data 0.1.0

Shared descriptor, manifest, and subscription types for the live-feed publisher SDK and the live-stream consumer SDK.
Documentation
//! Wire-shaped schema used in feed manifests and subscription acks.
//!
//! The intent is a serde-friendly minimal description that downstream
//! consumers can render without taking a dependency on a specific
//! columnar runtime. Publisher SDKs build these from their native
//! schema types at manifest construction time.

use serde::{Deserialize, Serialize};

/// Ordered list of fields that make up a feed's schema.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct WireSchema {
    pub fields: Vec<FieldSpec>,
}

impl WireSchema {
    pub fn new(fields: Vec<FieldSpec>) -> Self {
        Self { fields }
    }

    pub fn field(&self, name: &str) -> Option<&FieldSpec> {
        self.fields.iter().find(|f| f.name == name)
    }
}

/// One field in a [`WireSchema`].
///
/// `dtype` is a free-form string for 0.1.0. Common values mirror Arrow
/// logical types, for example: `i32`, `i64`, `u32`, `u64`, `f32`, `f64`,
/// `bool`, `string`, `large_string`, `categorical32`, `datetime[ms]`.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FieldSpec {
    pub name: String,
    pub dtype: String,
    #[serde(default)]
    pub nullable: bool,
}

impl FieldSpec {
    pub fn new(name: impl Into<String>, dtype: impl Into<String>) -> Self {
        Self { name: name.into(), dtype: dtype.into(), nullable: false }
    }

    pub fn nullable(mut self, nullable: bool) -> Self {
        self.nullable = nullable;
        self
    }
}