use std::ffi::{self, CStr, NulError};
use thiserror::Error;
#[derive(Error, Debug, PartialEq, Eq)]
pub enum RrdError {
#[error(transparent)]
NulError(#[from] NulError),
#[error("Path encoding error")]
PathEncodingError,
#[error("librrd: \"{0}\"")]
LibRrdError(String),
#[error("Internal error: {0}")]
Internal(String),
#[error("Invalid argument: {0}")]
InvalidArgument(String),
}
pub type RrdResult<T> = Result<T, RrdError>;
#[derive(Debug, PartialEq, Eq, Error)]
#[error("Invalid argument: {0}")]
pub struct InvalidArgument(pub(crate) &'static str);
impl From<InvalidArgument> for RrdError {
fn from(value: InvalidArgument) -> Self {
RrdError::InvalidArgument(value.0.to_string())
}
}
pub(crate) fn return_code_to_result(rc: ffi::c_int) -> RrdResult<()> {
match rc {
0 => Ok(()),
_ => Err(get_rrd_error().unwrap_or_else(|| {
RrdError::Internal("Unknown error - no librrd error info".to_string())
})),
}
}
pub(crate) fn get_rrd_error() -> Option<RrdError> {
unsafe {
let p = rrd_sys::rrd_get_error();
if p.is_null() {
None
} else {
let string = CStr::from_ptr(p).to_string_lossy().into_owned();
rrd_sys::rrd_clear_error();
Some(RrdError::LibRrdError(string))
}
}
}