diff options
author | Azul <azul@riseup.net> | 2020-10-09 20:05:33 +0200 |
---|---|---|
committer | Azul <azul@riseup.net> | 2020-10-26 17:47:09 +0100 |
commit | d662a80e8f7c96b72708e4124546f72d2712ed40 (patch) | |
tree | beb51cb910bdb1448e4a3edfe4059dca78eb7e8e | |
parent | 3fc8654d33c8c57542250eda8e910a2ffa0b8a81 (diff) |
openpgp: seal the Preferences trait
[Seal] the `cert::Preferences` trait
so it cannot be implemented for types outside this crate.
Therefore it can be extended in a non-breaking way.
Attempts to implement the trait will not compile.
refers: #538
[seal]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
-rw-r--r-- | openpgp/src/cert.rs | 13 | ||||
-rw-r--r-- | openpgp/src/cert/amalgamation.rs | 2 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 1 | ||||
-rw-r--r-- | openpgp/src/seal.rs | 46 |
4 files changed, 60 insertions, 2 deletions
diff --git a/openpgp/src/cert.rs b/openpgp/src/cert.rs index bcfd79be..abcc3ae5 100644 --- a/openpgp/src/cert.rs +++ b/openpgp/src/cert.rs @@ -437,8 +437,15 @@ type UnknownBundles = ComponentBundles<Unknown>; /// # Ok(()) } /// ``` /// -/// [Section 5.2.3.3]: https://tools.ietf.org/html/rfc4880#section-5.2.3.3 -pub trait Preferences<'a> { +/// # Sealed trait +/// +/// This trait is [sealed] and cannot be implemented for types outside this crate. +/// Therefore it can be extended in a non-breaking way. +/// If you want to implement the trait inside the crate +/// you also need to implement the `seal::Sealed` marker trait. +/// +/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +pub trait Preferences<'a>: crate::seal::Sealed { /// Returns the supported symmetric algorithms ordered by /// preference. /// @@ -2787,6 +2794,8 @@ pub struct ValidCert<'a> { time: time::SystemTime, } +impl<'a> crate::seal::Sealed for ValidCert<'a> {} + impl<'a> std::ops::Deref for ValidCert<'a> { type Target = Cert; diff --git a/openpgp/src/cert/amalgamation.rs b/openpgp/src/cert/amalgamation.rs index def67a4d..3d4602bc 100644 --- a/openpgp/src/cert/amalgamation.rs +++ b/openpgp/src/cert/amalgamation.rs @@ -1057,6 +1057,8 @@ pub struct ValidComponentAmalgamation<'a, C> { binding_signature: &'a Signature, } +impl<'a, C> crate::seal::Sealed for ValidComponentAmalgamation<'a, C> {} + /// A Valid User ID and its associated data. /// /// A specialized version of [`ValidComponentAmalgamation`]. diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index cce9ad6e..d71bb483 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -152,6 +152,7 @@ mod keyhandle; pub use keyhandle::KeyHandle; pub mod policy; +pub(crate) mod seal; pub(crate) mod utils; #[cfg(test)] diff --git a/openpgp/src/seal.rs b/openpgp/src/seal.rs new file mode 100644 index 00000000..bfdbd1e4 --- /dev/null +++ b/openpgp/src/seal.rs @@ -0,0 +1,46 @@ +//! [Sealing Traits] +//! +//! [sealing traits:] https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +//! +//! Prevent the implementation of traits outside of the crate +//! to allow extension of the traits at a later time. +//! +//! Mark a trait as sealed by deriving it from seal::Sealed. +//! +//! Only Implementations of seal::Sealed will be able to implement the trait. +//! Since seal::Sealed is only visible inside the crate +//! sealed traits can only be implemented in the crate. + +/// This trait is used to [seal] other traits so they cannot +/// be implemented for types outside this crate. +/// Therefore they can be extended in a non-breaking way. +/// +/// [seal]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +/// +/// # Examples +/// +/// For example the [`cert::Preferences`] trait is sealed. +/// Therefore attempts to implement it will not compile: +/// +/// [`cert::Preferences`]: ../cert/trait.Preferences.html +/// +/// ```compile_fail +/// # extern crate sequoia_openpgp as openpgp; +/// use openpgp::cert::prelude::*; +/// use openpgp::cert::Preferences; +/// use openpgp::types::*; +/// +/// pub struct InvalidComponentAmalgamation {} +/// impl<'a> Preferences<'a> for InvalidComponentAmalgamation { //~ ERROR `_x @` is not allowed in a tuple +/// fn preferred_symmetric_algorithms(&self) +/// -> Option<&'a [SymmetricAlgorithm]> { None } +/// fn preferred_hash_algorithms(&self) -> Option<&'a [HashAlgorithm]> { None } +/// fn preferred_compression_algorithms(&self) +/// -> Option<&'a [CompressionAlgorithm]> { None } +/// fn preferred_aead_algorithms(&self) -> Option<&'a [AEADAlgorithm]> { None } +/// fn key_server_preferences(&self) -> Option<KeyServerPreferences> { None } +/// fn preferred_key_server(&self) -> Option<&'a [u8]> { None } +/// fn features(&self) -> Option<Features> { None } +/// } +/// ``` +pub trait Sealed {} |