diff options
author | Neal H. Walfield <neal@pep.foundation> | 2020-04-01 20:54:04 +0200 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2020-04-01 20:54:04 +0200 |
commit | 21028b81840e577664ab39bab49c2cb4c5f44811 (patch) | |
tree | 71b7b33c82d4ada5d09ffefe9b1d4692499b5cfe | |
parent | 2a5f983b5ea5134d74b6fda6428af1c54d4fee9b (diff) |
WIP: Impl iter...neal/impliter
-rw-r--r-- | autocrypt/src/lib.rs | 2 | ||||
-rw-r--r-- | openpgp-ffi/src/cert.rs | 17 | ||||
-rw-r--r-- | openpgp/src/cert/bindings.rs | 6 | ||||
-rw-r--r-- | openpgp/src/cert/bundle.rs | 71 | ||||
-rw-r--r-- | openpgp/src/cert/component_iter.rs | 32 | ||||
-rw-r--r-- | openpgp/src/cert/keyiter.rs | 17 | ||||
-rw-r--r-- | openpgp/src/cert/mod.rs | 26 | ||||
-rw-r--r-- | openpgp/src/cert/prelude.rs | 5 |
8 files changed, 94 insertions, 82 deletions
diff --git a/autocrypt/src/lib.rs b/autocrypt/src/lib.rs index f336be9a..b9563b1c 100644 --- a/autocrypt/src/lib.rs +++ b/autocrypt/src/lib.rs @@ -1217,7 +1217,7 @@ Autocrypt-Gossip: addr=neal@walfield.org; keydata= .expect("Failed to parse key material."); assert_eq!(&cert.fingerprint().to_string(), "3E88 77C8 7727 4692 9751 89F5 D03F 6F86 5226 FE8B"); - assert_eq!(cert.userids().len(), 1); + assert_eq!(cert.userids().count(), 1); assert_eq!(cert.keys().subkeys().count(), 1); assert_eq!(cert.userids().next().unwrap().userid().value(), &b"Testy McTestface <testy@example.org>"[..]); diff --git a/openpgp-ffi/src/cert.rs b/openpgp-ffi/src/cert.rs index 9c3f43ad..ff73c2ab 100644 --- a/openpgp-ffi/src/cert.rs +++ b/openpgp-ffi/src/cert.rs @@ -406,19 +406,26 @@ pub extern "C" fn pgp_user_id_bundle_selfsig( /* UserIDBundleIter */ +/// Wraps a KeyIter for export via the FFI. +pub struct UserIDBundleIterWrapper<'a> { + iter: Box<dyn Iterator<Item=&'a UserIDBundle> + 'a>, +} + /// Returns an iterator over the Cert's user id bundles. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_cert_user_id_bundle_iter(cert: *const Cert) - -> *mut UserIDBundleIter<'static> + -> *mut UserIDBundleIterWrapper<'static> { let cert = cert.ref_raw(); - box_raw!(cert.userids().bundles()) + box_raw!(UserIDBundleIterWrapper { + iter: Box::new(cert.userids().bundles()) + }) } /// Frees a pgp_user_id_bundle_iter_t. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_user_id_bundle_iter_free( - iter: Option<&mut UserIDBundleIter>) + iter: Option<&mut UserIDBundleIterWrapper>) { ffi_free!(iter) } @@ -426,11 +433,11 @@ pub extern "C" fn pgp_user_id_bundle_iter_free( /// Returns the next `UserIDBundle`. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_user_id_bundle_iter_next<'a>( - iter: *mut UserIDBundleIter<'a>) + iter: *mut UserIDBundleIterWrapper<'a>) -> Option<&'a UserIDBundle> { let iter = ffi_param_ref_mut!(iter); - iter.next() + iter.iter.next() } /* cert::KeyIter. */ diff --git a/openpgp/src/cert/bindings.rs b/openpgp/src/cert/bindings.rs index a11a578a..aa5f069d 100644 --- a/openpgp/src/cert/bindings.rs +++ b/openpgp/src/cert/bindings.rs @@ -98,7 +98,7 @@ impl UserID { /// let (cert, _) = CertBuilder::new().generate()?; /// let mut keypair = cert.primary_key().key().clone() /// .mark_parts_secret()?.into_keypair()?; - /// assert_eq!(cert.userids().len(), 0); + /// assert_eq!(cert.userids().count(), 0); /// /// // Generate a userid and a binding signature. /// let userid = UserID::from("test@example.org"); @@ -110,7 +110,7 @@ impl UserID { /// let cert = cert.merge_packets(vec![userid.into(), binding.into()])?; /// /// // Check that we have a userid. - /// assert_eq!(cert.userids().len(), 1); + /// assert_eq!(cert.userids().count(), 1); /// # Ok(()) } pub fn bind(&self, signer: &mut dyn Signer, cert: &Cert, signature: signature::Builder) @@ -233,7 +233,7 @@ impl UserAttribute { /// .generate()?; /// let mut keypair = cert.primary_key().key().clone() /// .mark_parts_secret()?.into_keypair()?; - /// assert_eq!(cert.userids().len(), 0); + /// assert_eq!(cert.userids().count(), 0); /// /// // Generate a user attribute and a binding signature. /// let user_attr = UserAttribute::new(&[ diff --git a/openpgp/src/cert/bundle.rs b/openpgp/src/cert/bundle.rs index 15227e5b..f35642c3 100644 --- a/openpgp/src/cert/bundle.rs +++ b/openpgp/src/cert/bundle.rs @@ -1,6 +1,5 @@ //! Types for certificate components. -use std::slice; use std::time; use std::ops::Deref; @@ -475,38 +474,38 @@ impl ComponentBundle<Unknown> { } } -/// An iterator over `ComponentBundle`s. -pub struct ComponentBundleIter<'a, C> { - pub(crate) iter: Option<slice::Iter<'a, ComponentBundle<C>>>, -} - -/// An iterator over `KeyBundle`s. -pub type UnfilteredKeyBundleIter<'a, P, R> = ComponentBundleIter<'a, Key<P, R>>; -/// An iterator over `UserIDBundle`s. -pub type UserIDBundleIter<'a> = ComponentBundleIter<'a, UserID>; -/// An iterator over `UserAttributeBundle`s. -pub type UserAttributeBundleIter<'a> = ComponentBundleIter<'a, UserAttribute>; -/// An iterator over `UnknownBundle`s. -pub type UnknownBundleIter<'a> = ComponentBundleIter<'a, Unknown>; - -impl<'a, C> Iterator for ComponentBundleIter<'a, C> -{ - type Item = &'a ComponentBundle<C>; - - fn next(&mut self) -> Option<Self::Item> { - match self.iter { - Some(ref mut iter) => iter.next(), - None => None, - } - } -} - -impl<'a, C> ExactSizeIterator for ComponentBundleIter<'a, C> -{ - fn len(&self) -> usize { - match self.iter { - Some(ref iter) => iter.len(), - None => 0, - } - } -} +// /// An iterator over `ComponentBundle`s. +// pub struct ComponentBundleIter<'a, C> { +// pub(crate) iter: Option<slice::Iter<'a, ComponentBundle<C>>>, +// } +// +// /// An iterator over `KeyBundle`s. +// pub type UnfilteredKeyBundleIter<'a, P, R> = ComponentBundleIter<'a, Key<P, R>>; +// /// An iterator over `UserIDBundle`s. +// pub type UserIDBundleIter<'a> = ComponentBundleIter<'a, UserID>; +// /// An iterator over `UserAttributeBundle`s. +// pub type UserAttributeBundleIter<'a> = ComponentBundleIter<'a, UserAttribute>; +// /// An iterator over `UnknownBundle`s. +// pub type UnknownBundleIter<'a> = ComponentBundleIter<'a, Unknown>; +// +// impl<'a, C> Iterator for ComponentBundleIter<'a, C> +// { +// type Item = &'a ComponentBundle<C>; +// +// fn next(&mut self) -> Option<Self::Item> { +// match self.iter { +// Some(ref mut iter) => iter.next(), +// None => None, +// } +// } +// } +// +// impl<'a, C> ExactSizeIterator for ComponentBundleIter<'a, C> +// { +// fn len(&self) -> usize { +// match self.iter { +// Some(ref iter) => iter.len(), +// None => 0, +// } +// } +// } diff --git a/openpgp/src/cert/component_iter.rs b/openpgp/src/cert/component_iter.rs index c0e82117..a6dcdefd 100644 --- a/openpgp/src/cert/component_iter.rs +++ b/openpgp/src/cert/component_iter.rs @@ -16,7 +16,7 @@ use crate::{ /// By default, `ComponentIter` returns all components without context. pub struct ComponentIter<'a, C> { cert: &'a Cert, - iter: ComponentBundleIter<'a, C>, + iter: Box<Iterator<Item=&'a ComponentBundle<C>> + 'a>, } impl<'a, C> fmt::Debug for ComponentIter<'a, C> { @@ -26,7 +26,9 @@ impl<'a, C> fmt::Debug for ComponentIter<'a, C> { } } -impl<'a, C> Iterator for ComponentIter<'a, C> { +impl<'a, C> Iterator for ComponentIter<'a, C> + where C: 'a +{ type Item = ComponentAmalgamation<'a, C>; fn next(&mut self) -> Option<Self::Item> { @@ -34,14 +36,15 @@ impl<'a, C> Iterator for ComponentIter<'a, C> { } } -impl<'a, C> ComponentIter<'a, C> { +impl<'a, C> ComponentIter<'a, C> where C: 'a { /// Returns a new `ComponentIter` instance. pub(crate) fn new(cert: &'a Cert, - iter: std::slice::Iter<'a, ComponentBundle<C>>) -> Self + iter: impl Iterator<Item=&'a ComponentBundle<C>> + 'a) -> Self where Self: 'a { ComponentIter { - cert, iter: ComponentBundleIter { iter: Some(iter), }, + cert, + iter: Box::new(iter), } } @@ -69,7 +72,8 @@ impl<'a, C> ComponentIter<'a, C> { /// A component binding is similar to a component amalgamation, /// but is not bound to a specific time. It contains the /// component and all relevant signatures. - pub fn bundles(self) -> ComponentBundleIter<'a, C> { + pub fn bundles(self) -> impl Iterator<Item=&'a ComponentBundle<C>> + { self.iter } } @@ -85,7 +89,7 @@ impl<'a, C> ComponentIter<'a, C> { pub struct ValidComponentIter<'a, C> { // This is an option to make it easier to create an empty ValidComponentIter. cert: &'a Cert, - iter: ComponentBundleIter<'a, C>, + iter: Box<Iterator<Item=&'a ComponentBundle<C>> + 'a>, policy: &'a dyn Policy, // The time. @@ -106,7 +110,7 @@ impl<'a, C> fmt::Debug for ValidComponentIter<'a, C> { } impl<'a, C> Iterator for ValidComponentIter<'a, C> - where C: std::fmt::Debug + where C: 'a, C: std::fmt::Debug { type Item = ValidComponentAmalgamation<'a, C>; @@ -147,11 +151,13 @@ impl<'a, C> Iterator for ValidComponentIter<'a, C> } } -impl<'a, C> ExactSizeIterator for ComponentIter<'a, C> { - fn len(&self) -> usize { - self.iter.len() - } -} +// impl<'a, C> ExactSizeIterator for ComponentIter<'a, C> +// where C: 'a +// { +// fn len(&self) -> usize { +// self.iter.len() +// } +// } impl<'a, C> ValidComponentIter<'a, C> { /// Filters by whether a component is definitely revoked. diff --git a/openpgp/src/cert/keyiter.rs b/openpgp/src/cert/keyiter.rs index 0cfc3e23..5175f176 100644 --- a/openpgp/src/cert/keyiter.rs +++ b/openpgp/src/cert/keyiter.rs @@ -6,6 +6,7 @@ use std::borrow::Borrow; use crate::{ KeyHandle, types::RevocationStatus, + packet::Key, packet::key, packet::key::SecretKeyMaterial, types::KeyFlags, @@ -35,9 +36,10 @@ pub struct KeyIter<'a, P, R> // This is an option to make it easier to create an empty KeyIter. cert: Option<&'a Cert>, primary: bool, - subkey_iter: UnfilteredKeyBundleIter<'a, - key::PublicParts, - key::SubordinateRole>, + subkey_iter: Box<dyn Iterator< + Item=&'a ComponentBundle<Key<key::PublicParts, + key::SubordinateRole>>> + + 'a>, // If not None, filters by whether a key has a secret. secret: Option<bool>, @@ -189,7 +191,7 @@ impl<'a, P, R> KeyIter<'a, P, R> KeyIter { cert: Some(cert), primary: false, - subkey_iter: cert.subkeys(), + subkey_iter: Box::new(cert.subkeys()), // The filters. secret: None, @@ -451,9 +453,10 @@ pub struct ValidKeyIter<'a, P, R> // This is an option to make it easier to create an empty ValidKeyIter. cert: Option<&'a Cert>, primary: bool, - subkey_iter: UnfilteredKeyBundleIter<'a, - key::PublicParts, - key::SubordinateRole>, + subkey_iter: Box<dyn Iterator< + Item=&'a ComponentBundle<Key<key::PublicParts, + key::SubordinateRole>>> + + 'a>, // The policy. policy: &'a dyn Policy, diff --git a/openpgp/src/cert/mod.rs b/openpgp/src/cert/mod.rs index e5d74ec9..067d68ea 100644 --- a/openpgp/src/cert/mod.rs +++ b/openpgp/src/cert/mod.rs @@ -661,15 +661,17 @@ impl Cert { } /// Returns an iterator over the Cert's subkeys. - pub(crate) fn subkeys(&self) -> UnfilteredKeyBundleIter<key::PublicParts, - key::SubordinateRole> + pub(crate) fn subkeys(&self) + -> impl Iterator<Item=&ComponentBundle<Key<key::PublicParts, + key::SubordinateRole>>> { - UnfilteredKeyBundleIter { iter: Some(self.subkeys.iter()) } + self.subkeys.iter() } /// Returns an iterator over the Cert's unknown components. - pub fn unknowns(&self) -> UnknownBundleIter { - UnknownBundleIter { iter: Some(self.unknowns.iter()) } + pub fn unknowns(&self) -> impl Iterator<Item=&ComponentBundle<Unknown>> + { + self.unknowns.iter() } /// Returns a slice containing all bad signatures. @@ -2755,7 +2757,7 @@ mod test { // tsk is now a cert, but it still has its private bits. assert!(tsk.primary.key().has_secret()); assert!(tsk.is_tsk()); - let subkey_count = tsk.subkeys().len(); + let subkey_count = tsk.subkeys().count(); assert!(subkey_count > 0); assert!(tsk.subkeys().all(|k| k.key().has_secret())); @@ -2773,13 +2775,13 @@ mod test { let merge1 = cert.clone().merge(tsk.clone()).unwrap(); assert!(merge1.is_tsk()); assert!(merge1.primary.key().has_secret()); - assert_eq!(merge1.subkeys().len(), subkey_count); + assert_eq!(merge1.subkeys().count(), subkey_count); assert!(merge1.subkeys().all(|k| k.key().has_secret())); let merge2 = tsk.clone().merge(cert.clone()).unwrap(); assert!(merge2.is_tsk()); assert!(merge2.primary.key().has_secret()); - assert_eq!(merge2.subkeys().len(), subkey_count); + assert_eq!(merge2.subkeys().count(), subkey_count); assert!(merge2.subkeys().all(|k| k.key().has_secret())); } @@ -2828,7 +2830,7 @@ Pu1xwz57O4zo1VYf6TqHJzVC3OMvMUM2hhdecMUe5x6GorNaj6g= .add_transport_encryption_subkey() .add_certification_subkey() .generate().unwrap(); - assert_eq!(cert.subkeys().len(), 2); + assert_eq!(cert.subkeys().count(), 2); let pile = cert .into_packet_pile() .into_children() @@ -2849,7 +2851,7 @@ Pu1xwz57O4zo1VYf6TqHJzVC3OMvMUM2hhdecMUe5x6GorNaj6g= eprintln!("parse back"); let cert = Cert::from_packet_pile(PacketPile::from(pile)).unwrap(); - assert_eq!(cert.subkeys().len(), 2); + assert_eq!(cert.subkeys().count(), 2); } #[test] @@ -3162,7 +3164,7 @@ Pu1xwz57O4zo1VYf6TqHJzVC3OMvMUM2hhdecMUe5x6GorNaj6g= .add_signing_subkey() .generate().unwrap(); - assert_eq!(bob.userids().len(), 1); + assert_eq!(bob.userids().count(), 1); let bob_userid_binding = bob.userids().nth(0).unwrap(); assert_eq!(bob_userid_binding.userid().value(), b"bob@bar.com"); @@ -3185,7 +3187,7 @@ Pu1xwz57O4zo1VYf6TqHJzVC3OMvMUM2hhdecMUe5x6GorNaj6g= // Make sure the certification is merged, and put in the right // place. - assert_eq!(bob.userids().len(), 1); + assert_eq!(bob.userids().count(), 1); let bob_userid_binding = bob.userids().nth(0).unwrap(); assert_eq!(bob_userid_binding.userid().value(), b"bob@bar.com"); diff --git a/openpgp/src/cert/prelude.rs b/openpgp/src/cert/prelude.rs index 10278021..43738290 100644 --- a/openpgp/src/cert/prelude.rs +++ b/openpgp/src/cert/prelude.rs @@ -33,19 +33,14 @@ pub use crate::cert::{ amalgamation::ValidComponentAmalgamation, amalgamation::ValidateAmalgamation as _, bundle::ComponentBundle, - bundle::ComponentBundleIter, bundle::ComponentIter, bundle::KeyBundle, bundle::KeyIter, bundle::PrimaryKeyBundle, bundle::SubkeyBundle, - bundle::UnfilteredKeyBundleIter, bundle::UnknownBundle, - bundle::UnknownBundleIter, bundle::UserAttributeBundle, - bundle::UserAttributeBundleIter, bundle::UserIDBundle, - bundle::UserIDBundleIter, bundle::ValidComponentIter, bundle::ValidKeyIter, key_amalgamation::ErasedKeyAmalgamation, |