use libc::size_t; /// A more detailed error object returned by some hyper functions. pub struct hyper_error(crate::Error); /// A return code for many of hyper's methods. #[repr(C)] pub enum hyper_code { /// All is well. HYPERE_OK, /// General error, details in the `hyper_error *`. HYPERE_ERROR, /// A function argument was invalid. HYPERE_INVALID_ARG, /// The IO transport returned an EOF when one wasn't expected. /// /// This typically means an HTTP request or response was expected, but the /// connection closed cleanly without sending (all of) it. HYPERE_UNEXPECTED_EOF, /// Aborted by a user supplied callback. HYPERE_ABORTED_BY_CALLBACK, /// An optional hyper feature was not enabled. #[cfg_attr(feature = "http2", allow(unused))] HYPERE_FEATURE_NOT_ENABLED, /// The peer sent an HTTP message that could not be parsed. HYPERE_INVALID_PEER_MESSAGE, } // ===== impl hyper_error ===== impl hyper_error { fn code(&self) -> hyper_code { use crate::error::Kind as ErrorKind; use crate::error::User; match self.0.kind() { ErrorKind::Parse(_) => hyper_code::HYPERE_INVALID_PEER_MESSAGE, ErrorKind::IncompleteMessage => hyper_code::HYPERE_UNEXPECTED_EOF, ErrorKind::User(User::AbortedByCallback) => hyper_code::HYPERE_ABORTED_BY_CALLBACK, // TODO: add more variants _ => hyper_code::HYPERE_ERROR, } } fn print_to(&self, dst: &mut [u8]) -> usize { use std::io::Write; let mut dst = std::io::Cursor::new(dst); // A write! error doesn't matter. As much as possible will have been // written, and the Cursor position will know how far that is (even // if that is zero). let _ = write!(dst, "{}", &self.0); dst.position() as usize } } ffi_fn! { /// Frees a `hyper_error`. fn hyper_error_free(err: *mut hyper_error) { drop(non_null!(Box::from_raw(err) ?= ())); } } ffi_fn! { /// Get an equivalent `hyper_code` from this error. fn hyper_error_code(err: *const hyper_error) -> hyper_code { non_null!(&*err ?= hyper_code::HYPERE_INVALID_ARG).code() } } ffi_fn! { /// Print the details of this error to a buffer. /// /// The `dst_len` value must be the maximum length that the buffer can /// store. /// /// The return value is number of bytes that were written to `dst`. fn hyper_error_print(err: *const hyper_error, dst: *mut u8, dst_len: size_t) -> size_t { let dst = unsafe { std::slice::from_raw_parts_mut(dst, dst_len) }; non_null!(&*err ?= 0).print_to(dst) } }