Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/nornir-wire/src/view/rows.rs

//! **Warehouse-row** view-model DTOs that cross the wire — the exact rows the
//! server ships to a thin viz client (serialize → JSON → deserialize), so the
//! remote 🧬 nornir pane renders the identical data the embedded (warehouse) path
//! reads. Plain serde, relocated from their nornir home; `nornir` re-exports each
//! from its original path so the Arrow encode/decode (free functions over the
//! public fields) and the panes compile unchanged.

/// One row of the `workspace ls` roster — the projection BOTH the fat (registry
/// `Workspace`) and thin (proto) faces map into, so they render identically
/// (CLI⟺UI parity, the Nornir-tab roster's data). AUT9. Relocated from
/// `nornir/src/registry.rs`; `nornir::registry` re-exports it.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct RosterRow {
    pub name: String,
    pub mode: String,
    pub members: usize,
    pub last_synced: String,
    /// PO1 — the rolled-up POPULATE verdict for this workspace (latest clone/fetch
    /// outcome per member → a workspace state). `"green"` (all members' latest ok),
    /// `"red"` (≥1 member's latest is an error), `"stale"` (never populated — no
    /// clone_events), or `""` when the populate roll-up wasn't requested
    /// (`workspace ls` without `--status`). The roster's red/green badge.
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub populate: String,
    /// The first failing member (when `populate == "red"`), else empty.
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub failing_member: String,
    /// That member's latest error detail (when `populate == "red"`), else empty.
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub last_error: String,
}

/// One row of the `clone_events` table — a single member's clone/fetch (or the
/// workspace republish) outcome.
///
/// `serde` derives let the server ship the exact rows to a thin viz client over
/// the `Viz.CloneEvents` RPC (serialize → JSON → deserialize), so the remote 🧬
/// nornir pane + `nornir --server workspace events` render the identical populate
/// status the embedded path reads from the warehouse. Relocated from
/// `nornir/src/warehouse/clone_events.rs`; that module re-exports it and keeps the
/// Arrow sink over its public fields.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct CloneEventRow {
    /// Event time, microseconds since the Unix epoch (UTC).
    pub ts_micros: i64,
    /// The workspace this fetch belonged to.
    pub workspace: String,
    /// The member that was fetched (or `*` for a workspace-level `republish`).
    pub member: String,
    /// The git remote that was cloned/fetched (empty for a republish row).
    pub remote: String,
    /// `clone-fetch` | `republish`.
    pub op: String,
    /// `ok` | `error`.
    pub status: String,
    /// On error: the error chain (`{e:#}`). On ok: the resolved SHA (clone-fetch)
    /// or the snapshot id (republish). Stored as "" never null so SQL readers see
    /// no surprise nulls.
    pub detail: String,
    /// Wall-clock duration of the op, milliseconds.
    pub elapsed_ms: i64,
}