use std::io::{self, prelude::*};
use ffi;
use libc;
use crate::Error;
pub use cstr_argument::CStrArgument;
pub type SmallVec<T> = ::smallvec::SmallVec<[T; 4]>;
macro_rules! impl_wrapper {
($T:ty$(, $Args:expr)*) => {
#[inline]
pub unsafe fn from_raw(raw: $T) -> Self {
Self(NonNull::<$T>::new(raw).unwrap()$(, $Args)*)
}
#[inline]
pub fn as_raw(&self) -> $T {
self.0.as_ptr()
}
#[inline]
pub fn into_raw(self) -> $T {
let raw = self.as_raw();
::std::mem::forget(self);
raw
}
};
}
macro_rules! impl_list_iterator {
($Vis:vis struct $Name:ident($Item:ident: $Raw:ty)) => {
#[derive(Clone)]
$Vis struct $Name<'a>(Option<$Item<'a>>);
impl $Name<'_> {
#[inline]
pub unsafe fn from_list(first: $Raw) -> Self {
$Name(first.as_mut().map(|r| $Item::from_raw(r)))
}
}
impl<'a> Iterator for $Name<'a> {
type Item = $Item<'a>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
unsafe {
self.0.take().map(|c| {
self.0 = (*c.as_raw()).next.as_mut().map(|r| $Item::from_raw(r));
c
})
}
}
}
impl ::std::iter::FusedIterator for $Name<'_> {}
impl ::std::fmt::Debug for $Name<'_> {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
};
}
macro_rules! ffi_enum_wrapper {
($(#[$Attr:meta])* $Vis:vis enum $Name:ident($Default:ident): $T:ty {
$($(#[$ItemAttr:meta])* $Item:ident = $Value:expr),+ $(,)?
}) => {
$(#[$Attr])*
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
$Vis enum $Name {
$($(#[$ItemAttr])* $Item,)+
}
impl $Name {
#[inline]
pub unsafe fn from_raw(raw: $T) -> $Name {
$(if raw == $Value {
$Name::$Item
} else )+ {
$Name::$Default
}
}
#[inline]
pub fn raw(&self) -> $T {
match *self {
$($Name::$Item => $Value,)+
}
}
}
impl ::std::fmt::Debug for $Name {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
$($Name::$Item => {
write!(f, concat!(stringify!($Name), "::",
stringify!($Item), "({:?})"), self.raw())
})+
}
}
}
};
($(#[$Attr:meta])* $Vis:vis enum $Name:ident: $T:ty {
$($(#[$ItemAttr:meta])* $Item:ident = $Value:expr),+ $(,)?
}) => {
$(#[$Attr])*
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
$Vis enum $Name {
$($(#[$ItemAttr])* $Item,)+
Other($T),
}
impl $Name {
#[inline]
pub unsafe fn from_raw(raw: $T) -> $Name {
$(if raw == $Value {
$Name::$Item
} else )+ {
$Name::Other(raw)
}
}
#[inline]
pub fn raw(&self) -> $T {
match *self {
$($Name::$Item => $Value,)+
$Name::Other(other) => other,
}
}
}
impl ::std::fmt::Debug for $Name {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
$($Name::$Item => {
write!(f, concat!(stringify!($Name), "::",
stringify!($Item), "({:?})"), self.raw())
})+
_ => write!(f, concat!(stringify!($Name), "({:?})"), self.raw()),
}
}
}
};
}
pub(crate) struct FdWriter(libc::c_int);
impl FdWriter {
pub unsafe fn new(fd: libc::c_int) -> FdWriter {
Self(fd)
}
}
impl Write for FdWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let result = unsafe { ffi::gpgme_io_write(self.0, buf.as_ptr().cast(), buf.len()) };
usize::try_from(result).map_err(|_| Error::last_os_error().into())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
pub(crate) trait Ptr {
type Inner;
}
impl<T> Ptr for *mut T {
type Inner = T;
}
impl<T> Ptr for *const T {
type Inner = T;
}