send_sync_static/
lib.rs

1#![forbid(unsafe_code)]
2#![no_std]
3
4//!
5//! A very basic crate, whose only purpose is to allow marking types [`Send`], [`Sync`], and `'static`
6//!
7
8use core::future::Future;
9
10///
11/// A marker which identifies a type as [`Send`], [`Sync`], and `'static`.
12/// This trait is automatically implemented for any types which fulfill these requirements,
13/// and it is intended to be used as a shorthand for writing out each bound. For example:
14/// ```
15/// use send_sync_static::SSS;
16/// pub async fn send_data<D>(data: D) where D: SSS {
17///   // Do something here
18/// }
19/// ```
20///
21/// Code written explicitly using [`Send`], [`Sync`], and `'static` is fully interchangeable with this trait.
22///
23pub trait SSS: Send + Sync + 'static {}
24
25impl<S> SSS for S where S: Send + Sync + 'static {}
26
27///
28/// A marker which identifies a [`Future`] (but not necessarily its output) as [`Send`], [`Sync`], and `'static`.
29///
30/// This trait is automatically implemented for futures which fulfill these requirements,
31/// and it is intended to be used as a shorthand for writing out each bound. For example:
32/// ```
33/// use send_sync_static::{FutureSSS, SSS};
34/// pub fn send_data<D: SSS>(data: D) -> impl FutureSSS {
35///   // Guarantees the async block is always Send, Sync, and 'static
36///   async move {
37///     // Do something here
38///     drop(data)
39///   }
40/// }
41/// ```
42/// This can be combined with RPITIT, an upcoming stable feature.
43/// ```ignore
44/// use send_sync_static::FutureSSS;
45/// pub trait Database {
46///   fn add_user(&self, user: String) -> impl FutureSSS<Output = ()>;
47/// }
48/// ```
49///
50/// Code written explicitly using [`Send`], [`Sync`], and `'static` is fully interchangeable with this trait.
51///
52pub trait FutureSSS: Future + SSS {}
53
54impl<F> FutureSSS for F where F: Future + SSS {}
55
56#[cfg(test)]
57mod tests {
58    use crate::{FutureSSS, SSS};
59
60    #[test]
61    fn implemented() {
62        fn assert_sss<V: SSS>(_val: V) {}
63        fn assert_future_sss<F: FutureSSS<Output = usize>>(f: F) -> Option<usize> {
64            assert_sss(f);
65            None
66        }
67
68        assert_sss(0usize);
69        assert_future_sss(async { 0usize });
70    }
71}