use std::ffi::{CStr, NulError};
use std::fmt;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
Auth(String),
Network(String),
Invalid(String),
Video(String),
Ffi(String),
InteriorNul,
InvalidUtf8,
Timeout,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Auth(m)
| Error::Network(m)
| Error::Invalid(m)
| Error::Video(m)
| Error::Ffi(m) => write!(f, "adamo: {m}"),
Error::InteriorNul => f.write_str("adamo: string contained an interior NUL byte"),
Error::InvalidUtf8 => f.write_str("adamo: FFI returned non-UTF-8 data"),
Error::Timeout => f.write_str("adamo: receive timed out"),
}
}
}
impl std::error::Error for Error {}
impl From<NulError> for Error {
fn from(_: NulError) -> Self {
Error::InteriorNul
}
}
pub(crate) fn last_ffi_error() -> Error {
let (msg, code) = unsafe {
let ptr = adamo_sys::adamo_last_error();
if ptr.is_null() {
return Error::Ffi("(no error message)".into());
}
match CStr::from_ptr(ptr).to_str() {
Ok(s) => (s.to_owned(), adamo_sys::adamo_last_error_code()),
Err(_) => return Error::InvalidUtf8,
}
};
match code {
1 => Error::Auth(msg),
2 => Error::Network(msg),
3 => Error::Timeout,
4 => Error::Invalid(msg),
5 => Error::Video(msg),
_ => Error::Ffi(msg),
}
}