supercode-interchange 0.4.17

Canonical, provider-neutral session interchange primitives for Supercode
Documentation
//! The codec contract both pieces obey (`docs/ONTOLOGY.md` ยง2.5): every
//! artifact a codec reads or writes names the [`Fidelity`] it reached and,
//! only at [`Fidelity::Semantic`], the loss it accepted. The session half is
//! the [`crate::Session`] loaders and writers; the world half implements
//! [`WorldCodec`].

use std::path::Path;

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::{Fidelity, Result};

/// What one artifact reached on the way in or out.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ArtifactFidelity {
    /// Path relative to the home the codec read or wrote.
    pub path: String,
    /// The tier reached.
    pub fidelity: Fidelity,
    /// Named loss; non-empty only when `fidelity` tolerates residue.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub loss: Vec<String>,
}

impl ArtifactFidelity {
    /// An artifact reproduced or reused byte for byte.
    pub fn byte(path: impl Into<String>) -> Self {
        Self {
            path: path.into(),
            fidelity: Fidelity::ByteLossless,
            loss: Vec::new(),
        }
    }

    /// Every value survived; the container was re-synthesized.
    pub fn value(path: impl Into<String>) -> Self {
        Self {
            path: path.into(),
            fidelity: Fidelity::ValueLossless,
            loss: Vec::new(),
        }
    }

    /// Meaning survived; `loss` says what did not.
    pub fn semantic(path: impl Into<String>, loss: Vec<String>) -> Self {
        Self {
            path: path.into(),
            fidelity: Fidelity::Semantic,
            loss,
        }
    }
}

/// A harness's operational home compiled into a world value and back.
pub trait WorldCodec<W> {
    /// Read a home into the world value, naming what each artifact reached.
    fn compile(&self, home: &Path) -> Result<(W, Vec<ArtifactFidelity>)>;
    /// Write the world value as this harness's home, naming what each artifact
    /// reached; a write that would have to guess is an error naming its gate.
    fn decompile(&self, world: &W, dest: &Path) -> Result<Vec<ArtifactFidelity>>;
}