extern crate libc;
use std::error::Error as StdError;
use std::fmt::{Display, Result as FmtResult, Formatter};
pub mod sys {
extern crate libc;
#[repr(C)]
pub struct virError {
pub code: libc::c_int,
pub domain: libc::c_int,
pub message: *mut libc::c_char,
pub level: libc::c_uint,
}
pub type virErrorPtr = *mut virError;
}
#[link(name = "virt")]
extern "C" {
fn virGetLastError() -> sys::virErrorPtr;
}
#[derive(Debug, PartialEq)]
#[repr(C)]
pub enum ErrorLevel {
NONE = 0,
WARNING = 1,
ERROR = 2,
}
impl_from! { u32, ErrorLevel }
#[derive(Debug, PartialEq)]
pub struct Error {
pub code: i32,
pub domain: i32,
pub message: String,
pub level: ErrorLevel,
}
impl Error {
pub fn new() -> Error {
unsafe {
let ptr: sys::virErrorPtr = virGetLastError();
Error {
code: (*ptr).code,
domain: (*ptr).domain,
message: c_chars_to_string!((*ptr).message, nofree),
level: ErrorLevel::from((*ptr).level),
}
}
}
}
impl StdError for Error {
fn description(&self) -> &str {
self.message.as_str()
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f,
"{:?}: code: {} domain: {} - {}",
self.level,
self.code,
self.domain,
self.message)
}
}