From dc27849e0e2c3772632f93c217dfa1da656a501f Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Wed, 11 Oct 2017 13:51:46 +0200 Subject: [PATCH] impl From<&mut Store> for StoreProxy --- src/lib.rs | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e61ff76..304f537 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,7 @@ #![warn(missing_docs)] use std::any::Any; +use std::borrow::Cow; use std::cell::Cell; use std::marker::PhantomData; use std::rc::Rc; @@ -167,10 +168,28 @@ impl Store { /// This can be usefull for code requiering access to a store, /// but wanting to be generic over being called from a value /// scope or not. + /// + /// You can also use the `From` and `Into` traits to perform + /// this conversion. pub fn as_proxy<'a>(&'a mut self) -> StoreProxy<'a> { StoreProxy { store: self, - borrowed: Vec::new(), + borrowed: Cow::Owned(Vec::new()), + } + } +} + +impl<'a> ::std::convert::From<&'a mut Store> for StoreProxy<'a> { + fn from(store: &'a mut Store) -> StoreProxy<'a> { + store.as_proxy() + } +} + +impl<'a, 'b> ::std::convert::From<&'a mut StoreProxy<'b>> for StoreProxy<'a> where 'b: 'a { + fn from(proxy: &'a mut StoreProxy<'b>) -> StoreProxy<'a> { + StoreProxy { + store: proxy.store, + borrowed: proxy.borrowed.clone() } } } @@ -185,7 +204,7 @@ impl Store { /// use. pub struct StoreProxy<'store> { store: &'store mut Store, - borrowed: Vec, + borrowed: Cow<'store, [usize]>, } impl<'store> StoreProxy<'store> { @@ -248,9 +267,9 @@ impl<'store> StoreProxy<'store> { let mut deeper_proxy = StoreProxy { store: &mut *self.store, borrowed: { - let mut my_borrowed = self.borrowed.clone(); + let mut my_borrowed = self.borrowed.clone().into_owned(); my_borrowed.push(token.id); - my_borrowed + Cow::Owned(my_borrowed) }, }; f(&mut deeper_proxy, value) @@ -346,8 +365,7 @@ mod tests { let mut store = Store::new(); let token = store.insert(42); store.with_value(&token, |proxy, _| { - proxy.with_value(&token, |_, _| { - }); + proxy.with_value(&token, |_, _| {}); }); } @@ -381,4 +399,20 @@ mod tests { }); } + #[test] + fn generic_into_store_proxy() { + fn insert_42<'a, S: Into>>(s: S) -> Token { + let mut proxy = s.into(); + proxy.insert(42) + } + + let mut store = Store::new(); + let token1 = insert_42(&mut store); + let token2 = store.with_value(&token1, |proxy, _| { + insert_42(proxy) + }); + assert_eq!(*store.get(&token1), 42); + assert_eq!(*store.get(&token2), 42); + } + }