Crates.io | borrow_with_ref_obj |
lib.rs | borrow_with_ref_obj |
version | 0.1.3 |
source | src |
created_at | 2018-10-02 16:49:36.002954 |
updated_at | 2018-10-02 17:13:37.799453 |
description | Versions of Borrow[Mut] that return reference objects (Ex. std::cell::Ref) |
homepage | |
repository | https://gitlab.com/colonelthirtytwo/borrow_with_ref_obj |
max_upload_size | |
id | 87638 |
size | 22,133 |
Versions of the Borrow
and BorrowMut
traits that can return
reference objects (such as std::cell::Ref
) instead of references directly.
This allows you to accept T
, &T
, Rc<RefCell<T>>
, Arc<Mutex<T>>
, and
Arc<RwLock<T>>
by requiring a single trait.
See the crate documentation for more information.
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.