Skip to content

Instantly share code, notes, and snippets.

@stevedonovan
Created April 14, 2017 13:49
Show Gist options
  • Save stevedonovan/7e3a6d8c8921e3eff16c4b11ab82b8d7 to your computer and use it in GitHub Desktop.
Save stevedonovan/7e3a6d8c8921e3eff16c4b11ab82b8d7 to your computer and use it in GitHub Desktop.

Revisions

  1. stevedonovan created this gist Apr 14, 2017.
    93 changes: 93 additions & 0 deletions shared.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@
    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()));



    }