<commit_before>#[macro_use]
extern crate log;

use std::collections::{BTreeMap, BTreeSet};

/// The version type alias used to uniquely reference migrations.
pub type Version = i64;

/// All migrations will implement this trait, and a migration trait specific to the chosen adapter.
/// This trait defines the metadata for tracking migration sequence and for human reference.
pub trait Migration {
    /// An ordered (but not necessarily sequential), unique identifier for this migration.
    /// Registered migrations will be applied in ascending order by version.
    fn version(&self) -> Version;

    /// A message describing the effects of this migration.
    fn description(&self) -> &'static str;
}

/// Efficiently implement the `Migration` trait for a given type.
///
/// ## Example
///
/// ```rust
/// # #[macro_use]
/// # extern crate schemamama;
/// struct MyMigration;
/// migration!(MyMigration, 100, "create some lovely database tables");
///
/// # fn main() {
/// use schemamama::Migration;
/// let m = MyMigration;
/// assert_eq!(m.version(), 100);
/// assert_eq!(m.description(), "create some lovely database tables");
/// # }
/// ```
#[macro_export]
macro_rules! migration {
    ($ty:ident, $version:expr, $description:expr) => {
        impl $crate::Migration for $ty {
            fn version(&self) -> $crate::Version { $version }
            fn description(&self) -> &'static str { $description }
        }
    }
}

/// Use this trait to connect the migrator to your chosen database technology.
pub trait Adapter {
    /// An alias to a specific trait that extends `Migration`. Typically, the aforementioned trait
    /// will declare functions that the adapter will use to migrate upwards and downwards.
    type MigrationType: Migration + ?Sized;

    /// An adapter-specific error type that can be returned from any of this trait's methods.
    type Error;

    /// Returns the latest migration version, or `None` if no migrations have been recorded.
    fn current_version(&self) -> Result<Option<Version>, Self::Error>;

    /// Returns a set of the versions of all of the currently applied migrations.
    fn migrated_versions(&self) -> Result<BTreeSet<Version>, Self::Error>;

    /// Applies the specified migration.
    fn apply_migration(&self, migration: &Self::MigrationType) -> Result<(), Self::Error>;

    /// Reverts the specified migration.
    fn revert_migration(&self, migration: &Self::MigrationType) -> Result<(), Self::Error>;
}

/// Maintains an ordered collection of migrations to utilize.
pub struct Migrator<T: Adapter> {
    adapter: T,
    migrations: BTreeMap<Version, Box<T::MigrationType>>
}

impl<T: Adapter> Migrator<T> {
    /// Create a migrator with a given adapter.
    pub fn new(adapter: T) -> Migrator<T> {
        Migrator { adapter: adapter, migrations: BTreeMap::new() }
    }

    /// Get a reference to the adapter.
    pub fn adapter(&self) -> &T {
        &self.adapter
    }

    /// Register a migration. If a migration with the same version is already registered, a warning
    /// is logged and the registration fails.
    pub fn register(&mut self, migration: Box<T::MigrationType>) {
        let version = migration.version();
        if self.version_registered(version) {
            warn!("Migration with version {:?} is already registered", version);
        } else {
            self.migrations.insert(version, migration);
        }
    }

    /// Returns true is a migration with the provided version has been registered.
    pub fn version_registered(&self, version: Version) -> bool {
        self.migrations.contains_key(&version)
    }

    /// Returns the set of all registered migration versions.
    pub fn registered_versions(&self) -> BTreeSet<Version> {
        self.migrations.keys().cloned().collect()
    }

    /// Returns the lowest version of the registered migrations, or `None` if no migrations have
    /// been registered.
    pub fn first_version(&self) -> Option<Version> {
        self.migrations.keys().next().map(|v| *v)
    }

    /// Returns the highest version of the registered migrations, or `None` if no migrations have
    /// been registered.
    pub fn last_version(&self) -> Option<Version> {
        self.migrations.keys().last().map(|v| *v)
    }

    /// Returns the latest migration version, or `None` if no migrations have been recorded.
    pub fn current_version(&self) -> Result<Option<Version>, T::Error> {
        self.adapter.current_version()
    }

    /// Returns a set of the versions of all of the currently applied migrations.
    pub fn migrated_versions(&self) -> Result<BTreeSet<Version>, T::Error> {
        self.adapter.migrated_versions()
    }

    /// Rollback to the specified version (exclusive), or rollback to the state before any
    /// registered migrations were applied if `None` is specified.
    pub fn down(&self, to: Option<Version>) -> Result<(), T::Error> {
        let from = try!(self.current_version());
        if from.is_none() {
            return Ok(());
        }

        let migrated_versions = try!(self.migrated_versions());
        let targets = self.migrations.iter()
            // Rollback migrations from latest to oldest:
            .rev()
            // Rollback the current version, and all versions downwards until the specified version
            // (exclusive):
            .filter(|&(&v, _)| within_range(v, to, from))
            // Rollback only the migrations that are actually already migrated (in the case that
            // some intermediary migrations were never executed).
            .filter(|&(v, _)| migrated_versions.contains(v));

        for (version, migration) in targets {
            info!("Reverting migration {:?}: {}", version, migration.description());
            try!(self.adapter.revert_migration(migration));
        }

        Ok(())
    }

    /// Migrate to the specified version (inclusive).
    pub fn up(&self, to: Option<Version>) -> Result<(), T::Error> {
        let migrated_versions = try!(self.migrated_versions());
        let targets = self.migrations.iter()
            // Execute all versions upwards until the specified version (inclusive):
            .filter(|&(&v, _)| within_range(v, None, to))
            // Execute only the migrations that are actually not already migrated (in the case that
            // some intermediary migrations were previously executed).
            .filter(|&(v, _)| !migrated_versions.contains(v));

        for (version, migration) in targets {
            info!("Applying migration {:?}: {}", version, migration.description());
            try!(self.adapter.apply_migration(migration));
        }

        Ok(())
    }
}

// Tests whether a `Version` is within a range defined by the exclusive `low` and the inclusive
// `high` bounds.
fn within_range(version: Version, low: Option<Version>, high: Option<Version>) -> bool {
    match (low, high) {
        (None, None) => true,
        (Some(low), None) => version > low,
        (None, Some(high)) => version <= high,
        (Some(low), Some(high)) => version > low && version <= high,
    }
}

#[test]
fn test_within_range() {
    // no lower or upper bound
    assert!(within_range(0, None, None));
    assert!(within_range(42, None, None));
    assert!(within_range(100000, None, None));

    // both lower and upper bounds
    assert!(!within_range(1, Some(2), Some(5)));
    assert!(!within_range(2, Some(2), Some(5)));
    assert!(within_range(3, Some(2), Some(5)));
    assert!(within_range(5, Some(2), Some(5)));
    assert!(!within_range(6, Some(2), Some(5)));

    // lower bound only
    assert!(!within_range(0, Some(5), None));
    assert!(!within_range(4, Some(5), None));
    assert!(!within_range(5, Some(5), None));
    assert!(within_range(6, Some(5), None));
    assert!(within_range(60, Some(5), None));

    // upper bound only
    assert!(within_range(0, None, Some(5)));
    assert!(within_range(5, None, Some(5)));
    assert!(!within_range(6, None, Some(5)));
}
<commit_msg>Create `Error` to expose migration failure info<commit_after>#[macro_use]
extern crate log;

use std::collections::{BTreeMap, BTreeSet};

/// The version type alias used to uniquely reference migrations.
pub type Version = i64;

/// All migrations will implement this trait, and a migration trait specific to the chosen adapter.
/// This trait defines the metadata for tracking migration sequence and for human reference.
pub trait Migration {
    /// An ordered (but not necessarily sequential), unique identifier for this migration.
    /// Registered migrations will be applied in ascending order by version.
    fn version(&self) -> Version;

    /// A message describing the effects of this migration.
    fn description(&self) -> &'static str;
}

/// A migration's direction.
#[derive(Debug)]
pub enum Direction {
    Down,
    Up,
}

/// An all-encompassing error type that can be returned during interaction with the migrator
/// adapter.
#[derive(Debug)]
pub enum Error<E> {
    /// A generic error that occurred while interacting with the adapter.
    Adapter(E),
    /// An error that arose from the adapter specifically during a migration's execution.
    Migration {
        /// The version of the migration that failed.
        version: Version,
        /// The description of the migration that failed.
        description: &'static str,
        /// The direction in which the failed migration was ran.
        direction: Direction,
        /// The underlying error from the adapter.
        error: E,
    }
}

/// Efficiently implement the `Migration` trait for a given type.
///
/// ## Example
///
/// ```rust
/// # #[macro_use]
/// # extern crate schemamama;
/// struct MyMigration;
/// migration!(MyMigration, 100, "create some lovely database tables");
///
/// # fn main() {
/// use schemamama::Migration;
/// let m = MyMigration;
/// assert_eq!(m.version(), 100);
/// assert_eq!(m.description(), "create some lovely database tables");
/// # }
/// ```
#[macro_export]
macro_rules! migration {
    ($ty:ident, $version:expr, $description:expr) => {
        impl $crate::Migration for $ty {
            fn version(&self) -> $crate::Version { $version }
            fn description(&self) -> &'static str { $description }
        }
    }
}

/// Use this trait to connect the migrator to your chosen database technology.
pub trait Adapter {
    /// An alias to a specific trait that extends `Migration`. Typically, the aforementioned trait
    /// will declare functions that the adapter will use to migrate upwards and downwards.
    type MigrationType: Migration + ?Sized;

    /// An adapter-specific error type that can be returned from any of this trait's methods.
    type Error;

    /// Returns the latest migration version, or `None` if no migrations have been recorded.
    fn current_version(&self) -> Result<Option<Version>, Self::Error>;

    /// Returns a set of the versions of all of the currently applied migrations.
    fn migrated_versions(&self) -> Result<BTreeSet<Version>, Self::Error>;

    /// Applies the specified migration.
    fn apply_migration(&self, migration: &Self::MigrationType) -> Result<(), Self::Error>;

    /// Reverts the specified migration.
    fn revert_migration(&self, migration: &Self::MigrationType) -> Result<(), Self::Error>;
}

/// Maintains an ordered collection of migrations to utilize.
pub struct Migrator<T: Adapter> {
    adapter: T,
    migrations: BTreeMap<Version, Box<T::MigrationType>>
}

impl<T: Adapter> Migrator<T> {
    /// Create a migrator with a given adapter.
    pub fn new(adapter: T) -> Migrator<T> {
        Migrator { adapter: adapter, migrations: BTreeMap::new() }
    }

    /// Get a reference to the adapter.
    pub fn adapter(&self) -> &T {
        &self.adapter
    }

    /// Register a migration. If a migration with the same version is already registered, a warning
    /// is logged and the registration fails.
    pub fn register(&mut self, migration: Box<T::MigrationType>) {
        let version = migration.version();
        if self.version_registered(version) {
            warn!("Migration with version {:?} is already registered", version);
        } else {
            self.migrations.insert(version, migration);
        }
    }

    /// Returns true is a migration with the provided version has been registered.
    pub fn version_registered(&self, version: Version) -> bool {
        self.migrations.contains_key(&version)
    }

    /// Returns the set of all registered migration versions.
    pub fn registered_versions(&self) -> BTreeSet<Version> {
        self.migrations.keys().cloned().collect()
    }

    /// Returns the lowest version of the registered migrations, or `None` if no migrations have
    /// been registered.
    pub fn first_version(&self) -> Option<Version> {
        self.migrations.keys().next().map(|v| *v)
    }

    /// Returns the highest version of the registered migrations, or `None` if no migrations have
    /// been registered.
    pub fn last_version(&self) -> Option<Version> {
        self.migrations.keys().last().map(|v| *v)
    }

    /// Returns the latest migration version, or `None` if no migrations have been recorded.
    pub fn current_version(&self) -> Result<Option<Version>, Error<T::Error>> {
        match self.adapter.current_version() {
            Ok(ver) => Ok(ver),
            Err(err) => Err(Error::Adapter(err)),
        }
    }

    /// Returns a set of the versions of all of the currently applied migrations.
    pub fn migrated_versions(&self) -> Result<BTreeSet<Version>, Error<T::Error>> {
        match self.adapter.migrated_versions() {
            Ok(vers) => Ok(vers),
            Err(err) => Err(Error::Adapter(err)),
        }
    }

    /// Rollback to the specified version (exclusive), or rollback to the state before any
    /// registered migrations were applied if `None` is specified.
    pub fn down(&self, to: Option<Version>) -> Result<(), Error<T::Error>> {
        let from = try!(self.current_version());
        if from.is_none() {
            return Ok(());
        }

        let migrated_versions = try!(self.migrated_versions());
        let targets = self.migrations.iter()
            // Rollback migrations from latest to oldest:
            .rev()
            // Rollback the current version, and all versions downwards until the specified version
            // (exclusive):
            .filter(|&(&v, _)| within_range(v, to, from))
            // Rollback only the migrations that are actually already migrated (in the case that
            // some intermediary migrations were never executed).
            .filter(|&(v, _)| migrated_versions.contains(v));

        for (&version, migration) in targets {
            info!("Reverting migration {:?}: {}", version, migration.description());
            if let Err(err) = self.adapter.revert_migration(migration) {
                return Err(Error::Migration {
                    version: version,
                    description: migration.description(),
                    direction: Direction::Down,
                    error: err,
                });
            }
        }

        Ok(())
    }

    /// Migrate to the specified version (inclusive).
    pub fn up(&self, to: Option<Version>) -> Result<(), Error<T::Error>> {
        let migrated_versions = try!(self.migrated_versions());
        let targets = self.migrations.iter()
            // Execute all versions upwards until the specified version (inclusive):
            .filter(|&(&v, _)| within_range(v, None, to))
            // Execute only the migrations that are actually not already migrated (in the case that
            // some intermediary migrations were previously executed).
            .filter(|&(v, _)| !migrated_versions.contains(v));

        for (&version, migration) in targets {
            info!("Applying migration {:?}: {}", version, migration.description());
            if let Err(err) = self.adapter.apply_migration(migration) {
                return Err(Error::Migration {
                    version: version,
                    description: migration.description(),
                    direction: Direction::Up,
                    error: err,
                });
            }
        }

        Ok(())
    }
}

// Tests whether a `Version` is within a range defined by the exclusive `low` and the inclusive
// `high` bounds.
fn within_range(version: Version, low: Option<Version>, high: Option<Version>) -> bool {
    match (low, high) {
        (None, None) => true,
        (Some(low), None) => version > low,
        (None, Some(high)) => version <= high,
        (Some(low), Some(high)) => version > low && version <= high,
    }
}

#[test]
fn test_within_range() {
    // no lower or upper bound
    assert!(within_range(0, None, None));
    assert!(within_range(42, None, None));
    assert!(within_range(100000, None, None));

    // both lower and upper bounds
    assert!(!within_range(1, Some(2), Some(5)));
    assert!(!within_range(2, Some(2), Some(5)));
    assert!(within_range(3, Some(2), Some(5)));
    assert!(within_range(5, Some(2), Some(5)));
    assert!(!within_range(6, Some(2), Some(5)));

    // lower bound only
    assert!(!within_range(0, Some(5), None));
    assert!(!within_range(4, Some(5), None));
    assert!(!within_range(5, Some(5), None));
    assert!(within_range(6, Some(5), None));
    assert!(within_range(60, Some(5), None));

    // upper bound only
    assert!(within_range(0, None, Some(5)));
    assert!(within_range(5, None, Some(5)));
    assert!(!within_range(6, None, Some(5)));
}
<|endoftext|>


<commit_before>extern crate uname;
extern crate libc;
extern crate users;
extern crate md5;
extern crate sha2;
extern crate nix;

use std::ffi::CStr;

use libc::c_char;

use backend::Backend;
use platform::platform::Platform;
use resource::file::File;
use resource::service::Service;
use provider::Providers;

pub mod backend;
pub mod platform;
pub mod resource;
pub mod provider;
pub mod error;

pub struct Specinfra<'a> {
    pub backend: &'a Backend,
    pub platform: Box<Platform>,
    pub providers: Box<Providers>,
}

pub fn new(b: &Backend) -> Result<Specinfra, error::Error> {
    let p = try!(b.detect_platform().ok_or(platform::error::Error));
    let providers = p.get_providers();
    Ok(Specinfra {
        backend: b,
        platform: p,
        providers: providers,
    })
}

impl<'a> Specinfra<'a> {
    pub fn file(&self, name: &'static str) -> File {
        File::new(name, self.backend, &self.providers.file)
    }

    pub fn service(&self, name: &'static str) -> Service {
        Service::new(name, self.backend, &self.providers.service)
    }
}

// Wrapper functions for FFI

use backend::BackendWrapper;

#[no_mangle]
pub extern "C" fn specinfra_new<'a>(ptr: *const BackendWrapper) -> *const Specinfra<'a> {
    let b = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };
    Box::into_raw(Box::new(self::new(&*b.backend).unwrap()))
}

#[no_mangle]
pub extern "C" fn specinfra_free(ptr: *mut Specinfra) {
    if ptr.is_null() {
        return;
    }
    unsafe {
        Box::from_raw(ptr);
    }
}

#[no_mangle]
pub extern "C" fn specinfra_file(ptr: *const Specinfra, name: *const c_char) -> *const File {
    let s = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };

    let name = unsafe {
        assert!(!name.is_null());
        CStr::from_ptr(name)
    };

    Box::into_raw(Box::new(s.file(name.to_str().unwrap())))
}
<commit_msg>Add constructor function of service for FFI<commit_after>extern crate uname;
extern crate libc;
extern crate users;
extern crate md5;
extern crate sha2;
extern crate nix;

use std::ffi::CStr;

use libc::c_char;

use backend::Backend;
use platform::platform::Platform;
use resource::file::File;
use resource::service::Service;
use provider::Providers;

pub mod backend;
pub mod platform;
pub mod resource;
pub mod provider;
pub mod error;

pub struct Specinfra<'a> {
    pub backend: &'a Backend,
    pub platform: Box<Platform>,
    pub providers: Box<Providers>,
}

pub fn new(b: &Backend) -> Result<Specinfra, error::Error> {
    let p = try!(b.detect_platform().ok_or(platform::error::Error));
    let providers = p.get_providers();
    Ok(Specinfra {
        backend: b,
        platform: p,
        providers: providers,
    })
}

impl<'a> Specinfra<'a> {
    pub fn file(&self, name: &'static str) -> File {
        File::new(name, self.backend, &self.providers.file)
    }

    pub fn service(&self, name: &'static str) -> Service {
        Service::new(name, self.backend, &self.providers.service)
    }
}

// Wrapper functions for FFI

use backend::BackendWrapper;

#[no_mangle]
pub extern "C" fn specinfra_new<'a>(ptr: *const BackendWrapper) -> *const Specinfra<'a> {
    let b = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };
    Box::into_raw(Box::new(self::new(&*b.backend).unwrap()))
}

#[no_mangle]
pub extern "C" fn specinfra_free(ptr: *mut Specinfra) {
    if ptr.is_null() {
        return;
    }
    unsafe {
        Box::from_raw(ptr);
    }
}

#[no_mangle]
pub extern "C" fn specinfra_file(ptr: *const Specinfra, name: *const c_char) -> *const File {
    let s = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };

    let name = unsafe {
        assert!(!name.is_null());
        CStr::from_ptr(name)
    };

    Box::into_raw(Box::new(s.file(name.to_str().unwrap())))
}

#[no_mangle]
pub extern "C" fn specinfra_service(ptr: *const Specinfra, name: *const c_char) -> *const Service {
    let s = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };

    let name = unsafe {
        assert!(!name.is_null());
        CStr::from_ptr(name)
    };

    Box::into_raw(Box::new(s.service(name.to_str().unwrap())))
}
<|endoftext|>


<commit_before>//! # Examples
//!
//! ```
//! use objpool::PoolBuilder;
//! use std::thread;
//!
//! let p = PoolBuilder::new(|| 0).max_items(5).finalize();
//! let mut handles = Vec::new();
//! for _ in 0..10 {
//!     let pool = p.clone();
//!     handles.push(thread::spawn(move || {
//!         for _ in 0..1000 {
//!             *pool.get() += 1;
//!         }
//!     }));
//! }
//!
//! for handle in handles {
//!     handle.join().unwrap();
//! }
//! assert_eq!(*p.get() + *p.get() + *p.get() + *p.get() + *p.get(), 10000);
//! ```

use std::error::Error;
use std::fmt::{self, Debug, Display, Formatter};
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, Condvar, Mutex, Weak};
use std::time::{Duration, SystemTime};

pub struct Pool<T, F> where F: Fn() -> T {
    create: F,
    items: Mutex<Items<T>>,
    item_available: Condvar,
    weak_self: Weak<Pool<T, F>>,
}

impl<T, F> Pool<T, F> where F: Fn() -> T {
    pub fn new(create: F) -> Arc<Pool<T, F>> {
        Pool::new_impl(create, None)
    }

    fn new_impl(create: F, max_items: Option<usize>) -> Arc<Pool<T, F>> {
        let pool = Arc::new(Pool {
            create: create,
            items: Mutex::new(Items {
                available: Vec::new(),
                count: 0,
                max: max_items,
            }),
            item_available: Condvar::new(),
            weak_self: Weak::new(),
        });
        unsafe {
            let ptr = &pool.weak_self as *const Weak<Pool<T, F>> as *mut Weak<Pool<T, F>>;
            *ptr = Arc::downgrade(&pool);
        }
        pool
    }

    pub fn get(&self) -> Item<T, F> {
        self.get_impl(None).unwrap()
    }

    pub fn get_timeout(&self, duration: Duration) -> Result<Item<T, F>, TimeoutError> {
        self.get_impl(Some(duration))
    }

    fn get_impl(&self, duration: Option<Duration>) -> Result<Item<T, F>, TimeoutError> {
        let mut items = self.items.lock().unwrap();
        let item = match items.available.pop() {
            Some(item) => item,
            None => {
                if items.count < items.max.unwrap_or(std::usize::MAX) {
                    items.count += 1;
                    drop(items);
                    (self.create)()
                } else {
                    let start = SystemTime::now();
                    while items.available.is_empty() {
                        items = match duration {
                            Some(duration) => {
                                let elapsed = match start.elapsed() {
                                    Ok(elapsed) => elapsed,
                                    Err(_) => Duration::from_secs(0),
                                };
                                if elapsed >= duration {
                                    return Err(TimeoutError);
                                }
                                let (items, wait_result) =
                                    self.item_available.wait_timeout(items, duration - elapsed).unwrap();
                                if wait_result.timed_out() {
                                    return Err(TimeoutError);
                                }
                                items
                            },
                            None => self.item_available.wait(items).unwrap(),
                        }
                    }
                    items.available.pop().unwrap()
                }
            }
        };
        Ok(Item {
            item: Some(item),
            pool: self.weak_self.upgrade().unwrap(),
        })
    }

    fn put(&self, item: T) {
        self.items.lock().unwrap().available.push(item);
        self.item_available.notify_one();
    }
}

impl<T, F> Debug for Pool<T, F> where F: Fn() -> T {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.debug_struct("Pool")
            .field("items", &*self.items.lock().unwrap())
            .finish()
    }
}

pub struct PoolBuilder<T, F> where F: Fn() -> T {
    create: F,
    max_items: Option<usize>,
}

impl<T, F> PoolBuilder<T, F> where F: Fn() -> T {
    pub fn new(create: F) -> PoolBuilder<T, F> {
        PoolBuilder { create: create, max_items: None }
    }

    pub fn max_items(mut self, max_items: usize) -> PoolBuilder<T, F> {
        self.max_items = Some(max_items);
        self
    }

    pub fn finalize(self) -> Arc<Pool<T, F>> {
        Pool::new_impl(self.create, self.max_items)
    }
}

struct Items<T> {
    available: Vec<T>,
    count: usize,
    max: Option<usize>,
}

impl<T> Debug for Items<T> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.debug_struct("Items")
            .field("available", &self.available.len())
            .field("count", &self.count)
            .field("max", &self.max)
            .finish()
    }
}

pub struct Item<T, F> where F: Fn() -> T {
    item: Option<T>,
    pool: Arc<Pool<T, F>>,
}

impl<T, F> Debug for Item<T, F> where T: Debug, F: Fn() -> T {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.debug_struct("Item")
            .field("item", &self.item)
            .finish()
    }
}

impl<T, F> Deref for Item<T, F> where F: Fn() -> T {
    type Target = T;

    fn deref(&self) -> &T {
        self.item.as_ref().unwrap()
    }
}

impl<T, F> DerefMut for Item<T, F> where F: Fn() -> T {
    fn deref_mut(&mut self) -> &mut T {
        self.item.as_mut().unwrap()
    }
}

impl<T, F> Drop for Item<T, F> where F: Fn() -> T {
    fn drop(&mut self) {
        self.pool.put(self.item.take().unwrap());
    }
}

#[derive(Debug, Eq, PartialEq)]
pub struct TimeoutError;

impl Display for TimeoutError {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.write_str("wait timed out")
    }
}

impl Error for TimeoutError {
    fn description(&self) -> &str {
        "wait timed out"
    }
}

#[cfg(test)]
mod tests {
    use std::error::Error;
    use std::time::{Duration, SystemTime};
    use std::thread;
    use super::*;

    trait AsMillis {
        fn as_millis(&self) -> u64;
    }

    impl AsMillis for Duration {
        fn as_millis(&self) -> u64 {
            self.as_secs() * 1000 + self.subsec_nanos() as u64 / 1000000
        }
    }

    #[test]
    fn pool_builder() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let _x = pool.get();
        assert_eq!(pool.get_timeout(Duration::from_secs(0)).err(), Some(TimeoutError));
    }

    #[test]
    fn pool_get() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let x = pool.get();
        let p = pool.clone();
        let start = SystemTime::now();
        let handle = thread::spawn(move || {
            let _ = p.get();
        });
        thread::sleep(Duration::from_millis(100));
        drop(x);
        handle.join().unwrap();
        let elapsed_ms = start.elapsed().unwrap().as_millis();
        assert!(elapsed_ms >= 50 && elapsed_ms < 150);
    }

    #[test]
    fn pool_get_mut() {
        let pool = Pool::new(|| 0);
        *pool.get() = 4;
        assert_eq!(*pool.get(), 4);
    }

    #[test]
    fn pool_get_timeout_ok() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let x = pool.get();
        let p = pool.clone();
        let start = SystemTime::now();
        let handle = thread::spawn(move || {
            let _ = p.get_timeout(Duration::from_secs(1)).unwrap();
        });
        thread::sleep(Duration::from_millis(100));
        drop(x);
        handle.join().unwrap();
        let elapsed_ms = start.elapsed().unwrap().as_millis();
        assert!(elapsed_ms >= 50 && elapsed_ms < 150);
    }

    #[test]
    fn pool_get_timeout_err() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let _x = pool.get();
        let p = pool.clone();
        let start = SystemTime::now();
        let handle = thread::spawn(move || {
            assert_eq!(p.get_timeout(Duration::from_millis(100)).err(), Some(TimeoutError));
        });
        while start.elapsed().unwrap().as_millis() < 100 {
            pool.item_available.notify_one();
        }
        handle.join().unwrap();
        let elapsed_ms = start.elapsed().unwrap().as_millis();
        assert!(elapsed_ms >= 50 && elapsed_ms < 150);
    }

    #[test]
    fn pool_debug() {
        let pool = PoolBuilder::new(|| 0).max_items(5).finalize();
        assert_eq!(format!("{:?}", pool),
            "Pool { items: Items { available: 0, count: 0, max: Some(5) } }");
        let x = pool.get();
        let _y = pool.get();
        let _z = pool.get();
        drop(x);
        assert_eq!(format!("{:?}", pool),
            "Pool { items: Items { available: 1, count: 3, max: Some(5) } }");
    }

    #[test]
    fn item_debug() {
        let pool = Pool::new(|| 0);
        let x = pool.get();
        assert_eq!(format!("{:?}", x), "Item { item: Some(0) }");
    }

    #[test]
    fn timeout_error() {
        assert_eq!(format!("{}", TimeoutError), "wait timed out");
        assert_eq!(TimeoutError.description(), "wait timed out");
    }
}
<commit_msg>rename some locals<commit_after>//! # Examples
//!
//! ```
//! use objpool::PoolBuilder;
//! use std::thread;
//!
//! let pool = PoolBuilder::new(|| 0).max_items(5).finalize();
//! let mut handles = Vec::new();
//! for _ in 0..10 {
//!     let pool = pool.clone();
//!     handles.push(thread::spawn(move || {
//!         for _ in 0..1000 {
//!             *pool.get() += 1;
//!         }
//!     }));
//! }
//!
//! for handle in handles {
//!     handle.join().unwrap();
//! }
//! assert_eq!(*pool.get() + *pool.get() + *pool.get() + *pool.get() + *pool.get(), 10000);
//! ```

use std::error::Error;
use std::fmt::{self, Debug, Display, Formatter};
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, Condvar, Mutex, Weak};
use std::time::{Duration, SystemTime};

pub struct Pool<T, F> where F: Fn() -> T {
    create: F,
    items: Mutex<Items<T>>,
    item_available: Condvar,
    weak_self: Weak<Pool<T, F>>,
}

impl<T, F> Pool<T, F> where F: Fn() -> T {
    pub fn new(create: F) -> Arc<Pool<T, F>> {
        Pool::new_impl(create, None)
    }

    fn new_impl(create: F, max_items: Option<usize>) -> Arc<Pool<T, F>> {
        let pool = Arc::new(Pool {
            create: create,
            items: Mutex::new(Items {
                available: Vec::new(),
                count: 0,
                max: max_items,
            }),
            item_available: Condvar::new(),
            weak_self: Weak::new(),
        });
        unsafe {
            let ptr = &pool.weak_self as *const Weak<Pool<T, F>> as *mut Weak<Pool<T, F>>;
            *ptr = Arc::downgrade(&pool);
        }
        pool
    }

    pub fn get(&self) -> Item<T, F> {
        self.get_impl(None).unwrap()
    }

    pub fn get_timeout(&self, duration: Duration) -> Result<Item<T, F>, TimeoutError> {
        self.get_impl(Some(duration))
    }

    fn get_impl(&self, duration: Option<Duration>) -> Result<Item<T, F>, TimeoutError> {
        let mut items = self.items.lock().unwrap();
        let item = match items.available.pop() {
            Some(item) => item,
            None => {
                if items.count < items.max.unwrap_or(std::usize::MAX) {
                    items.count += 1;
                    drop(items);
                    (self.create)()
                } else {
                    let start = SystemTime::now();
                    while items.available.is_empty() {
                        items = match duration {
                            Some(duration) => {
                                let elapsed = match start.elapsed() {
                                    Ok(elapsed) => elapsed,
                                    Err(_) => Duration::from_secs(0),
                                };
                                if elapsed >= duration {
                                    return Err(TimeoutError);
                                }
                                let (items, wait_result) =
                                    self.item_available.wait_timeout(items, duration - elapsed).unwrap();
                                if wait_result.timed_out() {
                                    return Err(TimeoutError);
                                }
                                items
                            },
                            None => self.item_available.wait(items).unwrap(),
                        }
                    }
                    items.available.pop().unwrap()
                }
            }
        };
        Ok(Item {
            item: Some(item),
            pool: self.weak_self.upgrade().unwrap(),
        })
    }

    fn put(&self, item: T) {
        self.items.lock().unwrap().available.push(item);
        self.item_available.notify_one();
    }
}

impl<T, F> Debug for Pool<T, F> where F: Fn() -> T {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.debug_struct("Pool")
            .field("items", &*self.items.lock().unwrap())
            .finish()
    }
}

pub struct PoolBuilder<T, F> where F: Fn() -> T {
    create: F,
    max_items: Option<usize>,
}

impl<T, F> PoolBuilder<T, F> where F: Fn() -> T {
    pub fn new(create: F) -> PoolBuilder<T, F> {
        PoolBuilder { create: create, max_items: None }
    }

    pub fn max_items(mut self, max_items: usize) -> PoolBuilder<T, F> {
        self.max_items = Some(max_items);
        self
    }

    pub fn finalize(self) -> Arc<Pool<T, F>> {
        Pool::new_impl(self.create, self.max_items)
    }
}

struct Items<T> {
    available: Vec<T>,
    count: usize,
    max: Option<usize>,
}

impl<T> Debug for Items<T> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.debug_struct("Items")
            .field("available", &self.available.len())
            .field("count", &self.count)
            .field("max", &self.max)
            .finish()
    }
}

pub struct Item<T, F> where F: Fn() -> T {
    item: Option<T>,
    pool: Arc<Pool<T, F>>,
}

impl<T, F> Debug for Item<T, F> where T: Debug, F: Fn() -> T {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.debug_struct("Item")
            .field("item", &self.item)
            .finish()
    }
}

impl<T, F> Deref for Item<T, F> where F: Fn() -> T {
    type Target = T;

    fn deref(&self) -> &T {
        self.item.as_ref().unwrap()
    }
}

impl<T, F> DerefMut for Item<T, F> where F: Fn() -> T {
    fn deref_mut(&mut self) -> &mut T {
        self.item.as_mut().unwrap()
    }
}

impl<T, F> Drop for Item<T, F> where F: Fn() -> T {
    fn drop(&mut self) {
        self.pool.put(self.item.take().unwrap());
    }
}

#[derive(Debug, Eq, PartialEq)]
pub struct TimeoutError;

impl Display for TimeoutError {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        fmt.write_str("wait timed out")
    }
}

impl Error for TimeoutError {
    fn description(&self) -> &str {
        "wait timed out"
    }
}

#[cfg(test)]
mod tests {
    use std::error::Error;
    use std::time::{Duration, SystemTime};
    use std::thread;
    use super::*;

    trait AsMillis {
        fn as_millis(&self) -> u64;
    }

    impl AsMillis for Duration {
        fn as_millis(&self) -> u64 {
            self.as_secs() * 1000 + self.subsec_nanos() as u64 / 1000000
        }
    }

    #[test]
    fn pool_builder() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let _x = pool.get();
        assert_eq!(pool.get_timeout(Duration::from_secs(0)).err(), Some(TimeoutError));
    }

    #[test]
    fn pool_get() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let x = pool.get();
        let start = SystemTime::now();
        let handle = thread::spawn(move || {
            let _ = pool.get();
        });
        thread::sleep(Duration::from_millis(100));
        drop(x);
        handle.join().unwrap();
        let elapsed_ms = start.elapsed().unwrap().as_millis();
        assert!(elapsed_ms >= 50 && elapsed_ms < 150);
    }

    #[test]
    fn pool_get_mut() {
        let pool = Pool::new(|| 0);
        *pool.get() = 4;
        assert_eq!(*pool.get(), 4);
    }

    #[test]
    fn pool_get_timeout_ok() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let x = pool.get();
        let start = SystemTime::now();
        let handle = thread::spawn(move || {
            let _ = pool.get_timeout(Duration::from_secs(1)).unwrap();
        });
        thread::sleep(Duration::from_millis(100));
        drop(x);
        handle.join().unwrap();
        let elapsed_ms = start.elapsed().unwrap().as_millis();
        assert!(elapsed_ms >= 50 && elapsed_ms < 150);
    }

    #[test]
    fn pool_get_timeout_err() {
        let pool = PoolBuilder::new(|| 0).max_items(1).finalize();
        let _x = pool.get();
        let start = SystemTime::now();
        let handle = {
            let pool = pool.clone();
            thread::spawn(move || {
                assert_eq!(pool.get_timeout(Duration::from_millis(100)).err(), Some(TimeoutError));
            })
        };
        while start.elapsed().unwrap().as_millis() < 100 {
            pool.item_available.notify_one();
        }
        handle.join().unwrap();
        let elapsed_ms = start.elapsed().unwrap().as_millis();
        assert!(elapsed_ms >= 50 && elapsed_ms < 150);
    }

    #[test]
    fn pool_debug() {
        let pool = PoolBuilder::new(|| 0).max_items(5).finalize();
        assert_eq!(format!("{:?}", pool),
            "Pool { items: Items { available: 0, count: 0, max: Some(5) } }");
        let x = pool.get();
        let _y = pool.get();
        let _z = pool.get();
        drop(x);
        assert_eq!(format!("{:?}", pool),
            "Pool { items: Items { available: 1, count: 3, max: Some(5) } }");
    }

    #[test]
    fn item_debug() {
        let pool = Pool::new(|| 0);
        let x = pool.get();
        assert_eq!(format!("{:?}", x), "Item { item: Some(0) }");
    }

    #[test]
    fn timeout_error() {
        assert_eq!(format!("{}", TimeoutError), "wait timed out");
        assert_eq!(TimeoutError.description(), "wait timed out");
    }
}
<|endoftext|>


<commit_before>pub use self::image_pub::CifarImage;
pub use self::dataset::CifarDataset;
mod image;
mod image_pub;
mod dataset;
<commit_msg>change order<commit_after>mod image;
mod image_pub;
mod dataset;
pub use self::image_pub::CifarImage;
pub use self::dataset::CifarDataset;
<|endoftext|>


<commit_before>#![crate_name = "bindgen"]
#![crate_type = "dylib"]

extern crate syntex_syntax as syntax;
extern crate libc;
#[macro_use] extern crate log;

use std::collections::HashSet;
use std::default::Default;
use std::io::{Write, self};

use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::print::pprust;
use syntax::print::pp::eof;
use syntax::ptr::P;

use types::Global;

mod types;
mod clangll;
mod clang;
mod gen;
mod parser;

pub struct BindgenOptions {
    pub match_pat: Vec<String>,
    pub builtins: bool,
    pub links: Vec<(String, LinkType)>,
    pub emit_ast: bool,
    pub fail_on_unknown_type: bool,
    pub override_enum_ty: String,
    pub clang_args: Vec<String>,
}

impl Default for BindgenOptions {
    fn default() -> BindgenOptions {
        BindgenOptions {
            match_pat: Vec::new(),
            builtins: false,
            links: Vec::new(),
            emit_ast: false,
            fail_on_unknown_type: false,
            override_enum_ty: "".to_string(),
            clang_args: Vec::new()
        }
    }
}

#[derive(Copy, Clone)]
pub enum LinkType {
    Default,
    Static,
    Framework
}

pub trait Logger {
    fn error(&self, msg: &str);
    fn warn(&self, msg: &str);
}

pub struct Bindings {
    module: ast::Mod
}

impl Bindings {
    pub fn generate(options: &BindgenOptions, logger: Option<&Logger>, span: Option<Span>) -> Result<Bindings, ()> {
        let l = DummyLogger;
        let logger = match logger {
            Some(l) => l,
            None => &l as &Logger
        };

        let span = match span {
            Some(s) => s,
            None => DUMMY_SP
        };

        let globals = try!(parse_headers(options, logger));

        let module = ast::Mod {
            inner: span,
            items: gen::gen_mod(&options.links[..], globals, span)
        };

        Ok(Bindings {
            module: module
        })
    }

    pub fn into_ast(self) -> Vec<P<ast::Item>> {
        self.module.items
    }

    pub fn to_string(&self) -> String {
        let mut mod_str = Vec::new();
        {
            let ref_writer = Box::new(mod_str.by_ref()) as Box<Write>;
            self.write(ref_writer).ok().expect("Could not write bindings to string");
        }
        String::from_utf8(mod_str).unwrap()
    }

    pub fn write<'a>(&'a self, mut writer: Box<Write + 'a>) -> io::Result<()> {
        try!(writer.write("/* automatically generated by rust-bindgen */\n\n".as_bytes()));
        let mut ps = pprust::rust_printer(writer);
        try!(ps.print_mod(&self.module, &[]));
        try!(ps.print_remaining_comments());
        try!(eof(&mut ps.s));
        ps.s.out.flush()
    }
}

struct DummyLogger;

impl Logger for DummyLogger {
    fn error(&self, _msg: &str) { }
    fn warn(&self, _msg: &str) { }
}

fn parse_headers(options: &BindgenOptions, logger: &Logger) -> Result<Vec<Global>, ()> {
    fn str_to_ikind(s: &str) -> Option<types::IKind> {
        match s {
            "uchar"     => Some(types::IUChar),
            "schar"     => Some(types::ISChar),
            "ushort"    => Some(types::IUShort),
            "sshort"    => Some(types::IShort),
            "uint"      => Some(types::IUInt),
            "sint"      => Some(types::IInt),
            "ulong"     => Some(types::IULong),
            "slong"     => Some(types::ILong),
            "ulonglong" => Some(types::IULongLong),
            "slonglong" => Some(types::ILongLong),
            _           => None,
        }
    }

    let clang_opts = parser::ClangParserOptions {
        builtin_names: builtin_names(),
        builtins: options.builtins,
        match_pat: options.match_pat.clone(),
        emit_ast: options.emit_ast,
        fail_on_unknown_type: options.fail_on_unknown_type,
        override_enum_ty: str_to_ikind(&options.override_enum_ty[..]),
        clang_args: options.clang_args.clone(),
    };

    parser::parse(clang_opts, logger)
}

fn builtin_names() -> HashSet<String> {
    let mut names = HashSet::new();
    let keys = [
        "__va_list_tag",
        "__va_list",
        "__builtin_va_list",
    ];

    keys.iter().all(|s| {
        names.insert(s.to_string());
        true
    });

    return names;
}
<commit_msg>Add a builder interface to libbindgen<commit_after>#![crate_name = "bindgen"]
#![crate_type = "dylib"]

extern crate syntex_syntax as syntax;
extern crate libc;
#[macro_use] extern crate log;

use std::collections::HashSet;
use std::default::Default;
use std::io::{Write, self};
use std::fs::OpenOptions;
use std::path::Path;

use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::print::pprust;
use syntax::print::pp::eof;
use syntax::ptr::P;

use types::Global;

mod types;
mod clangll;
mod clang;
mod gen;
mod parser;

#[derive(Clone)]
pub struct Builder<'a> {
    options: BindgenOptions,
    logger: Option<&'a Logger>
}

pub fn builder<'a>() -> Builder<'a> {
    Default::default()
}

impl<'a> Builder<'a> {
    pub fn header<T: Into<String>>(&mut self, header: T) -> &mut Self {
        self.options.clang_args.push(header.into());
        self
    }

    pub fn link<T: Into<String>>(&mut self, library: T) -> &mut Self {
        self.options.links.push((library.into(), LinkType::Default));
        self
    }

    pub fn link_static<T: Into<String>>(&mut self, library: T) -> &mut Self {
        self.options.links.push((library.into(), LinkType::Static));
        self
    }

    pub fn link_framework<T: Into<String>>(&mut self, library: T) -> &mut Self {
        self.options.links.push((library.into(), LinkType::Framework));
        self
    }

    pub fn forbid_unknown_types(&mut self) -> &mut Self {
        self.options.fail_on_unknown_type = true;
        self
    }

    pub fn emit_builtins(&mut self) -> &mut Self {
        self.options.builtins = true;
        self
    }

    pub fn log(&mut self, logger: &'a Logger) -> &mut Self {
        self.logger = Some(logger);
        self
    }

    pub fn generate(&self) -> Result<Bindings, ()> {
        Bindings::generate(&self.options, self.logger, None)
    }
}

impl<'a> Default for Builder<'a> {
    fn default() -> Builder<'a> {
        Builder {
            logger: None,
            options: Default::default()
        }
    }
}

#[derive(Clone)]
/// Deprecated - use a `Builder` instead
pub struct BindgenOptions {
    pub match_pat: Vec<String>,
    pub builtins: bool,
    pub links: Vec<(String, LinkType)>,
    pub emit_ast: bool,
    pub fail_on_unknown_type: bool,
    pub override_enum_ty: String,
    pub clang_args: Vec<String>,
}

impl Default for BindgenOptions {
    fn default() -> BindgenOptions {
        BindgenOptions {
            match_pat: Vec::new(),
            builtins: false,
            links: Vec::new(),
            emit_ast: false,
            fail_on_unknown_type: false,
            override_enum_ty: "".to_string(),
            clang_args: Vec::new()
        }
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum LinkType {
    Default,
    Static,
    Framework
}

pub trait Logger {
    fn error(&self, msg: &str);
    fn warn(&self, msg: &str);
}

#[derive(Clone)]
pub struct Bindings {
    module: ast::Mod
}

impl Bindings {
    /// Deprecated - use a `Builder` instead
    pub fn generate(options: &BindgenOptions, logger: Option<&Logger>, span: Option<Span>) -> Result<Bindings, ()> {
        let l = DummyLogger;
        let logger = match logger {
            Some(l) => l,
            None => &l as &Logger
        };

        let span = match span {
            Some(s) => s,
            None => DUMMY_SP
        };

        let globals = try!(parse_headers(options, logger));

        let module = ast::Mod {
            inner: span,
            items: gen::gen_mod(&options.links[..], globals, span)
        };

        Ok(Bindings {
            module: module
        })
    }

    pub fn into_ast(self) -> Vec<P<ast::Item>> {
        self.module.items
    }

    pub fn to_string(&self) -> String {
        let mut mod_str = Vec::new();
        {
            let ref_writer = Box::new(mod_str.by_ref()) as Box<Write>;
            self.write(ref_writer).ok().expect("Could not write bindings to string");
        }
        String::from_utf8(mod_str).unwrap()
    }

    pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
        let file = try!(OpenOptions::new().write(true).truncate(true).create(true).open(path));
        self.write(Box::new(file))
    }

    pub fn write<'a>(&'a self, mut writer: Box<Write + 'a>) -> io::Result<()> {
        try!(writer.write("/* automatically generated by rust-bindgen */\n\n".as_bytes()));
        let mut ps = pprust::rust_printer(writer);
        try!(ps.print_mod(&self.module, &[]));
        try!(ps.print_remaining_comments());
        try!(eof(&mut ps.s));
        ps.s.out.flush()
    }
}

struct DummyLogger;

impl Logger for DummyLogger {
    fn error(&self, _msg: &str) { }
    fn warn(&self, _msg: &str) { }
}

fn parse_headers(options: &BindgenOptions, logger: &Logger) -> Result<Vec<Global>, ()> {
    fn str_to_ikind(s: &str) -> Option<types::IKind> {
        match s {
            "uchar"     => Some(types::IUChar),
            "schar"     => Some(types::ISChar),
            "ushort"    => Some(types::IUShort),
            "sshort"    => Some(types::IShort),
            "uint"      => Some(types::IUInt),
            "sint"      => Some(types::IInt),
            "ulong"     => Some(types::IULong),
            "slong"     => Some(types::ILong),
            "ulonglong" => Some(types::IULongLong),
            "slonglong" => Some(types::ILongLong),
            _           => None,
        }
    }

    let clang_opts = parser::ClangParserOptions {
        builtin_names: builtin_names(),
        builtins: options.builtins,
        match_pat: options.match_pat.clone(),
        emit_ast: options.emit_ast,
        fail_on_unknown_type: options.fail_on_unknown_type,
        override_enum_ty: str_to_ikind(&options.override_enum_ty[..]),
        clang_args: options.clang_args.clone(),
    };

    parser::parse(clang_opts, logger)
}

fn builtin_names() -> HashSet<String> {
    let mut names = HashSet::new();
    let keys = [
        "__va_list_tag",
        "__va_list",
        "__builtin_va_list",
    ];

    keys.iter().all(|s| {
        names.insert(s.to_string());
        true
    });

    return names;
}

#[test]
fn builder_state()
{
    let logger = DummyLogger;
    let mut build = builder();
    {
        build.header("example.h");
        build.link_static("m");
        build.log(&logger);
    }
    assert!(build.logger.is_some());
    assert!(build.options.clang_args.binary_search(&"example.h".to_string()).is_ok());
    assert!(build.options.links.binary_search(&("m".to_string(), LinkType::Static)).is_ok());
}<|endoftext|>


<commit_before>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate serde;
extern crate serde_json;

use serde::Deserialize;
use std::fmt;
use std::io::{self, Read};
use std::convert;
use std::collections::HashMap;
use std::net::{
    self,
    TcpListener,
    TcpStream,
};
use std::sync::{
    self,
    Mutex,
    Arc,
};
use std::sync::mpsc::{
    channel,
    sync_channel,
    Sender,
    SyncSender,
    Receiver,
};
use std::time;
use std::thread;

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    Json(serde_json::Error),
    Sender,
    Unimplemented,
    Impossible
}

impl convert::From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        match err {
            serde_json::Error::IoError(err) => Error::Io(err),
            err => Error::Json(err),
        }
    }
}

impl convert::From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl<T> convert::From<sync::mpsc::SendError<T>> for Error {
    fn from(_: sync::mpsc::SendError<T>) -> Error {
        Error::Sender
    }
}

pub type Result<T> = std::result::Result<T, Error>;

pub fn handle_conn<F, Request, Reply>(mut stream: TcpStream, f: Arc<F>) -> Result<()>
    where Request: fmt::Debug + serde::de::Deserialize,
          Reply: fmt::Debug + serde::ser::Serialize,
          F: Serve<Request, Reply>
{
    let read_stream = try!(stream.try_clone());
    let mut de = serde_json::Deserializer::new(read_stream.bytes());
    loop {
        println!("read");
        let request_packet: Packet<Request> = try!(Packet::deserialize(&mut de));
        match request_packet {
            Packet::Shutdown => break,
            Packet::Message(id, message) => {
                let reply = try!(f.serve(&message));
                let reply_packet = Packet::Message(id, reply);
                println!("write");
                try!(serde_json::to_writer(&mut stream, &reply_packet));
            },
        }
    }
    Ok(())
}

pub fn serve<F, Request, Reply>(listener: TcpListener, f: Arc<F>) -> Error
    where Request: fmt::Debug + serde::de::Deserialize,
          Reply: fmt::Debug + serde::ser::Serialize,
          F: 'static + Serve<Request, Reply>,
{
    for conn in listener.incoming() {
        let conn = match conn {
            Err(err) => return convert::From::from(err),
            Ok(c) => c,
        };
        let f = f.clone();
        thread::spawn(move || {
            if let Err(err) = handle_conn(conn, f) {
                println!("error handling connection: {:?}", err);
            }
        });
    }
    Error::Impossible
}

pub trait Serve<Request, Reply>: Send + Sync {
    fn serve(&self, request: &Request) -> io::Result<Reply>;
}

#[derive(Debug, Clone, Serialize, Deserialize)]
enum Packet<T> {
    Message(u64, T),
    Shutdown,
}

struct Handle<T> {
    id: u64,
    sender: Sender<T>,
}

enum ReceiverMessage<Reply> {
    Handle(Handle<Reply>),
    Packet(Packet<Reply>),
    Shutdown,
}

fn receiver<Reply>(messages: Receiver<ReceiverMessage<Reply>>) -> Result<()> {
    let mut ready_handles: HashMap<u64, Handle<Reply>> = HashMap::new();
    for message in messages.into_iter() {
        match message {
            ReceiverMessage::Handle(handle) => {
                ready_handles.insert(handle.id, handle);
            },
            ReceiverMessage::Packet(Packet::Shutdown) => break,
            ReceiverMessage::Packet(Packet::Message(id, message)) => {
                let handle = ready_handles.remove(&id).unwrap();
                try!(handle.sender.send(message));
            }
            ReceiverMessage::Shutdown => break,
        }
    }
    Ok(())
}

fn reader<Reply>(stream: TcpStream, tx: SyncSender<ReceiverMessage<Reply>>)
    where Reply: serde::Deserialize
{
    use serde_json::Error::SyntaxError;
    use serde_json::ErrorCode::EOFWhileParsingValue;
    let mut de = serde_json::Deserializer::new(stream.bytes());
    loop {
        match Packet::deserialize(&mut de) {
            Ok(packet) =>{
                println!("send!");
                tx.send(ReceiverMessage::Packet(packet)).unwrap();
            },
            // TODO: This shutdown logic is janky.. What's the right way to do this?
            Err(SyntaxError(EOFWhileParsingValue, _, _)) => break,
            Err(SyntaxError(ExpectedValue, _, _)) => break,
            Err(err) => panic!("unexpected error while parsing!: {:?}", err),
        }
    }
}

fn increment(cur_id: &mut u64) -> u64 {
    let id = *cur_id;
    *cur_id += 1;
    id
}

struct SyncedClientState{
    next_id: u64,
    stream: TcpStream,
}

pub struct Client<Reply> {
    synced_state: Mutex<SyncedClientState>,
    handles_tx: SyncSender<ReceiverMessage<Reply>>,
    reader_guard: thread::JoinHandle<()>,
}

impl<Reply> Client<Reply>
    where Reply: serde::de::Deserialize + Send + 'static
{
    pub fn new(stream: TcpStream) -> Result<Self> {
        let (handles_tx, receiver_rx) = sync_channel(0);
        let read_stream = try!(stream.try_clone());
        try!(read_stream.set_read_timeout(Some(time::Duration::from_millis(50))));
        let reader_handles_tx = handles_tx.clone();
        let guard = thread::spawn(move || reader(read_stream, reader_handles_tx));
        thread::spawn(move || receiver(receiver_rx));
        Ok(Client{
            synced_state: Mutex::new(SyncedClientState{
                next_id: 0,
                stream: stream,
            }),
            reader_guard: guard,
            handles_tx: handles_tx,
        })
    }

    pub fn rpc<Request>(&self, request: &Request) -> Result<Reply>
        where Request: serde::ser::Serialize + Clone + Send + 'static
    {
        let (tx, rx) = channel();
        let mut state = self.synced_state.lock().unwrap();
        let id = increment(&mut state.next_id);
        try!(self.handles_tx.send(ReceiverMessage::Handle(Handle{
            id: id,
            sender: tx,
        })));
        let packet = Packet::Message(id, request.clone());
        try!(serde_json::to_writer(&mut state.stream, &packet));
        Ok(rx.recv().unwrap())
    }

    pub fn join<Request: serde::Serialize>(self) -> Result<()> {
        let mut state = self.synced_state.lock().unwrap();
        let packet: Packet<Request> = Packet::Shutdown;
        try!(serde_json::to_writer(&mut state.stream, &packet));
        try!(state.stream.shutdown(net::Shutdown::Both));
        self.reader_guard.join().unwrap();
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io;
    use std::net::{TcpStream, TcpListener};
    use std::sync::{Arc, Mutex};
    use std::thread;

    fn pair() -> (TcpStream, TcpListener) {
        let addr = "127.0.0.1:9000";
        // Do this one first so that we don't get connection refused :)
        let listener = TcpListener::bind(addr).unwrap();
        (TcpStream::connect(addr).unwrap(), listener)
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
    enum Request {
        Increment
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    enum Reply {
        Increment(u64)
    }

    struct Server {
        counter: Mutex<u64>,
    }

    impl Serve<Request, Reply> for Server {
        fn serve(&self, _: &Request) -> io::Result<Reply> {
            let mut counter = self.counter.lock().unwrap();
            let reply = Reply::Increment(*counter);
            *counter += 1;
            Ok(reply)
        }
    }

    impl Server {
        fn count(&self) -> u64 {
            *self.counter.lock().unwrap()
        }
    }

    #[test]
    fn test() {
        let (client_stream, server_streams) = pair();
        let server = Arc::new(Server{counter: Mutex::new(0)});
        let thread_server = server.clone();
        thread::spawn(move || serve(server_streams, thread_server));
        let client = Client::new(client_stream).unwrap();
        assert_eq!(Reply::Increment(0), client.rpc(&Request::Increment).unwrap());
        assert_eq!(1, server.count());
        assert_eq!(Reply::Increment(1), client.rpc(&Request::Increment).unwrap());
        assert_eq!(2, server.count());
        client.join::<Request>().unwrap();
    }
}
<commit_msg>Really have a non-clone thing? tests are a mess though<commit_after>#![feature(const_fn)]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate serde;
extern crate serde_json;

use serde::Deserialize;
use std::fmt;
use std::io::{self, Read};
use std::convert;
use std::collections::HashMap;
use std::net::{
    self,
    TcpListener,
    TcpStream,
};
use std::sync::{
    self,
    Mutex,
    Arc,
};
use std::sync::mpsc::{
    channel,
    sync_channel,
    Sender,
    SyncSender,
    Receiver,
};
use std::time;
use std::thread;

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    Json(serde_json::Error),
    Sender,
    Unimplemented,
    Impossible
}

impl convert::From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        match err {
            serde_json::Error::IoError(err) => Error::Io(err),
            err => Error::Json(err),
        }
    }
}

impl convert::From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl<T> convert::From<sync::mpsc::SendError<T>> for Error {
    fn from(_: sync::mpsc::SendError<T>) -> Error {
        Error::Sender
    }
}

pub type Result<T> = std::result::Result<T, Error>;

pub fn handle_conn<F, Request, Reply>(mut stream: TcpStream, f: Arc<F>) -> Result<()>
    where Request: fmt::Debug + serde::de::Deserialize,
          Reply: fmt::Debug + serde::ser::Serialize,
          F: Serve<Request, Reply>
{
    let read_stream = try!(stream.try_clone());
    let mut de = serde_json::Deserializer::new(read_stream.bytes());
    loop {
        println!("read");
        let request_packet: Packet<Request> = try!(Packet::deserialize(&mut de));
        match request_packet {
            Packet::Shutdown => break,
            Packet::Message(id, message) => {
                let reply = try!(f.serve(&message));
                let reply_packet = Packet::Message(id, reply);
                println!("write");
                try!(serde_json::to_writer(&mut stream, &reply_packet));
            },
        }
    }
    Ok(())
}

pub fn serve<F, Request, Reply>(listener: TcpListener, f: Arc<F>) -> Error
    where Request: fmt::Debug + serde::de::Deserialize,
          Reply: fmt::Debug + serde::ser::Serialize,
          F: 'static + Serve<Request, Reply>,
{
    for conn in listener.incoming() {
        let conn = match conn {
            Err(err) => return convert::From::from(err),
            Ok(c) => c,
        };
        let f = f.clone();
        thread::spawn(move || {
            if let Err(err) = handle_conn(conn, f) {
                println!("error handling connection: {:?}", err);
            }
        });
    }
    Error::Impossible
}

pub trait Serve<Request, Reply>: Send + Sync {
    fn serve(&self, request: &Request) -> io::Result<Reply>;
}

#[derive(Debug, Clone, Serialize, Deserialize)]
enum Packet<T> {
    Message(u64, T),
    Shutdown,
}

struct Handle<T> {
    id: u64,
    sender: Sender<T>,
}

enum ReceiverMessage<Reply> {
    Handle(Handle<Reply>),
    Packet(Packet<Reply>),
    Shutdown,
}

fn receiver<Reply>(messages: Receiver<ReceiverMessage<Reply>>) -> Result<()> {
    let mut ready_handles: HashMap<u64, Handle<Reply>> = HashMap::new();
    for message in messages.into_iter() {
        match message {
            ReceiverMessage::Handle(handle) => {
                ready_handles.insert(handle.id, handle);
            },
            ReceiverMessage::Packet(Packet::Shutdown) => break,
            ReceiverMessage::Packet(Packet::Message(id, message)) => {
                let handle = ready_handles.remove(&id).unwrap();
                try!(handle.sender.send(message));
            }
            ReceiverMessage::Shutdown => break,
        }
    }
    Ok(())
}

fn reader<Reply>(stream: TcpStream, tx: SyncSender<ReceiverMessage<Reply>>)
    where Reply: serde::Deserialize
{
    use serde_json::Error::SyntaxError;
    use serde_json::ErrorCode::EOFWhileParsingValue;
    let mut de = serde_json::Deserializer::new(stream.bytes());
    loop {
        match Packet::deserialize(&mut de) {
            Ok(packet) =>{
                println!("send!");
                tx.send(ReceiverMessage::Packet(packet)).unwrap();
            },
            // TODO: This shutdown logic is janky.. What's the right way to do this?
            Err(SyntaxError(EOFWhileParsingValue, _, _)) => break,
            Err(err) => panic!("unexpected error while parsing!: {:?}", err),
        }
    }
}

fn increment(cur_id: &mut u64) -> u64 {
    let id = *cur_id;
    *cur_id += 1;
    id
}

struct SyncedClientState<Reply> {
    next_id: u64,
    stream: TcpStream,
    handles_tx: SyncSender<ReceiverMessage<Reply>>,
}

pub struct Client<Reply> {
    synced_state: Mutex<SyncedClientState<Reply>>,
    reader_guard: thread::JoinHandle<()>,
}

impl<Reply> Client<Reply>
    where Reply: serde::de::Deserialize + Send + 'static
{
    pub fn new(stream: TcpStream) -> Result<Self> {
        let (handles_tx, receiver_rx) = sync_channel(0);
        let read_stream = try!(stream.try_clone());
        try!(read_stream.set_read_timeout(Some(time::Duration::from_millis(50))));
        let reader_handles_tx = handles_tx.clone();
        let guard = thread::spawn(move || reader(read_stream, reader_handles_tx));
        thread::spawn(move || receiver(receiver_rx));
        Ok(Client{
            synced_state: Mutex::new(SyncedClientState{
                next_id: 0,
                stream: stream,
                handles_tx: handles_tx,
            }),
            reader_guard: guard,
        })
    }

    pub fn rpc<Request>(&self, request: &Request) -> Result<Reply>
        where Request: serde::ser::Serialize + Clone + Send + 'static
    {
        let (tx, rx) = channel();
        let mut state = self.synced_state.lock().unwrap();
        let id = increment(&mut state.next_id);
        try!(state.handles_tx.send(ReceiverMessage::Handle(Handle{
            id: id,
            sender: tx,
        })));
        let packet = Packet::Message(id, request.clone());
        try!(serde_json::to_writer(&mut state.stream, &packet));
        Ok(rx.recv().unwrap())
    }

    pub fn join<Request: serde::Serialize>(self) -> Result<()> {
        let mut state = self.synced_state.lock().unwrap();
        let packet: Packet<Request> = Packet::Shutdown;
        try!(serde_json::to_writer(&mut state.stream, &packet));
        try!(state.stream.shutdown(net::Shutdown::Both));
        self.reader_guard.join().unwrap();
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io;
    use std::net::{TcpStream, TcpListener, SocketAddr};
    use std::str::FromStr;
    use std::sync::{Arc, Mutex, Barrier};
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    const port: AtomicUsize = AtomicUsize::new(10000);

    fn pair() -> (TcpStream, TcpListener) {
        let addr = format!("127.0.0.1:{}", port.fetch_add(1, Ordering::SeqCst));
        println!("what the fuck {}", &addr);
        // Do this one first so that we don't get connection refused :)
        let listener = TcpListener::bind(&*addr).unwrap();
        (TcpStream::connect(&*addr).unwrap(), listener)
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
    enum Request {
        Increment
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    enum Reply {
        Increment(u64)
    }

    struct Server {
        counter: Mutex<u64>,
    }

    impl Serve<Request, Reply> for Server {
        fn serve(&self, _: &Request) -> io::Result<Reply> {
            let mut counter = self.counter.lock().unwrap();
            let reply = Reply::Increment(*counter);
            *counter += 1;
            Ok(reply)
        }
    }

    impl Server {
        fn new() -> Server {
            Server{counter: Mutex::new(0)}
        }

        fn count(&self) -> u64 {
            *self.counter.lock().unwrap()
        }
    }

    #[test]
    fn test() {
        let (client_stream, server_streams) = pair();
        let server = Arc::new(Server::new());
        let thread_server = server.clone();
        let guard = thread::spawn(move || serve(server_streams, thread_server));
        let client = Client::new(client_stream).unwrap();
        assert_eq!(Reply::Increment(0), client.rpc(&Request::Increment).unwrap());
        assert_eq!(1, server.count());
        assert_eq!(Reply::Increment(1), client.rpc(&Request::Increment).unwrap());
        assert_eq!(2, server.count());
        client.join::<Request>().unwrap();
        guard.join();
    }

    struct BarrierServer {
        barrier: Barrier,
        inner: Server,
    }

    impl Serve<Request, Reply> for BarrierServer {
        fn serve(&self, request: &Request) -> io::Result<Reply> {
            self.barrier.wait();
            let reply = try!(self.inner.serve(request));
            Ok(reply)
        }
    }

    impl BarrierServer {
        fn new(n: usize) -> BarrierServer {
            BarrierServer{barrier: Barrier::new(n), inner: Server::new()}
        }

        fn count(&self) -> u64 {
            self.inner.count()
        }
    }

    #[test]
    fn test_concurrent() {
        let (client_stream, server_streams) = pair();
        let server = Arc::new(BarrierServer::new(10));
        let thread_server = server.clone();
        let guard = thread::spawn(move || serve(server_streams, thread_server));
        let client: Arc<Client<Reply>> = Arc::new(Client::new(client_stream).unwrap());
        let mut join_handles = vec![];
        for _ in 0..10 {
            let my_client = client.clone();
            join_handles.push(thread::spawn(move || my_client.rpc(&Request::Increment).unwrap()));
        }
        for handle in join_handles.into_iter() {
            handle.join();
        }
        assert_eq!(10, server.count());
        let client = match Arc::try_unwrap(client) {
            Err(_) => panic!("couldn't unwrap arc"),
            Ok(c) => c,
        };
        client.join::<Request>().unwrap();
        guard.join();
    }
}
<|endoftext|>


<commit_before>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::winbase::STD_INPUT_HANDLE
    };
    unsafe {
        let handle = kernel32::GetStdHandle(handle);
        let mut out = 0;
        panic!("result {:#?} last err {:#?}",
        kernel32::GetConsoleMode(handle, &mut out),
    kernel32::GetLastError());
        kernel32::GetConsoleMode(handle, &mut out) != 0
    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<commit_msg>use the handle we've already got<commit_after>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::winbase::STD_INPUT_HANDLE
    };
    unsafe {
        let mut out = 0;
        kernel32::GetConsoleMode(handle, &mut out) != 0
    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 lazy-static.rs Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

Attributes (including doc comments) are supported as well:

```rust
# #[macro_use]
# extern crate lazy_static;
# fn main() {
lazy_static! {
    /// This is an example for using doc comment attributes
    static ref EXAMPLE: u8 = 42;
}
# }
```

# Semantics

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a unique type that
implements `Deref<TYPE>` and stores it in a static with name `NAME`. (Attributes end up
attaching to this type.)

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object. Note that this can lead to deadlocks
if you have multiple lazy statics that depend on each other in their initialization.

Apart from the lazy initialization, the resulting "static ref" variables
have generally the same properties as regular "static" variables:

- Any type in them needs to fulfill the `Sync` trait.
- If the type has a destructor, then it will not run when the process exits.

# Example

Using the macro:

```rust
#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
    static ref COUNT: usize = HASHMAP.len();
    static ref NUMBER: u32 = times_two(21);
}

fn times_two(n: u32) -> u32 { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden static variable that is guarded by an atomic check on each access.

# Cargo features

This crate provides two cargo features:

- `nightly`: This uses unstable language features only available on the nightly release channel for a more optimal implementation. In practice this currently means avoiding a heap allocation per static. This feature might get deprecated at a later point once all relevant optimizations are usable from stable.
- `spin_no_std` (implies `nightly`): This allows using this crate in a no-std environment, by depending on the standalone `spin` crate.

Both features depend on unstable language features, which means
no guarantees can be made about them in regard to SemVer stability.

*/

#![doc(html_root_url = "https://docs.rs/lazy_static/1.2.0")]
#![no_std]

#[cfg(not(feature = "spin_no_std"))]
#[path="inline_lazy.rs"]
#[doc(hidden)]
pub mod lazy;

#[cfg(feature = "spin_no_std")]
#[path="core_lazy.rs"]
#[doc(hidden)]
pub mod lazy;

#[doc(hidden)]
pub use core::ops::Deref as __Deref;

#[macro_export(local_inner_macros)]
#[doc(hidden)]
macro_rules! __lazy_static_internal {
    // optional visibility restrictions are wrapped in `()` to allow for
    // explicitly passing otherwise implicit information about private items
    ($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        __lazy_static_internal!(@MAKE TY, $(#[$attr])*, ($($vis)*), $N);
        __lazy_static_internal!(@TAIL, $N : $T = $e);
        lazy_static!($($t)*);
    };
    (@TAIL, $N:ident : $T:ty = $e:expr) => {
        impl $crate::__Deref for $N {
            type Target = $T;
            fn deref(&self) -> &$T {
                #[inline(always)]
                fn __static_ref_initialize() -> $T { $e }

                #[inline(always)]
                fn __stability() -> &'static $T {
                    __lazy_static_create!(LAZY, $T);
                    LAZY.get(__static_ref_initialize)
                }
                __stability()
            }
        }
        impl $crate::LazyStatic for $N {
            fn initialize(lazy: &Self) {
                let _ = &**lazy;
            }
        }
    };
    // `vis` is wrapped in `()` to prevent parsing ambiguity
    (@MAKE TY, $(#[$attr:meta])*, ($($vis:tt)*), $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        $(#[$attr])*
        $($vis)* struct $N {__private_field: ()}
        #[doc(hidden)]
        $($vis)* static $N: $N = $N {__private_field: ()};
    };
    () => ()
}

#[macro_export(local_inner_macros)]
macro_rules! lazy_static {
    ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        // use `()` to explicitly forward the information about private items
        __lazy_static_internal!($(#[$attr])* () static ref $N : $T = $e; $($t)*);
    };
    ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        __lazy_static_internal!($(#[$attr])* (pub) static ref $N : $T = $e; $($t)*);
    };
    ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        __lazy_static_internal!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $e; $($t)*);
    };
    () => ()
}

/// Support trait for enabling a few common operation on lazy static values.
///
/// This is implemented by each defined lazy static, and
/// used by the free functions in this crate.
pub trait LazyStatic {
    #[doc(hidden)]
    fn initialize(lazy: &Self);
}

/// Takes a shared reference to a lazy static and initializes
/// it if it has not been already.
///
/// This can be used to control the initialization point of a lazy static.
///
/// Example:
///
/// ```rust
/// #[macro_use]
/// extern crate lazy_static;
///
/// lazy_static! {
///     static ref BUFFER: Vec<u8> = (0..65537).collect();
/// }
///
/// fn main() {
///     lazy_static::initialize(&BUFFER);
///
///     // ...
///     work_with_initialized_data(&BUFFER);
/// }
/// # fn work_with_initialized_data(_: &[u8]) {}
/// ```
pub fn initialize<T: LazyStatic>(lazy: &T) {
    LazyStatic::initialize(lazy);
}
<commit_msg>remove reference to the nightly feature from crate docs<commit_after>// Copyright 2016 lazy-static.rs Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

Attributes (including doc comments) are supported as well:

```rust
# #[macro_use]
# extern crate lazy_static;
# fn main() {
lazy_static! {
    /// This is an example for using doc comment attributes
    static ref EXAMPLE: u8 = 42;
}
# }
```

# Semantics

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a unique type that
implements `Deref<TYPE>` and stores it in a static with name `NAME`. (Attributes end up
attaching to this type.)

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object. Note that this can lead to deadlocks
if you have multiple lazy statics that depend on each other in their initialization.

Apart from the lazy initialization, the resulting "static ref" variables
have generally the same properties as regular "static" variables:

- Any type in them needs to fulfill the `Sync` trait.
- If the type has a destructor, then it will not run when the process exits.

# Example

Using the macro:

```rust
#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
    static ref COUNT: usize = HASHMAP.len();
    static ref NUMBER: u32 = times_two(21);
}

fn times_two(n: u32) -> u32 { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden static variable that is guarded by an atomic check on each access.

# Cargo features

This crate provides two cargo features:

- `spin_no_std`: This allows using this crate in a no-std environment, by depending on the standalone `spin` crate.

Both features depend on unstable language features, which means
no guarantees can be made about them in regard to SemVer stability.

*/

#![doc(html_root_url = "https://docs.rs/lazy_static/1.2.0")]
#![no_std]

#[cfg(not(feature = "spin_no_std"))]
#[path="inline_lazy.rs"]
#[doc(hidden)]
pub mod lazy;

#[cfg(feature = "spin_no_std")]
#[path="core_lazy.rs"]
#[doc(hidden)]
pub mod lazy;

#[doc(hidden)]
pub use core::ops::Deref as __Deref;

#[macro_export(local_inner_macros)]
#[doc(hidden)]
macro_rules! __lazy_static_internal {
    // optional visibility restrictions are wrapped in `()` to allow for
    // explicitly passing otherwise implicit information about private items
    ($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        __lazy_static_internal!(@MAKE TY, $(#[$attr])*, ($($vis)*), $N);
        __lazy_static_internal!(@TAIL, $N : $T = $e);
        lazy_static!($($t)*);
    };
    (@TAIL, $N:ident : $T:ty = $e:expr) => {
        impl $crate::__Deref for $N {
            type Target = $T;
            fn deref(&self) -> &$T {
                #[inline(always)]
                fn __static_ref_initialize() -> $T { $e }

                #[inline(always)]
                fn __stability() -> &'static $T {
                    __lazy_static_create!(LAZY, $T);
                    LAZY.get(__static_ref_initialize)
                }
                __stability()
            }
        }
        impl $crate::LazyStatic for $N {
            fn initialize(lazy: &Self) {
                let _ = &**lazy;
            }
        }
    };
    // `vis` is wrapped in `()` to prevent parsing ambiguity
    (@MAKE TY, $(#[$attr:meta])*, ($($vis:tt)*), $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        $(#[$attr])*
        $($vis)* struct $N {__private_field: ()}
        #[doc(hidden)]
        $($vis)* static $N: $N = $N {__private_field: ()};
    };
    () => ()
}

#[macro_export(local_inner_macros)]
macro_rules! lazy_static {
    ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        // use `()` to explicitly forward the information about private items
        __lazy_static_internal!($(#[$attr])* () static ref $N : $T = $e; $($t)*);
    };
    ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        __lazy_static_internal!($(#[$attr])* (pub) static ref $N : $T = $e; $($t)*);
    };
    ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        __lazy_static_internal!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $e; $($t)*);
    };
    () => ()
}

/// Support trait for enabling a few common operation on lazy static values.
///
/// This is implemented by each defined lazy static, and
/// used by the free functions in this crate.
pub trait LazyStatic {
    #[doc(hidden)]
    fn initialize(lazy: &Self);
}

/// Takes a shared reference to a lazy static and initializes
/// it if it has not been already.
///
/// This can be used to control the initialization point of a lazy static.
///
/// Example:
///
/// ```rust
/// #[macro_use]
/// extern crate lazy_static;
///
/// lazy_static! {
///     static ref BUFFER: Vec<u8> = (0..65537).collect();
/// }
///
/// fn main() {
///     lazy_static::initialize(&BUFFER);
///
///     // ...
///     work_with_initialized_data(&BUFFER);
/// }
/// # fn work_with_initialized_data(_: &[u8]) {}
/// ```
pub fn initialize<T: LazyStatic>(lazy: &T) {
    LazyStatic::initialize(lazy);
}
<|endoftext|>


<commit_before>/// Df2 files are waveform files from an Optech LiDAR system.

extern crate byteorder;

use std::fs::File;
use std::io::{self, BufReader, Read};
use std::path::Path;

use byteorder::{LittleEndian, ReadBytesExt};

/// Our custom error enum.
#[derive(Debug)]
pub enum Error {
    Io(io::Error),
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

/// Our custom result type.
pub type Result<T> = std::result::Result<T, Error>;

/// Reads df2 waveform data.
#[derive(Debug)]
pub struct Reader<R: Read> {
    reader: R,
}

impl Reader<BufReader<File>> {
    /// Opens a reader for the file at a path.
    ///
    /// # Examples
    ///
    /// ```
    /// use df2::Reader;
    /// let reader = Reader::from_path("data/one-shot.df2").unwrap();
    /// ```
    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Reader<BufReader<File>>> {
        let file = BufReader::new(File::open(path)?);
        Ok(Reader { reader: file })
    }
}

impl<R: Read> Reader<R> {
    /// Reads one shot.
    ///
    /// # Examples
    ///
    /// ```
    /// # use df2::Reader;
    /// let mut reader = Reader::from_path("data/one-shot.df2").unwrap();
    /// let shot = reader.read_one().unwrap().unwrap();
    /// ```
    pub fn read_one(&mut self) -> Result<Option<Shot>> {
        let number = self.reader.read_u16::<LittleEndian>()?;
        Ok(Some(Shot { number: number }))
    }
}

impl<R: Read> Iterator for Reader<R> {
    type Item = Result<Shot>;
    fn next(&mut self) -> Option<Result<Shot>> {
        unimplemented!()
    }
}

/// A laser shot.
pub struct Shot {
    /// The shot number (one-indexed).
    pub number: u16,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn reader_from_path() {
        assert!(Reader::from_path("data/one-shot.df2").is_ok());
    }

    #[test]
    fn reader_read_one() {
        let mut reader = Reader::from_path("data/one-shot.df2").unwrap();
        let shot = reader.read_one().unwrap().unwrap();
        assert_eq!(1, shot.number);
    }

    #[test]
    fn reader_iterator() {
        let shots: Vec<_> = Reader::from_path("data/one-shot.df2").unwrap().collect();
        assert_eq!(1, shots.len());
    }
}
<commit_msg>Stop iterating when we're at the end<commit_after>/// Df2 files are waveform files from an Optech LiDAR system.

extern crate byteorder;

use std::fs::File;
use std::io::{self, BufReader, Read, ErrorKind};
use std::path::Path;

use byteorder::{LittleEndian, ReadBytesExt};

/// Our custom error enum.
#[derive(Debug)]
pub enum Error {
    Io(io::Error),
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

/// Our custom result type.
pub type Result<T> = std::result::Result<T, Error>;

/// Reads df2 waveform data.
#[derive(Debug)]
pub struct Reader<R: Read> {
    reader: R,
}

impl Reader<BufReader<File>> {
    /// Opens a reader for the file at a path.
    ///
    /// # Examples
    ///
    /// ```
    /// use df2::Reader;
    /// let reader = Reader::from_path("data/one-shot.df2").unwrap();
    /// ```
    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Reader<BufReader<File>>> {
        let file = BufReader::new(File::open(path)?);
        Ok(Reader { reader: file })
    }
}

impl<R: Read> Reader<R> {
    /// Reads one shot.
    ///
    /// # Examples
    ///
    /// ```
    /// # use df2::Reader;
    /// let mut reader = Reader::from_path("data/one-shot.df2").unwrap();
    /// let shot = reader.read_one().unwrap().unwrap();
    /// ```
    pub fn read_one(&mut self) -> Result<Option<Shot>> {
        let number = match self.reader.read_u16::<LittleEndian>() {
            Ok(number) => number,
            Err(err) => {
                match err.kind() {
                    ErrorKind::UnexpectedEof => return Ok(None),
                    _ => return Err(err.into()),
                }
            }
        };
        Ok(Some(Shot { number: number }))
    }
}

impl<R: Read> Iterator for Reader<R> {
    type Item = Result<Shot>;
    fn next(&mut self) -> Option<Result<Shot>> {
        match self.read_one() {
            Ok(option) => {
                match option {
                    Some(shot) => Some(Ok(shot)),
                    None => None,
                }
            }
            Err(err) => Some(Err(err)),
        }
    }
}

/// A laser shot.
pub struct Shot {
    /// The shot number (one-indexed).
    pub number: u16,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn reader_from_path() {
        assert!(Reader::from_path("data/one-shot.df2").is_ok());
    }

    #[test]
    fn reader_read_one() {
        let mut reader = Reader::from_path("data/one-shot.df2").unwrap();
        let shot = reader.read_one().unwrap().unwrap();
        assert_eq!(1, shot.number);
    }

    #[test]
    fn reader_iterator() {
        let shots: Vec<_> = Reader::from_path("data/one-shot.df2").unwrap().collect();
        assert_eq!(1, shots.len());
    }
}
<|endoftext|>


<commit_before>//! This crate serves matrix manipulation for
//! [rust-ndarray](https://github.com/bluss/rust-ndarray).
//!
//! They are implemented as traits,
//! [Matrix](matrix/trait.Matrix.html), [SquareMatrix](square/trait.SquareMatrix.html),
//! [TriangularMatrix](triangular/trait.TriangularMatrix.html), and
//! [HermiteMatrix](hermite/trait.HermiteMatrix.html)
//!
//! Matrix
//! -------
//! - [singular-value decomposition](matrix/trait.Matrix.html#tymethod.svd)
//! - [LU decomposition](matrix/trait.Matrix.html#tymethod.lu)
//! - [QR decomposition](matrix/trait.Matrix.html#tymethod.qr)
//! - [operator norm for L1 norm](matrix/trait.Matrix.html#tymethod.norm_1)
//! - [operator norm for L-inf norm](matrix/trait.Matrix.html#tymethod.norm_i)
//! - [Frobeiuns norm](matrix/trait.Matrix.html#tymethod.norm_f)
//!
//! SquareMatrix
//! -------------
//! - [inverse of matrix](square/trait.SquareMatrix.html#tymethod.inv)
//! - [trace of matrix](square/trait.SquareMatrix.html#tymethod.trace)
//! - [WIP] eigenvalue
//!
//! TriangularMatrix
//! ------------------
//! - [solve linear problem with upper triangular matrix](triangular/trait.TriangularMatrix.html#tymethod.solve_upper)
//! - [solve linear problem with lower triangular matrix](triangular/trait.TriangularMatrix.html#tymethod.solve_lower)
//!
//! HermiteMatrix
//! --------------
//! - [eigenvalue analysis](hermite/trait.HermiteMatrix.html#tymethod.eigh)
//! - [symmetric square root](hermite/trait.HermiteMatrix.html#tymethod.ssqrt)
//! - [Cholesky factorization](hermite/trait.HermiteMatrix.html#tymethod.cholesky)

extern crate lapack;
extern crate num_traits;
#[macro_use(s)]
extern crate ndarray;

pub mod prelude;
pub mod error;
pub mod vector;
pub mod matrix;
pub mod square;
pub mod hermite;
pub mod triangular;

pub mod qr;
pub mod svd;
pub mod eigh;
pub mod opnorm;
pub mod solve;
pub mod cholesky;

pub mod topology;
<commit_msg>Fix mod def<commit_after>//! This crate serves matrix manipulation for
//! [rust-ndarray](https://github.com/bluss/rust-ndarray).
//!
//! They are implemented as traits,
//! [Matrix](matrix/trait.Matrix.html), [SquareMatrix](square/trait.SquareMatrix.html),
//! [TriangularMatrix](triangular/trait.TriangularMatrix.html), and
//! [HermiteMatrix](hermite/trait.HermiteMatrix.html)
//!
//! Matrix
//! -------
//! - [singular-value decomposition](matrix/trait.Matrix.html#tymethod.svd)
//! - [LU decomposition](matrix/trait.Matrix.html#tymethod.lu)
//! - [QR decomposition](matrix/trait.Matrix.html#tymethod.qr)
//! - [operator norm for L1 norm](matrix/trait.Matrix.html#tymethod.norm_1)
//! - [operator norm for L-inf norm](matrix/trait.Matrix.html#tymethod.norm_i)
//! - [Frobeiuns norm](matrix/trait.Matrix.html#tymethod.norm_f)
//!
//! SquareMatrix
//! -------------
//! - [inverse of matrix](square/trait.SquareMatrix.html#tymethod.inv)
//! - [trace of matrix](square/trait.SquareMatrix.html#tymethod.trace)
//! - [WIP] eigenvalue
//!
//! TriangularMatrix
//! ------------------
//! - [solve linear problem with upper triangular matrix](triangular/trait.TriangularMatrix.html#tymethod.solve_upper)
//! - [solve linear problem with lower triangular matrix](triangular/trait.TriangularMatrix.html#tymethod.solve_lower)
//!
//! HermiteMatrix
//! --------------
//! - [eigenvalue analysis](hermite/trait.HermiteMatrix.html#tymethod.eigh)
//! - [symmetric square root](hermite/trait.HermiteMatrix.html#tymethod.ssqrt)
//! - [Cholesky factorization](hermite/trait.HermiteMatrix.html#tymethod.cholesky)

extern crate lapack;
extern crate num_traits;
#[macro_use(s)]
extern crate ndarray;

pub mod prelude;
pub mod error;
pub mod vector;
pub mod matrix;
pub mod square;
pub mod hermite;
pub mod triangular;

pub mod qr;
pub mod svd;
pub mod eigh;
pub mod opnorm;
pub mod solve;
pub mod cholesky;

pub mod util;
<|endoftext|>


<commit_before>#![deny(warnings)]
#![deny(unused)]
#![deny(future_incompatible)]
#![deny(bad_style)]

extern crate bytes;
#[macro_use]
extern crate futures;
extern crate futures_state_stream;
extern crate imap_proto;
extern crate native_tls;
extern crate nom;
extern crate tokio;
extern crate tokio_io;
extern crate tokio_tls;

pub mod client;
pub mod proto;

pub use client::TlsClient;

pub mod types {
    pub use imap_proto::types::*;
}
<commit_msg>Export ImapClient trait at top level<commit_after>#![deny(warnings)]
#![deny(unused)]
#![deny(future_incompatible)]
#![deny(bad_style)]

extern crate bytes;
#[macro_use]
extern crate futures;
extern crate futures_state_stream;
extern crate imap_proto;
extern crate native_tls;
extern crate nom;
extern crate tokio;
extern crate tokio_io;
extern crate tokio_tls;

pub mod client;
pub mod proto;

pub use client::{ImapClient, TlsClient};

pub mod types {
    pub use imap_proto::types::*;
}
<|endoftext|>