Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An ergonomic way of saying Rc<RefCell>
use std::rc::Rc;
use std::cell::{RefCell,Ref, RefMut};
use std::ops::Deref;
use std::fmt;
#[derive(Clone)]
struct Shared<T> {
v: Rc<RefCell<T>>
}
impl <T> Shared<T> {
fn new(t: T)-> Shared<T> {
Shared{v: Rc::new(RefCell::new(t))}
}
}
impl <T> Shared<T> {
fn borrow(&self) -> Ref<T> {
self.v.borrow()
}
fn borrow_mut(&self) -> RefMut<T> {
self.v.borrow_mut()
}
fn as_ptr(&self) -> *mut T {
self.v.as_ptr()
}
}
impl <T: fmt::Display> fmt::Display for Shared<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.deref())
}
}
impl <T: fmt::Debug> fmt::Debug for Shared<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.deref())
}
}
impl <'a,T> Deref for Shared<T>{
type Target = T;
#[inline]
fn deref(&self) -> &T {
unsafe {self.as_ptr().as_ref().unwrap()}
}
}
/*
// Cute, but useless, since it needs to be mutable
// and so can't be shared anyway
impl <'a, T> DerefMut for Shared<T>
{ #[inline]
fn deref_mut(&mut self) -> &mut T {
unsafe {self.as_ptr().as_mut().unwrap()}
}
}
*/
fn split (s: Shared<String>) -> Vec<String> {
s.split_whitespace().map(|s| s.to_string()).collect()
}
fn main() {
let s = Shared::new("hello".to_string());
let s2 = s.clone();
s2.borrow_mut().push('!');
println!("{:?}",s2);
// Deref kicking in...
let n = s2.len();
println!("{:?}", n);
// mutation has to be explicit
s2.borrow_mut().push_str(" dolly");
println!("{:?} {}",s2.borrow(), s);
println!("{:?}", split(s2.clone()));
}
@the-shank

This comment has been minimized.

Copy link

the-shank commented Aug 2, 2019

This is great! And so readable!

@wdanilo

This comment has been minimized.

Copy link

wdanilo commented Nov 20, 2019

@stevedonovan I think the implementation is unsound. The unsafe {self.as_ptr().as_ref().unwrap()} part gives you what is inside the RefCell but does not prevent anyone from calling borrow_mut while the deref is still in scope.

@stevedonovan

This comment has been minimized.

Copy link
Owner Author

stevedonovan commented Nov 20, 2019

You are completely correct, alas.

@mamcx

This comment has been minimized.

Copy link

mamcx commented Dec 15, 2019

Some way to fix it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.