<commit_before>#![feature(io, core)]
//! Fern is a runtime-configurable rust logging library.

//! Current features are:
//!
//! - Multiple loggers. You can create as many loggers as you need, and configure them separately.
//! - Configurable output format via closures.
//! - Multiple outputs per logger - current options are to a file, or to stdout/stderr (or any
//!   combination of those)
//! - Each output can have a Level configured, so you can output all log messages to a log file,
//!   and only have warnings and above show up in the console!
//! - You can also define your own custom logging endpoints - have messages end up where you need
//!   them!
//! - Thread-local logger storage. This allows for convenient debug/info/warning/severe!() and
//!   log!() macros via the fern_macros package.
//!
//! fern is still in development, and most features are experimental. The library is subject to
//! change in non-backwards-compatible ways.
//!
//! This library can only be used while complying to the license terms in the `LICENSE` file.
//!
//! Examples
//! ========
//!
//! Usually, the first thing you want to do is create a logger. In fern, you can do this by first
//! creating a LoggerConfig struct, and then calling `.into_logger()` to turn it into a logger.
//!
//! Here's a logger that simply logs all messages to stdout, and an output.log file, formatting
//! each message with the current date, time, and logging level.
//!
//! ```no_test
//! let logger_config = fern::LoggerConfig {
//!     format: box |msg: &str, level: &fern::Level| {
//!         return format!("[{}][{}] {}", chrono::Local::now().format("%Y-%m-%d][%H:%M:%S"), level, msg);
//!     },
//!     output: vec![fern::OutputConfig::Stdout, fern::OutputConfig::File(Path::new("output.log"))],
//!     level: fern::Level::Debug,
//! };
//! ```
//!
//! In the above example, here's what each part does.
//!
//! `format:` is a closure which all messages will be run through. In this example, use a
//! format!() macro to format the messages using the current time, date, and logging level.
//!
//! Side note: `chrono::Local::now().format("%Y-%m-%d][%H:%M:%S")` is a usage of the chrono time
//! library, and just returns the date in the format described. An output of this might look like
//! `2014-12-01][12:55:04`.
//!
//! With this formatting, the final output of the logger will look something like:
//!
//! ```text
//! [2014-12-01][12:55:04][INFO] A message logged at the Level::Info logging level.
//! ```
//!
//! `output:` is a Vec<> of other configurations to send the messages to. In this example, we send
//! them to `OutputConfig::Stdout` and `OutputConfig::File(Path::new("output.log"))`.
//! This will send messages to the console, and to a file called "output.log".
//!
//! `level:` is a `fern::Level` which describes the minimum level that should be allowed to pass
//! through this logger. Setting this to `Level::Debug` allows all messages to be logged, as Debug
//! is the lowest logging level.
//!
//! After creating your logging config, you can turn it into a Logger using `into_logger()`:
//!
//! ```no_test
//! let logger = match logger_config.into_logger() {
//!     Ok(v) => v,
//!     Err(e) => panic!("Failed to create logger! Error: {}", e),
//! };
//! ```
//!
//! Eventually, this section will contain a few more examples as well. For now though, the above,
//! along with the LoggerConfig and OutputConfig docs, should be enough to get you started on
//! configuring your logger.
//!
//! #### Logging
//!
//! The next part of logging that you'll probably want to do is actually output some messages.
//!
//! The recommended/easiest way to do this is using the `local` module, along with the
//! `fern_macros` crate.
//!
//! To initialize your logger into thread-local storage for use, you can use
//! `fern::local::set_thread_logger()`
//!
//! ```no_test
//! use std::sync;
//!
//! fern::local::set_thread_logger(sync::Arc::new(logger));
//! ```
//!
//! You can then log anywhere in this thread using the following macros from fern_macros:
//!
//! ```no_test
//! #[macro_use]
//! extern crate fern_macros;
//!
//! // ...
//!
//! info!("A message logged at info level");
//!
//! let var = true;
//! debug!("Debugging message containing a variable value: {}", var);
//!
//! warning!("Something bad happened!");
//!
//! severe!("Something really bad happened!");
//! ```
//!
//! If your application is multi-threaded, you can spread the logger across threads as follows:
//!
//! ```no_test
//! use std::sync;
//!
//! let logger_arc = sync::Arc::new(logger); // Create a reference counted logger
//!
//! fern::local::set_thread_logger(logger_arc.clone()); // Initialize the logger for this thread.
//!
//! spawn(move || {
//!     // Initialize the logger for this worker thread.
//!     fern::local::set_thread_logger(logger_arc.clone());
//!
//!     // Do other calculations, and log more here as well.
//! });
//! ```
//!
//! You can also pass the reference counted logger between functions - if you don't want to
//! type out `sync::Arc<Box<fern::Logger + Sync + Send>>` for all the function declarations, you
//! can use `fern::ArcLogger` instead.

pub use errors::Error;
pub use api::{Logger, BoxedLogger, ArcLogger, Level};
pub use config::{LoggerConfig, OutputConfig};
pub use loggers::NullLogger;

#[unstable]
pub mod local;
mod api;
mod config;
mod loggers;
mod errors;
<commit_msg>Add path feature.<commit_after>#![feature(io, core, path)]
//! Fern is a runtime-configurable rust logging library.

//! Current features are:
//!
//! - Multiple loggers. You can create as many loggers as you need, and configure them separately.
//! - Configurable output format via closures.
//! - Multiple outputs per logger - current options are to a file, or to stdout/stderr (or any
//!   combination of those)
//! - Each output can have a Level configured, so you can output all log messages to a log file,
//!   and only have warnings and above show up in the console!
//! - You can also define your own custom logging endpoints - have messages end up where you need
//!   them!
//! - Thread-local logger storage. This allows for convenient debug/info/warning/severe!() and
//!   log!() macros via the fern_macros package.
//!
//! fern is still in development, and most features are experimental. The library is subject to
//! change in non-backwards-compatible ways.
//!
//! This library can only be used while complying to the license terms in the `LICENSE` file.
//!
//! Examples
//! ========
//!
//! Usually, the first thing you want to do is create a logger. In fern, you can do this by first
//! creating a LoggerConfig struct, and then calling `.into_logger()` to turn it into a logger.
//!
//! Here's a logger that simply logs all messages to stdout, and an output.log file, formatting
//! each message with the current date, time, and logging level.
//!
//! ```no_test
//! let logger_config = fern::LoggerConfig {
//!     format: box |msg: &str, level: &fern::Level| {
//!         return format!("[{}][{}] {}", chrono::Local::now().format("%Y-%m-%d][%H:%M:%S"), level, msg);
//!     },
//!     output: vec![fern::OutputConfig::Stdout, fern::OutputConfig::File(Path::new("output.log"))],
//!     level: fern::Level::Debug,
//! };
//! ```
//!
//! In the above example, here's what each part does.
//!
//! `format:` is a closure which all messages will be run through. In this example, use a
//! format!() macro to format the messages using the current time, date, and logging level.
//!
//! Side note: `chrono::Local::now().format("%Y-%m-%d][%H:%M:%S")` is a usage of the chrono time
//! library, and just returns the date in the format described. An output of this might look like
//! `2014-12-01][12:55:04`.
//!
//! With this formatting, the final output of the logger will look something like:
//!
//! ```text
//! [2014-12-01][12:55:04][INFO] A message logged at the Level::Info logging level.
//! ```
//!
//! `output:` is a Vec<> of other configurations to send the messages to. In this example, we send
//! them to `OutputConfig::Stdout` and `OutputConfig::File(Path::new("output.log"))`.
//! This will send messages to the console, and to a file called "output.log".
//!
//! `level:` is a `fern::Level` which describes the minimum level that should be allowed to pass
//! through this logger. Setting this to `Level::Debug` allows all messages to be logged, as Debug
//! is the lowest logging level.
//!
//! After creating your logging config, you can turn it into a Logger using `into_logger()`:
//!
//! ```no_test
//! let logger = match logger_config.into_logger() {
//!     Ok(v) => v,
//!     Err(e) => panic!("Failed to create logger! Error: {}", e),
//! };
//! ```
//!
//! Eventually, this section will contain a few more examples as well. For now though, the above,
//! along with the LoggerConfig and OutputConfig docs, should be enough to get you started on
//! configuring your logger.
//!
//! #### Logging
//!
//! The next part of logging that you'll probably want to do is actually output some messages.
//!
//! The recommended/easiest way to do this is using the `local` module, along with the
//! `fern_macros` crate.
//!
//! To initialize your logger into thread-local storage for use, you can use
//! `fern::local::set_thread_logger()`
//!
//! ```no_test
//! use std::sync;
//!
//! fern::local::set_thread_logger(sync::Arc::new(logger));
//! ```
//!
//! You can then log anywhere in this thread using the following macros from fern_macros:
//!
//! ```no_test
//! #[macro_use]
//! extern crate fern_macros;
//!
//! // ...
//!
//! info!("A message logged at info level");
//!
//! let var = true;
//! debug!("Debugging message containing a variable value: {}", var);
//!
//! warning!("Something bad happened!");
//!
//! severe!("Something really bad happened!");
//! ```
//!
//! If your application is multi-threaded, you can spread the logger across threads as follows:
//!
//! ```no_test
//! use std::sync;
//!
//! let logger_arc = sync::Arc::new(logger); // Create a reference counted logger
//!
//! fern::local::set_thread_logger(logger_arc.clone()); // Initialize the logger for this thread.
//!
//! spawn(move || {
//!     // Initialize the logger for this worker thread.
//!     fern::local::set_thread_logger(logger_arc.clone());
//!
//!     // Do other calculations, and log more here as well.
//! });
//! ```
//!
//! You can also pass the reference counted logger between functions - if you don't want to
//! type out `sync::Arc<Box<fern::Logger + Sync + Send>>` for all the function declarations, you
//! can use `fern::ArcLogger` instead.

pub use errors::Error;
pub use api::{Logger, BoxedLogger, ArcLogger, Level};
pub use config::{LoggerConfig, OutputConfig};
pub use loggers::NullLogger;

#[unstable]
pub mod local;
mod api;
mod config;
mod loggers;
mod errors;
<|endoftext|>


<commit_before>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use std::fs::File;
use std::io::Read;

extern crate rustc_serialize;

pub type ERes<T> = Result<T, String>;

pub fn err<T>(msg: &str) -> ERes<T> {
    Err(String::from(msg))
}

macro_rules! fail {
    ($expr:expr) => (
        return Err(::std::error::FromError::from_error($expr));
    )
}

fn read_file(name: &str) -> ERes<String> {
    let mut f = try!(match File::open(name) {
        Ok(f) => Ok(f),
        Err(err) => Err(format!("open error in file '{}': {}", name, err))
    });
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(err) => Err(format!("read error in file '{}': {}", name, err))
    }
}

pub mod footprint;
pub mod schematic;
<commit_msg>make read_file public<commit_after>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use std::fs::File;
use std::io::Read;

extern crate rustc_serialize;

pub type ERes<T> = Result<T, String>;

pub fn err<T>(msg: &str) -> ERes<T> {
    Err(String::from(msg))
}

macro_rules! fail {
    ($expr:expr) => (
        return Err(::std::error::FromError::from_error($expr));
    )
}

pub fn read_file(name: &str) -> ERes<String> {
    let mut f = try!(match File::open(name) {
        Ok(f) => Ok(f),
        Err(err) => Err(format!("open error in file '{}': {}", name, err))
    });
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(err) => Err(format!("read error in file '{}': {}", name, err))
    }
}

pub mod footprint;
pub mod schematic;
<|endoftext|>


<commit_before>//! ByteSize is an utility that easily makes bytes size representation
//! and helps its arithmetic operations.
//!
//! ## Example
//!
//! ```ignore
//! extern crate bytesize;
//!
//! use bytesize::ByteSize;
//!
//! fn byte_arithmetic_operator() {
//!   let x = ByteSize::mb(1);
//!   let y = ByteSize::kb(100);
//!
//!   let plus = x + y;
//!   print!("{} bytes", plus.as_usize());
//!
//!   let minus = ByteSize::tb(100) - ByteSize::gb(4);
//!   print!("{} bytes", minus.as_usize());
//! }
//!
//! It also provides its human readable string as follows:
//!
//! ```ignore
//!  assert_eq!("482 GiB".to_string(), ByteSize::gb(518).to_string(true));
//!  assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false));
//! ```

extern crate num;

use std::fmt::{Display,Formatter,Result};
use std::ops::{Add,Sub,Mul,Div};

/// byte size for 1 byte
pub static B: usize = 1;
/// bytes size for 1 kilobyte
pub static KB: usize = 1000;
/// bytes size for 1 megabyte
pub static MB: usize = 1000000;
/// bytes size for 1 gigabyte
pub static GB: usize = 1000000000;
/// bytes size for 1 terabyte
pub static TB: usize = 1000000000000;
/// bytes size for 1 petabyte
pub static PB: usize = 1000000000000000;

/// bytes size for 1 kibibyte
pub static KIB: usize = 1024;
/// bytes size for 1 mebibyte
pub static MIB: usize = 1048576;
/// bytes size for 1 gibibyte
pub static GIB: usize = 1073741824;
/// bytes size for 1 tebibyte
pub static TIB: usize = 1099511627776;
/// bytes size for 1 pebibyte
pub static PIB: usize = 1125899906842624;

#[derive(Debug, Copy, Clone)]
/// Byte size representation
pub struct ByteSize {
  size: usize
}

impl ByteSize {
  #[inline(always)]
  pub fn b(size: usize) -> ByteSize {
    ByteSize {size: size}
  }

  #[inline(always)]
  pub fn kb(size: usize) -> ByteSize {
    ByteSize {size: size * KB}
  }

  #[inline(always)]
  pub fn kib(size: usize) -> ByteSize {
   ByteSize {size: size * KIB}
  }

  #[inline(always)]
  pub fn mb(size: usize) -> ByteSize {
    ByteSize {size: size * MB}
  }

  #[inline(always)]
  pub fn mib(size: usize) -> ByteSize {
    ByteSize {size: size * MIB}
  }

  #[inline(always)]
  pub fn gb(size: usize) -> ByteSize {
    ByteSize {size: size * GB}
  }

  #[inline(always)]
  pub fn gib(size: usize) -> ByteSize {
    ByteSize {size: size * GIB}
  }

  #[inline(always)]
  pub fn tb(size: usize) -> ByteSize {
    ByteSize {size: size * TB}
  }

  #[inline(always)]
  pub fn tib(size: usize) -> ByteSize {
    ByteSize {size: size * TIB}
  }

  #[inline(always)]
  pub fn pb(size: usize) -> ByteSize {
    ByteSize {size: size * PB}
  }

  #[inline(always)]
  pub fn pib(size: usize) -> ByteSize {
    ByteSize {size: size * PIB}
  }

  #[inline(always)]
  pub fn as_usize(&self) -> usize {
    self.size
  }

  pub fn to_string(&self, si: bool) -> String
  {

    let unit = if si { KIB } else { KB };

    if self.size < unit {
      {format!("{} B", self.size)}
    } else {
      let exp = ((self.size as f64).ln() / (if si {LN_KIB} else {LN_KB})) as usize;

      if si {
        format!("{} {}iB",(self.size / num::pow(unit, exp)), UNITS_SI.as_bytes()[exp - 1] as char)
      } else {
        format!("{} {}B",(self.size / num::pow(unit, exp)), UNITS.as_bytes()[exp - 1] as char)
      }
    }
  }
}

static UNITS:    &'static str = "KMGTPE";
static UNITS_SI: &'static str = "kMGTPE";
static LN_KB: f64 = 6.931471806; // ln 1024
static LN_KIB: f64 = 6.907755279; // ln 1000

impl Display for ByteSize {
  fn fmt(&self, f: &mut Formatter) -> Result {
    write!(f, "{}", self.to_string(false))
  }
}

impl Add<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size + rhs)}
  }
}

impl Add<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size + rhs.size)}
  }
}

impl Sub<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size - rhs)}
  }
}

impl Sub<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size - rhs.size)}
  }
}

impl Mul<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn mul(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size * rhs)}
  }
}

impl Div<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn div(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size / rhs)}
  }
}

#[test]
fn test_arithmetic() {
  let x = ByteSize::mb(1);
  let y = ByteSize::kb(100);

  assert_eq!(
    (x + y).as_usize(),
    1100000
  );
  assert_eq!(
    (x + (100*1000)).as_usize(),
    1100000
  );

  assert_eq!(
    (x - y).as_usize(),
    900000
  );
  assert_eq!(
    (x - (100*1000)).as_usize(),
    900000
  );
}

#[allow(dead_code)]
fn assert_display(expected: &str, b: ByteSize) {
  assert_eq!(expected, format!("{}", b));
}

#[test]
fn test_display() {
  assert_display("215 B", ByteSize::b(215));
  assert_display("301 KB", ByteSize::kb(301));
  assert_display("419 MB", ByteSize::mb(419));
  assert_display("518 GB", ByteSize::gb(518));
  assert_display("815 TB", ByteSize::tb(815));
  assert_display("609 PB", ByteSize::pb(609));
}

#[allow(dead_code)]
fn assert_to_string(expected: &str, b: ByteSize, si: bool) {
  assert_eq!(expected.to_string(), b.to_string(si));
}

#[test]
fn test_to_string() {
  assert_to_string("215 B", ByteSize::b(215), true);
  assert_to_string("215 B", ByteSize::b(215), false);

  assert_to_string("293 kiB", ByteSize::kb(301), true);
  assert_to_string("301 KB", ByteSize::kb(301), false);

  assert_to_string("399 MiB", ByteSize::mb(419), true);
  assert_to_string("419 MB", ByteSize::mb(419), false);

  assert_to_string("482 GiB", ByteSize::gb(518), true);
  assert_to_string("518 GB", ByteSize::gb(518), false);

  assert_to_string("741 TiB", ByteSize::tb(815), true);
  assert_to_string("815 TB", ByteSize::tb(815), false);

  assert_to_string("540 PiB", ByteSize::pb(609), true);
  assert_to_string("609 PB", ByteSize::pb(609), false);
}
<commit_msg>Fixed the doc error.<commit_after>//! ByteSize is an utility that easily makes bytes size representation
//! and helps its arithmetic operations.
//!
//! ## Example
//!
//! ```ignore
//! extern crate bytesize;
//!
//! use bytesize::ByteSize;
//!
//! fn byte_arithmetic_operator() {
//!   let x = ByteSize::mb(1);
//!   let y = ByteSize::kb(100);
//!
//!   let plus = x + y;
//!   print!("{} bytes", plus.as_usize());
//!
//!   let minus = ByteSize::tb(100) - ByteSize::gb(4);
//!   print!("{} bytes", minus.as_usize());
//! }
//! ```
//!
//! It also provides its human readable string as follows:
//!
//! ```ignore
//!  assert_eq!("482 GiB".to_string(), ByteSize::gb(518).to_string(true));
//!  assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false));
//! ```

extern crate num;

use std::fmt::{Display,Formatter,Result};
use std::ops::{Add,Sub,Mul,Div};

/// byte size for 1 byte
pub static B: usize = 1;
/// bytes size for 1 kilobyte
pub static KB: usize = 1000;
/// bytes size for 1 megabyte
pub static MB: usize = 1000000;
/// bytes size for 1 gigabyte
pub static GB: usize = 1000000000;
/// bytes size for 1 terabyte
pub static TB: usize = 1000000000000;
/// bytes size for 1 petabyte
pub static PB: usize = 1000000000000000;

/// bytes size for 1 kibibyte
pub static KIB: usize = 1024;
/// bytes size for 1 mebibyte
pub static MIB: usize = 1048576;
/// bytes size for 1 gibibyte
pub static GIB: usize = 1073741824;
/// bytes size for 1 tebibyte
pub static TIB: usize = 1099511627776;
/// bytes size for 1 pebibyte
pub static PIB: usize = 1125899906842624;

#[derive(Debug, Copy, Clone)]
/// Byte size representation
pub struct ByteSize {
  size: usize
}

impl ByteSize {
  #[inline(always)]
  pub fn b(size: usize) -> ByteSize {
    ByteSize {size: size}
  }

  #[inline(always)]
  pub fn kb(size: usize) -> ByteSize {
    ByteSize {size: size * KB}
  }

  #[inline(always)]
  pub fn kib(size: usize) -> ByteSize {
   ByteSize {size: size * KIB}
  }

  #[inline(always)]
  pub fn mb(size: usize) -> ByteSize {
    ByteSize {size: size * MB}
  }

  #[inline(always)]
  pub fn mib(size: usize) -> ByteSize {
    ByteSize {size: size * MIB}
  }

  #[inline(always)]
  pub fn gb(size: usize) -> ByteSize {
    ByteSize {size: size * GB}
  }

  #[inline(always)]
  pub fn gib(size: usize) -> ByteSize {
    ByteSize {size: size * GIB}
  }

  #[inline(always)]
  pub fn tb(size: usize) -> ByteSize {
    ByteSize {size: size * TB}
  }

  #[inline(always)]
  pub fn tib(size: usize) -> ByteSize {
    ByteSize {size: size * TIB}
  }

  #[inline(always)]
  pub fn pb(size: usize) -> ByteSize {
    ByteSize {size: size * PB}
  }

  #[inline(always)]
  pub fn pib(size: usize) -> ByteSize {
    ByteSize {size: size * PIB}
  }

  #[inline(always)]
  pub fn as_usize(&self) -> usize {
    self.size
  }

  pub fn to_string(&self, si: bool) -> String
  {

    let unit = if si { KIB } else { KB };

    if self.size < unit {
      {format!("{} B", self.size)}
    } else {
      let exp = ((self.size as f64).ln() / (if si {LN_KIB} else {LN_KB})) as usize;

      if si {
        format!("{} {}iB",(self.size / num::pow(unit, exp)), UNITS_SI.as_bytes()[exp - 1] as char)
      } else {
        format!("{} {}B",(self.size / num::pow(unit, exp)), UNITS.as_bytes()[exp - 1] as char)
      }
    }
  }
}

static UNITS:    &'static str = "KMGTPE";
static UNITS_SI: &'static str = "kMGTPE";
static LN_KB: f64 = 6.931471806; // ln 1024
static LN_KIB: f64 = 6.907755279; // ln 1000

impl Display for ByteSize {
  fn fmt(&self, f: &mut Formatter) -> Result {
    write!(f, "{}", self.to_string(false))
  }
}

impl Add<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size + rhs)}
  }
}

impl Add<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size + rhs.size)}
  }
}

impl Sub<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size - rhs)}
  }
}

impl Sub<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size - rhs.size)}
  }
}

impl Mul<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn mul(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size * rhs)}
  }
}

impl Div<usize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn div(self, rhs: usize) -> ByteSize {
    ByteSize {size: (self.size / rhs)}
  }
}

#[test]
fn test_arithmetic() {
  let x = ByteSize::mb(1);
  let y = ByteSize::kb(100);

  assert_eq!(
    (x + y).as_usize(),
    1100000
  );
  assert_eq!(
    (x + (100*1000)).as_usize(),
    1100000
  );

  assert_eq!(
    (x - y).as_usize(),
    900000
  );
  assert_eq!(
    (x - (100*1000)).as_usize(),
    900000
  );
}

#[allow(dead_code)]
fn assert_display(expected: &str, b: ByteSize) {
  assert_eq!(expected, format!("{}", b));
}

#[test]
fn test_display() {
  assert_display("215 B", ByteSize::b(215));
  assert_display("301 KB", ByteSize::kb(301));
  assert_display("419 MB", ByteSize::mb(419));
  assert_display("518 GB", ByteSize::gb(518));
  assert_display("815 TB", ByteSize::tb(815));
  assert_display("609 PB", ByteSize::pb(609));
}

#[allow(dead_code)]
fn assert_to_string(expected: &str, b: ByteSize, si: bool) {
  assert_eq!(expected.to_string(), b.to_string(si));
}

#[test]
fn test_to_string() {
  assert_to_string("215 B", ByteSize::b(215), true);
  assert_to_string("215 B", ByteSize::b(215), false);

  assert_to_string("293 kiB", ByteSize::kb(301), true);
  assert_to_string("301 KB", ByteSize::kb(301), false);

  assert_to_string("399 MiB", ByteSize::mb(419), true);
  assert_to_string("419 MB", ByteSize::mb(419), false);

  assert_to_string("482 GiB", ByteSize::gb(518), true);
  assert_to_string("518 GB", ByteSize::gb(518), false);

  assert_to_string("741 TiB", ByteSize::tb(815), true);
  assert_to_string("815 TB", ByteSize::tb(815), false);

  assert_to_string("540 PiB", ByteSize::pb(609), true);
  assert_to_string("609 PB", ByteSize::pb(609), false);
}
<|endoftext|>


<commit_before>//! Solvent is a dependency resolver library written in rust.
//!
//! Solvent helps you to resolve dependency orderings by building up a dependency
//! graph and then resolving the dependences of some target node in an order such
//! that each output depends only upon the previous outputs.
//!
//! It is currently quite simple, but is still useful.
//!
//! #Example
//!
//! ```rust
//! extern crate solvent;
//!
//! use solvent::DepGraph;
//!
//! fn main() {
//!     // Create a new empty DepGraph.  Must be `mut` or else it cannot
//!     // be used by the rest of the library.
//!     let mut depgraph: DepGraph = DepGraph::new();
//!
//!     // You can register a dependency like this.  Solvent will
//!     // automatically create nodes for any term it has not seen before.
//!     // This means 'b' depends on 'd'
//!     depgraph.register_dependency("b","d");
//!
//!     // You can also register multiple dependencies at once
//!     depgraph.register_dependencies("a",&["b","c","d"]);
//!     depgraph.register_dependencies("c",&["e"]);
//!
//!     // Iterate through each dependency of "a".  The dependencies will be
//!     // returned in an order such that each output only depends on the
//!     // previous outputs (or nothing).  The target itself will be output
//!     // last.
//!     for node in depgraph.dependencies_of("a") {
//!         print!("{} ", node.unwrap());
//!     }
//! }
//! ```
//!
//! The above will output:  `d b e c a` or `e c d b a` or some other valid
//! dependency order.
//!
//! The algorithm is not deterministic, and may give a different answer each
//! time it is run.  Beware.
//!
//! The iterator dependencies_of() returns an Option<Result<String,SolventError>>.
//! The for loop handles the Option part for you, but you may want to check the
//! result for SolventErrors.  Once an error is returned, all subsequent calls to
//! the iterator next() will yield None.
//!
//! You can also mark some elements as already satisfied, and the iterator
//! will take that into account:
//!
//! ```ignore
//! depgraph.mark_as_satisfied(["e","c"]);
//! ```
//!
//! Dependency cycles are detected and will return SolventError::CycleDetected.

#![crate_name = "solvent"]
#![crate_type = "lib"]

// Required for log and rustdoc:
#![feature(phase)]
#[phase(plugin, link)]

extern crate log;

use std::collections::{HashMap,HashSet};
use std::collections::hash_map::{Occupied,Vacant};
use std::iter::{Iterator};
#[allow(unused_imports)]
use std::task;

/// This is the dependency graph.
#[deriving(Clone)]
pub struct DepGraph {
    /// List of dependencies.  Key is the element, values are the
    /// other elements that the key element depends upon.
    pub dependencies: HashMap<String,HashSet<String>>,

    /// Nodes already satisfied.  dependencies_of() will prune
    /// dependency searches at these nodes, and not output nodes
    /// registered here.
    pub satisfied: HashSet<String>,
}

#[deriving(Copy,Show,PartialEq)]
pub enum SolventError {
    CycleDetected,
    // TODO once we implement conflicts: Conflict(String)
}

/// This iterates through the dependencies of the DepGraph's target
pub struct DepGraphIterator<'a> {
    depgraph: &'a DepGraph,

    // Target we are trying to satisfy
    target: String,

    // Elements already satisfied during this iterator's walk
    satisfied: HashSet<String>,

    // Current path, for cycle detection
    curpath: HashSet<String>,

    // Halted.  Used so that it can return None after an Err is returned.
    halted: bool,
}

impl DepGraph {

    /// Create an empty DepGraph.
    pub fn new() -> DepGraph
    {
        DepGraph {
            dependencies: HashMap::new(),
            satisfied: HashSet::new(),
        }
    }

    /// Add a dependency to a DepGraph.  The node does not need
    /// to pre-exist, nor do the dependency nodes.  But if the
    /// node does pre-exist, the depends_on will be added to its
    /// existing dependency list.
    pub fn register_dependency<'a>( &mut self,
                                node: &'a str,
                                depends_on: &'a str )
    {
        match self.dependencies.entry( String::from_str(node) ) {
            Vacant(entry) => {
                let mut deps = HashSet::with_capacity(1);
                deps.insert( String::from_str(depends_on) );
                entry.set( deps );
            },
            Occupied(mut entry) => {
                (*entry.get_mut()).insert(String::from_str(depends_on));
            },
        }
    }

    /// Add multiple dependencies of one node to a DepGraph.  The
    /// node does not need to pre-exist, nor do the dependency elements.
    /// But if the node does pre-exist, the depends_on will be added
    /// to its existing dependency list.
    pub fn register_dependencies<'a>( &mut self,
                                  node: &'a str,
                                  depends_on: &'a[&'a str] )
    {
        match self.dependencies.entry( String::from_str(node) ) {
            Vacant(entry) => {
                let mut deps = HashSet::with_capacity( depends_on.len() );
                for s in depends_on.iter() {
                    deps.insert( String::from_str(*s) );
                }
                entry.set( deps );
            },
            Occupied(mut entry) => {
                for s in depends_on.iter() {
                    (*entry.get_mut()).insert( String::from_str(*s) );
                }
            },
        }
    }

    /// This marks a node as satisfied.  Iterators will not output
    /// such nodes.
    pub fn mark_as_satisfied<'a>( &mut self,
                                   nodes: &'a[&'a str] )
    {
        for node in nodes.iter() {
            self.satisfied.insert(String::from_str(*node));
        }
    }

    /// Get an iterator to iterate through the dependencies of
    /// the target node.
    pub fn dependencies_of<'a>(&'a self, target: &str) -> DepGraphIterator<'a>
    {
        // TODO: iterator's satisfied could start empty, and all checks
        //       could separately check depgraph's and iterator's.  That
        //       would avoid the copy.
        DepGraphIterator {
            depgraph: self,
            target: target.into_string(),
            satisfied: self.satisfied.clone(),
            curpath: HashSet::new(),
            halted: false,
        }
    }
}

impl<'a> DepGraphIterator<'a> {

    fn get_next_dependency(&mut self, node: &String) -> Result<String,SolventError>
    {
        if self.curpath.contains(node) {
            return Err(SolventError::CycleDetected);
        }
        self.curpath.insert(node.clone());

        let deplist = match self.depgraph.dependencies.get(node) {
            None => return Ok(node.clone()),
            Some(deplist) => deplist.clone() // ouch
        };

        for n in deplist.iter() {
            // Prune satisfied nodes
            if self.satisfied.contains(n) {
                continue;
            }

            return self.get_next_dependency(n);
        }
        // nodes dependencies are satisfied
        Ok(node.clone())
    }
}

impl<'a> Iterator< Result<String,SolventError> > for DepGraphIterator<'a> {
    /// Get next dependency.  Returns None when finished.  If
    /// Some(Err(SolventError)) occurs, all subsequent calls will
    /// return None.
    fn next(&mut self) -> Option< Result<String,SolventError> >
    {
        if self.halted {
            return None;
        }

        let node = self.target.clone();
        if self.satisfied.contains(&node) {
            return None;
        }

        self.curpath.clear();
        let next = match self.get_next_dependency(&node) {
            Ok(d) => d,
            Err(e) => {
                self.halted = true;
                return Some(Err(e));
            }
        };
        self.satisfied.insert(next.clone());
        Some(Ok(next))
    }
}

#[test]
fn solvent_test_branching() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c","d"]);
    depgraph.register_dependency("b","d");
    depgraph.register_dependencies("c",&["e","m","g"]);
    depgraph.register_dependency("e","f");
    depgraph.register_dependency("g","h");
    depgraph.register_dependency("h","i");
    depgraph.register_dependencies("i",&["j","k"]);
    depgraph.register_dependencies("k",&["l","m"]);
    depgraph.register_dependency("m","n");

    let mut results: Vec<String> = Vec::new();

    for node in depgraph.dependencies_of("a") {
        // detect infinite looping bugs
        assert!(results.len() < 30);

        let n = node.unwrap();

        // Check that all of that nodes dependencies have already been output
        let deps: Option<&HashSet<String>> = depgraph.dependencies.get(&n);
        if deps.is_some() {
            for dep in deps.unwrap().iter() {
                assert!( results.contains(dep) );
            }
        }

        results.push(n.clone());
    }

    // Be sure we actually output enough stuff
    assert!(results.len() == 14);

    // Be sure each output is unique
    for result in results.iter() {
        let mut count = 0u;
        for result2 in results.iter() {
            if result == result2 { count = count + 1; }
        }
        assert!(count == 1);
    }
}

#[test]
fn solvent_test_updating_dependencies() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c"]);
    depgraph.register_dependency("a","d");
    assert!(depgraph.dependencies.get("a").unwrap().contains("b"));
    assert!(depgraph.dependencies.get("a").unwrap().contains("c"));
    assert!(depgraph.dependencies.get("a").unwrap().contains("d"));
}

#[test]
fn solvent_test_circular() {

    let mut depgraph: DepGraph = DepGraph::new();
    depgraph.register_dependency("a","b");
    depgraph.register_dependency("b","c");
    depgraph.register_dependency("c","a");

    for node in depgraph.dependencies_of("a") {
        assert!(node.is_err());
        assert!(node.unwrap_err() == SolventError::CycleDetected);
    }
}

#[test]
fn solvent_test_satisfied_stoppage() {

    let mut depgraph: DepGraph = DepGraph::new();
    depgraph.register_dependencies("superconn", &[]);
    depgraph.register_dependencies("owneruser", &["superconn"]);
    depgraph.register_dependencies("appuser", &["superconn"]);
    depgraph.register_dependencies("database", &["owneruser"]);
    depgraph.register_dependencies("ownerconn", &["database","owneruser"]);
    depgraph.register_dependencies("adminconn", &["database"]);
    depgraph.register_dependencies("extensions", &["database","adminconn"]);
    depgraph.register_dependencies("schema_table", &["database","ownerconn"]);
    depgraph.register_dependencies("schemas", &["ownerconn","extensions","schema_table","appuser"]);
    depgraph.register_dependencies("appconn", &["database","appuser","schemas"]);

    depgraph.mark_as_satisfied(&["owneruser","appuser"]);

    let mut results: Vec<String> = Vec::new();

    for node in depgraph.dependencies_of("appconn") {
        assert!(results.len() < 30);
        results.push(node.unwrap());
    }

    // Be sure we did not depend on these
    assert!( !results.contains(&String::from_str("appuser")) );
    assert!( !results.contains(&String::from_str("owneruser")) );
    assert!( !results.contains(&String::from_str("superconn")) );

    // Be sure we actually output enough stuff
    assert!(results.len() == 7);

    // Be sure each output is unique
    for result in results.iter() {
        let mut count = 0u;
        for result2 in results.iter() {
            if result == result2 { count = count + 1; }
        }
        assert!(count == 1);
    }
}

<commit_msg>upstream rust: Occupied/Vacant enum variants;  into_string() depr.<commit_after>//! Solvent is a dependency resolver library written in rust.
//!
//! Solvent helps you to resolve dependency orderings by building up a dependency
//! graph and then resolving the dependences of some target node in an order such
//! that each output depends only upon the previous outputs.
//!
//! It is currently quite simple, but is still useful.
//!
//! #Example
//!
//! ```rust
//! extern crate solvent;
//!
//! use solvent::DepGraph;
//!
//! fn main() {
//!     // Create a new empty DepGraph.  Must be `mut` or else it cannot
//!     // be used by the rest of the library.
//!     let mut depgraph: DepGraph = DepGraph::new();
//!
//!     // You can register a dependency like this.  Solvent will
//!     // automatically create nodes for any term it has not seen before.
//!     // This means 'b' depends on 'd'
//!     depgraph.register_dependency("b","d");
//!
//!     // You can also register multiple dependencies at once
//!     depgraph.register_dependencies("a",&["b","c","d"]);
//!     depgraph.register_dependencies("c",&["e"]);
//!
//!     // Iterate through each dependency of "a".  The dependencies will be
//!     // returned in an order such that each output only depends on the
//!     // previous outputs (or nothing).  The target itself will be output
//!     // last.
//!     for node in depgraph.dependencies_of("a") {
//!         print!("{} ", node.unwrap());
//!     }
//! }
//! ```
//!
//! The above will output:  `d b e c a` or `e c d b a` or some other valid
//! dependency order.
//!
//! The algorithm is not deterministic, and may give a different answer each
//! time it is run.  Beware.
//!
//! The iterator dependencies_of() returns an Option<Result<String,SolventError>>.
//! The for loop handles the Option part for you, but you may want to check the
//! result for SolventErrors.  Once an error is returned, all subsequent calls to
//! the iterator next() will yield None.
//!
//! You can also mark some elements as already satisfied, and the iterator
//! will take that into account:
//!
//! ```ignore
//! depgraph.mark_as_satisfied(["e","c"]);
//! ```
//!
//! Dependency cycles are detected and will return SolventError::CycleDetected.

#![crate_name = "solvent"]
#![crate_type = "lib"]

// Required for log and rustdoc:
#![feature(phase)]
#[phase(plugin, link)]

extern crate log;

use std::collections::{HashMap,HashSet};
use std::collections::hash_map::Entry;
use std::iter::{Iterator};
#[allow(unused_imports)]
use std::task;
use std::borrow::ToOwned;

/// This is the dependency graph.
#[deriving(Clone)]
pub struct DepGraph {
    /// List of dependencies.  Key is the element, values are the
    /// other elements that the key element depends upon.
    pub dependencies: HashMap<String,HashSet<String>>,

    /// Nodes already satisfied.  dependencies_of() will prune
    /// dependency searches at these nodes, and not output nodes
    /// registered here.
    pub satisfied: HashSet<String>,
}

#[deriving(Copy,Show,PartialEq)]
pub enum SolventError {
    CycleDetected,
    // TODO once we implement conflicts: Conflict(String)
}

/// This iterates through the dependencies of the DepGraph's target
pub struct DepGraphIterator<'a> {
    depgraph: &'a DepGraph,

    // Target we are trying to satisfy
    target: String,

    // Elements already satisfied during this iterator's walk
    satisfied: HashSet<String>,

    // Current path, for cycle detection
    curpath: HashSet<String>,

    // Halted.  Used so that it can return None after an Err is returned.
    halted: bool,
}

impl DepGraph {

    /// Create an empty DepGraph.
    pub fn new() -> DepGraph
    {
        DepGraph {
            dependencies: HashMap::new(),
            satisfied: HashSet::new(),
        }
    }

    /// Add a dependency to a DepGraph.  The node does not need
    /// to pre-exist, nor do the dependency nodes.  But if the
    /// node does pre-exist, the depends_on will be added to its
    /// existing dependency list.
    pub fn register_dependency<'a>( &mut self,
                                node: &'a str,
                                depends_on: &'a str )
    {
        match self.dependencies.entry( String::from_str(node) ) {
            Entry::Vacant(entry) => {
                let mut deps = HashSet::with_capacity(1);
                deps.insert( String::from_str(depends_on) );
                entry.set( deps );
            },
            Entry::Occupied(mut entry) => {
                (*entry.get_mut()).insert(String::from_str(depends_on));
            },
        }
    }

    /// Add multiple dependencies of one node to a DepGraph.  The
    /// node does not need to pre-exist, nor do the dependency elements.
    /// But if the node does pre-exist, the depends_on will be added
    /// to its existing dependency list.
    pub fn register_dependencies<'a>( &mut self,
                                  node: &'a str,
                                  depends_on: &'a[&'a str] )
    {
        match self.dependencies.entry( String::from_str(node) ) {
            Entry::Vacant(entry) => {
                let mut deps = HashSet::with_capacity( depends_on.len() );
                for s in depends_on.iter() {
                    deps.insert( String::from_str(*s) );
                }
                entry.set( deps );
            },
            Entry::Occupied(mut entry) => {
                for s in depends_on.iter() {
                    (*entry.get_mut()).insert( String::from_str(*s) );
                }
            },
        }
    }

    /// This marks a node as satisfied.  Iterators will not output
    /// such nodes.
    pub fn mark_as_satisfied<'a>( &mut self,
                                   nodes: &'a[&'a str] )
    {
        for node in nodes.iter() {
            self.satisfied.insert(String::from_str(*node));
        }
    }

    /// Get an iterator to iterate through the dependencies of
    /// the target node.
    pub fn dependencies_of<'a>(&'a self, target: &str) -> DepGraphIterator<'a>
    {
        // TODO: iterator's satisfied could start empty, and all checks
        //       could separately check depgraph's and iterator's.  That
        //       would avoid the copy.
        DepGraphIterator {
            depgraph: self,
            target: target.to_owned(),
            satisfied: self.satisfied.clone(),
            curpath: HashSet::new(),
            halted: false,
        }
    }
}

impl<'a> DepGraphIterator<'a> {

    fn get_next_dependency(&mut self, node: &String) -> Result<String,SolventError>
    {
        if self.curpath.contains(node) {
            return Err(SolventError::CycleDetected);
        }
        self.curpath.insert(node.clone());

        let deplist = match self.depgraph.dependencies.get(node) {
            None => return Ok(node.clone()),
            Some(deplist) => deplist.clone() // ouch
        };

        for n in deplist.iter() {
            // Prune satisfied nodes
            if self.satisfied.contains(n) {
                continue;
            }

            return self.get_next_dependency(n);
        }
        // nodes dependencies are satisfied
        Ok(node.clone())
    }
}

impl<'a> Iterator< Result<String,SolventError> > for DepGraphIterator<'a> {
    /// Get next dependency.  Returns None when finished.  If
    /// Some(Err(SolventError)) occurs, all subsequent calls will
    /// return None.
    fn next(&mut self) -> Option< Result<String,SolventError> >
    {
        if self.halted {
            return None;
        }

        let node = self.target.clone();
        if self.satisfied.contains(&node) {
            return None;
        }

        self.curpath.clear();
        let next = match self.get_next_dependency(&node) {
            Ok(d) => d,
            Err(e) => {
                self.halted = true;
                return Some(Err(e));
            }
        };
        self.satisfied.insert(next.clone());
        Some(Ok(next))
    }
}

#[test]
fn solvent_test_branching() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c","d"]);
    depgraph.register_dependency("b","d");
    depgraph.register_dependencies("c",&["e","m","g"]);
    depgraph.register_dependency("e","f");
    depgraph.register_dependency("g","h");
    depgraph.register_dependency("h","i");
    depgraph.register_dependencies("i",&["j","k"]);
    depgraph.register_dependencies("k",&["l","m"]);
    depgraph.register_dependency("m","n");

    let mut results: Vec<String> = Vec::new();

    for node in depgraph.dependencies_of("a") {
        // detect infinite looping bugs
        assert!(results.len() < 30);

        let n = node.unwrap();

        // Check that all of that nodes dependencies have already been output
        let deps: Option<&HashSet<String>> = depgraph.dependencies.get(&n);
        if deps.is_some() {
            for dep in deps.unwrap().iter() {
                assert!( results.contains(dep) );
            }
        }

        results.push(n.clone());
    }

    // Be sure we actually output enough stuff
    assert!(results.len() == 14);

    // Be sure each output is unique
    for result in results.iter() {
        let mut count = 0u;
        for result2 in results.iter() {
            if result == result2 { count = count + 1; }
        }
        assert!(count == 1);
    }
}

#[test]
fn solvent_test_updating_dependencies() {
    let mut depgraph: DepGraph = DepGraph::new();

    depgraph.register_dependencies("a",&["b","c"]);
    depgraph.register_dependency("a","d");
    assert!(depgraph.dependencies.get("a").unwrap().contains("b"));
    assert!(depgraph.dependencies.get("a").unwrap().contains("c"));
    assert!(depgraph.dependencies.get("a").unwrap().contains("d"));
}

#[test]
fn solvent_test_circular() {

    let mut depgraph: DepGraph = DepGraph::new();
    depgraph.register_dependency("a","b");
    depgraph.register_dependency("b","c");
    depgraph.register_dependency("c","a");

    for node in depgraph.dependencies_of("a") {
        assert!(node.is_err());
        assert!(node.unwrap_err() == SolventError::CycleDetected);
    }
}

#[test]
fn solvent_test_satisfied_stoppage() {

    let mut depgraph: DepGraph = DepGraph::new();
    depgraph.register_dependencies("superconn", &[]);
    depgraph.register_dependencies("owneruser", &["superconn"]);
    depgraph.register_dependencies("appuser", &["superconn"]);
    depgraph.register_dependencies("database", &["owneruser"]);
    depgraph.register_dependencies("ownerconn", &["database","owneruser"]);
    depgraph.register_dependencies("adminconn", &["database"]);
    depgraph.register_dependencies("extensions", &["database","adminconn"]);
    depgraph.register_dependencies("schema_table", &["database","ownerconn"]);
    depgraph.register_dependencies("schemas", &["ownerconn","extensions","schema_table","appuser"]);
    depgraph.register_dependencies("appconn", &["database","appuser","schemas"]);

    depgraph.mark_as_satisfied(&["owneruser","appuser"]);

    let mut results: Vec<String> = Vec::new();

    for node in depgraph.dependencies_of("appconn") {
        assert!(results.len() < 30);
        results.push(node.unwrap());
    }

    // Be sure we did not depend on these
    assert!( !results.contains(&String::from_str("appuser")) );
    assert!( !results.contains(&String::from_str("owneruser")) );
    assert!( !results.contains(&String::from_str("superconn")) );

    // Be sure we actually output enough stuff
    assert!(results.len() == 7);

    // Be sure each output is unique
    for result in results.iter() {
        let mut count = 0u;
        for result2 in results.iter() {
            if result == result2 { count = count + 1; }
        }
        assert!(count == 1);
    }
}

<|endoftext|>


<commit_before>#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]

#[macro_use]
extern crate bitflags;

extern crate fsevent_sys as fsevent;

use fsevent::core_foundation as cf;
use fsevent as fs;

use std::convert::AsRef;
use std::ffi::CStr;
use std::ptr;
use std::slice;
use std::slice::from_raw_parts_mut;
use std::str::from_utf8;

use std::sync::mpsc::Sender;

pub struct FsEvent {
    paths: cf::CFMutableArrayRef,
    since_when: fs::FSEventStreamEventId,
    latency: cf::CFTimeInterval,
    flags: fs::FSEventStreamCreateFlags,
    sender: Sender<Event>,
}

#[derive(Debug)]
pub struct Event {
    pub event_id: u64,
    pub flag: StreamFlags,
    pub path: String,
}

// Synchronize with
// /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Headers/FSEvents.h
bitflags! {
  #[repr(C)]
  pub struct StreamFlags: u32 {
    const NONE = 0x00000000;
    const MUST_SCAN_SUBDIRS = 0x00000001;
    const USER_DROPPED = 0x00000002;
    const KERNEL_DROPPED = 0x00000004;
    const IDS_WRAPPED = 0x00000008;
    const HISTORY_DONE = 0x00000010;
    const ROOT_CHANGED = 0x00000020;
    const MOUNT = 0x00000040;
    const UNMOUNT = 0x00000080;
    const ITEM_CREATED = 0x00000100;
    const ITEM_REMOVED = 0x00000200;
    const INOTE_META_MOD = 0x00000400;
    const ITEM_RENAMED = 0x00000800;
    const ITEM_MODIFIED = 0x00001000;
    const FINDER_INFO_MOD = 0x00002000;
    const ITEM_CHANGE_OWNER = 0x00004000;
    const ITEM_XATTR_MOD = 0x00008000;
    const IS_FILE = 0x00010000;
    const IS_DIR = 0x00020000;
    const IS_SYMLIMK = 0x00040000;
    const OWN_EVENT = 0x00080000;
    const IS_HARDLINK = 0x00100000;
    const IS_LAST_HARDLINK = 0x00200000;
    const ITEM_CLONED = 0x400000;
  }
}

impl std::fmt::Display for StreamFlags {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        if self.contains(StreamFlags::MUST_SCAN_SUBDIRS) {
            let _d = write!(f, "MUST_SCAN_SUBDIRS ");
        }
        if self.contains(StreamFlags::USER_DROPPED) {
            let _d = write!(f, "USER_DROPPED ");
        }
        if self.contains(StreamFlags::KERNEL_DROPPED) {
            let _d = write!(f, "KERNEL_DROPPED ");
        }
        if self.contains(StreamFlags::IDS_WRAPPED) {
            let _d = write!(f, "IDS_WRAPPED ");
        }
        if self.contains(StreamFlags::HISTORY_DONE) {
            let _d = write!(f, "HISTORY_DONE ");
        }
        if self.contains(StreamFlags::ROOT_CHANGED) {
            let _d = write!(f, "ROOT_CHANGED ");
        }
        if self.contains(StreamFlags::MOUNT) {
            let _d = write!(f, "MOUNT ");
        }
        if self.contains(StreamFlags::UNMOUNT) {
            let _d = write!(f, "UNMOUNT ");
        }
        if self.contains(StreamFlags::ITEM_CREATED) {
            let _d = write!(f, "ITEM_CREATED ");
        }
        if self.contains(StreamFlags::ITEM_REMOVED) {
            let _d = write!(f, "ITEM_REMOVED ");
        }
        if self.contains(StreamFlags::INOTE_META_MOD) {
            let _d = write!(f, "INOTE_META_MOD ");
        }
        if self.contains(StreamFlags::ITEM_RENAMED) {
            let _d = write!(f, "ITEM_RENAMED ");
        }
        if self.contains(StreamFlags::ITEM_MODIFIED) {
            let _d = write!(f, "ITEM_MODIFIED ");
        }
        if self.contains(StreamFlags::FINDER_INFO_MOD) {
            let _d = write!(f, "FINDER_INFO_MOD ");
        }
        if self.contains(StreamFlags::ITEM_CHANGE_OWNER) {
            let _d = write!(f, "ITEM_CHANGE_OWNER ");
        }
        if self.contains(StreamFlags::ITEM_XATTR_MOD) {
            let _d = write!(f, "ITEM_XATTR_MOD ");
        }
        if self.contains(StreamFlags::IS_FILE) {
            let _d = write!(f, "IS_FILE ");
        }
        if self.contains(StreamFlags::IS_DIR) {
            let _d = write!(f, "IS_DIR ");
        }
        if self.contains(StreamFlags::IS_SYMLIMK) {
            let _d = write!(f, "IS_SYMLIMK ");
        }
        if self.contains(StreamFlags::OWN_EVENT) {
            let _d = write!(f, "OWN_EVENT ");
        }
        if self.contains(StreamFlags::IS_LAST_HARDLINK) {
            let _d = write!(f, "IS_LAST_HARDLINK ");
        }
        if self.contains(StreamFlags::IS_HARDLINK) {
            let _d = write!(f, "IS_HARDLINK ");
        }
        if self.contains(StreamFlags::ITEM_CLONED) {
            let _d = write!(f, "ITEM_CLONED ");
        }
        write!(f, "")
    }
}

fn default_stream_context(info: *const FsEvent) -> fs::FSEventStreamContext {
    let ptr = info as *mut ::std::os::raw::c_void;
    fs::FSEventStreamContext {
        version: 0,
        info: ptr,
        retain: cf::NULL,
        copy_description: cf::NULL,
    }
}

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

#[derive(Debug)]
pub struct Error {
    msg: String,
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        &self.msg
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.msg.fmt(f)
    }
}

impl FsEvent {
    pub fn new(sender: Sender<Event>) -> FsEvent {
        let fsevent: FsEvent;

        unsafe {
            fsevent = FsEvent {
                paths: cf::CFArrayCreateMutable(
                    cf::kCFAllocatorDefault,
                    0,
                    &cf::kCFTypeArrayCallBacks,
                ),
                since_when: fs::kFSEventStreamEventIdSinceNow,
                latency: 0.0,
                flags: fs::kFSEventStreamCreateFlagFileEvents | fs::kFSEventStreamCreateFlagNoDefer,
                sender,
            };
        }
        fsevent
    }

    // https://github.com/thibaudgg/rb-fsevent/blob/master/ext/fsevent_watch/main.c
    pub fn append_path(&self, source: &str) -> Result<()> {
        unsafe {
            let mut err = ptr::null_mut();
            let cf_path = cf::str_path_to_cfstring_ref(source, &mut err);
            if !err.is_null() {
                let cf_str = cf::CFCopyDescription(err as cf::CFRef);
                let mut buf = [0; 1024];
                cf::CFStringGetCString(
                    cf_str,
                    buf.as_mut_ptr(),
                    buf.len() as cf::CFIndex,
                    cf::kCFStringEncodingUTF8,
                );
                Err(Error {
                    msg: CStr::from_ptr(buf.as_ptr())
                        .to_str()
                        .unwrap_or("Unknown error")
                        .to_string(),
                })
            } else {
                cf::CFArrayAppendValue(self.paths, cf_path);
                cf::CFRelease(cf_path);
                Ok(())
            }
        }
    }
    pub fn observe(&self) {
        let stream_context = default_stream_context(self);

        let cb = callback as *mut _;

        unsafe {
            let stream = fs::FSEventStreamCreate(
                cf::kCFAllocatorDefault,
                cb,
                &stream_context,
                self.paths,
                self.since_when,
                self.latency,
                self.flags,
            );

            // fs::FSEventStreamShow(stream);

            fs::FSEventStreamScheduleWithRunLoop(
                stream,
                cf::CFRunLoopGetCurrent(),
                cf::kCFRunLoopDefaultMode,
            );

            fs::FSEventStreamStart(stream);
            cf::CFRunLoopRun();

            fs::FSEventStreamFlushSync(stream);
            fs::FSEventStreamStop(stream);
        }
    }
}

#[allow(unused_variables)]
unsafe fn callback(
    stream_ref: fs::FSEventStreamRef,
    info: *mut ::std::os::raw::c_void,
    num_events: usize,                                 // size_t numEvents
    event_paths: *const *const ::std::os::raw::c_char, // void *eventPaths
    event_flags: *mut ::std::os::raw::c_void,          // const FSEventStreamEventFlags eventFlags[]
    event_ids: *mut ::std::os::raw::c_void,            // const FSEventStreamEventId eventIds[]
) {
    let num = num_events as usize;
    let e_ptr = event_flags as *mut u32;
    let i_ptr = event_ids as *mut u64;
    let fs_event = info as *mut FsEvent;

    let paths: &[*const ::std::os::raw::c_char] =
        std::mem::transmute(slice::from_raw_parts(event_paths, num));
    let flags = from_raw_parts_mut(e_ptr, num);
    let ids = from_raw_parts_mut(i_ptr, num);

    for p in 0..num {
        let i = CStr::from_ptr(paths[p]).to_bytes();
        let path = from_utf8(i).expect("Invalid UTF8 string.");
        let flag: StreamFlags = StreamFlags::from_bits(flags[p] as u32).expect(
            format!(
                "Unable to decode StreamFlags: {} for {}",
                flags[p] as u32, path
            ).as_ref(),
        );
        // println!("{}: {}", ids[p], flag);

        let event = Event {
            event_id: ids[p],
            flag,
            path: path.to_string(),
        };
        let _s = (*fs_event).sender.send(event);
    }
}
<commit_msg>Remove trivial numeric casts.<commit_after>#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]

#[macro_use]
extern crate bitflags;

extern crate fsevent_sys as fsevent;

use fsevent::core_foundation as cf;
use fsevent as fs;

use std::convert::AsRef;
use std::ffi::CStr;
use std::ptr;
use std::slice;
use std::slice::from_raw_parts_mut;
use std::str::from_utf8;

use std::sync::mpsc::Sender;

pub struct FsEvent {
    paths: cf::CFMutableArrayRef,
    since_when: fs::FSEventStreamEventId,
    latency: cf::CFTimeInterval,
    flags: fs::FSEventStreamCreateFlags,
    sender: Sender<Event>,
}

#[derive(Debug)]
pub struct Event {
    pub event_id: u64,
    pub flag: StreamFlags,
    pub path: String,
}

// Synchronize with
// /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Headers/FSEvents.h
bitflags! {
  #[repr(C)]
  pub struct StreamFlags: u32 {
    const NONE = 0x00000000;
    const MUST_SCAN_SUBDIRS = 0x00000001;
    const USER_DROPPED = 0x00000002;
    const KERNEL_DROPPED = 0x00000004;
    const IDS_WRAPPED = 0x00000008;
    const HISTORY_DONE = 0x00000010;
    const ROOT_CHANGED = 0x00000020;
    const MOUNT = 0x00000040;
    const UNMOUNT = 0x00000080;
    const ITEM_CREATED = 0x00000100;
    const ITEM_REMOVED = 0x00000200;
    const INOTE_META_MOD = 0x00000400;
    const ITEM_RENAMED = 0x00000800;
    const ITEM_MODIFIED = 0x00001000;
    const FINDER_INFO_MOD = 0x00002000;
    const ITEM_CHANGE_OWNER = 0x00004000;
    const ITEM_XATTR_MOD = 0x00008000;
    const IS_FILE = 0x00010000;
    const IS_DIR = 0x00020000;
    const IS_SYMLIMK = 0x00040000;
    const OWN_EVENT = 0x00080000;
    const IS_HARDLINK = 0x00100000;
    const IS_LAST_HARDLINK = 0x00200000;
    const ITEM_CLONED = 0x400000;
  }
}

impl std::fmt::Display for StreamFlags {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        if self.contains(StreamFlags::MUST_SCAN_SUBDIRS) {
            let _d = write!(f, "MUST_SCAN_SUBDIRS ");
        }
        if self.contains(StreamFlags::USER_DROPPED) {
            let _d = write!(f, "USER_DROPPED ");
        }
        if self.contains(StreamFlags::KERNEL_DROPPED) {
            let _d = write!(f, "KERNEL_DROPPED ");
        }
        if self.contains(StreamFlags::IDS_WRAPPED) {
            let _d = write!(f, "IDS_WRAPPED ");
        }
        if self.contains(StreamFlags::HISTORY_DONE) {
            let _d = write!(f, "HISTORY_DONE ");
        }
        if self.contains(StreamFlags::ROOT_CHANGED) {
            let _d = write!(f, "ROOT_CHANGED ");
        }
        if self.contains(StreamFlags::MOUNT) {
            let _d = write!(f, "MOUNT ");
        }
        if self.contains(StreamFlags::UNMOUNT) {
            let _d = write!(f, "UNMOUNT ");
        }
        if self.contains(StreamFlags::ITEM_CREATED) {
            let _d = write!(f, "ITEM_CREATED ");
        }
        if self.contains(StreamFlags::ITEM_REMOVED) {
            let _d = write!(f, "ITEM_REMOVED ");
        }
        if self.contains(StreamFlags::INOTE_META_MOD) {
            let _d = write!(f, "INOTE_META_MOD ");
        }
        if self.contains(StreamFlags::ITEM_RENAMED) {
            let _d = write!(f, "ITEM_RENAMED ");
        }
        if self.contains(StreamFlags::ITEM_MODIFIED) {
            let _d = write!(f, "ITEM_MODIFIED ");
        }
        if self.contains(StreamFlags::FINDER_INFO_MOD) {
            let _d = write!(f, "FINDER_INFO_MOD ");
        }
        if self.contains(StreamFlags::ITEM_CHANGE_OWNER) {
            let _d = write!(f, "ITEM_CHANGE_OWNER ");
        }
        if self.contains(StreamFlags::ITEM_XATTR_MOD) {
            let _d = write!(f, "ITEM_XATTR_MOD ");
        }
        if self.contains(StreamFlags::IS_FILE) {
            let _d = write!(f, "IS_FILE ");
        }
        if self.contains(StreamFlags::IS_DIR) {
            let _d = write!(f, "IS_DIR ");
        }
        if self.contains(StreamFlags::IS_SYMLIMK) {
            let _d = write!(f, "IS_SYMLIMK ");
        }
        if self.contains(StreamFlags::OWN_EVENT) {
            let _d = write!(f, "OWN_EVENT ");
        }
        if self.contains(StreamFlags::IS_LAST_HARDLINK) {
            let _d = write!(f, "IS_LAST_HARDLINK ");
        }
        if self.contains(StreamFlags::IS_HARDLINK) {
            let _d = write!(f, "IS_HARDLINK ");
        }
        if self.contains(StreamFlags::ITEM_CLONED) {
            let _d = write!(f, "ITEM_CLONED ");
        }
        write!(f, "")
    }
}

fn default_stream_context(info: *const FsEvent) -> fs::FSEventStreamContext {
    let ptr = info as *mut ::std::os::raw::c_void;
    fs::FSEventStreamContext {
        version: 0,
        info: ptr,
        retain: cf::NULL,
        copy_description: cf::NULL,
    }
}

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

#[derive(Debug)]
pub struct Error {
    msg: String,
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        &self.msg
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.msg.fmt(f)
    }
}

impl FsEvent {
    pub fn new(sender: Sender<Event>) -> FsEvent {
        let fsevent: FsEvent;

        unsafe {
            fsevent = FsEvent {
                paths: cf::CFArrayCreateMutable(
                    cf::kCFAllocatorDefault,
                    0,
                    &cf::kCFTypeArrayCallBacks,
                ),
                since_when: fs::kFSEventStreamEventIdSinceNow,
                latency: 0.0,
                flags: fs::kFSEventStreamCreateFlagFileEvents | fs::kFSEventStreamCreateFlagNoDefer,
                sender,
            };
        }
        fsevent
    }

    // https://github.com/thibaudgg/rb-fsevent/blob/master/ext/fsevent_watch/main.c
    pub fn append_path(&self, source: &str) -> Result<()> {
        unsafe {
            let mut err = ptr::null_mut();
            let cf_path = cf::str_path_to_cfstring_ref(source, &mut err);
            if !err.is_null() {
                let cf_str = cf::CFCopyDescription(err as cf::CFRef);
                let mut buf = [0; 1024];
                cf::CFStringGetCString(
                    cf_str,
                    buf.as_mut_ptr(),
                    buf.len() as cf::CFIndex,
                    cf::kCFStringEncodingUTF8,
                );
                Err(Error {
                    msg: CStr::from_ptr(buf.as_ptr())
                        .to_str()
                        .unwrap_or("Unknown error")
                        .to_string(),
                })
            } else {
                cf::CFArrayAppendValue(self.paths, cf_path);
                cf::CFRelease(cf_path);
                Ok(())
            }
        }
    }
    pub fn observe(&self) {
        let stream_context = default_stream_context(self);

        let cb = callback as *mut _;

        unsafe {
            let stream = fs::FSEventStreamCreate(
                cf::kCFAllocatorDefault,
                cb,
                &stream_context,
                self.paths,
                self.since_when,
                self.latency,
                self.flags,
            );

            // fs::FSEventStreamShow(stream);

            fs::FSEventStreamScheduleWithRunLoop(
                stream,
                cf::CFRunLoopGetCurrent(),
                cf::kCFRunLoopDefaultMode,
            );

            fs::FSEventStreamStart(stream);
            cf::CFRunLoopRun();

            fs::FSEventStreamFlushSync(stream);
            fs::FSEventStreamStop(stream);
        }
    }
}

#[allow(unused_variables)]
unsafe fn callback(
    stream_ref: fs::FSEventStreamRef,
    info: *mut ::std::os::raw::c_void,
    num_events: usize,                                 // size_t numEvents
    event_paths: *const *const ::std::os::raw::c_char, // void *eventPaths
    event_flags: *mut ::std::os::raw::c_void,          // const FSEventStreamEventFlags eventFlags[]
    event_ids: *mut ::std::os::raw::c_void,            // const FSEventStreamEventId eventIds[]
) {
    let num = num_events;
    let e_ptr = event_flags as *mut u32;
    let i_ptr = event_ids as *mut u64;
    let fs_event = info as *mut FsEvent;

    let paths: &[*const ::std::os::raw::c_char] =
        std::mem::transmute(slice::from_raw_parts(event_paths, num));
    let flags = from_raw_parts_mut(e_ptr, num);
    let ids = from_raw_parts_mut(i_ptr, num);

    for p in 0..num {
        let i = CStr::from_ptr(paths[p]).to_bytes();
        let path = from_utf8(i).expect("Invalid UTF8 string.");
        let flag: StreamFlags = StreamFlags::from_bits(flags[p])
            .expect(format!("Unable to decode StreamFlags: {} for {}", flags[p], path).as_ref());
        // println!("{}: {}", ids[p], flag);

        let event = Event {
            event_id: ids[p],
            flag,
            path: path.to_string(),
        };
        let _s = (*fs_event).sender.send(event);
    }
}
<|endoftext|>


<commit_before>// DOCS

extern crate iron;
extern crate oven;
extern crate cookie;
extern crate persistent;

use iron::prelude::*;
use iron::typemap::Key;
use iron::middleware;
use oven::prelude::*;

/// Re-export of the Cookie class.
pub use cookie::Cookie;

/// Iron middleware providing user loging management
///
/// Stores the configuration in persistent data and adds an oven with the specified key.
pub struct LoginManager {
    signing_key: Vec<u8>,
    /// Configuration for this manager
    pub config: Config,
}

impl LoginManager {
    /// Construct a new login middleware using the provided signing key
    pub fn new(signing_key: Vec<u8>) -> LoginManager {
        LoginManager {
            signing_key: signing_key,
            config: Config::defaults(),
        }
    }
}

impl middleware::AroundMiddleware for LoginManager {
    fn around(self, handler: Box<middleware::Handler>) -> Box<middleware::Handler> {
        let mut ch = Chain::new(handler);
        let key = self.signing_key;

        ch.link(oven::new(key));
        ch.link(persistent::Read::<Config>::both(self.config));

        Box::new(ch)
    }
}

/// Configuration
#[derive(Debug, Clone)]
pub struct Config {
    /// This cookie contains the default values that will be used for session cookies.
    ///
    /// You may e.g. override `httponly` or `secure` however you wish.
    pub cookie_base: Cookie,
}

impl Config {
    /// Construct a configuration instance with default values
    pub fn defaults() -> Self {
        Config {
            cookie_base: {
                let mut c = Cookie::new("logged_in_user".to_owned(), "".to_owned());
                c.httponly = true;
                c.path = Some("/".to_owned());
                c
            },
        }
    }
}

impl Key for Config { type Value = Config; }

/// Trait repesenting an authenticated user
pub trait User: Send + Sync + Sized {
    /// Create a `User` instance from a user id
    fn from_user_id(request: &mut Request, user_id: &str) -> Option<Self>;
    /// Get the user_id associated with this `User`
    fn get_user_id(&self) -> String;
    /// Create a `Login<Self>` instance (no need to override)
    fn get_login(request: &mut Request) -> Login<Self> {
        Login::from_request(request)
    }
}

/// Login state
///
/// To construct this within a request, use `User::get_login()`
pub struct Login<U: User> {
    user: Option<U>,
    config: Config,
}

impl<U: User> Login<U> {
    fn from_request(request: &mut Request) -> Login<U> {
        let config = request.get::<persistent::Read<Config>>()
                            .expect("config is not found in request");
        let config = (*config).clone();
        let user_id = match request.get_cookie(&config.cookie_base.name) {
            Some(c) if !c.value.is_empty() => Some(c.value.clone()),
            _ => None,
        };

        Login {
            user: user_id.and_then(|user_id| U::from_user_id(request, &user_id)),
            config: config,
        }
    }

    /// Unwrap into the `User` instance
    pub fn get_user(self) -> Option<U> {
        self.user
    }

    /// Log in as the passed `User` instance
    pub fn log_in(mut self, user: U) -> LoginModifier<U> {
        self.user = Some(user);
        LoginModifier { login: self }
    }

    /// Log out (clearing the cookie)
    pub fn log_out(mut self) -> LoginModifier<U> {
        self.user = None;
        LoginModifier { login: self }
    }
}

/// Iron modifier that updates the cookie
pub struct LoginModifier<U: User> {
    login: Login<U>,
}
impl<U: User> iron::modifier::Modifier<Response> for LoginModifier<U> {
    fn modify(self, response: &mut Response) {
        response.set_cookie({
            let mut x = self.login.config.cookie_base.clone();
            x.value = self.login.user
                .map_or_else(|| "".to_owned(), |u| u.get_user_id());
            x
        });
    }
}
<commit_msg>Deprecate<commit_after>// DOCS

extern crate iron;
extern crate oven;
extern crate cookie;
extern crate persistent;

use iron::prelude::*;
use iron::typemap::Key;
use iron::middleware;
use oven::prelude::*;

/// Re-export of the Cookie class.
pub use cookie::Cookie;

/// Iron middleware providing user loging management
///
/// Stores the configuration in persistent data and adds an oven with the specified key.
#[deprecated(since="0.5.1", note="Please use iron-sessionstorage. This entire crate is deprecated.")]
pub struct LoginManager {
    signing_key: Vec<u8>,
    /// Configuration for this manager
    pub config: Config,
}

impl LoginManager {
    /// Construct a new login middleware using the provided signing key
    pub fn new(signing_key: Vec<u8>) -> LoginManager {
        LoginManager {
            signing_key: signing_key,
            config: Config::defaults(),
        }
    }
}

impl middleware::AroundMiddleware for LoginManager {
    fn around(self, handler: Box<middleware::Handler>) -> Box<middleware::Handler> {
        let mut ch = Chain::new(handler);
        let key = self.signing_key;

        ch.link(oven::new(key));
        ch.link(persistent::Read::<Config>::both(self.config));

        Box::new(ch)
    }
}

/// Configuration
#[derive(Debug, Clone)]
pub struct Config {
    /// This cookie contains the default values that will be used for session cookies.
    ///
    /// You may e.g. override `httponly` or `secure` however you wish.
    pub cookie_base: Cookie,
}

impl Config {
    /// Construct a configuration instance with default values
    pub fn defaults() -> Self {
        Config {
            cookie_base: {
                let mut c = Cookie::new("logged_in_user".to_owned(), "".to_owned());
                c.httponly = true;
                c.path = Some("/".to_owned());
                c
            },
        }
    }
}

impl Key for Config { type Value = Config; }

/// Trait repesenting an authenticated user
pub trait User: Send + Sync + Sized {
    /// Create a `User` instance from a user id
    fn from_user_id(request: &mut Request, user_id: &str) -> Option<Self>;
    /// Get the user_id associated with this `User`
    fn get_user_id(&self) -> String;
    /// Create a `Login<Self>` instance (no need to override)
    fn get_login(request: &mut Request) -> Login<Self> {
        Login::from_request(request)
    }
}

/// Login state
///
/// To construct this within a request, use `User::get_login()`
pub struct Login<U: User> {
    user: Option<U>,
    config: Config,
}

impl<U: User> Login<U> {
    fn from_request(request: &mut Request) -> Login<U> {
        let config = request.get::<persistent::Read<Config>>()
                            .expect("config is not found in request");
        let config = (*config).clone();
        let user_id = match request.get_cookie(&config.cookie_base.name) {
            Some(c) if !c.value.is_empty() => Some(c.value.clone()),
            _ => None,
        };

        Login {
            user: user_id.and_then(|user_id| U::from_user_id(request, &user_id)),
            config: config,
        }
    }

    /// Unwrap into the `User` instance
    pub fn get_user(self) -> Option<U> {
        self.user
    }

    /// Log in as the passed `User` instance
    pub fn log_in(mut self, user: U) -> LoginModifier<U> {
        self.user = Some(user);
        LoginModifier { login: self }
    }

    /// Log out (clearing the cookie)
    pub fn log_out(mut self) -> LoginModifier<U> {
        self.user = None;
        LoginModifier { login: self }
    }
}

/// Iron modifier that updates the cookie
pub struct LoginModifier<U: User> {
    login: Login<U>,
}
impl<U: User> iron::modifier::Modifier<Response> for LoginModifier<U> {
    fn modify(self, response: &mut Response) {
        response.set_cookie({
            let mut x = self.login.config.cookie_base.clone();
            x.value = self.login.user
                .map_or_else(|| "".to_owned(), |u| u.get_user_id());
            x
        });
    }
}
<|endoftext|>


<commit_before>
//! **petgraph** is a graph data structure library.
//!
//! The most prominent type is [`Graph`](./graph/struct.Graph.html) which is
//! a directed or undirected graph with arbitrary mutable node and edge weights.
//! It is based on rustc's graph implementation.
//!
//! Petgraph also provides [`GraphMap`](./graphmap/struct.GraphMap.html) which
//! is an undirected hashmap-backed graph which only allows simple node identifiers
//! (such as integers or references).

extern crate fixedbitset;

use std::cmp::Ordering;
use std::hash::{self, Hash};
use std::fmt;
use std::ops::{Deref};

pub use scored::MinScored;
pub use graphmap::GraphMap;
pub use graph::Graph;

pub use self::EdgeDirection::{Outgoing, Incoming};
pub use visit::{
    Bfs,
    BfsIter,
    Dfs,
    DfsIter,
};

mod scored;
pub mod algo;
#[doc(hidden)] // Not for public consumption -- only for testing
pub mod generate;
pub mod graphmap;
pub mod graph;
pub mod visit;
pub mod unionfind;
mod dijkstra;
mod isomorphism;
mod traits_graph;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum EdgeDirection {
    /// An `Outgoing` edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An `Incoming` edge is an inbound edge *to* the current node.
    Incoming = 1
}

impl EdgeDirection {
    #[inline]
    fn opposite(&self) -> EdgeDirection {
        match *self {
            Outgoing => Incoming,
            Incoming => Outgoing,
        }
    }
}

/// Marker type for a directed graph.
#[derive(Copy, Clone, Debug)]
pub struct Directed;

/// Marker type for an undirected graph.
#[derive(Copy, Clone, Debug)]
pub struct Undirected;

/// A graph's edge type determines whether is has directed edges or not.
pub trait EdgeType {
    fn is_directed() -> bool;
}

impl EdgeType for Directed {
    #[inline]
    fn is_directed() -> bool { true }
}

impl EdgeType for Undirected {
    #[inline]
    fn is_directed() -> bool { false }
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
    a == b
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptr_eq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T> Hash for Ptr<'b, T>
{
    fn hash<H: hash::Hasher>(&self, st: &mut H)
    {
        let ptr = (self.0) as *const T;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Convert an element like `(i, j)` or `(i, j, w)` into
/// a triple of source, target, edge weight.
///
/// For `Graph::from_edges` and `GraphMap::from_edges`.
pub trait IntoWeightedEdge<Ix, E> {
    fn into_edge(self) -> (Ix, Ix, E);
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix)
    where Ix: Copy, E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = *self;
        (s, t, E::default())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix, E)
    where Ix: Copy, E: Clone
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self.clone()
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix)
    where E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = self;
        (s, t, E::default())
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix, E)
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self
    }
}
<commit_msg>Add another IntoWeightedEdges impl<commit_after>
//! **petgraph** is a graph data structure library.
//!
//! The most prominent type is [`Graph`](./graph/struct.Graph.html) which is
//! a directed or undirected graph with arbitrary mutable node and edge weights.
//! It is based on rustc's graph implementation.
//!
//! Petgraph also provides [`GraphMap`](./graphmap/struct.GraphMap.html) which
//! is an undirected hashmap-backed graph which only allows simple node identifiers
//! (such as integers or references).

extern crate fixedbitset;

use std::cmp::Ordering;
use std::hash::{self, Hash};
use std::fmt;
use std::ops::{Deref};

pub use scored::MinScored;
pub use graphmap::GraphMap;
pub use graph::Graph;

pub use self::EdgeDirection::{Outgoing, Incoming};
pub use visit::{
    Bfs,
    BfsIter,
    Dfs,
    DfsIter,
};

mod scored;
pub mod algo;
#[doc(hidden)] // Not for public consumption -- only for testing
pub mod generate;
pub mod graphmap;
pub mod graph;
pub mod visit;
pub mod unionfind;
mod dijkstra;
mod isomorphism;
mod traits_graph;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum EdgeDirection {
    /// An `Outgoing` edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An `Incoming` edge is an inbound edge *to* the current node.
    Incoming = 1
}

impl EdgeDirection {
    #[inline]
    fn opposite(&self) -> EdgeDirection {
        match *self {
            Outgoing => Incoming,
            Incoming => Outgoing,
        }
    }
}

/// Marker type for a directed graph.
#[derive(Copy, Clone, Debug)]
pub struct Directed;

/// Marker type for an undirected graph.
#[derive(Copy, Clone, Debug)]
pub struct Undirected;

/// A graph's edge type determines whether is has directed edges or not.
pub trait EdgeType {
    fn is_directed() -> bool;
}

impl EdgeType for Directed {
    #[inline]
    fn is_directed() -> bool { true }
}

impl EdgeType for Undirected {
    #[inline]
    fn is_directed() -> bool { false }
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
    a == b
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptr_eq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T> Hash for Ptr<'b, T>
{
    fn hash<H: hash::Hasher>(&self, st: &mut H)
    {
        let ptr = (self.0) as *const T;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Convert an element like `(i, j)` or `(i, j, w)` into
/// a triple of source, target, edge weight.
///
/// For `Graph::from_edges` and `GraphMap::from_edges`.
pub trait IntoWeightedEdge<Ix, E> {
    fn into_edge(self) -> (Ix, Ix, E);
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix)
    where Ix: Copy, E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = *self;
        (s, t, E::default())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix, E)
    where Ix: Copy, E: Clone
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self.clone()
    }
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix, &'a E)
    where Ix: Copy, E: Clone
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (a, b, c) = self;
        (a, b, c.clone())
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix)
    where E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = self;
        (s, t, E::default())
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix, E)
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self
    }
}
<|endoftext|>