verit-core 0.2.0

Internal: portable core engine for Exavian Veritate. Not a public API — depend on `verit`.
Documentation
//! Dynamic values for the write path. The prototype has no codegen; you build
//! a `Value` tree against a runtime [`crate::Schema`] and encode it. A struct
//! value lists (field id, value) pairs — omitted fields are absent (their
//! presence bit stays 0 and readers see `None`).

#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    Bool(bool),
    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    F32(f32),
    F64(f64),
    Str(String),
    Bytes(Vec<u8>),
    /// Raw enum value; enums are open, so this need not name a known variant.
    Enum(u32),
    List(Vec<Value>),
    /// (field id, value) pairs. Order does not matter; duplicate ids are an
    /// encode-time error.
    Struct(Vec<(u16, Value)>),
    /// (key, value) entries. Order does not matter — the encoder sorts entries
    /// by key into canonical order; duplicate keys are an encode-time error.
    Map(Vec<(Value, Value)>),
    /// A list of scalars in native form — the bulk-write peer of
    /// [`Scalars`]. Encodes byte-identically to the equivalent
    /// [`Value::List`], without allocating a `Value` per element.
    Scalars(Scalars),
    /// A `union` value: the variant tag (index into the schema's variant list)
    /// and that variant's value.
    Union(u32, Box<Value>),
}

impl Value {
    pub fn str(s: &str) -> Value {
        Value::Str(s.to_string())
    }

    /// A `list<f32>` from a slice, without building a `Value` per element —
    /// the shape an embedding vector wants.
    pub fn f32_list(xs: &[f32]) -> Value {
        Value::Scalars(Scalars::F32(xs.to_vec()))
    }

    /// A `list<f64>` from a slice.
    pub fn f64_list(xs: &[f64]) -> Value {
        Value::Scalars(Scalars::F64(xs.to_vec()))
    }

    pub fn kind(&self) -> &'static str {
        match self {
            Value::Bool(_) => "bool",
            Value::U8(_) => "u8",
            Value::U16(_) => "u16",
            Value::U32(_) => "u32",
            Value::U64(_) => "u64",
            Value::I8(_) => "i8",
            Value::I16(_) => "i16",
            Value::I32(_) => "i32",
            Value::I64(_) => "i64",
            Value::F32(_) => "f32",
            Value::F64(_) => "f64",
            Value::Str(_) => "string",
            Value::Bytes(_) => "bytes",
            Value::Enum(_) => "enum",
            Value::List(_) => "list",
            Value::Struct(_) => "struct",
            Value::Map(_) => "map",
            Value::Scalars(s) => s.kind(),
            Value::Union(..) => "union",
        }
    }
}

/// A run of scalars held in its native Rust form.
///
/// Building a `list<f32>` of 1,536 elements as [`Value::List`] allocates 1,536
/// `Value` enums before a single byte is written — fine for a one-off
/// conversion, wrong for a hot write path. This carries the values as they
/// already are, and the encoder writes the whole run in one pass.
///
/// The output is **byte-identical** to the equivalent `Value::List`, so this is
/// purely a cost choice and never a wire-format one.
#[derive(Clone, Debug, PartialEq)]
pub enum Scalars {
    Bool(Vec<bool>),
    U8(Vec<u8>),
    U16(Vec<u16>),
    U32(Vec<u32>),
    U64(Vec<u64>),
    I8(Vec<i8>),
    I16(Vec<i16>),
    I32(Vec<i32>),
    I64(Vec<i64>),
    F32(Vec<f32>),
    F64(Vec<f64>),
}

impl Scalars {
    pub fn len(&self) -> usize {
        match self {
            Scalars::Bool(v) => v.len(),
            Scalars::U8(v) => v.len(),
            Scalars::U16(v) => v.len(),
            Scalars::U32(v) => v.len(),
            Scalars::U64(v) => v.len(),
            Scalars::I8(v) => v.len(),
            Scalars::I16(v) => v.len(),
            Scalars::I32(v) => v.len(),
            Scalars::I64(v) => v.len(),
            Scalars::F32(v) => v.len(),
            Scalars::F64(v) => v.len(),
        }
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn kind(&self) -> &'static str {
        match self {
            Scalars::Bool(_) => "list<bool>",
            Scalars::U8(_) => "list<u8>",
            Scalars::U16(_) => "list<u16>",
            Scalars::U32(_) => "list<u32>",
            Scalars::U64(_) => "list<u64>",
            Scalars::I8(_) => "list<i8>",
            Scalars::I16(_) => "list<i16>",
            Scalars::I32(_) => "list<i32>",
            Scalars::I64(_) => "list<i64>",
            Scalars::F32(_) => "list<f32>",
            Scalars::F64(_) => "list<f64>",
        }
    }
}