ultrahdr/
error.rs

1use crate::sys;
2use std::error::Error as StdError;
3use std::ffi::CStr;
4use std::fmt;
5
6/// Error produced by the safe wrappers around `libultrahdr`.
7#[derive(Debug, Clone)]
8pub struct Error {
9    /// Error code returned by `libultrahdr`.
10    pub code: sys::uhdr_codec_err_t,
11    /// Optional human-readable detail string when provided by the library.
12    pub detail: Option<String>,
13}
14
15/// Result alias used throughout the crate.
16pub type Result<T> = std::result::Result<T, Error>;
17
18impl Error {
19    pub(crate) fn alloc() -> Self {
20        Self {
21            code: sys::uhdr_codec_err_t::UHDR_CODEC_MEM_ERROR,
22            detail: Some("allocation failed".to_string()),
23        }
24    }
25
26    pub(crate) fn invalid_param(msg: impl Into<String>) -> Self {
27        Self {
28            code: sys::uhdr_codec_err_t::UHDR_CODEC_INVALID_PARAM,
29            detail: Some(msg.into()),
30        }
31    }
32}
33
34impl fmt::Display for Error {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        if let Some(detail) = &self.detail {
37            write!(f, "{:?}: {}", self.code, detail)
38        } else {
39            write!(f, "{:?}", self.code)
40        }
41    }
42}
43
44impl StdError for Error {}
45
46pub(crate) fn check(info: sys::uhdr_error_info_t) -> Result<()> {
47    if info.error_code == sys::uhdr_codec_err_t::UHDR_CODEC_OK {
48        return Ok(());
49    }
50    let detail = if info.has_detail != 0 && info.detail[0] != 0 {
51        // SAFETY: detail is a char buffer owned by the struct and expected to be null-terminated.
52        let s = unsafe { CStr::from_ptr(info.detail.as_ptr()) }
53            .to_string_lossy()
54            .into_owned();
55        if s.is_empty() { None } else { Some(s) }
56    } else {
57        None
58    };
59    Err(Error {
60        code: info.error_code,
61        detail,
62    })
63}