<commit_before>#[macro_use]
extern crate log;

use std::collections::{BTreeMap, BTreeSet};
use std::error::Error as StdError;
use std::fmt::{self, Display, Formatter};

/// 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,
    }
}

impl<E: StdError> StdError for Error<E> {
    fn description(&self) -> &str {
        match *self {
            Error::Adapter(ref err) => err.description(),
            Error::Migration { ref error, .. } => error.description(),
        }
    }

    fn cause(&self) -> Option<&StdError> {
        match *self {
            Error::Adapter(ref err) => Some(err),
            Error::Migration { ref error, .. } => Some(error),
        }
    }
}

impl<E: StdError> Display for Error<E> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::Adapter(ref err) => write!(f, "Adataper error: {}", err),
            Error::Migration { ref description, ref error, .. } => {
                write!(f, "Error running migration {}, error: {}", description, error)
            },
        }
    }
}

/// 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)));
}
<commit_msg>Relax lifetime for `Migration::description`<commit_after>#[macro_use]
extern crate log;

use std::collections::{BTreeMap, BTreeSet};
use std::error::Error as StdError;
use std::fmt::{self, Display, Formatter};

/// 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) -> String;
}

/// 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: String,
        /// The direction in which the failed migration was ran.
        direction: Direction,
        /// The underlying error from the adapter.
        error: E,
    }
}

impl<E: StdError> StdError for Error<E> {
    fn description(&self) -> &str {
        match *self {
            Error::Adapter(ref err) => err.description(),
            Error::Migration { ref error, .. } => error.description(),
        }
    }

    fn cause(&self) -> Option<&StdError> {
        match *self {
            Error::Adapter(ref err) => Some(err),
            Error::Migration { ref error, .. } => Some(error),
        }
    }
}

impl<E: StdError> Display for Error<E> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::Adapter(ref err) => write!(f, "Adataper error: {}", err),
            Error::Migration { ref description, ref error, .. } => {
                write!(f, "Error running migration {}, error: {}", description, error)
            },
        }
    }
}

/// 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) -> String { $description.into() }
        }
    }
}

/// 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 {
            let description = migration.description();
            info!("Reverting migration {:?}: {}", version, description);
            if let Err(err) = self.adapter.revert_migration(migration) {
                return Err(Error::Migration {
                    version: version,
                    description: 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 {
            let description = migration.description();
            info!("Applying migration {:?}: {}", version, description);
            if let Err(err) = self.adapter.apply_migration(migration) {
                return Err(Error::Migration {
                    version: version,
                    description: 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>// INSERT_README_VIA_MAKE
extern crate rustix;
extern crate tempfile;

use std::convert::AsRef;
use std::error::Error as ErrorTrait;
use std::fmt;
use std::fs;
use std::io;
use std::path;

pub use OverwriteBehavior::{AllowOverwrite, DisallowOverwrite};

/// Whether to allow overwriting if the target file exists.
#[derive(Clone, Copy)]
pub enum OverwriteBehavior {
    /// Overwrite files silently.
    AllowOverwrite,

    /// Don't overwrite files. `AtomicFile.write` will raise errors for such conditions only after
    /// you've already written your data.
    DisallowOverwrite,
}

/// Represents an error raised by `AtomicFile.write`.
#[derive(Debug)]
pub enum Error<E> {
    /// The error originated in the library itself, while it was either creating a temporary file
    /// or moving the file into place.
    Internal(io::Error),
    /// The error originated in the user-supplied callback.
    User(E),
}

/// If your callback returns a `std::io::Error`, you can unwrap this type to `std::io::Error`.
impl From<Error<io::Error>> for io::Error {
    fn from(e: Error<io::Error>) -> Self {
        match e {
            Error::Internal(x) => x,
            Error::User(x) => x,
        }
    }
}

impl<E: fmt::Display> fmt::Display for Error<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Internal(ref e) => e.fmt(f),
            Error::User(ref e) => e.fmt(f),
        }
    }
}

impl<E: ErrorTrait> ErrorTrait for Error<E> {
    fn cause(&self) -> Option<&dyn ErrorTrait> {
        match *self {
            Error::Internal(ref e) => Some(e),
            Error::User(ref e) => Some(e),
        }
    }
}

fn safe_parent(p: &path::Path) -> Option<&path::Path> {
    match p.parent() {
        None => None,
        Some(x) if x.as_os_str().is_empty() => Some(path::Path::new(".")),
        x => x,
    }
}

/// Create a file and write to it atomically, in a callback.
pub struct AtomicFile {
    /// Path to the final file that is atomically written.
    path: path::PathBuf,
    overwrite: OverwriteBehavior,
    /// Directory to which to write the temporary subdirectories.
    tmpdir: path::PathBuf,
}

impl AtomicFile {
    /// Helper for writing to the file at `path` atomically, in write-only mode.
    ///
    /// If `OverwriteBehaviour::DisallowOverwrite` is given,
    /// an `Error::Internal` containing an `std::io::ErrorKind::AlreadyExists`
    /// will be returned from `self.write(...)` if the file exists.
    ///
    /// The temporary file is written to a temporary subdirectory in `.`, to ensure
    /// it’s on the same filesystem (so that the move is atomic).
    pub fn new<P>(path: P, overwrite: OverwriteBehavior) -> Self
    where
        P: AsRef<path::Path>,
    {
        let p = path.as_ref();
        AtomicFile::new_with_tmpdir(
            p,
            overwrite,
            safe_parent(p).unwrap_or_else(|| path::Path::new(".")),
        )
    }

    /// Like `AtomicFile::new`, but the temporary file is written to a temporary subdirectory in `tmpdir`.
    ///
    /// TODO: does `tmpdir` have to exist?
    pub fn new_with_tmpdir<P, Q>(path: P, overwrite: OverwriteBehavior, tmpdir: Q) -> Self
    where
        P: AsRef<path::Path>,
        Q: AsRef<path::Path>,
    {
        AtomicFile {
            path: path.as_ref().to_path_buf(),
            overwrite,
            tmpdir: tmpdir.as_ref().to_path_buf(),
        }
    }

    /// Move the file to `self.path()`. Only call once! Not exposed!
    fn commit(&self, tmppath: &path::Path) -> io::Result<()> {
        match self.overwrite {
            AllowOverwrite => replace_atomic(tmppath, self.path()),
            DisallowOverwrite => move_atomic(tmppath, self.path()),
        }
    }

    /// Get the target filepath.
    pub fn path(&self) -> &path::Path {
        &self.path
    }

    /// Open a temporary file, call `f` on it (which is supposed to write to it), then move the
    /// file atomically to `self.path`.
    ///
    /// The temporary file is written to a randomized temporary subdirectory with prefix `.atomicwrite`.
    pub fn write<T, E, F>(&self, f: F) -> Result<T, Error<E>>
    where
        F: FnOnce(&mut fs::File) -> Result<T, E>,
    {
        let tmpdir = tempfile::Builder::new()
            .prefix(".atomicwrite")
            .tempdir_in(&self.tmpdir)
            .map_err(Error::Internal)?;

        let tmppath = tmpdir.path().join("tmpfile.tmp");
        let rv = {
            let mut tmpfile = fs::File::create(&tmppath).map_err(Error::Internal)?;
            let r = f(&mut tmpfile).map_err(Error::User)?;
            tmpfile.sync_all().map_err(Error::Internal)?;
            r
        };
        self.commit(&tmppath).map_err(Error::Internal)?;
        Ok(rv)
    }
}

#[cfg(unix)]
mod imp {
    use super::safe_parent;

    use rustix::fs::AtFlags;
    use std::{fs, io, path};

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        let src_parent_path = safe_parent(src).unwrap();
        let dst_parent_path = safe_parent(dst).unwrap();
        let src_child_path = src.file_name().unwrap();
        let dst_child_path = dst.file_name().unwrap();

        // Open the parent directories. If src and dst have the same parent
        // path, open it once and reuse it.
        let src_parent = fs::File::open(src_parent_path)?;
        let dst_parent;
        let dst_parent = if src_parent_path == dst_parent_path {
            &src_parent
        } else {
            dst_parent = fs::File::open(dst_parent_path)?;
            &dst_parent
        };

        // Do the `renameat`.
        rustix::fs::renameat(&src_parent, src_child_path, &dst_parent, dst_child_path)?;

        // Fsync the parent directory (or directories, if they're different).
        src_parent.sync_all()?;
        if src_parent_path != dst_parent_path {
            dst_parent.sync_all()?;
        }

        Ok(())
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        let src_parent_path = safe_parent(src).unwrap();
        let dst_parent_path = safe_parent(dst).unwrap();
        let src_child_path = src.file_name().unwrap();
        let dst_child_path = dst.file_name().unwrap();

        // Open the parent directories. If src and dst have the same parent
        // path, open it once and reuse it.
        let src_parent = fs::File::open(src_parent_path)?;
        let dst_parent;
        let dst_parent = if src_parent_path == dst_parent_path {
            &src_parent
        } else {
            dst_parent = fs::File::open(dst_parent_path)?;
            &dst_parent
        };

        // On Linux, use `renameat2` with `RENAME_NOREPLACE` if we have it, as
        // that does an atomic rename.
        #[cfg(any(target_os = "android", target_os = "linux"))]
        {
            use rustix::fs::RenameFlags;
            use std::sync::atomic::AtomicBool;
            use std::sync::atomic::Ordering::Relaxed;

            static NO_RENAMEAT2: AtomicBool = AtomicBool::new(false);
            if !NO_RENAMEAT2.load(Relaxed) {
                match rustix::fs::renameat_with(
                    &src_parent,
                    src_child_path,
                    &dst_parent,
                    dst_child_path,
                    RenameFlags::NOREPLACE,
                ) {
                    Ok(()) => {
                        // Fsync the parent directory (or directories, if
                        // they're different).
                        src_parent.sync_all()?;
                        if src_parent_path != dst_parent_path {
                            dst_parent.sync_all()?;
                        }
                        return Ok(());
                    }
                    Err(rustix::io::Error::NOSYS) => {
                        // The OS doesn't support `renameat2`; remember this so
                        // that we don't bother calling it again.
                        NO_RENAMEAT2.store(true, Relaxed);
                    }
                    Err(e) => return Err(e.into()),
                }
            }
        }

        // Otherwise, hard-link the src to the dst, and then delete the dst.
        rustix::fs::linkat(
            &src_parent,
            src_child_path,
            &dst_parent,
            dst_child_path,
            AtFlags::empty(),
        )?;
        rustix::fs::unlinkat(&src_parent, src_child_path, AtFlags::empty())?;

        // Fsync the parent directory (or directories, if they're different).
        src_parent.sync_all()?;
        if src_parent_path != dst_parent_path {
            dst_parent.sync_all()?;
        }

        Ok(())
    }
}

#[cfg(windows)]
mod imp {
    extern crate winapi;

    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;
    use std::{io, path};

    macro_rules! call {
        ($e: expr) => {
            if $e != 0 {
                Ok(())
            } else {
                Err(io::Error::last_os_error())
            }
        };
    }

    fn path_to_windows_str<T: AsRef<OsStr>>(x: T) -> Vec<winapi::shared::ntdef::WCHAR> {
        x.as_ref().encode_wide().chain(Some(0)).collect()
    }

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {
            winapi::um::winbase::MoveFileExW(
                path_to_windows_str(src).as_ptr(),
                path_to_windows_str(dst).as_ptr(),
                winapi::um::winbase::MOVEFILE_WRITE_THROUGH
                    | winapi::um::winbase::MOVEFILE_REPLACE_EXISTING,
            )
        })
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {
            winapi::um::winbase::MoveFileExW(
                path_to_windows_str(src).as_ptr(),
                path_to_windows_str(dst).as_ptr(),
                winapi::um::winbase::MOVEFILE_WRITE_THROUGH,
            )
        })
    }
}

/// Move `src` to `dst`. If `dst` exists, it will be silently overwritten.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::replace_atomic(src, dst)
}

/// Move `src` to `dst`. An error will be returned if `dst` exists.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::move_atomic(src, dst)
}
<commit_msg>Add a way to customize the OpenOptions for a file (#53)<commit_after>// INSERT_README_VIA_MAKE
extern crate rustix;
extern crate tempfile;

use std::convert::AsRef;
use std::error::Error as ErrorTrait;
use std::fmt;
use std::fs;
use std::io;
use std::path;

pub use OverwriteBehavior::{AllowOverwrite, DisallowOverwrite};

/// Whether to allow overwriting if the target file exists.
#[derive(Clone, Copy)]
pub enum OverwriteBehavior {
    /// Overwrite files silently.
    AllowOverwrite,

    /// Don't overwrite files. `AtomicFile.write` will raise errors for such conditions only after
    /// you've already written your data.
    DisallowOverwrite,
}

/// Represents an error raised by `AtomicFile.write`.
#[derive(Debug)]
pub enum Error<E> {
    /// The error originated in the library itself, while it was either creating a temporary file
    /// or moving the file into place.
    Internal(io::Error),
    /// The error originated in the user-supplied callback.
    User(E),
}

/// If your callback returns a `std::io::Error`, you can unwrap this type to `std::io::Error`.
impl From<Error<io::Error>> for io::Error {
    fn from(e: Error<io::Error>) -> Self {
        match e {
            Error::Internal(x) => x,
            Error::User(x) => x,
        }
    }
}

impl<E: fmt::Display> fmt::Display for Error<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Internal(ref e) => e.fmt(f),
            Error::User(ref e) => e.fmt(f),
        }
    }
}

impl<E: ErrorTrait> ErrorTrait for Error<E> {
    fn cause(&self) -> Option<&dyn ErrorTrait> {
        match *self {
            Error::Internal(ref e) => Some(e),
            Error::User(ref e) => Some(e),
        }
    }
}

fn safe_parent(p: &path::Path) -> Option<&path::Path> {
    match p.parent() {
        None => None,
        Some(x) if x.as_os_str().is_empty() => Some(path::Path::new(".")),
        x => x,
    }
}

/// Create a file and write to it atomically, in a callback.
pub struct AtomicFile {
    /// Path to the final file that is atomically written.
    path: path::PathBuf,
    overwrite: OverwriteBehavior,
    /// Directory to which to write the temporary subdirectories.
    tmpdir: path::PathBuf,
}

impl AtomicFile {
    /// Helper for writing to the file at `path` atomically, in write-only mode.
    ///
    /// If `OverwriteBehaviour::DisallowOverwrite` is given,
    /// an `Error::Internal` containing an `std::io::ErrorKind::AlreadyExists`
    /// will be returned from `self.write(...)` if the file exists.
    ///
    /// The temporary file is written to a temporary subdirectory in `.`, to ensure
    /// it’s on the same filesystem (so that the move is atomic).
    pub fn new<P>(path: P, overwrite: OverwriteBehavior) -> Self
    where
        P: AsRef<path::Path>,
    {
        let p = path.as_ref();
        AtomicFile::new_with_tmpdir(
            p,
            overwrite,
            safe_parent(p).unwrap_or_else(|| path::Path::new(".")),
        )
    }

    /// Like `AtomicFile::new`, but the temporary file is written to a temporary subdirectory in `tmpdir`.
    ///
    /// TODO: does `tmpdir` have to exist?
    pub fn new_with_tmpdir<P, Q>(path: P, overwrite: OverwriteBehavior, tmpdir: Q) -> Self
    where
        P: AsRef<path::Path>,
        Q: AsRef<path::Path>,
    {
        AtomicFile {
            path: path.as_ref().to_path_buf(),
            overwrite,
            tmpdir: tmpdir.as_ref().to_path_buf(),
        }
    }

    /// Move the file to `self.path()`. Only call once! Not exposed!
    fn commit(&self, tmppath: &path::Path) -> io::Result<()> {
        match self.overwrite {
            AllowOverwrite => replace_atomic(tmppath, self.path()),
            DisallowOverwrite => move_atomic(tmppath, self.path()),
        }
    }

    /// Get the target filepath.
    pub fn path(&self) -> &path::Path {
        &self.path
    }

    /// Open a temporary file, call `f` on it (which is supposed to write to it), then move the
    /// file atomically to `self.path`.
    ///
    /// The temporary file is written to a randomized temporary subdirectory with prefix `.atomicwrite`.
    pub fn write<T, E, F>(&self, f: F) -> Result<T, Error<E>>
    where
        F: FnOnce(&mut fs::File) -> Result<T, E>,
    {
        let mut options = fs::OpenOptions::new();
        // These are the same options as `File::create`.
        options.write(true).create(true).truncate(true);
        self.write_with_options(f, options)
    }

    /// Open a temporary file with custom [`OpenOptions`], call `f` on it (which is supposed to
    /// write to it), then move the file atomically to `self.path`.
    ///
    /// The temporary file is written to a randomized temporary subdirectory with prefix
    /// `.atomicwrite`.
    ///
    /// [`OpenOptions`]: fs::OpenOptions
    pub fn write_with_options<T, E, F>(&self, f: F, options: fs::OpenOptions) -> Result<T, Error<E>>
    where
        F: FnOnce(&mut fs::File) -> Result<T, E>,
    {
        let tmpdir = tempfile::Builder::new()
            .prefix(".atomicwrite")
            .tempdir_in(&self.tmpdir)
            .map_err(Error::Internal)?;

        let tmppath = tmpdir.path().join("tmpfile.tmp");
        let rv = {
            let mut tmpfile = options.open(&tmppath).map_err(Error::Internal)?;
            let r = f(&mut tmpfile).map_err(Error::User)?;
            tmpfile.sync_all().map_err(Error::Internal)?;
            r
        };
        self.commit(&tmppath).map_err(Error::Internal)?;
        Ok(rv)
    }
}

#[cfg(unix)]
mod imp {
    use super::safe_parent;

    use rustix::fs::AtFlags;
    use std::{fs, io, path};

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        let src_parent_path = safe_parent(src).unwrap();
        let dst_parent_path = safe_parent(dst).unwrap();
        let src_child_path = src.file_name().unwrap();
        let dst_child_path = dst.file_name().unwrap();

        // Open the parent directories. If src and dst have the same parent
        // path, open it once and reuse it.
        let src_parent = fs::File::open(src_parent_path)?;
        let dst_parent;
        let dst_parent = if src_parent_path == dst_parent_path {
            &src_parent
        } else {
            dst_parent = fs::File::open(dst_parent_path)?;
            &dst_parent
        };

        // Do the `renameat`.
        rustix::fs::renameat(&src_parent, src_child_path, &dst_parent, dst_child_path)?;

        // Fsync the parent directory (or directories, if they're different).
        src_parent.sync_all()?;
        if src_parent_path != dst_parent_path {
            dst_parent.sync_all()?;
        }

        Ok(())
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        let src_parent_path = safe_parent(src).unwrap();
        let dst_parent_path = safe_parent(dst).unwrap();
        let src_child_path = src.file_name().unwrap();
        let dst_child_path = dst.file_name().unwrap();

        // Open the parent directories. If src and dst have the same parent
        // path, open it once and reuse it.
        let src_parent = fs::File::open(src_parent_path)?;
        let dst_parent;
        let dst_parent = if src_parent_path == dst_parent_path {
            &src_parent
        } else {
            dst_parent = fs::File::open(dst_parent_path)?;
            &dst_parent
        };

        // On Linux, use `renameat2` with `RENAME_NOREPLACE` if we have it, as
        // that does an atomic rename.
        #[cfg(any(target_os = "android", target_os = "linux"))]
        {
            use rustix::fs::RenameFlags;
            use std::sync::atomic::AtomicBool;
            use std::sync::atomic::Ordering::Relaxed;

            static NO_RENAMEAT2: AtomicBool = AtomicBool::new(false);
            if !NO_RENAMEAT2.load(Relaxed) {
                match rustix::fs::renameat_with(
                    &src_parent,
                    src_child_path,
                    &dst_parent,
                    dst_child_path,
                    RenameFlags::NOREPLACE,
                ) {
                    Ok(()) => {
                        // Fsync the parent directory (or directories, if
                        // they're different).
                        src_parent.sync_all()?;
                        if src_parent_path != dst_parent_path {
                            dst_parent.sync_all()?;
                        }
                        return Ok(());
                    }
                    Err(rustix::io::Error::NOSYS) => {
                        // The OS doesn't support `renameat2`; remember this so
                        // that we don't bother calling it again.
                        NO_RENAMEAT2.store(true, Relaxed);
                    }
                    Err(e) => return Err(e.into()),
                }
            }
        }

        // Otherwise, hard-link the src to the dst, and then delete the dst.
        rustix::fs::linkat(
            &src_parent,
            src_child_path,
            &dst_parent,
            dst_child_path,
            AtFlags::empty(),
        )?;
        rustix::fs::unlinkat(&src_parent, src_child_path, AtFlags::empty())?;

        // Fsync the parent directory (or directories, if they're different).
        src_parent.sync_all()?;
        if src_parent_path != dst_parent_path {
            dst_parent.sync_all()?;
        }

        Ok(())
    }
}

#[cfg(windows)]
mod imp {
    extern crate winapi;

    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;
    use std::{io, path};

    macro_rules! call {
        ($e: expr) => {
            if $e != 0 {
                Ok(())
            } else {
                Err(io::Error::last_os_error())
            }
        };
    }

    fn path_to_windows_str<T: AsRef<OsStr>>(x: T) -> Vec<winapi::shared::ntdef::WCHAR> {
        x.as_ref().encode_wide().chain(Some(0)).collect()
    }

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {
            winapi::um::winbase::MoveFileExW(
                path_to_windows_str(src).as_ptr(),
                path_to_windows_str(dst).as_ptr(),
                winapi::um::winbase::MOVEFILE_WRITE_THROUGH
                    | winapi::um::winbase::MOVEFILE_REPLACE_EXISTING,
            )
        })
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {
            winapi::um::winbase::MoveFileExW(
                path_to_windows_str(src).as_ptr(),
                path_to_windows_str(dst).as_ptr(),
                winapi::um::winbase::MOVEFILE_WRITE_THROUGH,
            )
        })
    }
}

/// Move `src` to `dst`. If `dst` exists, it will be silently overwritten.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::replace_atomic(src, dst)
}

/// Move `src` to `dst`. An error will be returned if `dst` exists.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::move_atomic(src, dst)
}
<|endoftext|>


<commit_before>extern crate getopts;
use getopts::{optopt,optflag,getopts,OptGroup,usage};
use std::os;

use std::io;
use std::io::{IoResult, IoError};
use std::io::BufferedReader;
use std::io::File;

pub fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", usage(brief.as_slice(), opts));
}

pub fn cat(v: &Vec<String>, options: &getopts::Matches) {
    if v.is_empty() {
        cat_stdin(options);
    }
    else {
        // read files
        cat_files(v, options);
    }
}

fn cat_files(v: &Vec<String>, options: &getopts::Matches) {
    let mut printempty: bool = false;
    let mut linenum = 1u32;
    for filename in v.iter() {
        let path = Path::new(filename);

        if options.opt_present("v") || options.opt_present("t") {
            let mut file = BufferedReader::new(File::open(&path));
            loop {
                match file.read_byte() {
                    Ok(b) => { print_byte(b, options) },
                    Err(f) => { break; }
                }
            }
        }
        else {
            let mut file = BufferedReader::new(File::open(&path));
            for line in file.lines() {
                let (a, b) = handle_line(line, &mut printempty, &mut linenum, options);
                printempty = a;
                linenum = b;
            }
        }
    }
}

fn cat_stdin(options: &getopts::Matches) {
    let mut printempty: bool = false;
    let mut linenum = 1u32;
    for line in io::stdin().lock().lines() {
        let (a, b) = handle_line(line, &mut printempty, &mut linenum, options);
        printempty = a;
        linenum = b;
    }
}

fn handle_line<'a>(
    line: IoResult<String>,
    printempty: &'a mut bool,
    linenum: &'a mut u32,
    options: &getopts::Matches) -> (bool, u32) {
    let linestr = line.unwrap();
    if options.opt_present("s") {
        if !is_empty(&linestr) {
            if *printempty == true {
                println!("");
            }
            *linenum = *print_string(&linestr, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        *linenum = *print_string(&linestr, linenum, options);
    }
    (*printempty, *linenum)
}

fn print_string<'a>(s: &String, linenum: &'a mut u32, options: &getopts::Matches) -> &'a mut u32 {
    if options.opt_present("b") {
        if !is_empty(s) {
            print!("     {}  {}", linenum, s);
            *linenum = *linenum + 1;
        }
        else {
            print!("{}", s);
        }
    }
    else if options.opt_present("n") {
        print!("     {}  {}", linenum, s);
        *linenum = *linenum + 1;
    }
    else {
        print!("{}", s);
    }
    linenum
}

fn is_empty(line: &String) -> bool {
    let newline_str = "\n".to_string();
    let crlf_str = "\r\n".to_string();
    if line.is_empty() {
        true
    }
    else if line.eq(&newline_str) || line.eq(&crlf_str) {
        true
    }
    else {
        false
    }
}

fn print_byte(b: u8, options: &getopts::Matches) {
    if b > 31 || b == 10 || b == 9 {
        if options.opt_present("t") && b == 9 {
            print!("^{}", (b + 64) as char);
        }
        else {
            print!("{}", b as char);
        }
    }
    else {
        print!("^{}", (b + 64) as char);
    }
}

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

    #[test]
    fn assert_is_empty() {
        let s = "".to_string();
        assert!(is_empty(&s));
    }
    #[test]
    fn assert_is_empty_newline() {
        let s = "\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_crlf() {
        let s = "\r\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_char() {
        let s = "d".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_is_empty_ctrl_char() {
        let s = "".to_string();
        assert!(!is_empty(&s));
    }
}
<commit_msg>handles vt options with bn and s not terrible<commit_after>extern crate getopts;
use getopts::{optopt,optflag,getopts,OptGroup,usage};
use std::os;

use std::io;
use std::io::{IoResult, IoError};
use std::io::BufferedReader;
use std::io::File;

pub fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", usage(brief.as_slice(), opts));
}

pub fn cat(v: &Vec<String>, options: &getopts::Matches) {
    if v.is_empty() {
        cat_stdin(options);
    }
    else {
        // read files
        cat_files(v, options);
    }
}

fn cat_files(v: &Vec<String>, options: &getopts::Matches) {
    let mut printempty: bool = false;
    let mut linenum = 1u32;
    for filename in v.iter() {
        let path = Path::new(filename);
        let mut file = BufferedReader::new(File::open(&path));
        for line in file.lines() {
            let (a, b) = handle_line(line, &mut printempty, &mut linenum, options);
            printempty = a;
            linenum = b;
        }
    }
}

fn cat_stdin(options: &getopts::Matches) {
    let mut printempty: bool = false;
    let mut linenum = 1u32;
    for line in io::stdin().lock().lines() {
        let (a, b) = handle_line(line, &mut printempty, &mut linenum, options);
        printempty = a;
        linenum = b;
    }
}

fn handle_line<'a>(
    line: IoResult<String>,
    printempty: &'a mut bool,
    linenum: &'a mut u32,
    options: &getopts::Matches) -> (bool, u32) {
    let linestr = line.unwrap();
    if options.opt_present("s") {
        if !is_empty(&linestr) {
            if *printempty == true {
                println!("");
            }
            *linenum = *print_string(&linestr, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        *linenum = *print_string(&linestr, linenum, options);
    }
    (*printempty, *linenum)
}

fn print_string<'a>(s: &String, linenum: &'a mut u32, options: &getopts::Matches) -> &'a mut u32 {
    if options.opt_present("b") {
        if !is_empty(s) {
            print_numbered(s, linenum, options);
            *linenum = *linenum + 1;
        }
        else {
            print_unnumbered(s, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered(s, linenum, options);
        *linenum = *linenum + 1;
    }
    else {
        print_unnumbered(s, options);
    }
    linenum
}

fn print_numbered<'a>(s: &String, linenum: &'a mut u32, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        print!("      {} ", linenum);
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("     {}  {}", linenum, s);
    }
}

fn print_unnumbered(s: &String, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("{}", s);
    }
}

fn is_empty(line: &String) -> bool {
    let newline_str = "\n".to_string();
    let crlf_str = "\r\n".to_string();
    if line.is_empty() {
        true
    }
    else if line.eq(&newline_str) || line.eq(&crlf_str) {
        true
    }
    else {
        false
    }
}

fn print_byte(b: &u8, options: &getopts::Matches) {
    if *b > 31 || *b == 10 || *b == 9 {
        if options.opt_present("t") && *b == 9 {
            print!("^{}", (*b + 64) as char);
        }
        else {
            print!("{}", *b as char);
        }
    }
    else {
        print!("^{}", (*b + 64) as char);
    }
}

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

    #[test]
    fn assert_is_empty() {
        let s = "".to_string();
        assert!(is_empty(&s));
    }
    #[test]
    fn assert_is_empty_newline() {
        let s = "\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_crlf() {
        let s = "\r\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_char() {
        let s = "d".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_is_empty_ctrl_char() {
        let s = "".to_string();
        assert!(!is_empty(&s));
    }
}
<|endoftext|>


<commit_before>//! The enum `Either`.

use std::io::{self, Write, Read, BufRead};
use std::convert::{AsRef, AsMut};
use std::ops::Deref;
use std::ops::DerefMut;

pub use Either::{Left, Right};

/// `Either` represents an alternative holding one value out of
/// either of the two possible values.
///
/// `Either` is a general purpose sum type of two parts. For representing
/// success or error, use the regular `Result<T, E>` instead.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Either<L, R> {
    /// A value of type `L`.
    Left(L),
    /// A value of type `R`.
    Right(R),
}

macro_rules! either {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref $inner) => $result,
            Either::Right(ref $inner) => $result,
        }
    )
}

macro_rules! either_mut {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref mut $inner) => $result,
            Either::Right(ref mut $inner) => $result,
        }
    )
}

/// Helper macro for unwrapping the left side of an `Either` while returning
/// early with the right side if there is no left one. Can only be used in
/// functions that return `Either` because of the early return of `Right` that
/// it provides.
#[macro_export]
macro_rules! left {
    ($expr:expr) => (
        match $expr {
            Either::Left(val) => val,
            Either::Right(err) => return Either::Right(From::from(err))
        }
    )
}

/// Helper macro for unwrapping the right side of an `Either` while returning
/// early with the left side if there is no right one. Can only be used in
/// functions that return `Either` because of the early return of `Left` that
/// it provides.
#[macro_export]
macro_rules! right {
    ($expr:expr) => (
        match $expr {
            Either::Left(err) => return Either::Left(From::from(err)),
            Either::Right(val) => val
        }
    )
}

impl<L, R> Either<L, R> {
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            Right(_) => false,
        }
    }

    pub fn is_right(&self) -> bool {
        !self.is_left()
    }

    pub fn left(self) -> Option<L> {
        match self {
            Left(l) => Some(l),
            Right(_) => None,
        }
    }

    pub fn right(self) -> Option<R> {
        match self {
            Left(_) => None,
            Right(r) => Some(r),
        }
    }

    pub fn as_ref(&self) -> Either<&L, &R> {
        match *self {
            Left(ref inner) => Left(inner),
            Right(ref inner) => Right(inner),
        }
    }

    pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
        match *self {
            Left(ref mut inner) => Left(inner),
            Right(ref mut inner) => Right(inner),
        }
    }

    pub fn flip(self) -> Either<R, L> {
        match self {
            Left(l) => Right(l),
            Right(r) => Left(r),
        }
    }
}

/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
impl<L, R> From<Result<R, L>> for Either<L, R> {
    fn from(r: Result<R, L>) -> Self {
        match r {
            Err(e) => Left(e),
            Ok(o) => Right(o),
        }
    }
}

/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
impl<L, R> Into<Result<R, L>> for Either<L, R> {
    fn into(self) -> Result<R, L> {
        match self {
            Left(l) => Err(l),
            Right(r) => Ok(r),
        }
    }
}

/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
impl<L, R> Iterator for Either<L, R>
    where L: Iterator, R: Iterator<Item=L::Item>
{
    type Item = L::Item;

    fn next(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        either!(*self, inner => inner.size_hint())
    }
}

impl<L, R> DoubleEndedIterator for Either<L, R>
    where L: DoubleEndedIterator, R: DoubleEndedIterator<Item=L::Item>
{
    fn next_back(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next_back())
    }
}

impl<L, R> ExactSizeIterator for Either<L, R>
    where L: ExactSizeIterator, R: ExactSizeIterator<Item=L::Item>
{
}

/// `Either<L, R>` implements `Read` if both `L` and `R` do.
impl<L, R> Read for Either<L, R>
    where L: Read, R: Read
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read(buf))
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read_to_end(buf))
    }
}

impl<L, R> BufRead for Either<L, R>
    where L: BufRead, R: BufRead
{
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        either_mut!(*self, inner => inner.fill_buf())
    }

    fn consume(&mut self, amt: usize) {
        either_mut!(*self, inner => inner.consume(amt))
    }
}

/// `Either<L, R>` implements `Write` if both `L` and `R` do.
impl<L, R> Write for Either<L, R>
    where L: Write, R: Write
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.write(buf))
    }

    fn flush(&mut self) -> io::Result<()> {
        either_mut!(*self, inner => inner.flush())
    }
}

impl<L, R, Target> AsRef<Target> for Either<L, R>
    where L: AsRef<Target>, R: AsRef<Target>
{
    fn as_ref(&self) -> &Target {
        either!(*self, inner => inner.as_ref())
    }
}

impl<L, R, Target> AsMut<Target> for Either<L, R>
    where L: AsMut<Target>, R: AsMut<Target>
{
    fn as_mut(&mut self) -> &mut Target {
        either_mut!(*self, inner => inner.as_mut())
    }
}

impl<L, R> Deref for Either<L, R>
    where L: Deref, R: Deref<Target=L::Target>
{
    type Target = L::Target;

    fn deref(&self) -> &Self::Target {
        either!(*self, inner => &*inner)
    }
}

impl<L, R> DerefMut for Either<L, R>
    where L: DerefMut, R: DerefMut<Target=L::Target>
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        either_mut!(*self, inner => &mut *inner)
    }
}

#[test]
fn basic() {
    let mut e = Left(2);
    let r = Right(2);
    assert_eq!(e, Left(2));
    e = r;
    assert_eq!(e, Right(2));
    assert_eq!(e.left(), None);
    assert_eq!(e.right(), Some(2));
    assert_eq!(e.as_ref().right(), Some(&2));
    assert_eq!(e.as_mut().right(), Some(&mut 2));
}

#[test]
fn macros() {
    fn a() -> Either<u32, u32> {
        let x = left!(Right::<u32, u32>(1337));
        Left(x * 2)
    }
    assert_eq!(a(), Right(1337));

    fn b() -> Either<String, &'static str> {
        Right(right!(Left::<&str, &str>("foo bar")))
    }
    assert_eq!(b(), Left(String::from("foo bar")));
}

#[test]
fn deref() {
    fn is_str(_: &str) {}
    let value: Either<String, &str> = Left(String::from("test"));
    is_str(&*value);
}

#[test]
fn iter() {
    let x = 3;
    let mut iter = match x {
        1...3 => Left(0..10),
        _ => Right(17..),
    };

    assert_eq!(iter.next(), Some(0));
    assert_eq!(iter.count(), 9);
}

#[test]
fn read_write() {
    use std::io;

    let use_stdio = false;
    let mockdata = [0xff; 256];

    let mut reader = if use_stdio {
        Left(io::stdin())
    } else {
        Right(&mockdata[..])
    };

    let mut buf = [0u8; 16];
    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
    assert_eq!(&buf, &mockdata[..buf.len()]);

    let mut mockbuf = [0u8; 256];
    let mut writer = if use_stdio {
        Left(io::stdout())
    } else {
        Right(&mut mockbuf[..])
    };

    let buf = [1u8; 16];
    assert_eq!(writer.write(&buf).unwrap(), buf.len());
}
<commit_msg>Improve rubstness of macro definitions<commit_after>//! The enum `Either`.

use std::io::{self, Write, Read, BufRead};
use std::convert::{AsRef, AsMut};
use std::ops::Deref;
use std::ops::DerefMut;

pub use Either::{Left, Right};

/// `Either` represents an alternative holding one value out of
/// either of the two possible values.
///
/// `Either` is a general purpose sum type of two parts. For representing
/// success or error, use the regular `Result<T, E>` instead.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Either<L, R> {
    /// A value of type `L`.
    Left(L),
    /// A value of type `R`.
    Right(R),
}

macro_rules! either {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref $inner) => $result,
            Either::Right(ref $inner) => $result,
        }
    )
}

macro_rules! either_mut {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref mut $inner) => $result,
            Either::Right(ref mut $inner) => $result,
        }
    )
}

/// Macro for unwrapping the left side of an `Either`, which fails early
/// with the opposite side. Can only be used in functions that return
/// `Either` because of the early return of `Right` that it provides.
///
/// See also `right!` for its dual, which applies the same just to the
/// right side.
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate either; use either::*; fn main() {
/// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
///     let value = left!(wrapper);
///     Left(value * 2)
/// }
///
/// assert_eq!(twice(Left(2)), Left(4));
/// assert_eq!(twice(Right("ups")), Right("ups"));
/// # }
/// ```
#[macro_export]
macro_rules! left {
    ($expr:expr) => (
        match $expr {
            $crate::Left(val) => val,
            $crate::Right(err) => return $crate::Right(::std::convert::From::from(err))
        }
    )
}

/// Dual to `left!`, see its documentation for more information.
#[macro_export]
macro_rules! right {
    ($expr:expr) => (
        match $expr {
            $crate::Left(err) => return $crate::Left(::std::convert::From::from(err)),
            $crate::Right(val) => val
        }
    )
}

impl<L, R> Either<L, R> {
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            Right(_) => false,
        }
    }

    pub fn is_right(&self) -> bool {
        !self.is_left()
    }

    pub fn left(self) -> Option<L> {
        match self {
            Left(l) => Some(l),
            Right(_) => None,
        }
    }

    pub fn right(self) -> Option<R> {
        match self {
            Left(_) => None,
            Right(r) => Some(r),
        }
    }

    pub fn as_ref(&self) -> Either<&L, &R> {
        match *self {
            Left(ref inner) => Left(inner),
            Right(ref inner) => Right(inner),
        }
    }

    pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
        match *self {
            Left(ref mut inner) => Left(inner),
            Right(ref mut inner) => Right(inner),
        }
    }

    pub fn flip(self) -> Either<R, L> {
        match self {
            Left(l) => Right(l),
            Right(r) => Left(r),
        }
    }
}

/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
impl<L, R> From<Result<R, L>> for Either<L, R> {
    fn from(r: Result<R, L>) -> Self {
        match r {
            Err(e) => Left(e),
            Ok(o) => Right(o),
        }
    }
}

/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
impl<L, R> Into<Result<R, L>> for Either<L, R> {
    fn into(self) -> Result<R, L> {
        match self {
            Left(l) => Err(l),
            Right(r) => Ok(r),
        }
    }
}

/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
impl<L, R> Iterator for Either<L, R>
    where L: Iterator, R: Iterator<Item=L::Item>
{
    type Item = L::Item;

    fn next(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        either!(*self, inner => inner.size_hint())
    }
}

impl<L, R> DoubleEndedIterator for Either<L, R>
    where L: DoubleEndedIterator, R: DoubleEndedIterator<Item=L::Item>
{
    fn next_back(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next_back())
    }
}

impl<L, R> ExactSizeIterator for Either<L, R>
    where L: ExactSizeIterator, R: ExactSizeIterator<Item=L::Item>
{
}

/// `Either<L, R>` implements `Read` if both `L` and `R` do.
impl<L, R> Read for Either<L, R>
    where L: Read, R: Read
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read(buf))
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read_to_end(buf))
    }
}

impl<L, R> BufRead for Either<L, R>
    where L: BufRead, R: BufRead
{
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        either_mut!(*self, inner => inner.fill_buf())
    }

    fn consume(&mut self, amt: usize) {
        either_mut!(*self, inner => inner.consume(amt))
    }
}

/// `Either<L, R>` implements `Write` if both `L` and `R` do.
impl<L, R> Write for Either<L, R>
    where L: Write, R: Write
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.write(buf))
    }

    fn flush(&mut self) -> io::Result<()> {
        either_mut!(*self, inner => inner.flush())
    }
}

impl<L, R, Target> AsRef<Target> for Either<L, R>
    where L: AsRef<Target>, R: AsRef<Target>
{
    fn as_ref(&self) -> &Target {
        either!(*self, inner => inner.as_ref())
    }
}

impl<L, R, Target> AsMut<Target> for Either<L, R>
    where L: AsMut<Target>, R: AsMut<Target>
{
    fn as_mut(&mut self) -> &mut Target {
        either_mut!(*self, inner => inner.as_mut())
    }
}

impl<L, R> Deref for Either<L, R>
    where L: Deref, R: Deref<Target=L::Target>
{
    type Target = L::Target;

    fn deref(&self) -> &Self::Target {
        either!(*self, inner => &*inner)
    }
}

impl<L, R> DerefMut for Either<L, R>
    where L: DerefMut, R: DerefMut<Target=L::Target>
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        either_mut!(*self, inner => &mut *inner)
    }
}

#[test]
fn basic() {
    let mut e = Left(2);
    let r = Right(2);
    assert_eq!(e, Left(2));
    e = r;
    assert_eq!(e, Right(2));
    assert_eq!(e.left(), None);
    assert_eq!(e.right(), Some(2));
    assert_eq!(e.as_ref().right(), Some(&2));
    assert_eq!(e.as_mut().right(), Some(&mut 2));
}

#[test]
fn macros() {
    fn a() -> Either<u32, u32> {
        let x = left!(Right::<u32, u32>(1337));
        Left(x * 2)
    }
    assert_eq!(a(), Right(1337));

    fn b() -> Either<String, &'static str> {
        Right(right!(Left::<&str, &str>("foo bar")))
    }
    assert_eq!(b(), Left(String::from("foo bar")));
}

#[test]
fn deref() {
    fn is_str(_: &str) {}
    let value: Either<String, &str> = Left(String::from("test"));
    is_str(&*value);
}

#[test]
fn iter() {
    let x = 3;
    let mut iter = match x {
        1...3 => Left(0..10),
        _ => Right(17..),
    };

    assert_eq!(iter.next(), Some(0));
    assert_eq!(iter.count(), 9);
}

#[test]
fn read_write() {
    use std::io;

    let use_stdio = false;
    let mockdata = [0xff; 256];

    let mut reader = if use_stdio {
        Left(io::stdin())
    } else {
        Right(&mockdata[..])
    };

    let mut buf = [0u8; 16];
    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
    assert_eq!(&buf, &mockdata[..buf.len()]);

    let mut mockbuf = [0u8; 256];
    let mut writer = if use_stdio {
        Left(io::stdout())
    } else {
        Right(&mut mockbuf[..])
    };

    let buf = [1u8; 16];
    assert_eq!(writer.write(&buf).unwrap(), buf.len());
}
<|endoftext|>


<commit_before>//! A bit-set implementation for use in id-map. Notable differences from bit-set are the IntoIter
//! struct and retain() methods.

#![deny(missing_docs)]

#[cfg(test)] mod tests;

use std::{fmt, slice, vec};
use std::iter::FromIterator;

/// The element type of the set.
pub type Id = usize;

type Block = u32;
const BITS: usize = 32;

/// Given n and k return the largest integer m such that m*k <= n
fn ceil_div(n: usize, k: usize) -> usize {
    if n % k == 0 {
        n / k
    } else {
        n / k + 1
    }
}

/// A set of `usize` elements represented by a bit vector. Storage required is proportional to the
/// maximum element in the set.
pub struct IdSet {
    storage: Vec<Block>,
    len: usize,
}

impl IdSet {
    /// Creates an empty `IdSet`.
    pub fn new() -> Self {
        IdSet {
            storage: Vec::new(),
            len: 0,
        }
    }

    /// Creates a `IdSet` filled with all elements from 0 to n.
    pub fn new_filled(n: usize) -> Self {
        let (nwords, nbits) = (n / BITS, n % BITS);
        let mut storage = vec![!0; nwords];
        if nbits != 0 {
            storage.push((1u32 << nbits) - 1);
        }
        IdSet {
            storage,
            len: n,
        }
    }

    /// Creates a empty `IdSet` that can hold elements up to n before reallocating.
    pub fn with_capacity(n: usize) -> Self {
        IdSet {
            storage: Vec::with_capacity(ceil_div(n, BITS)),
            len: 0,
        }
    }

    /// Creates a set from a raw set of bytes.
    pub fn from_bytes(bytes: &[u32]) -> Self {
        let storage = Vec::from(bytes);
        let len = bytes.iter().map(|&word| word.count_ones() as usize).sum();
        IdSet { storage, len }
    }

    /// Returns the number of elements in the set.
    pub fn len(&self) -> usize {
        self.len
    }

    /// Removes all elements from the set.
    pub fn clear(&mut self) {
        self.storage.clear();
        self.len = 0;
    }

    /// Inserts the given elements into the set, returning true if it was not already in the set.
    pub fn insert(&mut self, id: Id) -> bool {
        let (word, bit) = (id / BITS, id % BITS);
        let mask = 1 << bit;

        if word < self.storage.len() {
            if (self.storage[word] & mask) == 0 {
                self.storage[word] |= mask;
                self.len += 1;
                true
            } else {
                false
            }
        } else {
            self.storage.resize(word + 1, 0);
            self.storage[word] = mask;
            self.len += 1;
            true
        }
    }

    /// Removes the given element from the set, returning true if it was in the set.
    pub fn remove(&mut self, id: Id) -> bool {
        let (word, bit) = (id / BITS, id % BITS);
        let mask = 1 << bit;

        if word < self.storage.len() {
            if (self.storage[word] & mask) != 0 {
                self.storage[word] &= !mask;
                self.len -= 1;
                true
            } else {
                false
            }
        } else {
            false
        }
    }

    /// Returns true if the given element is in the set.
    pub fn contains(&self, id: Id) -> bool {
        let (word, bit) = (id / BITS, id % BITS);
        let mask = 1 << bit;

        if word < self.storage.len() {
            (self.storage[word] & mask) != 0
        } else {
            false
        }
    }

    /// Remove all elements that don't satisfy the predicate.
    pub fn retain<F: FnMut(Id) -> bool>(&mut self, mut pred: F) {
        let mut id = 0;
        for word in &mut self.storage {
            for bit in 0..BITS {
                let mask = 1 << bit;
                if (*word & mask) != 0 && !pred(id) {
                    self.len -= 1;
                    *word &= !mask;
                }
                id += 1;
            }
        }
    }

    /// An iterator over all elements in increasing order.
    pub fn iter(&self) -> Iter {
        Iter {
            storage: self.storage.iter(),
            len: self.len,
            word: 0,
            mask: 0,
            id: 0,
        }
    }

    /// A consuming iterator over all elements in increasing order.
    pub fn into_iter(self) -> IntoIter {
        IntoIter {
            storage: self.storage.into_iter(),
            len: self.len,
            word: 0,
            mask: 0,
            id: 0,
        }
    }
}

impl Clone for IdSet {
    fn clone(&self) -> Self {
        IdSet {
            storage: self.storage.clone(),
            len: self.len,
        }
    }

    fn clone_from(&mut self, source: &Self) {
        self.storage.clone_from(&source.storage);
        self.len = source.len;
    }
}

impl fmt::Debug for IdSet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{{")?;
        let mut iter = self.iter();
        if let Some(id) = iter.next() {
            write!(f, "{:?}", id)?;
            for id in iter {
                write!(f, ", {:?}", id)?;
            }
        }
        write!(f, "}}")
    }
}

impl Default for IdSet {
    fn default() -> Self {
        IdSet::new()
    }
}

impl Eq for IdSet {}

impl PartialEq for IdSet {
    fn eq(&self, other: &Self) -> bool {
        if self.len != other.len {
            return false;
        }
        let (mut lhs, mut rhs) = (self.storage.iter(), other.storage.iter());
        loop {
            match (lhs.next(), rhs.next()) {
                (Some(&l), Some(&r)) => {
                    if l != r {
                        return false;
                    }
                },
                (None, None) => return true,
                (Some(&l), None) => return l == 0 && lhs.all(|&word| word == 0),
                (None, Some(&r)) => return r == 0 && rhs.all(|&word| word == 0),
            }
        }
    }
}

impl Extend<Id> for IdSet {
    fn extend<I: IntoIterator<Item = Id>>(&mut self, iter: I) {
        for id in iter {
            self.insert(id);
        }
    }
}

impl FromIterator<Id> for IdSet {
    fn from_iter<I: IntoIterator<Item = Id>>(iter: I) -> Self {
        let mut set = IdSet::new();
        for id in iter {
            set.insert(id);
        }
        set
    }
}

impl<'a> IntoIterator for &'a IdSet {
    type Item = Id;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

#[derive(Clone, Debug)]
/// An iterator over all elements in increasing order.
pub struct Iter<'a> {
    storage: slice::Iter<'a, u32>,
    len: usize,
    word: u32,
    mask: u32,
    id: Id,
}

impl<'a> Iterator for Iter<'a> {
    type Item = Id;

    fn next(&mut self) -> Option<Self::Item> {
        if self.len == 0 {
            return None;
        }
        loop {
            if self.mask == 0 {
                loop {
                    self.word = match self.storage.next() {
                        Some(&word) => word,
                        None => return None,
                    };
                    if self.word != 0 {
                        break;
                    }
                    self.id += BITS;
                }
                self.mask = 1;
            }
            let bit = self.word & self.mask;
            self.mask <<= 1;
            self.id += 1;
            if bit != 0 {
                self.len -= 1;
                return Some(self.id - 1);
            }
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl<'a> ExactSizeIterator for Iter<'a> {
    fn len(&self) -> usize {
        self.len
    }
}

#[derive(Clone, Debug)]
/// A consuming iterator over all elements in increasing order.
pub struct IntoIter {
    storage: vec::IntoIter<u32>,
    len: usize,
    word: u32,
    mask: u32,
    id: Id,
}

impl Iterator for IntoIter {
    type Item = Id;

    fn next(&mut self) -> Option<Self::Item> {
        if self.len == 0 {
            return None;
        }
        loop {
            if self.mask == 0 {
                loop {
                    self.word = match self.storage.next() {
                        Some(word) => word,
                        None => return None,
                    };
                    if self.word != 0 {
                        break;
                    }
                    self.id += BITS;
                }
                self.mask = 1;
            }
            let bit = self.word & self.mask;
            self.mask <<= 1;
            self.id += 1;
            if bit != 0 {
                self.len -= 1;
                return Some(self.id - 1);
            }
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl ExactSizeIterator for IntoIter {
    fn len(&self) -> usize {
        self.len
    }
}<commit_msg>improve iter performance<commit_after>//! A bit-set implementation for use in id-map. Notable differences from bit-set are the IntoIter
//! struct and retain() methods.

#![deny(missing_docs)]

#[cfg(test)] mod tests;

use std::{fmt, slice, vec};
use std::iter::FromIterator;

/// The element type of the set.
pub type Id = usize;

type Block = u32;
const BITS: usize = 32;

/// Given n and k return the largest integer m such that m*k <= n
fn ceil_div(n: usize, k: usize) -> usize {
    if n % k == 0 {
        n / k
    } else {
        n / k + 1
    }
}

/// A set of `usize` elements represented by a bit vector. Storage required is proportional to the
/// maximum element in the set.
pub struct IdSet {
    storage: Vec<Block>,
    len: usize,
}

impl IdSet {
    /// Creates an empty `IdSet`.
    pub fn new() -> Self {
        IdSet {
            storage: Vec::new(),
            len: 0,
        }
    }

    /// Creates a `IdSet` filled with all elements from 0 to n.
    pub fn new_filled(n: usize) -> Self {
        let (nwords, nbits) = (n / BITS, n % BITS);
        let mut storage = vec![!0; nwords];
        if nbits != 0 {
            storage.push((1u32 << nbits) - 1);
        }
        IdSet {
            storage,
            len: n,
        }
    }

    /// Creates a empty `IdSet` that can hold elements up to n before reallocating.
    pub fn with_capacity(n: usize) -> Self {
        IdSet {
            storage: Vec::with_capacity(ceil_div(n, BITS)),
            len: 0,
        }
    }

    /// Creates a set from a raw set of bytes.
    pub fn from_bytes(bytes: &[u32]) -> Self {
        let storage = Vec::from(bytes);
        let len = bytes.iter().map(|&word| word.count_ones() as usize).sum();
        IdSet { storage, len }
    }

    /// Returns the number of elements in the set.
    pub fn len(&self) -> usize {
        self.len
    }

    /// Removes all elements from the set.
    pub fn clear(&mut self) {
        self.storage.clear();
        self.len = 0;
    }

    /// Inserts the given elements into the set, returning true if it was not already in the set.
    pub fn insert(&mut self, id: Id) -> bool {
        let (word, bit) = (id / BITS, id % BITS);
        let mask = 1 << bit;

        if word < self.storage.len() {
            if (self.storage[word] & mask) == 0 {
                self.storage[word] |= mask;
                self.len += 1;
                true
            } else {
                false
            }
        } else {
            self.storage.resize(word + 1, 0);
            self.storage[word] = mask;
            self.len += 1;
            true
        }
    }

    /// Removes the given element from the set, returning true if it was in the set.
    pub fn remove(&mut self, id: Id) -> bool {
        let (word, bit) = (id / BITS, id % BITS);
        let mask = 1 << bit;

        if word < self.storage.len() {
            if (self.storage[word] & mask) != 0 {
                self.storage[word] &= !mask;
                self.len -= 1;
                true
            } else {
                false
            }
        } else {
            false
        }
    }

    /// Returns true if the given element is in the set.
    pub fn contains(&self, id: Id) -> bool {
        let (word, bit) = (id / BITS, id % BITS);
        let mask = 1 << bit;

        if word < self.storage.len() {
            (self.storage[word] & mask) != 0
        } else {
            false
        }
    }

    /// Remove all elements that don't satisfy the predicate.
    pub fn retain<F: FnMut(Id) -> bool>(&mut self, mut pred: F) {
        let mut id = 0;
        for word in &mut self.storage {
            for bit in 0..BITS {
                let mask = 1 << bit;
                if (*word & mask) != 0 && !pred(id) {
                    self.len -= 1;
                    *word &= !mask;
                }
                id += 1;
            }
        }
    }

    /// An iterator over all elements in increasing order.
    pub fn iter(&self) -> Iter {
        Iter {
            storage: self.storage.iter(),
            len: self.len,
            word: 0,
            idx: 0,
        }
    }

    /// A consuming iterator over all elements in increasing order.
    pub fn into_iter(self) -> IntoIter {
        IntoIter {
            storage: self.storage.into_iter(),
            len: self.len,
            word: 0,
            idx: 0,
        }
    }
}

impl Clone for IdSet {
    fn clone(&self) -> Self {
        IdSet {
            storage: self.storage.clone(),
            len: self.len,
        }
    }

    fn clone_from(&mut self, source: &Self) {
        self.storage.clone_from(&source.storage);
        self.len = source.len;
    }
}

impl fmt::Debug for IdSet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{{")?;
        let mut iter = self.iter();
        if let Some(id) = iter.next() {
            write!(f, "{:?}", id)?;
            for id in iter {
                write!(f, ", {:?}", id)?;
            }
        }
        write!(f, "}}")
    }
}

impl Default for IdSet {
    fn default() -> Self {
        IdSet::new()
    }
}

impl Eq for IdSet {}

impl PartialEq for IdSet {
    fn eq(&self, other: &Self) -> bool {
        if self.len != other.len {
            return false;
        }
        let (mut lhs, mut rhs) = (self.storage.iter(), other.storage.iter());
        loop {
            match (lhs.next(), rhs.next()) {
                (Some(&l), Some(&r)) => {
                    if l != r {
                        return false;
                    }
                },
                (None, None) => return true,
                (Some(&l), None) => return l == 0 && lhs.all(|&word| word == 0),
                (None, Some(&r)) => return r == 0 && rhs.all(|&word| word == 0),
            }
        }
    }
}

impl Extend<Id> for IdSet {
    fn extend<I: IntoIterator<Item = Id>>(&mut self, iter: I) {
        for id in iter {
            self.insert(id);
        }
    }
}

impl FromIterator<Id> for IdSet {
    fn from_iter<I: IntoIterator<Item = Id>>(iter: I) -> Self {
        let mut set = IdSet::new();
        for id in iter {
            set.insert(id);
        }
        set
    }
}

impl<'a> IntoIterator for &'a IdSet {
    type Item = Id;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

#[derive(Clone, Debug)]
/// An iterator over all elements in increasing order.
pub struct Iter<'a> {
    storage: slice::Iter<'a, u32>,
    len: usize,
    word: u32,
    idx: usize,
}

impl<'a> Iterator for Iter<'a> {
    type Item = Id;

    fn next(&mut self) -> Option<Self::Item> {
        while self.word == 0 {
            match self.storage.next() {
                Some(&word) => self.word = word,
                None => return None,
            }
            self.idx += BITS;
        }
        // remove the LSB of the current word
        let bit = (self.word & (!self.word + 1)) - 1;
        self.word &= self.word - 1;
        self.len -= 1;
        Some(self.idx + bit.count_ones() as usize)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl<'a> ExactSizeIterator for Iter<'a> {
    fn len(&self) -> usize {
        self.len
    }
}

#[derive(Clone, Debug)]
/// A consuming iterator over all elements in increasing order.
pub struct IntoIter {
    storage: vec::IntoIter<u32>,
    len: usize,
    word: u32,
    idx: usize,
}

impl Iterator for IntoIter {
    type Item = Id;

    fn next(&mut self) -> Option<Self::Item> {
        while self.word == 0 {
            match self.storage.next() {
                Some(&word) => self.word = word,
                None => return None,
            }
            self.idx += BITS;
        }
        // remove the LSB of the current word
        let bit = (self.word & (!self.word + 1)) - 1;
        self.word &= self.word - 1;
        self.len -= 1;
        Some(self.idx + bit.count_ones() as usize)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl ExactSizeIterator for IntoIter {
    fn len(&self) -> usize {
        self.len
    }
}<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "fontconfig"]
#![crate_type = "lib"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![feature(globs)]

extern crate libc;

pub mod fontconfig;
<commit_msg>Removed built in language feature. Marked the unstable feature as unstable.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "fontconfig"]
#![crate_type = "lib"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![allow(unstable)]
extern crate libc;

pub mod fontconfig;
<|endoftext|>


<commit_before>#![feature(io, net, core, std_misc)]

#[macro_use] extern crate log;
extern crate hpack;

pub mod http;
pub mod client;

mod tests {
}
<commit_msg>Remove the `net` feature, as it is now stable<commit_after>#![feature(io, core, std_misc)]

#[macro_use] extern crate log;
extern crate hpack;

pub mod http;
pub mod client;

mod tests {
}
<|endoftext|>