llama-cpp-error-recorder 0.11.0

Captures errors raised inside FFI callbacks (which cannot unwind or return Result) for retrieval by the Rust code that drove the call
Documentation
use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FmtResult;

#[derive(Debug)]
pub struct RecordedError {
    inner: Box<dyn Error + Send + Sync>,
}

impl RecordedError {
    pub fn new(error: impl Into<Box<dyn Error + Send + Sync>>) -> Self {
        Self {
            inner: error.into(),
        }
    }

    #[must_use]
    pub fn message(&self) -> String {
        self.inner.to_string()
    }

    #[must_use]
    pub fn into_message(self) -> String {
        self.inner.to_string()
    }
}

impl Display for RecordedError {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
        Display::fmt(&self.inner, formatter)
    }
}

impl Error for RecordedError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        Some(self.inner.as_ref())
    }
}

#[cfg(test)]
mod tests {
    use std::error::Error;

    use super::RecordedError;

    #[test]
    fn message_returns_the_underlying_display() {
        let error = RecordedError::new("compute mask failed".to_string());

        assert_eq!(error.message(), "compute mask failed");
    }

    #[test]
    fn into_message_consumes_and_returns_the_display() {
        let error = RecordedError::new("reset failed".to_string());

        assert_eq!(error.into_message(), "reset failed");
    }

    #[test]
    fn display_formats_the_underlying_error() {
        let error = RecordedError::new("consume failed".to_string());

        assert_eq!(format!("{error}"), "consume failed");
    }

    #[test]
    fn source_exposes_the_underlying_error() {
        let error = RecordedError::new("inner boom".to_string());

        assert!(
            error
                .source()
                .is_some_and(|source| source.to_string() == "inner boom"),
            "a recorded error must expose its underlying error as the source"
        );
    }
}