#![feature(phase)]
#[phase(plugin, link)] extern crate mucell;
use mucell::{MuCell, Ref};
use std::collections::HashMap;
use std::borrow::Cow;
struct Inner {
pub value: Vec<int>,
munged: Option<Vec<int>>,
}
impl Inner {
pub fn new(value: Vec<int>) -> Inner {
Inner {
value: value,
munged: None,
}
}
#[allow(dead_code)]
pub fn set(&mut self, value: Vec<int>) {
self.value = value;
self.munged = None;
}
pub fn munge(&mut self) {
if self.munged.is_none() {
self.munged = Some(self.munged().into_owned());
}
}
pub fn munged(&self) -> Cow<Vec<int>, [int]> {
match self.munged {
Some(ref x) => Cow::Borrowed(x.as_slice()),
None => Cow::Owned(self.value.iter().map(|&x| x + 1).collect()),
}
}
pub fn assert_munged_exists(&self) {
assert!(self.munged.is_some())
}
pub fn assert_munged_does_not_exist(&self) {
assert!(self.munged.is_none())
}
}
mucell_ref_type! {
#[doc = "…"]
struct MungedRef<'a>(Inner)
impl Deref<[int]>
data: Cow<'a, Vec<int>, [int]> = |x| x.munged()
}
fn main() {
let mut items = HashMap::new();
items.insert("foo", MuCell::new(Inner::new(vec![1, 2, 3])));
items.insert("bar", MuCell::new(Inner::new(vec![4, 5, 6])));
items.insert("baz", MuCell::new(Inner::new(vec![7, 8, 9])));
let _active_borrow = items.get("bar").unwrap().borrow();
let item = items.get("foo").unwrap();
item.try_mutate(|x| x.munge());
item.borrow().assert_munged_exists();
let a = MungedRef::from(item);
assert_eq!(&*a, [2, 3, 4][]);
let item = items.get(&"bar").unwrap();
item.try_mutate(|x| x.munge());
item.borrow().assert_munged_does_not_exist();
let a = MungedRef::from(item);
assert_eq!(&*a, [5, 6, 7][]);
}