onelib 0.1.0

Rust implementation of the ONEcode file format
Documentation
use std::path::PathBuf;

use thiserror::Error;

/// Crate-level result type alias.
pub type Result<T> = std::result::Result<T, OneError>;

/// Errors returned by the onecode library.
#[derive(Error, Debug)]
pub enum OneError {
    #[error("I/O error on {path}")]
    Io {
        path: PathBuf,
        #[source]
        source: std::io::Error,
    },

    #[error("parse error on line {line}: {message}")]
    Parse { line: i64, message: String },

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

    #[error("version mismatch: file {file_major}.{file_minor}, library {lib_major}.{lib_minor}")]
    Version {
        file_major: i32,
        file_minor: i32,
        lib_major: i32,
        lib_minor: i32,
    },

    #[error("{operation} requires a binary file with an index")]
    NotBinary { operation: String },

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

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

/// Extension trait for attaching path context to [`std::io::Result`].
pub trait IoResultExt<T> {
    /// Attach a file path to an I/O error, converting it to [`OneError::Io`].
    fn with_path(self, path: impl Into<PathBuf>) -> Result<T>;
}

impl<T> IoResultExt<T> for std::io::Result<T> {
    fn with_path(self, path: impl Into<PathBuf>) -> Result<T> {
        self.map_err(|source| OneError::Io {
            path: path.into(),
            source,
        })
    }
}