weavatrix-clone 0.1.4

Evidence-first Type-1/2/3 code clone engine with deterministic families and bounded near-miss verification
Documentation
use std::{error::Error, fmt};

pub type Result<T> = std::result::Result<T, CloneError>;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CloneError {
    InvalidConfig {
        field: &'static str,
        reason: &'static str,
    },
    InvalidFragment {
        id: String,
        reason: &'static str,
    },
    DuplicateFragment(String),
    CapacityExceeded {
        resource: &'static str,
        limit: usize,
    },
    InvalidOutput(String),
    AccuracyGate {
        metric: &'static str,
        actual: u16,
        required: u16,
    },
    Repository(String),
}

impl fmt::Display for CloneError {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::InvalidConfig { field, reason } => {
                write!(formatter, "invalid clone config {field}: {reason}")
            }
            Self::InvalidFragment { id, reason } => {
                write!(formatter, "invalid fragment {id}: {reason}")
            }
            Self::DuplicateFragment(id) => write!(formatter, "duplicate fragment id: {id}"),
            Self::CapacityExceeded { resource, limit } => {
                write!(formatter, "{resource} exceeds configured limit {limit}")
            }
            Self::InvalidOutput(message) => write!(formatter, "invalid output: {message}"),
            Self::AccuracyGate {
                metric,
                actual,
                required,
            } => write!(
                formatter,
                "accuracy gate failed for {metric}: {actual} permille is below {required}"
            ),
            Self::Repository(message) => write!(formatter, "repository scan failed: {message}"),
        }
    }
}

impl Error for CloneError {}

#[cfg(test)]
mod tests {
    use crate::error::CloneError;

    #[test]
    fn formats_every_error_variant() {
        let errors = [
            CloneError::InvalidConfig {
                field: "limit",
                reason: "zero",
            },
            CloneError::InvalidFragment {
                id: "fragment".to_owned(),
                reason: "empty",
            },
            CloneError::DuplicateFragment("fragment".to_owned()),
            CloneError::CapacityExceeded {
                resource: "tokens",
                limit: 1,
            },
            CloneError::InvalidOutput("path".to_owned()),
            CloneError::AccuracyGate {
                metric: "recall",
                actual: 800,
                required: 900,
            },
            CloneError::Repository("incomplete".to_owned()),
        ];
        for error in errors {
            assert!(!error.to_string().is_empty());
            let as_error: &dyn std::error::Error = &error;
            assert!(as_error.source().is_none());
        }
    }
}