diff --git a/src/cell.rs b/src/cell.rs index 6633557..2c36c17 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -49,6 +49,16 @@ impl<'a, T> Drop for Ref<'a, T> { } } +impl<'a, T> Clone for Ref<'a, T> { + fn clone(&self) -> Self { + self.flag.fetch_add(1, Ordering::Release); + Ref { + flag: self.flag, + value: self.value, + } + } +} + /// A mutable reference to data in a `TrustCell`. /// /// Access the value via `std::ops::DerefMut` (e.g. `*val`) @@ -222,6 +232,16 @@ mod tests { assert_eq!(10, *a + *b); } + #[test] + fn allow_clone_reads() { + let cell: TrustCell<_> = TrustCell::new(5); + + let a = cell.borrow(); + let b = a.clone(); + + assert_eq!(10, *a + *b); + } + #[test] fn allow_single_write() { let cell: TrustCell<_> = TrustCell::new(5); @@ -295,4 +315,15 @@ mod tests { assert!(cell.try_borrow_mut().is_err()); } + + #[test] + fn cloned_borrow_does_not_allow_write() { + let cell: TrustCell<_> = TrustCell::new(5); + + let a = cell.borrow(); + let _b = a.clone(); + drop(a); + + assert!(cell.try_borrow_mut().is_err()); + } } diff --git a/src/world/mod.rs b/src/world/mod.rs index 9c8aefc..59519c0 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -47,6 +47,15 @@ where } } +impl<'a, T> Clone for Fetch<'a, T> { + fn clone(&self) -> Self { + Fetch { + inner: self.inner.clone(), + phantom: PhantomData, + } + } +} + /// Allows to fetch a resource in a system mutably. /// /// If the resource isn't strictly required, you should use