diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2022-04-22 12:39:30 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2022-04-22 12:54:35 +0200 |
commit | 5306588deb273583043b557f53b44da197033c93 (patch) | |
tree | 3cfe9268ff55bfd67fc265004df4a899017cdd99 | |
parent | 054ac1eaa9f5742f7d77b65549e4869aa1979333 (diff) |
net: Assert that public types are Send + Sync.
-rw-r--r-- | net/src/lib.rs | 3 | ||||
-rw-r--r-- | net/src/macros.rs | 69 |
2 files changed, 72 insertions, 0 deletions
diff --git a/net/src/lib.rs b/net/src/lib.rs index dbd47dc3..2a45fbd8 100644 --- a/net/src/lib.rs +++ b/net/src/lib.rs @@ -60,6 +60,7 @@ use openpgp::{ serialize::Serialize, }; +#[macro_use] mod macros; pub mod pks; pub mod updates; pub mod wkd; @@ -160,6 +161,8 @@ pub struct KeyServer { uri: Url, } +assert_send_and_sync!(KeyServer); + impl KeyServer { /// Returns a handle for the given URI. pub fn new(p: Policy, uri: &str) -> Result<Self> { diff --git a/net/src/macros.rs b/net/src/macros.rs new file mode 100644 index 00000000..caad17f5 --- /dev/null +++ b/net/src/macros.rs @@ -0,0 +1,69 @@ +//! Various macros used in this crate. + +/// A simple shortcut for ensuring a type is send and sync. +/// +/// For most types just call it after defining the type: +/// +/// ``` +/// pub struct MyStruct {} +/// assert_send_and_sync!(MyStruct); +/// ``` +/// +/// For types with lifetimes, use the anonymous lifetime: +/// +/// ``` +/// pub struct WithLifetime<'a> {} +/// assert_send_and_sync!(MyStruct<'_>); +/// ``` +/// +/// For a type generic over another type `W`, +/// pass the type `W` as a where clause +/// including a trait bound when needed: +/// +/// ``` +/// pub struct MyWriter<W: io::Write> {} +/// assert_send_and_sync!(MyWriterStruct<W> where W: io::Write); +/// ``` +/// +/// This will assert that `MyWriterStruct<W>` is `Send` and `Sync` +/// if `W` is `Send` and `Sync`. +/// +/// You can also combine the two and be generic over multiple types. +/// Just make sure to list all the types - even those without additional +/// trait bounds: +/// +/// ``` +/// pub struct MyWriterWithLifetime<'a, C, W: io::Write> {}; +/// assert_send_and_sync!(MyWriterStruct<'_, C, W> where C, W: io::Write); +/// ``` +/// +/// If you need multiple additional trait bounds on a single type +/// you can add them separated by `+` like in normal where clauses. +/// However you have to make sure they are `Identifiers` like `Write`. +/// In macro patterns `Paths` (like `io::Write`) may not be followed +/// by `+` characters. +macro_rules! assert_send_and_sync { + ( $x:ty where $( $g:ident$( : $a:path )? $(,)?)*) => { + impl<$( $g ),*> crate::macros::Sendable for $x + where $( $g: Send + Sync $( + $a )? ),* + {} + impl<$( $g ),*> crate::macros::Syncable for $x + where $( $g: Send + Sync $( + $a )? ),* + {} + }; + ( $x:ty where $( $g:ident$( : $a:ident $( + $b:ident )* )? $(,)?)*) => { + impl<$( $g ),*> crate::macros::Sendable for $x + where $( $g: Send + Sync $( + $a $( + $b )* )? ),* + {} + impl<$( $g ),*> crate::macros::Syncable for $x + where $( $g: Send + Sync $( + $a $( + $b )* )? ),* + {} + }; + ( $x:ty ) => { + impl crate::macros::Sendable for $x {} + impl crate::macros::Syncable for $x {} + }; +} + +pub(crate) trait Sendable : Send {} +pub(crate) trait Syncable : Sync {} |