Skip to content

Instantly share code, notes, and snippets.

@aldanor
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aldanor/a0d8da55e3fde02819e0 to your computer and use it in GitHub Desktop.
Save aldanor/a0d8da55e3fde02819e0 to your computer and use it in GitHub Desktop.
use std::cell::RefCell;
use std::rc::Rc;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
#[derive(Debug)]
struct Handle {
id: Rc<RefCell<i32>>,
}
impl Handle {
fn new(id: &Rc<RefCell<i32>>) -> Handle {
Handle { id: id.clone() }
}
fn close(&self) {
*self.id.borrow_mut() = -1;
}
}
#[derive(Debug)]
struct Factory {
pub registry: HashMap<i32, Rc<RefCell<i32>>>,
}
impl Factory {
fn new() -> Factory {
Factory { registry: HashMap::new() }
}
fn new_id(&mut self, id: i32) -> Handle {
let entry = self.registry.entry(id);
match entry {
Entry::Occupied(_) => println!("id {} already exists, returning a clone", id),
Entry::Vacant(_) => println!("creating a new id: {}", id),
};
let handle = entry.or_insert(Rc::new(RefCell::new(id)));
if *handle.borrow() != id {
println!("dangling id, creating a new ref cell");
*handle = Rc::new(RefCell::new(id));
}
Handle::new(handle)
}
}
fn main() {
let mut factory = Factory::new();
println!("-> creating a with id 42");
let a = factory.new_id(42);
println!("-> creating b with id 42");
let b = factory.new_id(42);
println!("factory: {:?}", factory);
println!("a: {:?}, b: {:?}", a, b);
println!("-> closing a");
a.close();
println!("factory: {:?}", factory);
println!("a: {:?}, b: {:?}", a, b);
println!("-> creating c with id 42");
let c = factory.new_id(42);
println!("-> creating d with id 42");
let d = factory.new_id(42);
println!("factory: {:?}", factory);
println!("a: {:?}, b: {:?}", a, b);
println!("c: {:?}, d: {:?}", c, d);
println!("-> closing c");
c.close();
println!("c: {:?}, d: {:?}", c, d);
}
/*
-> creating a with id 42
creating a new id: 42
-> creating b with id 42
id 42 already exists, returning a clone
factory: Factory { registry: {42: RefCell { value: 42 }} }
a: Handle { id: RefCell { value: 42 } }, b: Handle { id: RefCell { value: 42 } }
-> closing a
factory: Factory { registry: {42: RefCell { value: -1 }} }
a: Handle { id: RefCell { value: -1 } }, b: Handle { id: RefCell { value: -1 } }
-> creating c with id 42
id 42 already exists, returning a clone
dangling id, creating a new ref cell
-> creating d with id 42
id 42 already exists, returning a clone
factory: Factory { registry: {42: RefCell { value: 42 }} }
a: Handle { id: RefCell { value: -1 } }, b: Handle { id: RefCell { value: -1 } }
c: Handle { id: RefCell { value: 42 } }, d: Handle { id: RefCell { value: 42 } }
-> closing c
c: Handle { id: RefCell { value: -1 } }, d: Handle { id: RefCell { value: -1 } }
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment