shareable 0.1.1

Thread shareable objects using the minimal amount of synchronization.
Documentation
/* Copyright 2016 Joshua Gentry
 *
 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 * http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 * <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 * option. This file may not be copied, modified, or distributed
 * except according to those terms.
 */
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};


//*************************************************************************************************
/// Shareable boolean data element.
///
/// # Examples
///
/// ```
/// use std::sync::mpsc;
/// use std::thread;
/// use shareable::SharedBool;
///
/// // Multiple threads, atomic values are used.
/// let value1 = SharedBool::new(false);
/// let value2 = value1.clone();
///
/// let (tx, rx) = mpsc::channel();
///
/// let thread = thread::spawn(move || {
///     rx.recv();
///     assert_eq!(value2.get(), true);
/// });
///
/// value1.set(true);
///
/// tx.send(());
/// thread.join().unwrap();
/// ```
#[derive(Clone)]
pub struct SharedBool
{
    //---------------------------------------------------------------------------------------------
    /// The internal data element.
    data : Arc<AtomicBool>
}

impl SharedBool
{
    //********************************************************************************************
    /// Construct a new instance of the object.
    pub fn new(
        value : bool
        ) -> SharedBool
    {
        SharedBool {
            data : Arc::new(AtomicBool::new(value))
        }
    }

    //********************************************************************************************
    /// Set the value of the object.
    pub fn set(
        &self,
        value : bool
        )
    {
        self.data.store(value, Ordering::Relaxed);
    }

    //********************************************************************************************
    /// Returns the value of the object.
    pub fn get(&self) -> bool
    {
        self.data.load(Ordering::Relaxed)
    }
}

use std::fmt::{Debug, Display, Formatter, Error};

impl Debug for SharedBool
{
    //*********************************************************************************************
    /// Implementation of Debug.
    fn fmt(
        &self,
        f : &mut Formatter
        ) -> Result<(), Error>
    {
        write!(f, "{:?}", self.get())
    }
}

impl Display for SharedBool
{
    //*********************************************************************************************
    /// Implementation of Display.
    fn fmt(
        &self,
        f : &mut Formatter
        ) -> Result<(), Error>
    {
        write!(f, "{}", self.get())
    }
}

#[cfg(test)]
mod tests
{

    //*********************************************************************************************
    /// Test that get/set work with only 1 instance.
    #[test]
    fn test_single()
    {
        let test = super::SharedBool::new(false);

        assert_eq!(test.get(), false);
        test.set(true);
        assert_eq!(test.get(), true);
    }

    //*********************************************************************************************
    /// Test that get/set work with multiple instances.
    #[test]
    fn test_multiple()
    {
        let test1 = super::SharedBool::new(true);
        let test2 = test1.clone();
        let test3 = test2.clone();

        assert_eq!(test1.get(), true);
        assert_eq!(test2.get(), true);
        assert_eq!(test3.get(), true);

        test1.set(false);

        assert_eq!(test1.get(), false);
        assert_eq!(test2.get(), false);
        assert_eq!(test3.get(), false);

        test2.set(true);

        assert_eq!(test1.get(), true);
        assert_eq!(test2.get(), true);
        assert_eq!(test3.get(), true);

        test3.set(false);

        assert_eq!(test1.get(), false);
        assert_eq!(test2.get(), false);
        assert_eq!(test3.get(), false);
    }
}