Skip to main content

sendify/
sendify.rs

1/// Wraps an immutable reference to make it [`Send`](https://doc.rust-lang.org/nightly/core/marker/trait.Send.html) + [`Sync`](https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html).
2pub struct Sendify<T> {
3    ptr: *const T,
4}
5
6impl<T> Sendify<T> {
7    /// Wraps an immutable reference to make it [`Send`](https://doc.rust-lang.org/nightly/core/marker/trait.Send.html) + [`Sync`](https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html).
8    pub fn wrap(val: &T) -> Sendify<T> {
9        Sendify { ptr: val }
10    }
11
12    /// Unwraps the immutable reference. Make sure the reference is still valid while unwrapping it.
13    pub unsafe fn unwrap<'a>(self) -> &'a T {
14        self.ptr.as_ref().unwrap()
15    }
16}
17
18unsafe impl<T: Send + 'static> Send for Sendify<T> {}
19unsafe impl<T: Sync + 'static> Sync for Sendify<T> {}
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24    use std::thread;
25
26    #[test]
27    fn test_sendify() {
28        let data = "my string".to_owned();
29
30        let ref_val = &data;
31        let sendify_val = Sendify::wrap(ref_val);
32
33        thread::spawn(move || {
34            let ref_val = unsafe { sendify_val.unwrap() };
35            assert_eq!(ref_val, "my string")
36        })
37        .join()
38        .unwrap();
39
40        assert_eq!(data, "my string")
41    }
42}