summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-02-28 18:36:17 +0100
committerNeal H. Walfield <neal@pep.foundation>2020-02-28 18:36:17 +0100
commitbed057edbf45e989e768e2d8fac5ce7f0619d461 (patch)
tree3db23bec6e4832bac590506dbb2be59fb18de447
parent3037c4123921719183abd7b75a11bc8639ed9df8 (diff)
openpgp: Implement Iterator for more variants of {,Valid}KeyIter.
- Implement `Iterator` on KeyIter and ValidKeyIter for the cross product of {Primary, Subordinate, Unspecified} and {Public, Secret, Unspecified}.
-rw-r--r--openpgp/src/cert/keyiter.rs91
1 files changed, 55 insertions, 36 deletions
diff --git a/openpgp/src/cert/keyiter.rs b/openpgp/src/cert/keyiter.rs
index eee2899e..744fb2cc 100644
--- a/openpgp/src/cert/keyiter.rs
+++ b/openpgp/src/cert/keyiter.rs
@@ -66,32 +66,42 @@ impl<'a, P, R> fmt::Debug for KeyIter<'a, P, R>
}
}
-// Very carefully implement Iterator for
-// Key<{PublicParts,UnspecifiedParts}, _>. We cannot just abstract
-// over the parts, because then we cannot specialize the
-// implementation for Key<SecretParts, _> below.
macro_rules! impl_iterator {
- ($parts:path) => {
- impl<'a> Iterator for KeyIter<'a, $parts, key::UnspecifiedRole>
+ ($parts:path, $role:path, $item:ty) => {
+ impl<'a> Iterator for KeyIter<'a, $parts, $role>
{
- type Item = ErasedKeyAmalgamation<'a, $parts>;
+ type Item = $item;
fn next(&mut self) -> Option<Self::Item> {
- self.next_common().map(|k| k.into())
+ // We unwrap the result of the conversion. But, this
+ // is safe by construction: next_common only returns
+ // keys that can be correctly converted.
+ self.next_common().map(|k| k.try_into().expect("filtered"))
}
}
}
}
-impl_iterator!(key::PublicParts);
-impl_iterator!(key::UnspecifiedParts);
-impl<'a> Iterator for KeyIter<'a, key::SecretParts, key::UnspecifiedRole> {
- type Item = ErasedKeyAmalgamation<'a, key::SecretParts>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.next_common().map(|k| k.try_into().expect("has secret parts"))
- }
-}
+impl_iterator!(key::PublicParts, key::PrimaryRole,
+ PrimaryKeyAmalgamation<'a, key::PublicParts>);
+impl_iterator!(key::SecretParts, key::PrimaryRole,
+ PrimaryKeyAmalgamation<'a, key::SecretParts>);
+impl_iterator!(key::UnspecifiedParts, key::PrimaryRole,
+ PrimaryKeyAmalgamation<'a, key::UnspecifiedParts>);
+
+impl_iterator!(key::PublicParts, key::SubordinateRole,
+ SubordinateKeyAmalgamation<'a, key::PublicParts>);
+impl_iterator!(key::SecretParts, key::SubordinateRole,
+ SubordinateKeyAmalgamation<'a, key::SecretParts>);
+impl_iterator!(key::UnspecifiedParts, key::SubordinateRole,
+ SubordinateKeyAmalgamation<'a, key::UnspecifiedParts>);
+
+impl_iterator!(key::PublicParts, key::UnspecifiedRole,
+ ErasedKeyAmalgamation<'a, key::PublicParts>);
+impl_iterator!(key::SecretParts, key::UnspecifiedRole,
+ ErasedKeyAmalgamation<'a, key::SecretParts>);
+impl_iterator!(key::UnspecifiedParts, key::UnspecifiedRole,
+ ErasedKeyAmalgamation<'a, key::UnspecifiedParts>);
impl<'a, P, R> KeyIter<'a, P, R>
where P: key::KeyParts,
@@ -529,33 +539,42 @@ impl<'a, P, R> fmt::Debug for ValidKeyIter<'a, P, R>
}
}
-// Very carefully implement Iterator for
-// Key<{PublicParts,UnspecifiedParts}, _>. We cannot just abstract
-// over the parts, because then we cannot specialize the
-// implementation for Key<SecretParts, _> below.
-macro_rules! impl_valid_key_iterator {
- ($parts:path) => {
- impl<'a> Iterator for ValidKeyIter<'a, $parts, key::UnspecifiedRole>
+macro_rules! impl_iterator {
+ ($parts:path, $role:path, $item:ty) => {
+ impl<'a> Iterator for ValidKeyIter<'a, $parts, $role>
{
- type Item = ValidErasedKeyAmalgamation<'a, $parts>;
+ type Item = $item;
fn next(&mut self) -> Option<Self::Item> {
- self.next_common().map(|ka| ka.into())
+ // We unwrap the result of the conversion. But, this
+ // is safe by construction: next_common only returns
+ // keys that can be correctly converted.
+ self.next_common().map(|k| k.try_into().expect("filtered"))
}
}
}
}
-impl_valid_key_iterator!(key::PublicParts);
-impl_valid_key_iterator!(key::UnspecifiedParts);
-
-impl<'a> Iterator for ValidKeyIter<'a, key::SecretParts, key::UnspecifiedRole>
-{
- type Item = ValidErasedKeyAmalgamation<'a, key::SecretParts>;
- fn next(&mut self) -> Option<Self::Item> {
- self.next_common().map(|ka| ka.try_into().expect("has secret parts"))
- }
-}
+impl_iterator!(key::PublicParts, key::PrimaryRole,
+ ValidPrimaryKeyAmalgamation<'a, key::PublicParts>);
+impl_iterator!(key::SecretParts, key::PrimaryRole,
+ ValidPrimaryKeyAmalgamation<'a, key::SecretParts>);
+impl_iterator!(key::UnspecifiedParts, key::PrimaryRole,
+ ValidPrimaryKeyAmalgamation<'a, key::UnspecifiedParts>);
+
+impl_iterator!(key::PublicParts, key::SubordinateRole,
+ ValidSubordinateKeyAmalgamation<'a, key::PublicParts>);
+impl_iterator!(key::SecretParts, key::SubordinateRole,
+ ValidSubordinateKeyAmalgamation<'a, key::SecretParts>);
+impl_iterator!(key::UnspecifiedParts, key::SubordinateRole,
+ ValidSubordinateKeyAmalgamation<'a, key::UnspecifiedParts>);
+
+impl_iterator!(key::PublicParts, key::UnspecifiedRole,
+ ValidErasedKeyAmalgamation<'a, key::PublicParts>);
+impl_iterator!(key::SecretParts, key::UnspecifiedRole,
+ ValidErasedKeyAmalgamation<'a, key::SecretParts>);
+impl_iterator!(key::UnspecifiedParts, key::UnspecifiedRole,
+ ValidErasedKeyAmalgamation<'a, key::UnspecifiedParts>);
impl<'a, P, R> ValidKeyIter<'a, P, R>
where P: key::KeyParts,