latent-inspector 0.1.0

Fast CLI for inspecting and comparing learned representations across self-supervised vision models
Documentation
use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
    #[error("Model error: {0}")]
    Model(#[from] ModelError),

    #[error("Analysis error: {0}")]
    Analysis(#[from] AnalysisError),

    #[error("Visualization error: {0}")]
    Viz(#[from] VizError),

    #[error("Dataset error: {0}")]
    Dataset(#[from] DatasetError),

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    #[error("Image error: {0}")]
    Image(#[from] image::ImageError),

    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),

    #[error("HTTP error: {0}")]
    Http(#[from] reqwest::Error),

    #[error("Validation error: {0}")]
    Validation(#[from] ValidationError),
}

impl Error {
    pub fn exit_code(&self) -> i32 {
        match self {
            Error::Validation(ValidationError::Usage(_))
            | Error::Validation(ValidationError::MissingFixtures(_)) => 2,
            _ => 1,
        }
    }

    pub fn should_print(&self) -> bool {
        !matches!(
            self,
            Error::Validation(ValidationError::FailedValidation { .. })
        )
    }
}

#[derive(Error, Debug)]
pub enum ModelError {
    #[error("Model not found in registry: {0}")]
    NotFound(String),

    #[error("Model '{name}' is not available in the current implementation: {reason}")]
    Unavailable { name: String, reason: String },

    #[error("Model download failed for '{name}': {reason}")]
    DownloadFailed { name: String, reason: String },

    #[error("Model '{0}' is missing download metadata")]
    MissingDownloadMetadata(String),

    #[error("Model artifact path is invalid for '{name}': {path} ({reason})")]
    InvalidArtifactPath {
        name: String,
        path: String,
        reason: String,
    },

    #[error("Hash verification failed for '{name}': expected {expected}, got {actual}")]
    VerificationFailed {
        name: String,
        expected: String,
        actual: String,
    },

    #[error(
        "Model graph for '{name}' is missing expected {kind} '{expected}'. Available {kind}s: {available:?}"
    )]
    GraphMismatch {
        name: String,
        kind: String,
        expected: String,
        available: Vec<String>,
    },

    #[error("ONNX inference error: {0}")]
    InferenceFailed(String),

    #[error("Session creation failed: {0}")]
    SessionCreation(String),

    #[error("Preprocessing error: {0}")]
    Preprocessing(String),

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
}

#[derive(Error, Debug)]
pub enum AnalysisError {
    #[error("Insufficient data: {0}")]
    InsufficientData(String),

    #[error("Shape mismatch: expected {expected:?}, got {actual:?}")]
    ShapeMismatch {
        expected: Vec<usize>,
        actual: Vec<usize>,
    },

    #[error("Convergence failed after {iterations} iterations: {reason}")]
    ConvergenceFailed { iterations: usize, reason: String },

    #[error("Empty input: {0}")]
    EmptyInput(String),

    #[error("Non-finite numeric values detected: {context}")]
    NonFiniteValues { context: String },

    #[error("Patch count {patch_count} does not form a square patch grid for {context}")]
    InvalidPatchGrid { context: String, patch_count: usize },
}

#[derive(Error, Debug)]
pub enum VizError {
    #[error("Terminal render error: {0}")]
    Terminal(String),

    #[error("PNG export error: {0}")]
    Png(String),

    #[error("HTML generation error: {0}")]
    Html(String),

    #[error("JSON serialization error: {0}")]
    Json(String),

    #[error("Artifact manifest error: {0}")]
    Artifact(String),
}

#[derive(Error, Debug)]
pub enum DatasetError {
    #[error("Dataset directory not found: {0}")]
    DirectoryNotFound(String),

    #[error("No images found in: {0}")]
    NoImages(String),

    #[error("No usable images could be processed from: {0}")]
    NoUsableImages(String),

    #[error("Image load error for '{path}': {reason}")]
    ImageLoad { path: String, reason: String },

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
}

#[derive(Error, Debug)]
pub enum ValidationError {
    #[error("Usage error: {0}")]
    Usage(String),

    #[error("Validation fixtures are missing or invalid: {0}")]
    MissingFixtures(String),

    #[error("Validation contract mismatch for '{model}': {reason}")]
    ContractMismatch { model: String, reason: String },

    #[error("Validation failed for '{model}': {reason}")]
    FailedValidation { model: String, reason: String },

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),
}