summaryrefslogtreecommitdiffstats
path: root/net/src
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-04-22 12:39:30 +0200
committerJustus Winter <justus@sequoia-pgp.org>2022-04-22 12:54:35 +0200
commit5306588deb273583043b557f53b44da197033c93 (patch)
tree3cfe9268ff55bfd67fc265004df4a899017cdd99 /net/src
parent054ac1eaa9f5742f7d77b65549e4869aa1979333 (diff)
net: Assert that public types are Send + Sync.
Diffstat (limited to 'net/src')
-rw-r--r--net/src/lib.rs3
-rw-r--r--net/src/macros.rs69
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 {}