readsight 1.0.2

Multilingual readability library — 86 languages, 17 formulas, TeX-based syllable counting via the Frank M. Liang algorithm.
Documentation
//! Error type for the ReadSight engine.

use std::fmt;

/// Errors produced by the ReadSight engine.
///
/// Mirrors the PHP `ReadabilityEngineException` hierarchy as a single enum.
#[derive(Debug)]
pub enum Error {
    /// The requested language code has no data file.
    UnsupportedLanguage(String),
    /// The requested formula is not supported for the given language.
    UnsupportedFormula {
        /// Formula name.
        formula: String,
        /// Language code.
        language: String,
    },
    /// `analyze` (and formulas that depend on it) was called with empty text.
    EmptyText,
    /// A `.tex` pattern file could not be found.
    PatternFileNotFound(String),
    /// A pattern token failed to parse.
    PatternParse {
        /// The offending token.
        token: String,
        /// Line number within the file.
        line: usize,
        /// File name.
        file: String,
    },
    /// An invalid Wiener Sachtextformel variant (must be 1..=4) was requested.
    InvalidVariant(i32),
    /// A language regex pattern failed to compile.
    InvalidPattern(String),
    /// Underlying I/O error.
    Io(std::io::Error),
    /// JSON (de)serialization error.
    Json(serde_json::Error),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::UnsupportedLanguage(code) => {
                write!(f, "Language \"{code}\" is not supported.")
            }
            Error::UnsupportedFormula { formula, language } => write!(
                f,
                "Formula \"{formula}\" is not supported for language \"{language}\"."
            ),
            Error::EmptyText => write!(f, "Text cannot be empty."),
            Error::PatternFileNotFound(path) => {
                write!(f, "Pattern file \"{path}\" was not found.")
            }
            Error::PatternParse { token, line, file } => write!(
                f,
                "Failed to parse pattern token \"{token}\" at line {line} in file \"{file}\"."
            ),
            Error::InvalidVariant(v) => {
                write!(f, "Wiener Sachtextformel variant must be 1-4, got {v}.")
            }
            Error::InvalidPattern(p) => write!(f, "Invalid language pattern: {p}"),
            Error::Io(e) => write!(f, "I/O error: {e}"),
            Error::Json(e) => write!(f, "JSON error: {e}"),
        }
    }
}

impl std::error::Error for Error {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Error::Io(e) => Some(e),
            Error::Json(e) => Some(e),
            _ => None,
        }
    }
}

impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Self {
        Error::Io(e)
    }
}

impl From<serde_json::Error> for Error {
    fn from(e: serde_json::Error) -> Self {
        Error::Json(e)
    }
}

/// Convenience alias for `Result<T, readsight::Error>`.
pub type Result<T> = std::result::Result<T, Error>;