bottle 0.1.0

Actor model framework for Rust.
use std::sync::{RwLock, RwLockReadGuard, LockResult, PoisonError};

pub struct Actor<T: ?Sized> {
    pub lock: Option<RwLock<()>>,
    pub data: T
}

unsafe impl<T> Sync for Actor<T> {}
unsafe impl<T> Send for Actor<T> {}

impl<T: ?Sized> Actor<T> {
    pub unsafe fn uninitialized() -> Actor<T> where T: Sized {
        Actor {
            lock: None,
            data: unsafe { std::mem::uninitialized() }
        }
    }

    pub fn new(t: T) -> Actor<T> where T: Sized {
        Actor {
            lock: Some(RwLock::new(())),
            data: t
        }
    }
}

pub struct ActorReadGuard<'a, T: 'a + ?Sized> {
    guard: RwLockReadGuard<'a, ()>,
    data: &'a T
}

impl<T: ?Sized> Actor<T> {
    pub unsafe fn initialize(&mut self, mut t: T) where T: Sized {
        self.lock = Some(RwLock::new(()));
        std::mem::swap(&mut self.data, &mut t);
        std::mem::forget(t);
    }

    pub fn is_initialized(&self) -> bool {
        self.lock.is_some()
    }

    pub fn read<'a>(&self) -> LockResult<ActorReadGuard<T>> {
        match &self.lock {
            Some(lock) => {
                match lock.read() {
                    Ok(guard) => Ok(ActorReadGuard {
                        guard: guard,
                        data: &self.data
                    }),
                    Err(e) => Err(PoisonError::new(ActorReadGuard {
                        guard: e.into_inner(),
                        data: &self.data
                    }))
                }
            },
            None => {
                panic!("unallocated data")
            }
        }
    }
}