use std::error;
use std::ffi::{self, CStr};
use std::fmt;
use std::str;
use std::io;
use curl_sys;
#[derive(Clone, PartialEq)]
pub struct Error {
code: curl_sys::CURLcode,
extra: Option<Box<str>>,
}
pub fn error_with_extra(code: curl_sys::CURLcode, extra: Box<str>) -> Error {
Error {
code: code,
extra: Some(extra),
}
}
impl Error {
pub fn new(code: curl_sys::CURLcode) -> Error {
Error {
code: code,
extra: None,
}
}
pub fn is_unsupported_protocol(&self) -> bool {
self.code == curl_sys::CURLE_UNSUPPORTED_PROTOCOL
}
pub fn is_failed_init(&self) -> bool {
self.code == curl_sys::CURLE_FAILED_INIT
}
pub fn is_url_malformed(&self) -> bool {
self.code == curl_sys::CURLE_URL_MALFORMAT
}
pub fn is_couldnt_resolve_proxy(&self) -> bool {
self.code == curl_sys::CURLE_COULDNT_RESOLVE_PROXY
}
pub fn is_couldnt_resolve_host(&self) -> bool {
self.code == curl_sys::CURLE_COULDNT_RESOLVE_HOST
}
pub fn is_couldnt_connect(&self) -> bool {
self.code == curl_sys::CURLE_COULDNT_CONNECT
}
pub fn is_remote_access_denied(&self) -> bool {
self.code == curl_sys::CURLE_REMOTE_ACCESS_DENIED
}
pub fn is_partial_file(&self) -> bool {
self.code == curl_sys::CURLE_PARTIAL_FILE
}
pub fn is_quote_error(&self) -> bool {
self.code == curl_sys::CURLE_QUOTE_ERROR
}
pub fn is_http_returned_error(&self) -> bool {
self.code == curl_sys::CURLE_HTTP_RETURNED_ERROR
}
pub fn is_read_error(&self) -> bool {
self.code == curl_sys::CURLE_READ_ERROR
}
pub fn is_write_error(&self) -> bool {
self.code == curl_sys::CURLE_WRITE_ERROR
}
pub fn is_upload_failed(&self) -> bool {
self.code == curl_sys::CURLE_UPLOAD_FAILED
}
pub fn is_out_of_memory(&self) -> bool {
self.code == curl_sys::CURLE_OUT_OF_MEMORY
}
pub fn is_operation_timedout(&self) -> bool {
self.code == curl_sys::CURLE_OPERATION_TIMEDOUT
}
pub fn is_range_error(&self) -> bool {
self.code == curl_sys::CURLE_RANGE_ERROR
}
pub fn is_http_post_error(&self) -> bool {
self.code == curl_sys::CURLE_HTTP_POST_ERROR
}
pub fn is_ssl_connect_error(&self) -> bool {
self.code == curl_sys::CURLE_SSL_CONNECT_ERROR
}
pub fn is_bad_download_resume(&self) -> bool {
self.code == curl_sys::CURLE_BAD_DOWNLOAD_RESUME
}
pub fn is_file_couldnt_read_file(&self) -> bool {
self.code == curl_sys::CURLE_FILE_COULDNT_READ_FILE
}
pub fn is_function_not_found(&self) -> bool {
self.code == curl_sys::CURLE_FUNCTION_NOT_FOUND
}
pub fn is_aborted_by_callback(&self) -> bool {
self.code == curl_sys::CURLE_ABORTED_BY_CALLBACK
}
pub fn is_bad_function_argument(&self) -> bool {
self.code == curl_sys::CURLE_BAD_FUNCTION_ARGUMENT
}
pub fn is_interface_failed(&self) -> bool {
self.code == curl_sys::CURLE_INTERFACE_FAILED
}
pub fn is_too_many_redirects(&self) -> bool {
self.code == curl_sys::CURLE_TOO_MANY_REDIRECTS
}
pub fn is_unknown_option(&self) -> bool {
self.code == curl_sys::CURLE_UNKNOWN_OPTION
}
pub fn is_peer_failed_verification(&self) -> bool {
self.code == curl_sys::CURLE_PEER_FAILED_VERIFICATION
}
pub fn is_got_nothing(&self) -> bool {
self.code == curl_sys::CURLE_GOT_NOTHING
}
pub fn is_ssl_engine_notfound(&self) -> bool {
self.code == curl_sys::CURLE_SSL_ENGINE_NOTFOUND
}
pub fn is_ssl_engine_setfailed(&self) -> bool {
self.code == curl_sys::CURLE_SSL_ENGINE_SETFAILED
}
pub fn is_send_error(&self) -> bool {
self.code == curl_sys::CURLE_SEND_ERROR
}
pub fn is_recv_error(&self) -> bool {
self.code == curl_sys::CURLE_RECV_ERROR
}
pub fn is_ssl_certproblem(&self) -> bool {
self.code == curl_sys::CURLE_SSL_CERTPROBLEM
}
pub fn is_ssl_cipher(&self) -> bool {
self.code == curl_sys::CURLE_SSL_CIPHER
}
pub fn is_ssl_cacert(&self) -> bool {
self.code == curl_sys::CURLE_SSL_CACERT
}
pub fn is_bad_content_encoding(&self) -> bool {
self.code == curl_sys::CURLE_BAD_CONTENT_ENCODING
}
pub fn is_filesize_exceeded(&self) -> bool {
self.code == curl_sys::CURLE_FILESIZE_EXCEEDED
}
pub fn is_use_ssl_failed(&self) -> bool {
self.code == curl_sys::CURLE_USE_SSL_FAILED
}
pub fn is_send_fail_rewind(&self) -> bool {
self.code == curl_sys::CURLE_SEND_FAIL_REWIND
}
pub fn is_ssl_engine_initfailed(&self) -> bool {
self.code == curl_sys::CURLE_SSL_ENGINE_INITFAILED
}
pub fn is_login_denied(&self) -> bool {
self.code == curl_sys::CURLE_LOGIN_DENIED
}
pub fn is_conv_failed(&self) -> bool {
self.code == curl_sys::CURLE_CONV_FAILED
}
pub fn is_conv_required(&self) -> bool {
self.code == curl_sys::CURLE_CONV_REQD
}
pub fn is_ssl_cacert_badfile(&self) -> bool {
self.code == curl_sys::CURLE_SSL_CACERT_BADFILE
}
pub fn is_ssl_crl_badfile(&self) -> bool {
self.code == curl_sys::CURLE_SSL_CRL_BADFILE
}
pub fn is_ssl_shutdown_failed(&self) -> bool {
self.code == curl_sys::CURLE_SSL_SHUTDOWN_FAILED
}
pub fn is_again(&self) -> bool {
self.code == curl_sys::CURLE_AGAIN
}
pub fn is_ssl_issuer_error(&self) -> bool {
self.code == curl_sys::CURLE_SSL_ISSUER_ERROR
}
pub fn is_chunk_failed(&self) -> bool {
self.code == curl_sys::CURLE_CHUNK_FAILED
}
pub fn code(&self) -> curl_sys::CURLcode {
self.code
}
pub fn extra_description(&self) -> Option<&str> {
self.extra.as_ref().map(|s| &**s)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let desc = error::Error::description(self);
match self.extra {
Some(ref s) => write!(f, "[{}] {} ({})", self.code(), desc, s),
None => write!(f, "[{}] {}", self.code(), desc),
}
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Error")
.field("description", &error::Error::description(self))
.field("code", &self.code)
.field("extra", &self.extra)
.finish()
}
}
impl error::Error for Error {
fn description(&self) -> &str {
unsafe {
let s = curl_sys::curl_easy_strerror(self.code);
assert!(!s.is_null());
str::from_utf8(CStr::from_ptr(s).to_bytes()).unwrap()
}
}
}
#[derive(Clone, PartialEq)]
pub struct ShareError {
code: curl_sys::CURLSHcode,
}
impl ShareError {
pub fn new(code: curl_sys::CURLSHcode) -> ShareError {
ShareError { code: code }
}
pub fn is_bad_option(&self) -> bool {
self.code == curl_sys::CURLSHE_BAD_OPTION
}
pub fn is_in_use(&self) -> bool {
self.code == curl_sys::CURLSHE_IN_USE
}
pub fn is_invalid(&self) -> bool {
self.code == curl_sys::CURLSHE_INVALID
}
pub fn is_nomem(&self) -> bool {
self.code == curl_sys::CURLSHE_NOMEM
}
pub fn code(&self) -> curl_sys::CURLSHcode {
self.code
}
}
impl fmt::Display for ShareError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
error::Error::description(self).fmt(f)
}
}
impl fmt::Debug for ShareError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ShareError {{ description: {:?}, code: {} }}",
error::Error::description(self),
self.code)
}
}
impl error::Error for ShareError {
fn description(&self) -> &str {
unsafe {
let s = curl_sys::curl_share_strerror(self.code);
assert!(!s.is_null());
str::from_utf8(CStr::from_ptr(s).to_bytes()).unwrap()
}
}
}
#[derive(Clone, PartialEq)]
pub struct MultiError {
code: curl_sys::CURLMcode,
}
impl MultiError {
pub fn new(code: curl_sys::CURLMcode) -> MultiError {
MultiError { code: code }
}
pub fn is_bad_handle(&self) -> bool {
self.code == curl_sys::CURLM_BAD_HANDLE
}
pub fn is_bad_easy_handle(&self) -> bool {
self.code == curl_sys::CURLM_BAD_EASY_HANDLE
}
pub fn is_out_of_memory(&self) -> bool {
self.code == curl_sys::CURLM_OUT_OF_MEMORY
}
pub fn is_internal_error(&self) -> bool {
self.code == curl_sys::CURLM_INTERNAL_ERROR
}
pub fn is_bad_socket(&self) -> bool {
self.code == curl_sys::CURLM_BAD_SOCKET
}
pub fn is_unknown_option(&self) -> bool {
self.code == curl_sys::CURLM_UNKNOWN_OPTION
}
pub fn is_call_perform(&self) -> bool {
self.code == curl_sys::CURLM_CALL_MULTI_PERFORM
}
pub fn code(&self) -> curl_sys::CURLMcode {
self.code
}
}
impl fmt::Display for MultiError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
error::Error::description(self).fmt(f)
}
}
impl fmt::Debug for MultiError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "MultiError {{ description: {:?}, code: {} }}",
error::Error::description(self),
self.code)
}
}
impl error::Error for MultiError {
fn description(&self) -> &str {
unsafe {
let s = curl_sys::curl_multi_strerror(self.code);
assert!(!s.is_null());
str::from_utf8(CStr::from_ptr(s).to_bytes()).unwrap()
}
}
}
#[derive(Clone, PartialEq)]
pub struct FormError {
code: curl_sys::CURLFORMcode,
}
impl FormError {
pub fn new(code: curl_sys::CURLFORMcode) -> FormError {
FormError { code: code }
}
pub fn is_memory(&self) -> bool {
self.code == curl_sys::CURL_FORMADD_MEMORY
}
pub fn is_option_twice(&self) -> bool {
self.code == curl_sys::CURL_FORMADD_OPTION_TWICE
}
pub fn is_null(&self) -> bool {
self.code == curl_sys::CURL_FORMADD_NULL
}
pub fn is_unknown_option(&self) -> bool {
self.code == curl_sys::CURL_FORMADD_UNKNOWN_OPTION
}
pub fn is_incomplete(&self) -> bool {
self.code == curl_sys::CURL_FORMADD_INCOMPLETE
}
pub fn is_illegal_array(&self) -> bool {
self.code == curl_sys::CURL_FORMADD_ILLEGAL_ARRAY
}
pub fn is_disabled(&self) -> bool {
self.code == curl_sys::CURL_FORMADD_DISABLED
}
pub fn code(&self) -> curl_sys::CURLFORMcode {
self.code
}
}
impl fmt::Display for FormError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
error::Error::description(self).fmt(f)
}
}
impl fmt::Debug for FormError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FormError {{ description: {:?}, code: {} }}",
error::Error::description(self),
self.code)
}
}
impl error::Error for FormError {
fn description(&self) -> &str {
match self.code {
curl_sys::CURL_FORMADD_MEMORY => "allocation failure",
curl_sys::CURL_FORMADD_OPTION_TWICE => "one option passed twice",
curl_sys::CURL_FORMADD_NULL => "null pointer given for string",
curl_sys::CURL_FORMADD_UNKNOWN_OPTION => "unknown option",
curl_sys::CURL_FORMADD_INCOMPLETE => "form information not complete",
curl_sys::CURL_FORMADD_ILLEGAL_ARRAY => "illegal array in option",
curl_sys::CURL_FORMADD_DISABLED => {
"libcurl does not have support for this option compiled in"
}
_ => "unknown form error",
}
}
}
impl From<ffi::NulError> for Error {
fn from(_: ffi::NulError) -> Error {
Error { code: curl_sys::CURLE_CONV_FAILED, extra: None }
}
}
impl From<Error> for io::Error {
fn from(e: Error) -> io::Error {
io::Error::new(io::ErrorKind::Other, e)
}
}
impl From<ShareError> for io::Error {
fn from(e: ShareError) -> io::Error {
io::Error::new(io::ErrorKind::Other, e)
}
}
impl From<MultiError> for io::Error {
fn from(e: MultiError) -> io::Error {
io::Error::new(io::ErrorKind::Other, e)
}
}
impl From<FormError> for io::Error {
fn from(e: FormError) -> io::Error {
io::Error::new(io::ErrorKind::Other, e)
}
}