<commit_before>extern crate libc;

use self::libc::{c_char, c_uchar};

#[no_mangle]
pub extern fn anoncreds_create_claim(client_id: i32, command_id: i32,
                                     schema_id: *const c_char, attributes: *const c_char,
                                     claim_request: *const c_char,
                                     cb: extern fn(xcommand_id: i32, err: i32, claim: *const c_char)) {
    unimplemented!();
}

#[no_mangle]
pub extern fn anoncreds_create_claim_request(client_id: i32, command_id: i32,
                                             schema_id: *const c_char,
                                             cb: extern fn(xcommand_id: i32, err: i32,
                                                           claim_req: *const c_char)) {
    unimplemented!();
}

#[no_mangle]
pub extern fn anoncreds_create_proof(client_id: i32, command_id: i32,
                                     proof_input: *const c_char,
                                     nonce: *const c_uchar,
                                     cb: extern fn(xcommand_id: i32, err: i32,
                                                   proof: *const c_char, attrs: *const c_char)) {
    unimplemented!();
}

#[no_mangle]
pub extern fn anoncreds_verify_proof(client_id: i32, command_id: i32,
                                     proof_input: *const c_char,
                                     proof: *const c_uchar,
                                     revealed_attributes: *const c_uchar,
                                     nonce: *const c_uchar,
                                     cb: extern fn(xcommand_id: i32, err: i32)) {
    unimplemented!();
}<commit_msg>added documentation<commit_after>extern crate libc;

use self::libc::{c_char, c_uchar};

/// Issues claim.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// schema_id: id of schema.
/// attributes:  all names of attributes as a byte array.
/// claim_request:
///     A claim request containing prover ID and prover-generated values as a byte array.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Returns Claim.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn anoncreds_create_claim(client_id: i32, command_id: i32,
                                     schema_id: *const c_char, attributes: *const c_char,
                                     claim_request: *const c_char,
                                     cb: extern fn(xcommand_id: i32, err: i32, claim: *const c_char)) {
    unimplemented!();
}

/// Creates claim request.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// schema_id: id of schema.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Claim request.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn anoncreds_create_claim_request(client_id: i32, command_id: i32,
                                             schema_id: *const c_char,
                                             cb: extern fn(xcommand_id: i32, err: i32,
                                                           claim_req: *const c_char)) {
    unimplemented!();
}

/// Creates proof.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// proof_input: description of a proof to be presented
///     (revealed attributes, predicates, timestamps for non-revocation).
///     For example: {
///         names:['name', 'height'],
///         predicates: [{predicate: 'gt', value: 18, attr: age}]
///     }
/// nonce: verifier's nonce.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Proof.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn anoncreds_create_proof(client_id: i32, command_id: i32,
                                     proof_input: *const c_char,
                                     nonce: *const c_uchar,
                                     cb: extern fn(xcommand_id: i32, err: i32,
                                                   proof: *const c_char, attrs: *const c_char)) {
    unimplemented!();
}

/// Verifies proof.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// proof_input: description of a proof to be presented
///     (revealed attributes, predicates, timestamps for non-revocation).
///     For example: {
///         names:['name', 'height'],
///         predicates: [{predicate: 'gt', value: 18, attr: age}]
///     }
/// proof: a proof.
/// revealed_attributes:
///     values of revealed attributes (initial values, non-encoded).
/// nonce: verifier's nonce.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Claim request.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn anoncreds_verify_proof(client_id: i32, command_id: i32,
                                     proof_input: *const c_char,
                                     proof: *const c_uchar,
                                     revealed_attributes: *const c_uchar,
                                     nonce: *const c_uchar,
                                     cb: extern fn(xcommand_id: i32, err: i32)) {
    unimplemented!();
}<|endoftext|>


<commit_before>use std::path::posix::Path;
use std::os::homedir;

static MUXED_NAME_STR: &'static str = "muxed";

/// Return the users current homedir as a string.
fn homedir_string() -> String {
    let home_unwrap = homedir().unwrap();
    format!("{}", home_unwrap.display())
}

pub fn path() -> Path {
    Path::new(format!("{}/.{}/", homedir_string(), &MUXED_NAME_STR.to_string()))
}
<commit_msg>Test the expected Path for muxed root.<commit_after>use std::path::posix::Path;
#[cfg(not(test))] use std::os::homedir;

static MUXED_NAME_STR: &'static str = "muxed";

/// Return the users current homedir as a string.
#[cfg(not(test))] fn homedir_string() -> String {
    match homedir() {
        Some(dir) => format!("{}", dir.display()),
        None      => fail!("Impossible to get your home dir!")
    }
}

#[cfg(test)] fn homedir_string() -> String {
  String::from_str("/tmp")
}

pub fn path() -> Path {
    Path::new(format!("{}/.{}/", homedir_string(), &MUXED_NAME_STR.to_string()))
}

#[test]
pub fn path_returns_muxed_inside_homedir() {
    let path = format!("{}", path().display());
    let new = format!("{}", Path::new("/tmp/.muxed").display());
    assert_eq!(path, new)
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::fmt::Error as FmtError;
use std::fmt::{Display, Formatter};

generate_error_types!(CounterError, CounterErrorKind,
    StoreReadError          => "Store read error",
    StoreWriteError         => "Store write error",
    HeaderTypeError         => "Header type error",
    HeaderFieldMissingError => "Header field missing error"
);

<commit_msg>libimagcounter: Replace error module imports with macro helper<commit_after>generate_error_imports!();

generate_error_types!(CounterError, CounterErrorKind,
    StoreReadError          => "Store read error",
    StoreWriteError         => "Store write error",
    HeaderTypeError         => "Header type error",
    HeaderFieldMissingError => "Header field missing error"
);

<|endoftext|>


<commit_before>use std::convert::Into;

use chrono::naive::datetime::NaiveDateTime;
use chrono::naive::time::NaiveTime;
use chrono::naive::date::NaiveDate;
use chrono::Datelike;
use chrono::Timelike;

use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use module_path::ModuleEntryPath;

#[derive(Debug, Clone)]
pub struct DiaryId {
    name: String,
    year: i32,
    month: u32,
    day: u32,
    hour: u32,
    minute: u32,
}

impl DiaryId {

    pub fn new(name: String, y: i32, m: u32, d: u32, h: u32, min: u32) -> DiaryId {
        DiaryId {
            name: name,
            year: y,
            month: m,
            day: d,
            hour: h,
            minute: min,
        }
    }

    pub fn from_datetime<DT: Datelike + Timelike>(diary_name: String, dt: DT) -> DiaryId {
        DiaryId::new(diary_name, dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute())
    }

    pub fn diary_name(&self) -> &String {
        &self.name
    }

    pub fn year(&self) -> i32 {
        self.year
    }

    pub fn month(&self) -> u32 {
        self.month
    }

    pub fn day(&self) -> u32 {
        self.day
    }

    pub fn hour(&self) -> u32 {
        self.hour
    }

    pub fn minute(&self) -> u32 {
        self.minute
    }

    pub fn with_diary_name(mut self, name: String) -> DiaryId {
        self.name = name;
        self
    }

    pub fn with_year(mut self, year: i32) -> DiaryId {
        self.year = year;
        self
    }

    pub fn with_month(mut self, month: u32) -> DiaryId {
        self.month = month;
        self
    }

    pub fn with_day(mut self, day: u32) -> DiaryId {
        self.day = day;
        self
    }

    pub fn with_hour(mut self, hour: u32) -> DiaryId {
        self.hour = hour;
        self
    }

    pub fn with_minute(mut self, minute: u32) -> DiaryId {
        self.minute = minute;
        self
    }

}

impl Default for DiaryId {

    /// Create a default DiaryId which is a diaryid for a diary named "default" with
    /// time = 0000-00-00 00:00:00
    fn default() -> DiaryId {
        let dt = NaiveDateTime::new(NaiveDate::from_ymd(0, 0, 0), NaiveTime::from_hms(0, 0, 0));
        DiaryId::from_datetime(String::from("default"), dt)
    }
}

impl IntoStoreId for DiaryId {

    fn into_storeid(self) -> StoreId {
        let s : String = self.into();
        ModuleEntryPath::new(s).into_storeid()
    }

}

impl Into<String> for DiaryId {

    fn into(self) -> String {
        format!("{}/{:0>4}/{:0>2}/{:0>2}/{:0>2}:{:0>2}",
                self.name, self.year, self.month, self.day, self.hour, self.minute)
    }

}

impl Into<NaiveDateTime> for DiaryId {

    fn into(self) -> NaiveDateTime {
        let d = NaiveDate::from_ymd(self.year, self.month, self.day);
        let t = NaiveTime::from_hms(self.hour, self.minute, 0);
        NaiveDateTime::new(d, t)
    }

}

pub trait FromStoreId : Sized {

    fn from_storeid(&StoreId) -> Option<Self>;

}

use std::path::Component;

fn component_to_str<'a>(com: Component<'a>) -> Option<&'a str> {
    match com {
        Component::Normal(s) => Some(s),
        _ => None
    }.and_then(|s| s.to_str())
}

impl FromStoreId for DiaryId {

    fn from_storeid(s: &StoreId) -> Option<DiaryId> {
        use std::str::FromStr;

        let mut cmps   = s.components().rev();
        let (hour, minute) = match cmps.next().and_then(component_to_str)
            .and_then(|time| {
                let mut time = time.split(":");
                let hour     = time.next().and_then(|s| FromStr::from_str(s).ok());
                let minute   = time.next()
                    .and_then(|s| s.split("~").next())
                    .and_then(|s| FromStr::from_str(s).ok());

                debug!("Hour   = {:?}", hour);
                debug!("Minute = {:?}", minute);

                match (hour, minute) {
                    (Some(h), Some(m)) => Some((h, m)),
                    _ => None,
                }
            })
        {
            Some(s) => s,
            None => return None,
        };

        let day   :Option<u32> = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok());
        let month :Option<u32> = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok());
        let year  :Option<i32> = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok());
        let name       = cmps.next().and_then(component_to_str).map(String::from);

        debug!("Day   = {:?}", day);
        debug!("Month = {:?}", month);
        debug!("Year  = {:?}", year);
        debug!("Name  = {:?}", name);

        let day    = if day.is_none()    { return None; } else { day.unwrap() };
        let month  = if month.is_none()  { return None; } else { month.unwrap() };
        let year   = if year.is_none()   { return None; } else { year.unwrap() };
        let name   = if name.is_none()   { return None; } else { name.unwrap() };

        Some(DiaryId::new(name, year, month, day, hour, minute))
    }

}

<commit_msg>Add DiaryId::now(name) to create DiaryId at current time<commit_after>use std::convert::Into;

use chrono::naive::datetime::NaiveDateTime;
use chrono::naive::time::NaiveTime;
use chrono::naive::date::NaiveDate;
use chrono::Datelike;
use chrono::Timelike;

use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use module_path::ModuleEntryPath;

#[derive(Debug, Clone)]
pub struct DiaryId {
    name: String,
    year: i32,
    month: u32,
    day: u32,
    hour: u32,
    minute: u32,
}

impl DiaryId {

    pub fn new(name: String, y: i32, m: u32, d: u32, h: u32, min: u32) -> DiaryId {
        DiaryId {
            name: name,
            year: y,
            month: m,
            day: d,
            hour: h,
            minute: min,
        }
    }

    pub fn from_datetime<DT: Datelike + Timelike>(diary_name: String, dt: DT) -> DiaryId {
        DiaryId::new(diary_name, dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute())
    }

    pub fn diary_name(&self) -> &String {
        &self.name
    }

    pub fn year(&self) -> i32 {
        self.year
    }

    pub fn month(&self) -> u32 {
        self.month
    }

    pub fn day(&self) -> u32 {
        self.day
    }

    pub fn hour(&self) -> u32 {
        self.hour
    }

    pub fn minute(&self) -> u32 {
        self.minute
    }

    pub fn with_diary_name(mut self, name: String) -> DiaryId {
        self.name = name;
        self
    }

    pub fn with_year(mut self, year: i32) -> DiaryId {
        self.year = year;
        self
    }

    pub fn with_month(mut self, month: u32) -> DiaryId {
        self.month = month;
        self
    }

    pub fn with_day(mut self, day: u32) -> DiaryId {
        self.day = day;
        self
    }

    pub fn with_hour(mut self, hour: u32) -> DiaryId {
        self.hour = hour;
        self
    }

    pub fn with_minute(mut self, minute: u32) -> DiaryId {
        self.minute = minute;
        self
    }

    pub fn now(name: String) -> DiaryId {
        use chrono::offset::local::Local;

        let now = Local::now();
        let now_date = now.date().naive_local();
        let now_time = now.time();
        let dt = NaiveDateTime::new(now_date, now_time);

        DiaryId::new(name, dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute())
    }

}

impl Default for DiaryId {

    /// Create a default DiaryId which is a diaryid for a diary named "default" with
    /// time = 0000-00-00 00:00:00
    fn default() -> DiaryId {
        let dt = NaiveDateTime::new(NaiveDate::from_ymd(0, 0, 0), NaiveTime::from_hms(0, 0, 0));
        DiaryId::from_datetime(String::from("default"), dt)
    }
}

impl IntoStoreId for DiaryId {

    fn into_storeid(self) -> StoreId {
        let s : String = self.into();
        ModuleEntryPath::new(s).into_storeid()
    }

}

impl Into<String> for DiaryId {

    fn into(self) -> String {
        format!("{}/{:0>4}/{:0>2}/{:0>2}/{:0>2}:{:0>2}",
                self.name, self.year, self.month, self.day, self.hour, self.minute)
    }

}

impl Into<NaiveDateTime> for DiaryId {

    fn into(self) -> NaiveDateTime {
        let d = NaiveDate::from_ymd(self.year, self.month, self.day);
        let t = NaiveTime::from_hms(self.hour, self.minute, 0);
        NaiveDateTime::new(d, t)
    }

}

pub trait FromStoreId : Sized {

    fn from_storeid(&StoreId) -> Option<Self>;

}

use std::path::Component;

fn component_to_str<'a>(com: Component<'a>) -> Option<&'a str> {
    match com {
        Component::Normal(s) => Some(s),
        _ => None
    }.and_then(|s| s.to_str())
}

impl FromStoreId for DiaryId {

    fn from_storeid(s: &StoreId) -> Option<DiaryId> {
        use std::str::FromStr;

        let mut cmps   = s.components().rev();
        let (hour, minute) = match cmps.next().and_then(component_to_str)
            .and_then(|time| {
                let mut time = time.split(":");
                let hour     = time.next().and_then(|s| FromStr::from_str(s).ok());
                let minute   = time.next()
                    .and_then(|s| s.split("~").next())
                    .and_then(|s| FromStr::from_str(s).ok());

                debug!("Hour   = {:?}", hour);
                debug!("Minute = {:?}", minute);

                match (hour, minute) {
                    (Some(h), Some(m)) => Some((h, m)),
                    _ => None,
                }
            })
        {
            Some(s) => s,
            None => return None,
        };

        let day   :Option<u32> = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok());
        let month :Option<u32> = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok());
        let year  :Option<i32> = cmps.next().and_then(component_to_str).and_then(|s| FromStr::from_str(s).ok());
        let name       = cmps.next().and_then(component_to_str).map(String::from);

        debug!("Day   = {:?}", day);
        debug!("Month = {:?}", month);
        debug!("Year  = {:?}", year);
        debug!("Name  = {:?}", name);

        let day    = if day.is_none()    { return None; } else { day.unwrap() };
        let month  = if month.is_none()  { return None; } else { month.unwrap() };
        let year   = if year.is_none()   { return None; } else { year.unwrap() };
        let name   = if name.is_none()   { return None; } else { name.unwrap() };

        Some(DiaryId::new(name, year, month, day, hour, minute))
    }

}

<|endoftext|>


<commit_before><commit_msg>adds worker_id return from MasterNode::connect<commit_after><|endoftext|>


<commit_before>#[macro_use]
extern crate entity_rust;
#[macro_use]
extern crate lazy_static;
extern crate shared_mutex;

pub mod my_event {
	pub struct Data {
		x: i64
	}
}

system!( my_system {
	state! { x: i64 }

	on!( my_event, { positions: State }, {}) {
		self.x += 1;
	}

});

#[test]
fn generates_functions() {
	my_system::register();
}

#[test]
fn generates_state() {
	let s = my_system::State::default();
	assert!(s.x == 0);

	{
		let mut state = my_system::state.write().expect("System lock corrupted.");
		state.x = 2;
	}

	{
		let state = my_system::state.read().expect("System lock corrupted");
		assert!(state.x == 2);
	}

}<commit_msg>fix system test<commit_after>#[macro_use]
extern crate entity_rust;
#[macro_use]
extern crate lazy_static;
extern crate shared_mutex;

pub mod my_event {
	pub struct Data {
		x: i64
	}
}

system!( my_system {
	state! { x: i64 }

	on!( my_event, { positions: State }, {}) self => {
		self.x += 1;
	}

});

#[test]
fn generates_functions() {
	my_system::register();
}

#[test]
fn generates_state() {
	let s = my_system::State::default();
	assert!(s.x == 0);

	{
		let mut state = my_system::state.write().expect("System lock corrupted.");
		state.x = 2;
	}

	{
		let state = my_system::state.read().expect("System lock corrupted");
		assert!(state.x == 2);
	}

}<|endoftext|>


<commit_before>use std::env;
extern crate rawloader;
extern crate time;
use rawloader::decoders;

fn usage() {
  println!("benchmark <file>");
  std::process::exit(1);
}

static ITERATIONS: u32 = 100;

fn error(err: &str) {
  println!("ERROR: {}", err);
  std::process::exit(2);
}

fn main() {
  let args: Vec<_> = env::args().collect();
  if args.len() != 2 {
    usage();
  }
  let file = &args[1];
  println!("Loading file \"{}\"", file);

  let rawloader = decoders::RawLoader::new();
  let from_time = time::precise_time_ns();
  for _ in 0..ITERATIONS {
    match rawloader.decode_safe(file) {
      Ok(_) => {},
      Err(e) => error(&e),
    }
  }
  let to_time = time::precise_time_ns();
  println!("Decoded {} times in {} ms", ITERATIONS, (to_time - from_time)/1000000);
}
<commit_msg>Make benchmarker run for max(10s; 100 iterations)<commit_after>use std::env;
extern crate rawloader;
extern crate time;
use rawloader::decoders;

fn usage() {
  println!("benchmark <file>");
  std::process::exit(1);
}

static STEP_ITERATIONS: u32 = 10;
static MIN_ITERATIONS: u32 = 100;
static MIN_TIME: u64 = 10000000000;

fn error(err: &str) {
  println!("ERROR: {}", err);
  std::process::exit(2);
}

fn main() {
  let args: Vec<_> = env::args().collect();
  if args.len() != 2 {
    usage();
  }
  let file = &args[1];
  println!("Loading file \"{}\"", file);

  let rawloader = decoders::RawLoader::new();
  let from_time = time::precise_time_ns();
  let mut iterations = 0;
  loop {
    for _ in 0..STEP_ITERATIONS {
      match rawloader.decode_safe(file) {
        Ok(_) => {},
        Err(e) => error(&e),
      }
    }
    iterations += STEP_ITERATIONS;
    let to_time = time::precise_time_ns();
    if iterations >= MIN_ITERATIONS && (to_time-from_time) >= MIN_TIME {
      println!("Average decode time: {} ms ({} iterations)", (to_time-from_time)/(iterations as u64)/1000000, iterations);
      break;
    }
  }
}
<|endoftext|>


<commit_before>use common::util::*;
use std::fs::set_permissions;

static TEST_EXISTING_FILE:         &str = "existing_file.txt";
static TEST_HELLO_WORLD_SOURCE:    &str = "hello_world.txt";
static TEST_HELLO_WORLD_DEST:      &str = "copy_of_hello_world.txt";
static TEST_HOW_ARE_YOU_SOURCE:    &str = "how_are_you.txt";
static TEST_HOW_ARE_YOU_DEST:      &str = "hello_dir/how_are_you.txt";
static TEST_COPY_TO_FOLDER:        &str = "hello_dir/";
static TEST_COPY_TO_FOLDER_FILE:   &str = "hello_dir/hello_world.txt";
static TEST_COPY_FROM_FOLDER:      &str = "hello_dir_with_file/";
static TEST_COPY_FROM_FOLDER_FILE: &str = "hello_dir_with_file/hello_world.txt";

#[test]
fn test_cp_cp() {
    let (at, mut ucmd) = at_and_ucmd!();
    // Invoke our binary to make the copy.
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
                     .arg(TEST_HELLO_WORLD_DEST)
                     .run();

    // Check that the exit code represents a successful copy.
    let exit_success = result.success;
    assert!(exit_success);

    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_duplicate_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("specified more than once"));
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_multiple_files_target_is_file() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_EXISTING_FILE)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("not a directory"));
}

#[test]
fn test_cp_directory_not_recursive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("omitting directory"));
}

#[test]
fn test_cp_multiple_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
    assert_eq!(at.read(TEST_HOW_ARE_YOU_DEST), "How are you?\n");
}

#[test]
fn test_cp_recurse() {
    //let (at, mut ucmd) = at_and_ucmd!();
    let scene = TestScenario::new(util_name!());
    let at = &scene.fixtures;

    // Invoke our binary to make the copy.
    let result_to_dir = scene.ucmd()
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();
    assert!(result_to_dir.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");

    let result = scene.ucmd()
                     .arg("-r")
                     .arg(TEST_COPY_FROM_FOLDER)
                     .arg(TEST_COPY_TO_FOLDER)
                     .run();

    assert!(result.success);
    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs_t() {
    let (at, mut ucmd) = at_and_ucmd!();

    //using -t option
    let result_to_dir_t = ucmd
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .run();
    assert!(result_to_dir_t.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs() {
    let scene = TestScenario::new(util_name!());
    let at = &scene.fixtures;

    //using -t option
    let result_to_dir = scene.ucmd()
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();
    assert!(result_to_dir.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");

    let result_from_dir = scene.ucmd()
        .arg(TEST_COPY_FROM_FOLDER_FILE)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();
    assert!(result_from_dir.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_target_directory() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_arg_no_target_directory() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-v")
        .arg("-T")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("cannot overwrite directory"));
}

#[test]
fn test_cp_arg_interactive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg("-i")
        .pipe_in("N\n")
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(target_os="unix")]
fn test_cp_arg_link() {
    use std::os::linux::fs::MetadataExt;

    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.metadata(TEST_HELLO_WORLD_SOURCE).st_nlink(), 2);
}

#[test]
fn test_cp_arg_symlink() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--symbolic-link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert!(at.is_symlink(TEST_HELLO_WORLD_DEST));
}

#[test]
fn test_cp_arg_no_clobber() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--no-clobber")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(not(windows))]
fn test_cp_arg_force() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--force")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    println!("{:?}", result.stderr);
    println!("{:?}", result.stdout);

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

/// TODO: write a better test that differentiates --remove-destination
/// from --force. Also this test currently doesn't work on
/// Windows. This test originally checked file timestamps, which
/// proved to be unreliable per target / CI platform
#[test]
#[cfg(not(windows))]
fn test_cp_arg_remove_destination() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--remove-destination")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_backup() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--backup")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}~", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}

#[test]
fn test_cp_arg_suffix() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--suffix")
        .arg(".bak")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}.bak", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}
<commit_msg>Fix cp -r test<commit_after>use common::util::*;
use std::fs::set_permissions;

static TEST_EXISTING_FILE:           &str = "existing_file.txt";
static TEST_HELLO_WORLD_SOURCE:      &str = "hello_world.txt";
static TEST_HELLO_WORLD_DEST:        &str = "copy_of_hello_world.txt";
static TEST_HOW_ARE_YOU_SOURCE:      &str = "how_are_you.txt";
static TEST_HOW_ARE_YOU_DEST:        &str = "hello_dir/how_are_you.txt";
static TEST_COPY_TO_FOLDER:          &str = "hello_dir/";
static TEST_COPY_TO_FOLDER_FILE:     &str = "hello_dir/hello_world.txt";
static TEST_COPY_FROM_FOLDER:        &str = "hello_dir_with_file/";
static TEST_COPY_FROM_FOLDER_FILE:   &str = "hello_dir_with_file/hello_world.txt";
static TEST_COPY_TO_FOLDER_NEW:      &str = "hello_dir_new/";
static TEST_COPY_TO_FOLDER_NEW_FILE: &str = "hello_dir_new/hello_world.txt";

#[test]
fn test_cp_cp() {
    let (at, mut ucmd) = at_and_ucmd!();
    // Invoke our binary to make the copy.
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
                     .arg(TEST_HELLO_WORLD_DEST)
                     .run();

    // Check that the exit code represents a successful copy.
    let exit_success = result.success;
    assert!(exit_success);

    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_duplicate_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("specified more than once"));
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_multiple_files_target_is_file() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_EXISTING_FILE)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("not a directory"));
}

#[test]
fn test_cp_directory_not_recursive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("omitting directory"));
}

#[test]
fn test_cp_multiple_files() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
    assert_eq!(at.read(TEST_HOW_ARE_YOU_DEST), "How are you?\n");
}

#[test]
fn test_cp_recurse() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd
        .arg("-r")
        .arg(TEST_COPY_FROM_FOLDER)
        .arg(TEST_COPY_TO_FOLDER_NEW)
        .run();

    assert!(result.success);
    // Check the content of the destination file that was copied.
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_NEW_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs_t() {
    let (at, mut ucmd) = at_and_ucmd!();

    //using -t option
    let result_to_dir_t = ucmd
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .arg(TEST_HELLO_WORLD_SOURCE)
        .run();
    assert!(result_to_dir_t.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_with_dirs() {
    let scene = TestScenario::new(util_name!());
    let at = &scene.fixtures;

    //using -t option
    let result_to_dir = scene.ucmd()
        .arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_COPY_TO_FOLDER)
        .run();
    assert!(result_to_dir.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");

    let result_from_dir = scene.ucmd()
        .arg(TEST_COPY_FROM_FOLDER_FILE)
        .arg(TEST_HELLO_WORLD_DEST)
        .run();
    assert!(result_from_dir.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_target_directory() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-t")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}

#[test]
fn test_cp_arg_no_target_directory() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("-v")
        .arg("-T")
        .arg(TEST_COPY_TO_FOLDER)
        .run();

    assert!(!result.success);
    assert!(result.stderr.contains("cannot overwrite directory"));
}

#[test]
fn test_cp_arg_interactive() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .arg("-i")
        .pipe_in("N\n")
        .run();

    assert!(result.success);
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(target_os="unix")]
fn test_cp_arg_link() {
    use std::os::linux::fs::MetadataExt;

    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.metadata(TEST_HELLO_WORLD_SOURCE).st_nlink(), 2);
}

#[test]
fn test_cp_arg_symlink() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--symbolic-link")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert!(at.is_symlink(TEST_HELLO_WORLD_DEST));
}

#[test]
fn test_cp_arg_no_clobber() {
    let (at, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--no-clobber")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
    assert!(result.stderr.contains("Not overwriting"));
}

#[test]
#[cfg(not(windows))]
fn test_cp_arg_force() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--force")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    println!("{:?}", result.stderr);
    println!("{:?}", result.stdout);

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

/// TODO: write a better test that differentiates --remove-destination
/// from --force. Also this test currently doesn't work on
/// Windows. This test originally checked file timestamps, which
/// proved to be unreliable per target / CI platform
#[test]
#[cfg(not(windows))]
fn test_cp_arg_remove_destination() {
    let (at, mut ucmd) = at_and_ucmd!();

    // create dest without write permissions
    let mut permissions = at.make_file(TEST_HELLO_WORLD_DEST).metadata().unwrap().permissions();
    permissions.set_readonly(true);
    set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--remove-destination")
        .arg(TEST_HELLO_WORLD_DEST)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}

#[test]
fn test_cp_arg_backup() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--backup")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}~", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}

#[test]
fn test_cp_arg_suffix() {
    let (at, mut ucmd) = at_and_ucmd!();

    let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
        .arg("--suffix")
        .arg(".bak")
        .arg(TEST_HOW_ARE_YOU_SOURCE)
        .run();

    assert!(result.success);
    assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
    assert_eq!(at.read(&*format!("{}.bak", TEST_HOW_ARE_YOU_SOURCE)), "How are you?\n");
}
<|endoftext|>


<commit_before>//! # Diesel
//!
//! Diesel is an ORM and query builder designed to reduce the boilerplate for database interactions.
//! If this is your first time reading this documentation,
//! we recommend you start with the [getting started guide].
//! We also have [many other long form guides].
//!
//! [getting started guide]: https://diesel.rs/guides/getting-started/
//! [many other long form guides]: https://diesel.rs/guides
//!
//! # Where to find things
//!
//! ## Declaring your schema
//!
//! So Diesel is able to validate your queries at compile time,
//! it requires you to specify your schema in your code,
//! which you can do with [the `table!` macro][`table!`].
//! `diesel print-schema` or `infer_schema!` can be used
//! to automatically generate these macro calls
//! (by connecting to your database and querying its schema).
//!
//! [`table!`]: macro.table.html
//!
//! ## Getting started
//!
//! Queries usually start from either a table, or a function like [`update`].
//! Those functions can be found [here](#functions).
//!
//! Diesel provides a [`prelude` module](prelude),
//! which exports most of the typically used traits and types.
//! We are conservative about what goes in this module,
//! and avoid anything which has a generic name.
//! Files which use Diesel are expected to have `use diesel::prelude::*;`.
//!
//! [`update`]: fn.update.html
//!
//! ## Constructing a query
//!
//! The tools the query builder gives you can be put into these three categories:
//!
//! - "Query builder methods" are things that map to portions of a whole query
//!   (such as `ORDER` and `WHERE`). These methods usually have the same name
//!   as the SQL they map to, except for `WHERE` which is called `filter` in Diesel
//!   (To not conflict with the Rust keyword).
//!   These methods live in [the `query_dsl` module](query_dsl).
//! - "Expression methods" are things you would call on columns
//!   or other individual values.
//!   These methods live in [the `expression_methods` module](expression_methods)
//!   You can often find these by thinking "what would this be called"
//!   if it were a method
//!   and typing that into the search bar
//!   (e.g. `LIKE` is called `like` in Diesel).
//!   Most operators are named based on the Rust function which maps to that
//!   operator in [`std::ops`][]
//!   (For example `==` is called `.eq`, and `!=` is called `.ne`).
//! - "Bare functions" are normal SQL functions
//!   such as `sum`.
//!   They live in [the `dsl` module](dsl).
//!   Diesel only supports a very small number of these functions.
//!   You can declare additional functions you want to use
//!   with [the `sql_function!` macro][`sql_function!`].
//!
//! [`std::ops`]: //doc.rust-lang.org/stable/std/ops/index.html
//! [`sql_function!`]: macro.sql_function.html
//!
//! ## Serializing and Deserializing
//!
//! Types which represent the result of a SQL query implement
//! a trait called [`Queryable`].
//!
//! Diesel maps "Rust types" (e.g. `i32`) to and from "SQL types"
//! (e.g. [`diesel::sql_types::Integer`]).
//! You can find all the types supported by Diesel in [the `sql_types` module](sql_types).
//! These types are only used to represent a SQL type.
//! You should never put them on your `Queryable` structs.
//!
//! To find all the Rust types which can be used with a given SQL type,
//! see the documentation for that SQL type.
//!
//! To find all the SQL types which can be used with a Rust type,
//! go to the docs for either [`ToSql`] or [`FromSql`],
//! go to the "Implementors" section,
//! and find the Rust type you want to use.
//!
//! [`Queryable`]: deserialize/trait.Queryable.html
//! [`diesel::sql_types::Integer`]: sql_types/struct.Integer.html
//! [`ToSql`]: serialize/trait.ToSql.html
//! [`FromSql`]: deserialize/trait.FromSql.html
//!
//! ## Getting help
//!
//! If you run into problems, Diesel has a very active Gitter room.
//! You can come ask for help at
//! [gitter.im/diesel-rs/diesel](https://gitter.im/diesel-rs/diesel)

#![cfg_attr(
    feature = "large-tables",
    deprecated(
        since = "1.2.0", note = "The large-tables feature has been renamed to 32-column-tables"
    )
)]
#![cfg_attr(
    feature = "huge-tables",
    deprecated(
        since = "1.2.0", note = "The huge-tables feature has been renamed to 64-column-tables"
    )
)]
#![cfg_attr(
    feature = "x32-column-tables",
    deprecated(
        since = "1.2.1",
        note = "The x32-column-tables feature has been reanmed to 32-column-tables. The x was a workaround for a bug in crates.io that has since been resolved"
    )
)]
#![cfg_attr(
    feature = "x64-column-tables",
    deprecated(
        since = "1.2.1",
        note = "The x64-column-tables feature has been reanmed to 64-column-tables. The x was a workaround for a bug in crates.io that has since been resolved"
    )
)]
#![cfg_attr(
    feature = "x128-column-tables",
    deprecated(
        since = "1.2.1",
        note = "The x128-column-tables feature has been reanmed to 128-column-tables. The x was a workaround for a bug in crates.io that has since been resolved"
    )
)]
#![cfg_attr(feature = "unstable", feature(specialization, try_from))]
// Built-in Lints
#![deny(warnings, missing_debug_implementations, missing_copy_implementations, missing_docs)]
// Clippy lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        option_map_unwrap_or_else, option_map_unwrap_or, match_same_arms, type_complexity,
        redundant_field_names
    )
)]
#![cfg_attr(
    feature = "cargo-clippy",
    warn(
        option_unwrap_used, result_unwrap_used, print_stdout, wrong_pub_self_convention, mut_mut,
        non_ascii_literal, similar_names, unicode_not_nfc, enum_glob_use, if_not_else,
        items_after_statements, used_underscore_binding
    )
)]
#![cfg_attr(all(test, feature = "cargo-clippy"), allow(option_unwrap_used, result_unwrap_used))]

#[cfg(feature = "postgres")]
#[macro_use]
extern crate bitflags;
extern crate byteorder;
// This is required to make `diesel_derives` re-export, but cargo-clippy thinks its unused
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(unused_imports)]
#[macro_use]
extern crate diesel_derives;
#[doc(hidden)]
pub use diesel_derives::*;

#[macro_use]
mod macros;

#[cfg(test)]
#[macro_use]
extern crate cfg_if;

#[cfg(test)]
pub mod test_helpers;

pub mod associations;
pub mod backend;
pub mod connection;
pub mod data_types;
pub mod deserialize;
#[macro_use]
pub mod expression;
pub mod expression_methods;
#[doc(hidden)]
pub mod insertable;
pub mod query_builder;
pub mod query_dsl;
pub mod query_source;
#[cfg(feature = "r2d2")]
pub mod r2d2;
pub mod result;
pub mod serialize;
#[macro_use]
pub mod sql_types;
pub mod migration;
pub mod row;
pub mod types;

#[cfg(feature = "mysql")]
pub mod mysql;
#[cfg(feature = "postgres")]
pub mod pg;
#[cfg(feature = "sqlite")]
pub mod sqlite;

mod type_impls;
mod util;

pub mod dsl {
    //! Includes various helper types and bare functions which are named too
    //! generically to be included in prelude, but are often used when using Diesel.

    #[doc(inline)]
    pub use helper_types::*;

    #[doc(inline)]
    pub use expression::dsl::*;

    #[doc(inline)]
    pub use query_builder::functions::{delete, insert_into, insert_or_ignore_into, replace_into,
                                       select, sql_query, update};
}

pub mod helper_types {
    //! Provide helper types for concisely writing the return type of functions.
    //! As with iterators, it is unfortunately difficult to return a partially
    //! constructed query without exposing the exact implementation of the
    //! function. Without higher kinded types, these various DSLs can't be
    //! combined into a single trait for boxing purposes.
    //!
    //! All types here are in the form `<FirstType as
    //! DslName<OtherTypes>>::Output`. So the return type of
    //! `users.filter(first_name.eq("John")).order(last_name.asc()).limit(10)` would
    //! be `Limit<Order<FindBy<users, first_name, &str>, Asc<last_name>>>`
    use super::query_builder::locking_clause as lock;
    use super::query_dsl::methods::*;
    use super::query_dsl::*;
    use super::query_source::joins;

    #[doc(inline)]
    pub use expression::helper_types::*;

    /// Represents the return type of `.select(selection)`
    pub type Select<Source, Selection> = <Source as SelectDsl<Selection>>::Output;

    /// Represents the return type of `.filter(predicate)`
    pub type Filter<Source, Predicate> = <Source as FilterDsl<Predicate>>::Output;

    /// Represents the return type of `.filter(lhs.eq(rhs))`
    pub type FindBy<Source, Column, Value> = Filter<Source, Eq<Column, Value>>;

    /// Represents the return type of `.for_update()`
    #[cfg(feature = "with-deprecated")]
    #[allow(deprecated)]
    pub type ForUpdate<Source> = <Source as ForUpdateDsl>::Output;

    /// Represents the return type of `.for_update()`
    #[cfg(not(feature = "with-deprecated"))]
    pub type ForUpdate<Source> = <Source as LockingDsl<lock::ForUpdate>>::Output;

    /// Represents the return type of `.for_no_key_update()`
    pub type ForNoKeyUpdate<Source> = <Source as LockingDsl<lock::ForNoKeyUpdate>>::Output;

    /// Represents the return type of `.for_share()`
    pub type ForShare<Source> = <Source as LockingDsl<lock::ForShare>>::Output;

    /// Represents the return type of `.for_key_share()`
    pub type ForKeyShare<Source> = <Source as LockingDsl<lock::ForKeyShare>>::Output;

    /// Represents the return type of `.skip_locked()`
    pub type SkipLocked<Source> = <Source as ModifyLockDsl<lock::SkipLocked>>::Output;

    /// Represents the return type of `.no_wait()`
    pub type NoWait<Source> = <Source as ModifyLockDsl<lock::NoWait>>::Output;

    /// Represents the return type of `.find(pk)`
    pub type Find<Source, PK> = <Source as FindDsl<PK>>::Output;

    /// Represents the return type of `.or_filter(predicate)`
    pub type OrFilter<Source, Predicate> = <Source as OrFilterDsl<Predicate>>::Output;

    /// Represents the return type of `.order(ordering)`
    pub type Order<Source, Ordering> = <Source as OrderDsl<Ordering>>::Output;

    /// Represents the return type of `.then_order_by(ordering)`
    pub type ThenOrderBy<Source, Ordering> = <Source as ThenOrderDsl<Ordering>>::Output;

    /// Represents the return type of `.limit()`
    pub type Limit<Source> = <Source as LimitDsl>::Output;

    /// Represents the return type of `.offset()`
    pub type Offset<Source> = <Source as OffsetDsl>::Output;

    /// Represents the return type of `.inner_join(rhs)`
    pub type InnerJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::Inner>>::Output;

    /// Represents the return type of `.left_join(rhs)`
    pub type LeftJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::LeftOuter>>::Output;

    use super::associations::HasTable;
    use super::query_builder::{AsChangeset, IntoUpdateTarget, UpdateStatement};
    /// Represents the return type of `update(lhs).set(rhs)`
    pub type Update<Target, Changes> = UpdateStatement<
        <Target as HasTable>::Table,
        <Target as IntoUpdateTarget>::WhereClause,
        <Changes as AsChangeset>::Changeset,
    >;

    /// Represents the return type of `.into_boxed::<'a, DB>()`
    pub type IntoBoxed<'a, Source, DB> = <Source as BoxedDsl<'a, DB>>::Output;

    /// Represents the return type of `.distinct()`
    pub type Distinct<Source> = <Source as DistinctDsl>::Output;

    /// Represents the return type of `.distinct_on(expr)`
    #[cfg(feature = "postgres")]
    pub type DistinctOn<Source, Expr> = <Source as DistinctOnDsl<Expr>>::Output;

    /// Represents the return type of `.single_value()`
    pub type SingleValue<Source> = <Source as SingleValueDsl>::Output;
}

pub mod prelude {
    //! Re-exports important traits and types. Meant to be glob imported when using Diesel.
    pub use associations::{GroupedBy, Identifiable};
    pub use connection::Connection;
    #[deprecated(since = "1.1.0", note = "Explicitly `use diesel::deserialize::Queryable")]
    pub use deserialize::Queryable;
    pub use expression::{AppearsOnTable, BoxableExpression, Expression, IntoSql,
                         SelectableExpression};
    pub use expression_methods::*;
    #[doc(inline)]
    pub use insertable::Insertable;
    #[doc(hidden)]
    pub use query_dsl::GroupByDsl;
    pub use query_dsl::{BelongingToDsl, JoinOnDsl, QueryDsl, RunQueryDsl, SaveChangesDsl};

    pub use query_source::{Column, JoinTo, QuerySource, Table};
    pub use result::{ConnectionError, ConnectionResult, OptionalExtension, QueryResult};

    #[cfg(feature = "mysql")]
    pub use mysql::MysqlConnection;
    #[cfg(feature = "postgres")]
    pub use pg::PgConnection;
    #[cfg(feature = "sqlite")]
    pub use sqlite::SqliteConnection;
}

pub use prelude::*;
#[doc(inline)]
pub use query_builder::debug_query;
#[doc(inline)]
pub use query_builder::functions::{delete, insert_into, insert_or_ignore_into, replace_into,
                                   select, sql_query, update};
pub use result::Error::NotFound;

pub(crate) mod diesel {
    pub use super::*;
}
<commit_msg>Cleaned up confusing sentence<commit_after>//! # Diesel
//!
//! Diesel is an ORM and query builder designed to reduce the boilerplate for database interactions.
//! If this is your first time reading this documentation,
//! we recommend you start with the [getting started guide].
//! We also have [many other long form guides].
//!
//! [getting started guide]: https://diesel.rs/guides/getting-started/
//! [many other long form guides]: https://diesel.rs/guides
//!
//! # Where to find things
//!
//! ## Declaring your schema
//!
//! For Diesel to validate your queries at compile time
//! it requires you to specify your schema in your code,
//! which you can do with [the `table!` macro][`table!`].
//! `diesel print-schema` or `infer_schema!` can be used
//! to automatically generate these macro calls
//! (by connecting to your database and querying its schema).
//!
//! [`table!`]: macro.table.html
//!
//! ## Getting started
//!
//! Queries usually start from either a table, or a function like [`update`].
//! Those functions can be found [here](#functions).
//!
//! Diesel provides a [`prelude` module](prelude),
//! which exports most of the typically used traits and types.
//! We are conservative about what goes in this module,
//! and avoid anything which has a generic name.
//! Files which use Diesel are expected to have `use diesel::prelude::*;`.
//!
//! [`update`]: fn.update.html
//!
//! ## Constructing a query
//!
//! The tools the query builder gives you can be put into these three categories:
//!
//! - "Query builder methods" are things that map to portions of a whole query
//!   (such as `ORDER` and `WHERE`). These methods usually have the same name
//!   as the SQL they map to, except for `WHERE` which is called `filter` in Diesel
//!   (To not conflict with the Rust keyword).
//!   These methods live in [the `query_dsl` module](query_dsl).
//! - "Expression methods" are things you would call on columns
//!   or other individual values.
//!   These methods live in [the `expression_methods` module](expression_methods)
//!   You can often find these by thinking "what would this be called"
//!   if it were a method
//!   and typing that into the search bar
//!   (e.g. `LIKE` is called `like` in Diesel).
//!   Most operators are named based on the Rust function which maps to that
//!   operator in [`std::ops`][]
//!   (For example `==` is called `.eq`, and `!=` is called `.ne`).
//! - "Bare functions" are normal SQL functions
//!   such as `sum`.
//!   They live in [the `dsl` module](dsl).
//!   Diesel only supports a very small number of these functions.
//!   You can declare additional functions you want to use
//!   with [the `sql_function!` macro][`sql_function!`].
//!
//! [`std::ops`]: //doc.rust-lang.org/stable/std/ops/index.html
//! [`sql_function!`]: macro.sql_function.html
//!
//! ## Serializing and Deserializing
//!
//! Types which represent the result of a SQL query implement
//! a trait called [`Queryable`].
//!
//! Diesel maps "Rust types" (e.g. `i32`) to and from "SQL types"
//! (e.g. [`diesel::sql_types::Integer`]).
//! You can find all the types supported by Diesel in [the `sql_types` module](sql_types).
//! These types are only used to represent a SQL type.
//! You should never put them on your `Queryable` structs.
//!
//! To find all the Rust types which can be used with a given SQL type,
//! see the documentation for that SQL type.
//!
//! To find all the SQL types which can be used with a Rust type,
//! go to the docs for either [`ToSql`] or [`FromSql`],
//! go to the "Implementors" section,
//! and find the Rust type you want to use.
//!
//! [`Queryable`]: deserialize/trait.Queryable.html
//! [`diesel::sql_types::Integer`]: sql_types/struct.Integer.html
//! [`ToSql`]: serialize/trait.ToSql.html
//! [`FromSql`]: deserialize/trait.FromSql.html
//!
//! ## Getting help
//!
//! If you run into problems, Diesel has a very active Gitter room.
//! You can come ask for help at
//! [gitter.im/diesel-rs/diesel](https://gitter.im/diesel-rs/diesel)

#![cfg_attr(
    feature = "large-tables",
    deprecated(
        since = "1.2.0", note = "The large-tables feature has been renamed to 32-column-tables"
    )
)]
#![cfg_attr(
    feature = "huge-tables",
    deprecated(
        since = "1.2.0", note = "The huge-tables feature has been renamed to 64-column-tables"
    )
)]
#![cfg_attr(
    feature = "x32-column-tables",
    deprecated(
        since = "1.2.1",
        note = "The x32-column-tables feature has been reanmed to 32-column-tables. The x was a workaround for a bug in crates.io that has since been resolved"
    )
)]
#![cfg_attr(
    feature = "x64-column-tables",
    deprecated(
        since = "1.2.1",
        note = "The x64-column-tables feature has been reanmed to 64-column-tables. The x was a workaround for a bug in crates.io that has since been resolved"
    )
)]
#![cfg_attr(
    feature = "x128-column-tables",
    deprecated(
        since = "1.2.1",
        note = "The x128-column-tables feature has been reanmed to 128-column-tables. The x was a workaround for a bug in crates.io that has since been resolved"
    )
)]
#![cfg_attr(feature = "unstable", feature(specialization, try_from))]
// Built-in Lints
#![deny(warnings, missing_debug_implementations, missing_copy_implementations, missing_docs)]
// Clippy lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        option_map_unwrap_or_else, option_map_unwrap_or, match_same_arms, type_complexity,
        redundant_field_names
    )
)]
#![cfg_attr(
    feature = "cargo-clippy",
    warn(
        option_unwrap_used, result_unwrap_used, print_stdout, wrong_pub_self_convention, mut_mut,
        non_ascii_literal, similar_names, unicode_not_nfc, enum_glob_use, if_not_else,
        items_after_statements, used_underscore_binding
    )
)]
#![cfg_attr(all(test, feature = "cargo-clippy"), allow(option_unwrap_used, result_unwrap_used))]

#[cfg(feature = "postgres")]
#[macro_use]
extern crate bitflags;
extern crate byteorder;
// This is required to make `diesel_derives` re-export, but cargo-clippy thinks its unused
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(unused_imports)]
#[macro_use]
extern crate diesel_derives;
#[doc(hidden)]
pub use diesel_derives::*;

#[macro_use]
mod macros;

#[cfg(test)]
#[macro_use]
extern crate cfg_if;

#[cfg(test)]
pub mod test_helpers;

pub mod associations;
pub mod backend;
pub mod connection;
pub mod data_types;
pub mod deserialize;
#[macro_use]
pub mod expression;
pub mod expression_methods;
#[doc(hidden)]
pub mod insertable;
pub mod query_builder;
pub mod query_dsl;
pub mod query_source;
#[cfg(feature = "r2d2")]
pub mod r2d2;
pub mod result;
pub mod serialize;
#[macro_use]
pub mod sql_types;
pub mod migration;
pub mod row;
pub mod types;

#[cfg(feature = "mysql")]
pub mod mysql;
#[cfg(feature = "postgres")]
pub mod pg;
#[cfg(feature = "sqlite")]
pub mod sqlite;

mod type_impls;
mod util;

pub mod dsl {
    //! Includes various helper types and bare functions which are named too
    //! generically to be included in prelude, but are often used when using Diesel.

    #[doc(inline)]
    pub use helper_types::*;

    #[doc(inline)]
    pub use expression::dsl::*;

    #[doc(inline)]
    pub use query_builder::functions::{delete, insert_into, insert_or_ignore_into, replace_into,
                                       select, sql_query, update};
}

pub mod helper_types {
    //! Provide helper types for concisely writing the return type of functions.
    //! As with iterators, it is unfortunately difficult to return a partially
    //! constructed query without exposing the exact implementation of the
    //! function. Without higher kinded types, these various DSLs can't be
    //! combined into a single trait for boxing purposes.
    //!
    //! All types here are in the form `<FirstType as
    //! DslName<OtherTypes>>::Output`. So the return type of
    //! `users.filter(first_name.eq("John")).order(last_name.asc()).limit(10)` would
    //! be `Limit<Order<FindBy<users, first_name, &str>, Asc<last_name>>>`
    use super::query_builder::locking_clause as lock;
    use super::query_dsl::methods::*;
    use super::query_dsl::*;
    use super::query_source::joins;

    #[doc(inline)]
    pub use expression::helper_types::*;

    /// Represents the return type of `.select(selection)`
    pub type Select<Source, Selection> = <Source as SelectDsl<Selection>>::Output;

    /// Represents the return type of `.filter(predicate)`
    pub type Filter<Source, Predicate> = <Source as FilterDsl<Predicate>>::Output;

    /// Represents the return type of `.filter(lhs.eq(rhs))`
    pub type FindBy<Source, Column, Value> = Filter<Source, Eq<Column, Value>>;

    /// Represents the return type of `.for_update()`
    #[cfg(feature = "with-deprecated")]
    #[allow(deprecated)]
    pub type ForUpdate<Source> = <Source as ForUpdateDsl>::Output;

    /// Represents the return type of `.for_update()`
    #[cfg(not(feature = "with-deprecated"))]
    pub type ForUpdate<Source> = <Source as LockingDsl<lock::ForUpdate>>::Output;

    /// Represents the return type of `.for_no_key_update()`
    pub type ForNoKeyUpdate<Source> = <Source as LockingDsl<lock::ForNoKeyUpdate>>::Output;

    /// Represents the return type of `.for_share()`
    pub type ForShare<Source> = <Source as LockingDsl<lock::ForShare>>::Output;

    /// Represents the return type of `.for_key_share()`
    pub type ForKeyShare<Source> = <Source as LockingDsl<lock::ForKeyShare>>::Output;

    /// Represents the return type of `.skip_locked()`
    pub type SkipLocked<Source> = <Source as ModifyLockDsl<lock::SkipLocked>>::Output;

    /// Represents the return type of `.no_wait()`
    pub type NoWait<Source> = <Source as ModifyLockDsl<lock::NoWait>>::Output;

    /// Represents the return type of `.find(pk)`
    pub type Find<Source, PK> = <Source as FindDsl<PK>>::Output;

    /// Represents the return type of `.or_filter(predicate)`
    pub type OrFilter<Source, Predicate> = <Source as OrFilterDsl<Predicate>>::Output;

    /// Represents the return type of `.order(ordering)`
    pub type Order<Source, Ordering> = <Source as OrderDsl<Ordering>>::Output;

    /// Represents the return type of `.then_order_by(ordering)`
    pub type ThenOrderBy<Source, Ordering> = <Source as ThenOrderDsl<Ordering>>::Output;

    /// Represents the return type of `.limit()`
    pub type Limit<Source> = <Source as LimitDsl>::Output;

    /// Represents the return type of `.offset()`
    pub type Offset<Source> = <Source as OffsetDsl>::Output;

    /// Represents the return type of `.inner_join(rhs)`
    pub type InnerJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::Inner>>::Output;

    /// Represents the return type of `.left_join(rhs)`
    pub type LeftJoin<Source, Rhs> =
        <Source as JoinWithImplicitOnClause<Rhs, joins::LeftOuter>>::Output;

    use super::associations::HasTable;
    use super::query_builder::{AsChangeset, IntoUpdateTarget, UpdateStatement};
    /// Represents the return type of `update(lhs).set(rhs)`
    pub type Update<Target, Changes> = UpdateStatement<
        <Target as HasTable>::Table,
        <Target as IntoUpdateTarget>::WhereClause,
        <Changes as AsChangeset>::Changeset,
    >;

    /// Represents the return type of `.into_boxed::<'a, DB>()`
    pub type IntoBoxed<'a, Source, DB> = <Source as BoxedDsl<'a, DB>>::Output;

    /// Represents the return type of `.distinct()`
    pub type Distinct<Source> = <Source as DistinctDsl>::Output;

    /// Represents the return type of `.distinct_on(expr)`
    #[cfg(feature = "postgres")]
    pub type DistinctOn<Source, Expr> = <Source as DistinctOnDsl<Expr>>::Output;

    /// Represents the return type of `.single_value()`
    pub type SingleValue<Source> = <Source as SingleValueDsl>::Output;
}

pub mod prelude {
    //! Re-exports important traits and types. Meant to be glob imported when using Diesel.
    pub use associations::{GroupedBy, Identifiable};
    pub use connection::Connection;
    #[deprecated(since = "1.1.0", note = "Explicitly `use diesel::deserialize::Queryable")]
    pub use deserialize::Queryable;
    pub use expression::{AppearsOnTable, BoxableExpression, Expression, IntoSql,
                         SelectableExpression};
    pub use expression_methods::*;
    #[doc(inline)]
    pub use insertable::Insertable;
    #[doc(hidden)]
    pub use query_dsl::GroupByDsl;
    pub use query_dsl::{BelongingToDsl, JoinOnDsl, QueryDsl, RunQueryDsl, SaveChangesDsl};

    pub use query_source::{Column, JoinTo, QuerySource, Table};
    pub use result::{ConnectionError, ConnectionResult, OptionalExtension, QueryResult};

    #[cfg(feature = "mysql")]
    pub use mysql::MysqlConnection;
    #[cfg(feature = "postgres")]
    pub use pg::PgConnection;
    #[cfg(feature = "sqlite")]
    pub use sqlite::SqliteConnection;
}

pub use prelude::*;
#[doc(inline)]
pub use query_builder::debug_query;
#[doc(inline)]
pub use query_builder::functions::{delete, insert_into, insert_or_ignore_into, replace_into,
                                   select, sql_query, update};
pub use result::Error::NotFound;

pub(crate) mod diesel {
    pub use super::*;
}
<|endoftext|>


<commit_before>extern crate rand;

use util::{TAU, PI};

pub enum Waveform {
    Sine,
    Sawtooth,
    Noise,
}

pub struct Oscillator {
    sample_rate: f32,
    phase: f32,
    waveform: Waveform,
    frequency: f32,
}

impl Oscillator {
    pub fn new(sample_rate: f32) -> Oscillator {
        Oscillator {
            phase: 0.0,
            sample_rate: sample_rate,
            waveform: Waveform::Sine,
            frequency: 440f32,
        }
    }

    pub fn tick(&mut self) {
        self.phase = (self.phase + TAU * self.frequency / self.sample_rate) % TAU;
    }

    pub fn sample(&self) -> f32 {
        match self.waveform {
            Waveform::Sine => self.phase.sin(),
            Waveform::Sawtooth => self.phase / PI - 1.0f32,
            Waveform::Noise => 2f32 * rand::random::<f32>() - 1f32,
        }
    }

    pub fn fill(&mut self, buffer: &mut[f32]) {
        for out_sample in buffer.iter_mut() {
            self.tick();
            *out_sample = self.sample();
        }
    }

    pub fn set_waveform(&mut self, waveform: Waveform) {
        self.waveform = waveform;
    }

    pub fn set_frequency(&mut self, freq: f32) {
        self.frequency = freq;
    }
}

impl Iterator for Oscillator {
    type Item = f32;

    fn next(&mut self) -> Option<f32> {
        self.tick();
        Some(self.sample())
    }
}
<commit_msg>add square wave<commit_after>extern crate rand;

use util::{TAU, PI};

pub enum Waveform {
    Sine,
    Sawtooth,
    Square,
    Noise,
}

pub struct Oscillator {
    sample_rate: f32,
    phase: f32,
    waveform: Waveform,
    frequency: f32,
}

impl Oscillator {
    pub fn new(sample_rate: f32) -> Oscillator {
        Oscillator {
            phase: 0.0,
            sample_rate: sample_rate,
            waveform: Waveform::Sine,
            frequency: 440f32,
        }
    }

    pub fn tick(&mut self) {
        self.phase = (self.phase + TAU * self.frequency / self.sample_rate) % TAU;
    }

    pub fn sample(&self) -> f32 {
        match self.waveform {
            Waveform::Sine => self.phase.sin(),
            Waveform::Sawtooth => self.phase / PI - 1.0f32,
            Waveform::Square => if self.phase < PI { -1f32 } else { 1f32 },
            Waveform::Noise => 2f32 * rand::random::<f32>() - 1f32,
        }
    }

    pub fn fill(&mut self, buffer: &mut[f32]) {
        for out_sample in buffer.iter_mut() {
            self.tick();
            *out_sample = self.sample();
        }
    }

    pub fn set_waveform(&mut self, waveform: Waveform) {
        self.waveform = waveform;
    }

    pub fn set_frequency(&mut self, freq: f32) {
        self.frequency = freq;
    }
}

impl Iterator for Oscillator {
    type Item = f32;

    fn next(&mut self) -> Option<f32> {
        self.tick();
        Some(self.sample())
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::{zero, one};
use std::num::{sqrt, atan2};

use array::*;

/// A 2-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec2<S> { x: S, y: S }

/// A 3-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec3<S> { x: S, y: S, z: S }

/// A 4-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec4<S> { x: S, y: S, z: S, w: S }

// Utility macro for generating associated functions for the vectors
macro_rules! vec(
    (impl $Self:ident <$S:ident> { $($field:ident),+ }) => (
        impl<$S: Clone + Num> $Self<$S> {
            #[inline]
            pub fn new($($field: $S),+) -> $Self<$S> {
                $Self { $($field: $field),+ }
            }

            /// Construct a vector from a single value.
            #[inline]
            pub fn from_value(value: $S) -> $Self<$S> {
                Array::build(|_| value.clone())
            }

            /// The additive identity of the vector.
            #[inline]
            pub fn zero() -> $Self<$S> { $Self::from_value(zero()) }

            /// The additive identity of the vector.
            #[inline]
            pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
        }
    )
)

vec!(impl Vec2<S> { x, y })
vec!(impl Vec3<S> { x, y, z })
vec!(impl Vec4<S> { x, y, z, w })

array!(impl<S> Vec2<S> -> [S, ..2])
array!(impl<S> Vec3<S> -> [S, ..3])
array!(impl<S> Vec4<S> -> [S, ..4])

/// A trait that specifies a range of numeric operations for vectors. Not all
/// of these make sense from a linear algebra point of view, but are included
/// for pragmatic reasons.
pub trait Vector
<
    S: Clone + Num,
    Slice
>
:   Array<S, Slice>
+   Neg<Self>
{
    // TODO: These method impls use iterators and higher order functions to
    // provide generic impls for vector types of different dimensions. We
    // need to check llvm's output to see how well it optimses these.

    #[inline] fn add_s(&self, s: S) -> Self { self.map(|x| x.add(&s)) }
    #[inline] fn sub_s(&self, s: S) -> Self { self.map(|x| x.sub(&s)) }
    #[inline] fn mul_s(&self, s: S) -> Self { self.map(|x| x.mul(&s)) }
    #[inline] fn div_s(&self, s: S) -> Self { self.map(|x| x.div(&s)) }
    #[inline] fn rem_s(&self, s: S) -> Self { self.map(|x| x.rem(&s)) }

    #[inline] fn add_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.add(b) ) }
    #[inline] fn sub_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.sub(b) ) }
    #[inline] fn mul_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.mul(b) ) }
    #[inline] fn div_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.div(b) ) }
    #[inline] fn rem_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.rem(b) ) }

    #[inline] fn neg_self(&mut self) { for x in self.mut_iter() { *x = x.neg() } }

    #[inline] fn add_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.add(&s) } }
    #[inline] fn sub_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.sub(&s) } }
    #[inline] fn mul_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.mul(&s) } }
    #[inline] fn div_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.div(&s) } }
    #[inline] fn rem_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.rem(&s) } }

    #[inline] fn add_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.add(b) } }
    #[inline] fn sub_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.sub(b) } }
    #[inline] fn mul_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.mul(b) } }
    #[inline] fn div_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.div(b) } }
    #[inline] fn rem_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.rem(b) } }

    /// Vector dot product.
    #[inline]
    fn dot(&self, other: &Self) -> S {
        self.iter().zip(other.iter())
            .map(|(a, b)| a.mul(b))
            .fold(zero::<S>(), |a, b| a.add(&b))
    }

    /// The sum of each component of the vector.
    #[inline] fn comp_add(&self) -> S { self.iter().fold(zero::<S>(), |a, b| a.add(b)) }

    /// The product of each component of the vector.
    #[inline] fn comp_mul(&self) -> S { self.iter().fold(one::<S>(),  |a, b| a.mul(b)) }
}

impl<S: Clone + Num> Neg<Vec2<S>> for Vec2<S> { #[inline] fn neg(&self) -> Vec2<S> { self.map(|x| x.neg()) } }
impl<S: Clone + Num> Neg<Vec3<S>> for Vec3<S> { #[inline] fn neg(&self) -> Vec3<S> { self.map(|x| x.neg()) } }
impl<S: Clone + Num> Neg<Vec4<S>> for Vec4<S> { #[inline] fn neg(&self) -> Vec4<S> { self.map(|x| x.neg()) } }

impl<S: Clone + Num> Vector<S, [S, ..2]> for Vec2<S>;
impl<S: Clone + Num> Vector<S, [S, ..3]> for Vec3<S>;
impl<S: Clone + Num> Vector<S, [S, ..4]> for Vec4<S>;

/// Operations specific to numeric two-dimensional vectors.
impl<S: Clone + Num> Vec2<S> {
    /// The perpendicular dot product of the vector and `other`.
    #[inline]
    pub fn perp_dot(&self, other: &Vec2<S>) -> S {
        (self.x * other.y) - (self.y * other.x)
    }
}

/// Operations specific to numeric three-dimensional vectors.
impl<S: Clone + Num> Vec3<S> {
    /// Returns the cross product of the vector and `other`.
    #[inline]
    pub fn cross(&self, other: &Vec3<S>) -> Vec3<S> {
        Vec3::new((self.y * other.z) - (self.z * other.y),
                  (self.z * other.x) - (self.x * other.z),
                  (self.x * other.y) - (self.y * other.x))
    }
}

/// Specifies geometric operations for vectors. This is only implemented for
/// 2-dimensional and 3-dimensional vectors.
pub trait EuclideanVector
<
    S: Clone + Real + ApproxEq<S>,
    Slice
>
:   Vector<S, Slice>
{
    /// Returns `true` if the vector is perpendicular (at right angles to)
    /// the other vector.
    fn is_perpendicular(&self, other: &Self) -> bool {
        self.dot(other).approx_eq(&zero())
    }

    /// Returns the squared length of the vector. This does not perform an
    /// expensive square root operation like in the `length` method and can
    /// therefore be more efficient for comparing the lengths of two vectors.
    #[inline]
    fn length2(&self) -> S {
        self.dot(self)
    }

    /// The norm of the vector.
    #[inline]
    fn length(&self) -> S {
        sqrt(self.dot(self))
    }

    /// The angle between the vector and `other`.
    fn angle(&self, other: &Self) -> S;

    /// Returns a vector with the same direction, but with a `length` (or
    /// `norm`) of `1`.
    #[inline]
    fn normalize(&self) -> Self {
        self.normalize_to(one::<S>())
    }

    /// Returns a vector with the same direction and a given `length`.
    #[inline]
    fn normalize_to(&self, length: S) -> Self {
        self.mul_s(length / self.length())
    }

    /// Returns the result of linarly interpolating the length of the vector
    /// to the length of `other` by the specified amount.
    #[inline]
    fn lerp(&self, other: &Self, amount: S) -> Self {
        self.add_v(&other.sub_v(self).mul_s(amount))
    }
}

impl<S: Clone + Real + ApproxEq<S>> EuclideanVector<S, [S, ..2]> for Vec2<S> {
    #[inline]
    fn angle(&self, other: &Vec2<S>) -> S {
        atan2(self.perp_dot(other), self.dot(other))
    }
}

impl<S: Clone + Real + ApproxEq<S>> EuclideanVector<S, [S, ..3]> for Vec3<S> {
    #[inline]
    fn angle(&self, other: &Vec3<S>) -> S {
        atan2(self.cross(other).length(), self.dot(other))
    }
}
<commit_msg>Use `Float` for trait bounds instead of `Real + ApproxEq<S>`<commit_after>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::{zero, one};
use std::num::{sqrt, atan2};

use array::*;

/// A 2-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec2<S> { x: S, y: S }

/// A 3-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec3<S> { x: S, y: S, z: S }

/// A 4-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec4<S> { x: S, y: S, z: S, w: S }

// Utility macro for generating associated functions for the vectors
macro_rules! vec(
    (impl $Self:ident <$S:ident> { $($field:ident),+ }) => (
        impl<$S: Clone + Num> $Self<$S> {
            #[inline]
            pub fn new($($field: $S),+) -> $Self<$S> {
                $Self { $($field: $field),+ }
            }

            /// Construct a vector from a single value.
            #[inline]
            pub fn from_value(value: $S) -> $Self<$S> {
                Array::build(|_| value.clone())
            }

            /// The additive identity of the vector.
            #[inline]
            pub fn zero() -> $Self<$S> { $Self::from_value(zero()) }

            /// The additive identity of the vector.
            #[inline]
            pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
        }
    )
)

vec!(impl Vec2<S> { x, y })
vec!(impl Vec3<S> { x, y, z })
vec!(impl Vec4<S> { x, y, z, w })

array!(impl<S> Vec2<S> -> [S, ..2])
array!(impl<S> Vec3<S> -> [S, ..3])
array!(impl<S> Vec4<S> -> [S, ..4])

/// A trait that specifies a range of numeric operations for vectors. Not all
/// of these make sense from a linear algebra point of view, but are included
/// for pragmatic reasons.
pub trait Vector
<
    S: Clone + Num,
    Slice
>
:   Array<S, Slice>
+   Neg<Self>
{
    // TODO: These method impls use iterators and higher order functions to
    // provide generic impls for vector types of different dimensions. We
    // need to check llvm's output to see how well it optimses these.

    #[inline] fn add_s(&self, s: S) -> Self { self.map(|x| x.add(&s)) }
    #[inline] fn sub_s(&self, s: S) -> Self { self.map(|x| x.sub(&s)) }
    #[inline] fn mul_s(&self, s: S) -> Self { self.map(|x| x.mul(&s)) }
    #[inline] fn div_s(&self, s: S) -> Self { self.map(|x| x.div(&s)) }
    #[inline] fn rem_s(&self, s: S) -> Self { self.map(|x| x.rem(&s)) }

    #[inline] fn add_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.add(b) ) }
    #[inline] fn sub_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.sub(b) ) }
    #[inline] fn mul_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.mul(b) ) }
    #[inline] fn div_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.div(b) ) }
    #[inline] fn rem_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.rem(b) ) }

    #[inline] fn neg_self(&mut self) { for x in self.mut_iter() { *x = x.neg() } }

    #[inline] fn add_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.add(&s) } }
    #[inline] fn sub_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.sub(&s) } }
    #[inline] fn mul_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.mul(&s) } }
    #[inline] fn div_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.div(&s) } }
    #[inline] fn rem_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.rem(&s) } }

    #[inline] fn add_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.add(b) } }
    #[inline] fn sub_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.sub(b) } }
    #[inline] fn mul_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.mul(b) } }
    #[inline] fn div_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.div(b) } }
    #[inline] fn rem_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.rem(b) } }

    /// Vector dot product.
    #[inline]
    fn dot(&self, other: &Self) -> S {
        self.iter().zip(other.iter())
            .map(|(a, b)| a.mul(b))
            .fold(zero::<S>(), |a, b| a.add(&b))
    }

    /// The sum of each component of the vector.
    #[inline] fn comp_add(&self) -> S { self.iter().fold(zero::<S>(), |a, b| a.add(b)) }

    /// The product of each component of the vector.
    #[inline] fn comp_mul(&self) -> S { self.iter().fold(one::<S>(),  |a, b| a.mul(b)) }
}

impl<S: Clone + Num> Neg<Vec2<S>> for Vec2<S> { #[inline] fn neg(&self) -> Vec2<S> { self.map(|x| x.neg()) } }
impl<S: Clone + Num> Neg<Vec3<S>> for Vec3<S> { #[inline] fn neg(&self) -> Vec3<S> { self.map(|x| x.neg()) } }
impl<S: Clone + Num> Neg<Vec4<S>> for Vec4<S> { #[inline] fn neg(&self) -> Vec4<S> { self.map(|x| x.neg()) } }

impl<S: Clone + Num> Vector<S, [S, ..2]> for Vec2<S>;
impl<S: Clone + Num> Vector<S, [S, ..3]> for Vec3<S>;
impl<S: Clone + Num> Vector<S, [S, ..4]> for Vec4<S>;

/// Operations specific to numeric two-dimensional vectors.
impl<S: Clone + Num> Vec2<S> {
    /// The perpendicular dot product of the vector and `other`.
    #[inline]
    pub fn perp_dot(&self, other: &Vec2<S>) -> S {
        (self.x * other.y) - (self.y * other.x)
    }
}

/// Operations specific to numeric three-dimensional vectors.
impl<S: Clone + Num> Vec3<S> {
    /// Returns the cross product of the vector and `other`.
    #[inline]
    pub fn cross(&self, other: &Vec3<S>) -> Vec3<S> {
        Vec3::new((self.y * other.z) - (self.z * other.y),
                  (self.z * other.x) - (self.x * other.z),
                  (self.x * other.y) - (self.y * other.x))
    }
}

/// Specifies geometric operations for vectors. This is only implemented for
/// 2-dimensional and 3-dimensional vectors.
pub trait EuclideanVector
<
    S: Clone + Float,
    Slice
>
:   Vector<S, Slice>
{
    /// Returns `true` if the vector is perpendicular (at right angles to)
    /// the other vector.
    fn is_perpendicular(&self, other: &Self) -> bool {
        self.dot(other).approx_eq(&zero())
    }

    /// Returns the squared length of the vector. This does not perform an
    /// expensive square root operation like in the `length` method and can
    /// therefore be more efficient for comparing the lengths of two vectors.
    #[inline]
    fn length2(&self) -> S {
        self.dot(self)
    }

    /// The norm of the vector.
    #[inline]
    fn length(&self) -> S {
        sqrt(self.dot(self))
    }

    /// The angle between the vector and `other`.
    fn angle(&self, other: &Self) -> S;

    /// Returns a vector with the same direction, but with a `length` (or
    /// `norm`) of `1`.
    #[inline]
    fn normalize(&self) -> Self {
        self.normalize_to(one::<S>())
    }

    /// Returns a vector with the same direction and a given `length`.
    #[inline]
    fn normalize_to(&self, length: S) -> Self {
        self.mul_s(length / self.length())
    }

    /// Returns the result of linarly interpolating the length of the vector
    /// to the length of `other` by the specified amount.
    #[inline]
    fn lerp(&self, other: &Self, amount: S) -> Self {
        self.add_v(&other.sub_v(self).mul_s(amount))
    }
}

impl<S: Clone + Float> EuclideanVector<S, [S, ..2]> for Vec2<S> {
    #[inline]
    fn angle(&self, other: &Vec2<S>) -> S {
        atan2(self.perp_dot(other), self.dot(other))
    }
}

impl<S: Clone + Float> EuclideanVector<S, [S, ..3]> for Vec3<S> {
    #[inline]
    fn angle(&self, other: &Vec3<S>) -> S {
        atan2(self.cross(other).length(), self.dot(other))
    }
}
<|endoftext|>


<commit_before>/// Character classes

use std::char;
use std::cmp::{min, max};

/// A range of codepoints.
type Range = (char, char);

/// A character class is a non-empty collection of ranges.
pub enum CharClass {
    priv CCOwned(~[Range]),
    priv CCStatic(&'static [Range])
}

impl CharClass {
    /// Create a class from a vector of ranges.
    pub fn new(mut r: ~[Range]) -> CharClass {
        if r.iter().any(|&(lo, hi)| lo > hi) {
            fail!("invalid range");
        }

        r.sort_by(|a, b| {
            // Sort by start value ascending, end value descending
            match a.lo().cmp(&b.lo()) {
                Equal => b.hi().cmp(&a.hi()),
                o => o
            }
        });

        if r.len() > 0 {
            // Coalesce overlapping ranges in place
            let mut cursor = 0;
            for i in range(1, r.len()) {
                if r[cursor].hi() == char::MAX {
                    break
                } else if r[i].lo() <= next_char(r[cursor].hi()) {
                    // Merge the two ranges
                    r[cursor] = (
                        min(r[cursor].lo(), r[i].lo()),
                        max(r[cursor].hi(), r[i].hi()));
                } else {
                    cursor = i;
                }
            }
            r.truncate(cursor + 1); r.shrink_to_fit();
            CCOwned(r)
        } else {
            fail!("char class cannot be empty")
        }
    }

    /// Create a class matching a single code point.
    pub fn from_char(c: char) -> CharClass {
        CharClass::new(~[(c, c)])
    }

    ///
    /// Get the list of ranges contained in the character class.
    ///
    /// The returned vector is always sorted, with no overlapping
    /// ranges.
    ///
    pub fn ranges<'a>(&'a self) -> &'a [Range] {
        match *self {
            CCOwned(ref r) => {
                let r_borrow: &'a [Range] = *r;
                r_borrow
            },
            CCStatic(r) => {
                let r_borrow: &'a [Range] = r;
                r_borrow
            }
        }
    }

    /// Determine if the character is contained in the class.
    pub fn includes(&self, c: char) -> bool {
        self.ranges().bsearch(|&(lo, hi)| {
            if c < lo {
                Greater
            } else if hi < c {
                Less
            } else {
                Equal
            }
        }).is_some()
    }

    /// Return the negation of the character class.
    pub fn negate(&self) -> CharClass {
        let ranges = self.ranges();
        let mut result: ~[Range] = ~[];

        let first_lo = ranges[0].lo();
        if first_lo != '\0' {
            result.push(('\0', prev_char(first_lo)));
        }

        let mut last_hi = ranges[0].hi();
        for &(lo, hi) in ranges.slice_from(1).iter() {
            result.push((next_char(last_hi), prev_char(lo)));
            last_hi = hi;
        }

        if last_hi != char::MAX {
            result.push((next_char(last_hi), char::MAX));
        }

        CCOwned(result)
    }
}

trait RangeUtils {
    fn lo(&self) -> char;
    fn hi(&self) -> char;
}

impl RangeUtils for (char, char) {
    #[inline]
    fn lo(&self) -> char {
        let &(lo, _) = self;
        lo
    }

    #[inline]
    fn hi(&self) -> char {
        let &(_, hi) = self;
        hi
    }
}

#[inline]
fn prev_char(c: char) -> char {
    char::from_u32(c as u32 - 1).unwrap()
}

#[inline]
fn next_char(c: char) -> char {
    char::from_u32(c as u32 + 1).unwrap()
}

#[cfg(test)]
mod test {
    use std::char;
    use super::CharClass;

    #[test]
    #[should_fail]
    fn invalid_range() {
        let _ = CharClass::new(~[('b', 'a')]);
    }

    #[test]
    #[should_fail]
    fn empty_class() {
        let _ = CharClass::new(~[]);
    }

    #[test]
    fn class_sorted() {
        let c = CharClass::new(~[('y', 'z'), ('a', 'b')]);
        assert_eq!(c.ranges(), [('a', 'b'), ('y', 'z')]);
    }

    #[test]
    fn class_optimize() {
        let c = CharClass::new(~[('a', 'b'), ('c', 'd')]);
        assert_eq!(c.ranges(), [('a', 'd')]);
    }

    #[test]
    fn class_includes() {
        let c = CharClass::new(~[('a', 'b'), ('i', 'j'), ('y', 'z')]);
        assert!(c.includes('b'));
        assert!(c.includes('y'));
    }

    #[test]
    fn negate_simple() {
        let c = CharClass::new(~[('T', 's'), ('☻', '♪')]).negate();
        assert_eq!(c.ranges(), [('\0', 'S'), ('t', '☺'), ('♫', char::MAX)]);
    }

    #[test]
    fn negate_edge_case() {
        let c = CharClass::new(~[('\0', char::MAX)]).negate();
        assert_eq!(c.ranges(), []);
    }
}

pub mod ascii;
<commit_msg>Add more char class tests<commit_after>/// Character classes

use std::char;
use std::cmp::{min, max};

/// A range of codepoints.
type Range = (char, char);

/// A character class is a non-empty collection of ranges.
pub enum CharClass {
    priv CCOwned(~[Range]),
    priv CCStatic(&'static [Range])
}

impl CharClass {
    /// Create a class from a vector of ranges.
    pub fn new(mut r: ~[Range]) -> CharClass {
        if r.iter().any(|&(lo, hi)| lo > hi) {
            fail!("invalid range");
        }

        r.sort_by(|a, b| {
            // Sort by start value ascending, end value descending
            match a.lo().cmp(&b.lo()) {
                Equal => b.hi().cmp(&a.hi()),
                o => o
            }
        });

        if r.len() > 0 {
            // Coalesce overlapping ranges in place
            let mut cursor = 0;
            for i in range(1, r.len()) {
                if r[cursor].hi() == char::MAX {
                    break
                } else if r[i].lo() <= next_char(r[cursor].hi()) {
                    // Merge the two ranges
                    r[cursor] = (
                        min(r[cursor].lo(), r[i].lo()),
                        max(r[cursor].hi(), r[i].hi()));
                } else {
                    cursor = i;
                }
            }
            r.truncate(cursor + 1); r.shrink_to_fit();
            CCOwned(r)
        } else {
            fail!("char class cannot be empty")
        }
    }

    /// Create a class matching a single code point.
    pub fn from_char(c: char) -> CharClass {
        CharClass::new(~[(c, c)])
    }

    ///
    /// Get the list of ranges contained in the character class.
    ///
    /// The returned vector is always sorted, with no overlapping
    /// ranges.
    ///
    pub fn ranges<'a>(&'a self) -> &'a [Range] {
        match *self {
            CCOwned(ref r) => {
                let r_borrow: &'a [Range] = *r;
                r_borrow
            },
            CCStatic(r) => {
                let r_borrow: &'a [Range] = r;
                r_borrow
            }
        }
    }

    /// Determine if the character is contained in the class.
    pub fn includes(&self, c: char) -> bool {
        self.ranges().bsearch(|&(lo, hi)| {
            if c < lo {
                Greater
            } else if hi < c {
                Less
            } else {
                Equal
            }
        }).is_some()
    }

    /// Return the negation of the character class.
    pub fn negate(&self) -> CharClass {
        let ranges = self.ranges();
        let mut result: ~[Range] = ~[];

        let first_lo = ranges[0].lo();
        if first_lo != '\0' {
            result.push(('\0', prev_char(first_lo)));
        }

        let mut last_hi = ranges[0].hi();
        for &(lo, hi) in ranges.slice_from(1).iter() {
            result.push((next_char(last_hi), prev_char(lo)));
            last_hi = hi;
        }

        if last_hi != char::MAX {
            result.push((next_char(last_hi), char::MAX));
        }

        CCOwned(result)
    }
}

trait RangeUtils {
    fn lo(&self) -> char;
    fn hi(&self) -> char;
}

impl RangeUtils for (char, char) {
    #[inline]
    fn lo(&self) -> char {
        let &(lo, _) = self;
        lo
    }

    #[inline]
    fn hi(&self) -> char {
        let &(_, hi) = self;
        hi
    }
}

#[inline]
fn prev_char(c: char) -> char {
    char::from_u32(c as u32 - 1).unwrap()
}

#[inline]
fn next_char(c: char) -> char {
    char::from_u32(c as u32 + 1).unwrap()
}

#[cfg(test)]
mod test {
    use std::char;
    use super::CharClass;

    #[test]
    #[should_fail]
    fn invalid_range() {
        let _ = CharClass::new(~[('b', 'a')]);
    }

    #[test]
    #[should_fail]
    fn empty_class() {
        let _ = CharClass::new(~[]);
    }

    #[test]
    fn class_sorted() {
        let c = CharClass::new(~[('y', 'z'), ('a', 'b')]);
        assert_eq!(c.ranges(), [('a', 'b'), ('y', 'z')]);
    }

    #[test]
    fn class_optimize() {
        let c1 = CharClass::new(~[('a', 'b'), ('c', 'd')]);  // touching
        let c2 = CharClass::new(~[('a', 'c'), ('b', 'd')]);  // overlapping
        let c3 = CharClass::new(~[('a', 'd'), ('b', 'c')]);  // contained
        assert_eq!(c1.ranges(), [('a', 'd')]);
        assert_eq!(c2.ranges(), [('a', 'd')]);
        assert_eq!(c3.ranges(), [('a', 'd')]);
    }

    #[test]
    fn class_includes() {
        // This will fail if the bsearch is incorrect
        let c = CharClass::new(~[('a', 'b'), ('i', 'j'), ('y', 'z')]);
        assert!(c.includes('b'));
        assert!(c.includes('y'));
    }

    #[test]
    fn negate_simple() {
        let c = CharClass::new(~[('T', 's'), ('☻', '♪')]).negate();
        assert_eq!(c.ranges(), [('\0', 'S'), ('t', '☺'), ('♫', char::MAX)]);
    }

    #[test]
    fn negate_edge_case() {
        let c = CharClass::new(~[('\0', char::MAX)]).negate();
        assert_eq!(c.ranges(), []);
    }
}

pub mod ascii;
<|endoftext|>