vips/
error.rs

1//! Unify error types and libvips error capture
2//! ! This module defines a unified `Error` enum to represent errors from libvips operations,
3//! ! along with utility functions to capture and handle libvips error messages.
4//!
5//! ! # Example
6//! ! ```no_run
7//! ! use vips::error::{Error, Result, take_vips_error, code_to_result};
8//! !
9//! ! fn example() -> Result<()> {
10//! !     let code = 0 // hypothetical
11//! !     code_to_result(code)
12//! ! }
13//! ! ```
14//!
15
16use std::ffi::CStr;
17
18/// A specialized `Result` type for libvips operations
19///
20/// # Example
21/// ```no_run
22/// use vips::{Error, Result};
23///
24/// fn example() -> Result<()> {
25///     // some libvips operation
26///     Ok(())
27/// }
28/// ```
29pub type Result<T> = std::result::Result<T, Error>;
30
31#[derive(Debug)]
32pub enum Error {
33    InitFailed(String),
34    Vips(String),
35    Other(String),
36}
37
38impl std::fmt::Display for Error {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        match self {
41            Error::InitFailed(s) => write!(f, "vips init failed: {}", s),
42            Error::Vips(s) => write!(f, "vips error: {}", s),
43            Error::Other(s) => write!(f, "other error: {}", s),
44        }
45    }
46}
47
48impl std::error::Error for Error {}
49
50impl From<std::io::Error> for Error {
51    fn from(e: std::io::Error) -> Self {
52        Error::Other(e.to_string())
53    }
54}
55
56/// Read and empty the error buffer of libvips
57///
58/// # Returns
59/// An `Option<String>` containing the error message if there was an error, or `None` if there was no error.
60///
61pub fn take_vips_error() -> Option<String> {
62    unsafe {
63        let ptr = vips_sys::vips_error_buffer();
64        if ptr.is_null() {
65            return None;
66        }
67        let msg = CStr::from_ptr(ptr).to_string_lossy().into_owned();
68        vips_sys::vips_error_clear();
69        if msg.trim().is_empty() {
70            None
71        } else {
72            Some(msg)
73        }
74    }
75}
76
77/// Convert the return code (0=OK, non-0=ERR) convention in libvips to Result
78///
79/// # Arguments
80/// * `code` - The return code from a libvips function
81///
82/// # Returns
83/// A `Result<()>` which is `Ok(())` if the code is 0, or `Err(Error::Vips)` with the error message otherwise.
84///
85/// # Example
86/// ```no_run
87/// use vips::*;
88///
89/// fn example() -> Result<()> {
90///     let code = 1; // hypothetical
91///     code_to_result(code)
92/// }
93/// ```
94pub fn code_to_result(code: i32) -> Result<()> {
95    if code == 0 {
96        Ok(())
97    } else {
98        let msg = take_vips_error().unwrap_or_else(|| "Unknown error from libvips".to_string());
99        Err(Error::Vips(msg))
100    }
101}