summaryrefslogtreecommitdiffstats
path: root/ffi-macros
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-04-10 16:13:42 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-05-09 12:52:40 +0200
commit8e0f817f312f469871a5fbed6bb961f6117ba742 (patch)
tree17c84ff6799da82aa4a3db9c98284d60204e158d /ffi-macros
parent18f9530d8063f4c479e231ab137a7eabaef2ffe6 (diff)
ffi-macros: Derive Iterator.
Diffstat (limited to 'ffi-macros')
-rw-r--r--ffi-macros/src/lib.rs32
1 files changed, 32 insertions, 0 deletions
diff --git a/ffi-macros/src/lib.rs b/ffi-macros/src/lib.rs
index 83584fd7..3620549d 100644
--- a/ffi-macros/src/lib.rs
+++ b/ffi-macros/src/lib.rs
@@ -265,6 +265,7 @@ fn derive_functions() -> &'static HashMap<&'static str, DeriveFn>
h.insert("Debug", derive_debug as DeriveFn);
h.insert("Parse", derive_parse as DeriveFn);
h.insert("Serialize", derive_serialize as DeriveFn);
+ h.insert("Iterator", derive_iterator as DeriveFn);
h
};
}
@@ -904,3 +905,34 @@ fn derive_serialize(span: proc_macro2::Span, prefix: &str, name: &str,
}
}
}
+
+/// Derives prefix_name_next.
+fn derive_iterator(span: proc_macro2::Span, prefix: &str, name: &str,
+ wrapper_st: &syn::ItemStruct, _wrapped: &syn::Type,
+ arg: &Option<String>)
+ -> TokenStream2
+{
+ let wrapper = &wrapper_st.ident;
+ let generics = &wrapper_st.generics;
+ if arg.is_none() {
+ return syn::Error::new(span, "Expected type argument for Iterator")
+ .to_compile_error();
+ }
+ let item_type = match syn::parse_str::<syn::Type>(&arg.clone().unwrap()) {
+ Ok(t) => t,
+ Err(e) => return e.to_compile_error(),
+ };
+ let ident = syn::Ident::new(&format!("{}{}_next", prefix, name),
+ span);
+
+ quote! {
+ /// Gets the next item from the iterator.
+ #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "system"
+ fn #ident #generics (this: *mut #wrapper #generics)
+ -> Option<::std::ptr::NonNull<#item_type>> {
+ use ::RefMutRaw;
+ use ::MoveResultIntoRaw;
+ this.ref_mut_raw().next().move_into_raw()
+ }
+ }
+}