Crate borrow_with_ref_obj[−][src]
The BorrowWithRefObj
and BorrowMutWithRefObj
traits are versions of Borrow
and BorrowMut
that can return a reference
object (Such as std::cell::Ref
or std::sync::MutexGuard
) instead of just
a pointer.
This allows you to accept T
, &T
, Rc<RefCell<T>>
, Arc<Mutex<T>>
, and
Arc<RwLock<T>>
by requiring a single trait.
Note: using these traits requires using higher-ranked trait bounds, until RFC 1598 is implemented. See the example below.
Example
use borrow_with_ref_obj::BorrowWithRefObj; /// Example structure that can possibly share ownership of a u32. /// /// Modeled after a work queue getting data from a central source (ex. a /// database) that may or may not be shared with others. /// /// Note: Need to use higher-ranked trait bound here (for<'refr>), to tell /// rust that the object that `borrow` returns about its lifetime. struct Processor<Ref: for<'refr> BorrowWithRefObj<'refr, u32>> { /// Potentially-shared reference to a datum. /// Pretend this is a database connection or something like that. data_source: Ref, /// Queue of work to process work_queue: Vec<u32>, } impl<Ref: for<'refr> BorrowWithRefObj<'refr, u32>> Processor<Ref> { pub fn new(source: Ref) -> Self { Self { data_source: source, work_queue: vec![1,2,3,4,5], } } /// Processes one element in the work queue pub fn process_one(&mut self) { let current_work = match self.work_queue.pop() { Some(v) => v, None => { return; } }; let data_source = self.data_source.borrow(); let current_result = current_work + *data_source; println!("{}", current_result); } /// Processes all elements in the work queue pub fn process_all(&mut self) { while !self.work_queue.is_empty() { self.process_one(); } } } // Create a processor that is the sole owner of the data let mut sole_owning_processor = Processor::new(1); // Prints 2,3,4,5,6 sole_owning_processor.process_all(); // Creates a processor that borrows the data let value = 2; let mut borrowing_processor = Processor::new(&value); // Prints 3,4,5,6,7 sole_owning_processor.process_all(); // Creates a processor that shares ownership via Rc<RefCell<u32>> use std::rc::Rc; use std::cell::RefCell; let value = Rc::new(RefCell::new(1)); let mut rc_processor = Processor::new(Rc::clone(&value)); // Prints 2,3,4 rc_processor.process_one(); rc_processor.process_one(); rc_processor.process_one(); // Modify the value *value.borrow_mut() = 5; // Prints 9,10 rc_processor.process_one(); rc_processor.process_one(); // You can do the same as above with Arc<Mutex<T>> or Arc<RwLock<T>>, if you // need thread-safe access.
Structs
BoxedBorrowMutWithRefObj |
Dynamic |
BoxedBorrowWithRefObj |
Dynamic |
BoxedMutReference |
Wrapper for |
BoxedReference |
Wrapper for |
Traits
BorrowMutWithRefObj |
Mutable borrower whose reference is an object. |
BorrowWithRefObj |
Immutable borrower whose reference is an object. |