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}