summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-02-26 17:29:02 +0100
committerNeal H. Walfield <neal@pep.foundation>2020-02-26 21:21:58 +0100
commit6270592f75ac1eb71cfb94e777920c172a86bbe6 (patch)
treedf5ee8998f53d71a7265ffbda3924ca480472806
parent22b28b0eca7ea723c8544224f93dcb311697c26f (diff)
openpgp: Fix clone.
- derive(Clone) doesn't work with generic parameters that don't implement clone. - In the case of ComponentAmalgamation and ValidComponentAmalgamation, we don't need to require that their generic parameter implements Clone, because we're not cloning C, just the reference. See https://github.com/rust-lang/rust/issues/26925 .
-rw-r--r--openpgp/src/cert/amalgamation.rs67
1 files changed, 65 insertions, 2 deletions
diff --git a/openpgp/src/cert/amalgamation.rs b/openpgp/src/cert/amalgamation.rs
index f60589ae..10baf8ab 100644
--- a/openpgp/src/cert/amalgamation.rs
+++ b/openpgp/src/cert/amalgamation.rs
@@ -1,6 +1,7 @@
use std::borrow::Borrow;
use std::time;
use std::time::SystemTime;
+use std::clone::Clone;
use crate::{
cert::prelude::*,
@@ -205,12 +206,26 @@ pub trait ValidAmalgamation<'a, C: 'a> : Amalgamation<'a, C> {
}
/// A certificate's component and its associated data.
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct ComponentAmalgamation<'a, C>{
cert: &'a Cert,
bundle: &'a ComponentBundle<C>,
}
+// derive(Clone) doesn't work with generic parameters that don't
+// implement clone. But, we don't need to require that C implements
+// Clone, because we're not cloning C, just the reference.
+//
+// See: https://github.com/rust-lang/rust/issues/26925
+impl<'a, C> Clone for ComponentAmalgamation<'a, C> {
+ fn clone(&self) -> Self {
+ Self {
+ cert: self.cert,
+ bundle: self.bundle,
+ }
+ }
+}
+
impl<'a, C> std::ops::Deref for ComponentAmalgamation<'a, C> {
type Target = ComponentBundle<C>;
@@ -287,7 +302,7 @@ impl<'a> ComponentAmalgamation<'a, crate::packet::UserAttribute> {
}
/// A certificate's component and its associated data.
-#[derive(Debug, Clone)]
+#[derive(Debug)]
pub struct ValidComponentAmalgamation<'a, C> {
a: ComponentAmalgamation<'a, C>,
policy: &'a dyn Policy,
@@ -297,6 +312,22 @@ pub struct ValidComponentAmalgamation<'a, C> {
binding_signature: &'a Signature,
}
+// derive(Clone) doesn't work with generic parameters that don't
+// implement clone. But, we don't need to require that C implements
+// Clone, because we're not cloning C, just the reference.
+//
+// See: https://github.com/rust-lang/rust/issues/26925
+impl<'a, C> Clone for ValidComponentAmalgamation<'a, C> {
+ fn clone(&self) -> Self {
+ Self {
+ a: self.a.clone(),
+ policy: self.policy,
+ time: self.time,
+ binding_signature: self.binding_signature,
+ }
+ }
+}
+
impl<'a, C> std::ops::Deref for ValidComponentAmalgamation<'a, C> {
type Target = ComponentAmalgamation<'a, C>;
@@ -467,3 +498,35 @@ impl<'a, C> ValidAmalgamation<'a, C> for ValidComponentAmalgamation<'a, C> {
impl<'a, C> crate::cert::Preferences<'a, C>
for ValidComponentAmalgamation<'a, C> {}
+
+#[cfg(test)]
+mod test {
+ use crate::policy::StandardPolicy as P;
+ use crate::cert::prelude::*;
+ use crate::packet::UserID;
+
+ // derive(Clone) doesn't work with generic parameters that don't
+ // implement clone. Make sure that our custom implementations
+ // work.
+ //
+ // See: https://github.com/rust-lang/rust/issues/26925
+ #[test]
+ fn clone() {
+ let p = &P::new();
+
+ let (cert, _) = CertBuilder::new()
+ .add_userid("test@example.example")
+ .generate()
+ .unwrap();
+
+ let userid : ComponentAmalgamation<UserID>
+ = cert.userids().nth(0).unwrap();
+ assert_eq!(userid.userid(), userid.clone().userid());
+
+ let userid : ValidComponentAmalgamation<UserID>
+ = userid.with_policy(p, None).unwrap();
+ let c = userid.clone();
+ assert_eq!(userid.userid(), c.userid());
+ assert_eq!(userid.time(), c.time());
+ }
+}