summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-04-01 20:54:04 +0200
committerNeal H. Walfield <neal@pep.foundation>2020-04-01 20:54:04 +0200
commit21028b81840e577664ab39bab49c2cb4c5f44811 (patch)
tree71b7b33c82d4ada5d09ffefe9b1d4692499b5cfe
parent2a5f983b5ea5134d74b6fda6428af1c54d4fee9b (diff)
WIP: Impl iter...neal/impliter
-rw-r--r--autocrypt/src/lib.rs2
-rw-r--r--openpgp-ffi/src/cert.rs17
-rw-r--r--openpgp/src/cert/bindings.rs6
-rw-r--r--openpgp/src/cert/bundle.rs71
-rw-r--r--openpgp/src/cert/component_iter.rs32
-rw-r--r--openpgp/src/cert/keyiter.rs17
-rw-r--r--openpgp/src/cert/mod.rs26
-rw-r--r--openpgp/src/cert/prelude.rs5
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,