#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
pub mod cfg;
pub mod cmap;
pub mod cpg;
pub mod quorum;
pub mod votequorum;
mod sys;
use num_enum::TryFromPrimitive;
use std::convert::TryFrom;
use std::error::Error;
use std::ffi::CString;
use std::fmt;
use std::ptr::copy_nonoverlapping;
#[derive(Debug, Eq, PartialEq, Copy, Clone, TryFromPrimitive)]
#[repr(u32)]
pub enum CsError {
CsOk = 1,
CsErrLibrary = 2,
CsErrVersion = 3,
CsErrInit = 4,
CsErrTimeout = 5,
CsErrTryAgain = 6,
CsErrInvalidParam = 7,
CsErrNoMemory = 8,
CsErrBadHandle = 9,
CsErrBusy = 10,
CsErrAccess = 11,
CsErrNotExist = 12,
CsErrNameTooLong = 13,
CsErrExist = 14,
CsErrNoSpace = 15,
CsErrInterrupt = 16,
CsErrNameNotFound = 17,
CsErrNoResources = 18,
CsErrNotSupported = 19,
CsErrBadOperation = 20,
CsErrFailedOperation = 21,
CsErrMessageError = 22,
CsErrQueueFull = 23,
CsErrQueueNotAvailable = 24,
CsErrBadFlags = 25,
CsErrTooBig = 26,
CsErrNoSection = 27,
CsErrContextNotFound = 28,
CsErrTooManyGroups = 30,
CsErrSecurity = 100,
#[num_enum(default)]
CsErrRustCompat = 998, CsErrRustString = 999, }
pub type Result<T> = ::std::result::Result<T, CsError>;
impl fmt::Display for CsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CsError::CsOk => write!(f, "OK"),
CsError::CsErrLibrary => write!(f, "ErrLibrary"),
CsError::CsErrVersion => write!(f, "ErrVersion"),
CsError::CsErrInit => write!(f, "ErrInit"),
CsError::CsErrTimeout => write!(f, "ErrTimeout"),
CsError::CsErrTryAgain => write!(f, "ErrTryAgain"),
CsError::CsErrInvalidParam => write!(f, "ErrInvalidParam"),
CsError::CsErrNoMemory => write!(f, "ErrNoMemory"),
CsError::CsErrBadHandle => write!(f, "ErrbadHandle"),
CsError::CsErrBusy => write!(f, "ErrBusy"),
CsError::CsErrAccess => write!(f, "ErrAccess"),
CsError::CsErrNotExist => write!(f, "ErrNotExist"),
CsError::CsErrNameTooLong => write!(f, "ErrNameTooLong"),
CsError::CsErrExist => write!(f, "ErrExist"),
CsError::CsErrNoSpace => write!(f, "ErrNoSpace"),
CsError::CsErrInterrupt => write!(f, "ErrInterrupt"),
CsError::CsErrNameNotFound => write!(f, "ErrNameNotFound"),
CsError::CsErrNoResources => write!(f, "ErrNoResources"),
CsError::CsErrNotSupported => write!(f, "ErrNotSupported"),
CsError::CsErrBadOperation => write!(f, "ErrBadOperation"),
CsError::CsErrFailedOperation => write!(f, "ErrFailedOperation"),
CsError::CsErrMessageError => write!(f, "ErrMEssageError"),
CsError::CsErrQueueFull => write!(f, "ErrQueueFull"),
CsError::CsErrQueueNotAvailable => write!(f, "ErrQueueNotAvailable"),
CsError::CsErrBadFlags => write!(f, "ErrBadFlags"),
CsError::CsErrTooBig => write!(f, "ErrTooBig"),
CsError::CsErrNoSection => write!(f, "ErrNoSection"),
CsError::CsErrContextNotFound => write!(f, "ErrContextNotFound"),
CsError::CsErrTooManyGroups => write!(f, "ErrTooManyGroups"),
CsError::CsErrSecurity => write!(f, "ErrSecurity"),
CsError::CsErrRustCompat => write!(f, "ErrRustCompat"),
CsError::CsErrRustString => write!(f, "ErrRustString"),
}
}
}
impl Error for CsError {}
impl CsError {
fn from_c(cserr: u32) -> CsError {
match CsError::try_from(cserr) {
Ok(e) => e,
Err(_) => CsError::CsErrRustCompat,
}
}
}
#[derive(Copy, Clone)]
pub enum DispatchFlags {
One = 1,
All = 2,
Blocking = 3,
OneNonblocking = 4,
}
#[derive(Copy, Clone)]
pub enum TrackFlags {
Current = 1,
Changes = 2,
ChangesOnly = 4,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct NodeId {
id: u32,
}
impl fmt::Display for NodeId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.id)
}
}
impl From<u32> for NodeId {
fn from(id: u32) -> NodeId {
NodeId { id }
}
}
impl From<NodeId> for u32 {
fn from(nodeid: NodeId) -> u32 {
nodeid.id
}
}
fn string_from_bytes(bytes: *const ::std::os::raw::c_char, max_length: usize) -> Result<String> {
let mut newbytes = Vec::<u8>::new();
newbytes.resize(max_length, 0u8);
let mut length: usize = 0;
let mut count = 0;
let mut tmpbytes = bytes;
while count < max_length || length == 0 {
if unsafe { *tmpbytes } == 0 && length == 0 {
length = count;
break;
}
count += 1;
tmpbytes = unsafe { tmpbytes.offset(1) }
}
if length == 0 {
return Ok(String::new());
}
unsafe {
copy_nonoverlapping(bytes as *mut i8, newbytes.as_mut_ptr() as *mut i8, length);
}
let cs = match CString::new(&newbytes[0..length]) {
Ok(c1) => c1,
Err(_) => return Err(CsError::CsErrRustString),
};
match cs.into_string() {
Ok(s) => Ok(s),
Err(_) => Err(CsError::CsErrRustString),
}
}