diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-12-08 18:15:06 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-12-09 09:47:36 +0100 |
commit | a8523c266e9934864fe5d14348122187395a2770 (patch) | |
tree | c13927eaf8df09ee91a054fc73bdcaee889d51a6 | |
parent | ffda43c082b79f7698152287b8236b6c0c9918ec (diff) |
buffered-reader: Assert that all types are Send and Sync.
- See #615.
-rw-r--r-- | buffered-reader/src/adapter.rs | 5 | ||||
-rw-r--r-- | buffered-reader/src/decompress_bzip2.rs | 4 | ||||
-rw-r--r-- | buffered-reader/src/decompress_deflate.rs | 8 | ||||
-rw-r--r-- | buffered-reader/src/dup.rs | 4 | ||||
-rw-r--r-- | buffered-reader/src/eof.rs | 3 | ||||
-rw-r--r-- | buffered-reader/src/file_generic.rs | 3 | ||||
-rw-r--r-- | buffered-reader/src/file_unix.rs | 3 | ||||
-rw-r--r-- | buffered-reader/src/generic.rs | 4 | ||||
-rw-r--r-- | buffered-reader/src/lib.rs | 3 | ||||
-rw-r--r-- | buffered-reader/src/limitor.rs | 4 | ||||
-rw-r--r-- | buffered-reader/src/macros.rs | 52 | ||||
-rw-r--r-- | buffered-reader/src/memory.rs | 3 | ||||
-rw-r--r-- | buffered-reader/src/reserve.rs | 4 |
13 files changed, 100 insertions, 0 deletions
diff --git a/buffered-reader/src/adapter.rs b/buffered-reader/src/adapter.rs index 7b620a2b..65c7a8aa 100644 --- a/buffered-reader/src/adapter.rs +++ b/buffered-reader/src/adapter.rs @@ -16,6 +16,11 @@ pub struct Adapter<T: BufferedReader<B>, B: fmt::Debug, C: fmt::Debug> { cookie: C, } +assert_send_and_sync!(Adapter<T, B, C> + where T: BufferedReader<B>, + B: fmt::Debug, + C: fmt::Debug); + impl<T: BufferedReader<B>, B: fmt::Debug, C: fmt::Debug> fmt::Display for Adapter<T, B, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Adapter").finish() diff --git a/buffered-reader/src/decompress_bzip2.rs b/buffered-reader/src/decompress_bzip2.rs index c0c60653..8902c2af 100644 --- a/buffered-reader/src/decompress_bzip2.rs +++ b/buffered-reader/src/decompress_bzip2.rs @@ -13,6 +13,10 @@ pub struct Bzip<R: BufferedReader<C>, C: fmt::Debug> { reader: Generic<BzDecoder<R>, C>, } +assert_send_and_sync!(Bzip<R, C> + where R: BufferedReader<C>, + C: fmt::Debug); + impl <R: BufferedReader<()>> Bzip<R, ()> { /// Instantiates a new bzip decompression reader. /// diff --git a/buffered-reader/src/decompress_deflate.rs b/buffered-reader/src/decompress_deflate.rs index 6d8af629..43084a5f 100644 --- a/buffered-reader/src/decompress_deflate.rs +++ b/buffered-reader/src/decompress_deflate.rs @@ -13,6 +13,10 @@ pub struct Deflate<R: BufferedReader<C>, C: fmt::Debug> { reader: Generic<DeflateDecoder<R>, C>, } +assert_send_and_sync!(Deflate<R, C> + where R: BufferedReader<C>, + C: fmt::Debug); + impl <R: BufferedReader<()>> Deflate<R, ()> { /// Instantiates a new deflate decompression reader. /// @@ -127,6 +131,10 @@ pub struct Zlib<R: BufferedReader<C>, C: fmt::Debug> { reader: Generic<ZlibDecoder<R>, C>, } +assert_send_and_sync!(Zlib<R, C> + where R: BufferedReader<C>, + C: fmt::Debug); + impl <R: BufferedReader<()>> Zlib<R, ()> { /// Instantiates a new zlib decompression reader. /// diff --git a/buffered-reader/src/dup.rs b/buffered-reader/src/dup.rs index afca4296..50a9aa26 100644 --- a/buffered-reader/src/dup.rs +++ b/buffered-reader/src/dup.rs @@ -21,6 +21,10 @@ pub struct Dup<T: BufferedReader<C>, C: fmt::Debug> { cookie: C, } +assert_send_and_sync!(Dup<T, C> + where T: BufferedReader<C>, + C: fmt::Debug); + impl<T: BufferedReader<C>, C: fmt::Debug> fmt::Display for Dup<T, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Dup") diff --git a/buffered-reader/src/eof.rs b/buffered-reader/src/eof.rs index 7f36e074..c21ecde9 100644 --- a/buffered-reader/src/eof.rs +++ b/buffered-reader/src/eof.rs @@ -10,6 +10,9 @@ pub struct EOF<C> { cookie: C, } +assert_send_and_sync!(EOF<C> + where C: fmt::Debug); + impl<C> fmt::Display for EOF<C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("EOF") diff --git a/buffered-reader/src/file_generic.rs b/buffered-reader/src/file_generic.rs index 4a1cb830..cc9f1367 100644 --- a/buffered-reader/src/file_generic.rs +++ b/buffered-reader/src/file_generic.rs @@ -12,6 +12,9 @@ use crate::file_error::FileError; /// platform-specific versions. pub struct File<C: fmt::Debug>(Generic<fs::File, C>, PathBuf); +assert_send_and_sync!(File<C> + where C: fmt::Debug); + impl<C: fmt::Debug> fmt::Display for File<C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "File {:?}", self.1.display()) diff --git a/buffered-reader/src/file_unix.rs b/buffered-reader/src/file_unix.rs index 8adca1e6..9502021f 100644 --- a/buffered-reader/src/file_unix.rs +++ b/buffered-reader/src/file_unix.rs @@ -27,6 +27,9 @@ const MMAP_THRESHOLD: u64 = 16 * 4096; /// just using a generic reader. pub struct File<'a, C: fmt::Debug>(Imp<'a, C>, PathBuf); +assert_send_and_sync!(File<'_, C> + where C: fmt::Debug); + impl<'a, C: fmt::Debug> fmt::Display for File<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{} {:?}", self.0, self.1.display()) diff --git a/buffered-reader/src/generic.rs b/buffered-reader/src/generic.rs index 2332950e..25c56272 100644 --- a/buffered-reader/src/generic.rs +++ b/buffered-reader/src/generic.rs @@ -28,6 +28,10 @@ pub struct Generic<T: io::Read, C: fmt::Debug> { cookie: C, } +assert_send_and_sync!(Generic<T, C> + where T: io::Read, + C: fmt::Debug); + impl<T: io::Read, C: fmt::Debug> fmt::Display for Generic<T, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Generic") diff --git a/buffered-reader/src/lib.rs b/buffered-reader/src/lib.rs index 83f6da1c..45c12726 100644 --- a/buffered-reader/src/lib.rs +++ b/buffered-reader/src/lib.rs @@ -231,6 +231,9 @@ use std::cmp; use std::fmt; use std::convert::TryInto; +#[macro_use] +mod macros; + mod generic; mod memory; mod limitor; diff --git a/buffered-reader/src/limitor.rs b/buffered-reader/src/limitor.rs index 369c9f11..de75ee5e 100644 --- a/buffered-reader/src/limitor.rs +++ b/buffered-reader/src/limitor.rs @@ -13,6 +13,10 @@ pub struct Limitor<T: BufferedReader<C>, C: fmt::Debug> { cookie: C, } +assert_send_and_sync!(Limitor<T, C> + where T: BufferedReader<C>, + C: fmt::Debug); + impl<T: BufferedReader<C>, C: fmt::Debug> fmt::Display for Limitor<T, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Limitor") diff --git a/buffered-reader/src/macros.rs b/buffered-reader/src/macros.rs new file mode 100644 index 00000000..ff30d6fb --- /dev/null +++ b/buffered-reader/src/macros.rs @@ -0,0 +1,52 @@ +/// 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 second argument +/// including a trait bound when needed: +/// +/// ``` +/// pub struct MyWriter<W: io::Write> {} +/// assert_send_and_sync!(MyWriterStruct<W>, 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: +/// +/// ``` +/// pub struct MyWriterWithLifetime<a', C, W: io::Write> {} +/// assert_send_and_sync!(MyWriterStruct<'_, C, W>, C, W: io::Write); +/// ``` +/// +macro_rules! assert_send_and_sync { + ( $x:ty where $( $g:ident$( : $b:path )? $(,)?)*) => { + impl<$( $g ),*> crate::macros::Sendable for $x + where $( $g: Send + Sync $(+ $b)? ),* + {} + impl<$( $g ),*> crate::macros::Syncable for $x + where $( $g: Send + Sync $(+ $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 {} diff --git a/buffered-reader/src/memory.rs b/buffered-reader/src/memory.rs index de2f61bb..d13dd018 100644 --- a/buffered-reader/src/memory.rs +++ b/buffered-reader/src/memory.rs @@ -21,6 +21,9 @@ pub struct Memory<'a, C: fmt::Debug> { cookie: C, } +assert_send_and_sync!(Memory<'_, C> + where C: fmt::Debug); + impl<'a, C: fmt::Debug> fmt::Display for Memory<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Memory ({} of {} bytes read)", diff --git a/buffered-reader/src/reserve.rs b/buffered-reader/src/reserve.rs index 9d3d755f..b9c59b69 100644 --- a/buffered-reader/src/reserve.rs +++ b/buffered-reader/src/reserve.rs @@ -17,6 +17,10 @@ pub struct Reserve<T: BufferedReader<C>, C: fmt::Debug> { cookie: C, } +assert_send_and_sync!(Reserve<T, C> + where T: BufferedReader<C>, + C: fmt::Debug); + impl<T: BufferedReader<C>, C: fmt::Debug> fmt::Display for Reserve<T, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Reserve") |