use syn;
pub trait IterHelpers: Iterator {
fn try_skip_map<F, T, E>(&mut self, f: F) -> Result<Vec<T>, E>
where
F: FnMut(&Self::Item) -> Result<Option<T>, E>;
}
impl<I> IterHelpers for I
where
I: Iterator,
{
fn try_skip_map<F, T, E>(&mut self, mut f: F) -> Result<Vec<T>, E>
where
F: FnMut(&Self::Item) -> Result<Option<T>, E>,
{
let mut out = Vec::new();
while let Some(item) = self.next() {
if let Some(x) = f(&item)? {
out.push(x);
}
}
Ok(out)
}
}
pub fn find_first_some<T>(slice: &[Option<T>]) -> Option<&T> {
for x in slice {
if let &Some(ref x) = x {
return Some(x);
}
}
return None;
}
pub trait SynItemHelpers {
fn has_attr(&self, target: syn::Meta) -> bool;
fn is_no_mangle(&self) -> bool {
self.has_attr(syn::Meta::Word("no_mangle".into()))
}
}
impl SynItemHelpers for syn::ItemStruct {
fn has_attr(&self, target: syn::Meta) -> bool {
return self.attrs
.iter()
.filter_map(|x| x.interpret_meta())
.any(|attr| attr == target);
}
}
impl SynItemHelpers for syn::ItemFn {
fn has_attr(&self, target: syn::Meta) -> bool {
return self.attrs
.iter()
.filter_map(|x| x.interpret_meta())
.any(|attr| attr == target);
}
}
impl SynItemHelpers for syn::ItemStatic {
fn has_attr(&self, target: syn::Meta) -> bool {
return self.attrs
.iter()
.filter_map(|x| x.interpret_meta())
.any(|attr| attr == target);
}
}
impl SynItemHelpers for syn::Variant {
fn has_attr(&self, target: syn::Meta) -> bool {
return self.attrs
.iter()
.filter_map(|x| x.interpret_meta())
.any(|attr| attr == target);
}
}
impl SynItemHelpers for syn::Field {
fn has_attr(&self, target: syn::Meta) -> bool {
return self.attrs
.iter()
.filter_map(|x| x.interpret_meta())
.any(|attr| attr == target);
}
}
pub trait SynAbiHelpers {
fn is_c(&self) -> bool;
fn is_omitted(&self) -> bool;
}
impl SynAbiHelpers for Option<syn::Abi> {
fn is_c(&self) -> bool {
if let &Some(ref abi) = self {
if let Some(ref lit_string) = abi.name {
return lit_string.value() == String::from("C");
}
}
false
}
fn is_omitted(&self) -> bool {
if let &Some(ref abi) = self {
abi.name.is_none()
} else {
false
}
}
}
impl SynAbiHelpers for syn::Abi {
fn is_c(&self) -> bool {
if let Some(ref lit_string) = self.name {
lit_string.value() == String::from("C")
} else {
false
}
}
fn is_omitted(&self) -> bool {
self.name.is_none()
}
}