<commit_before>/// For types which have adjacent values.
pub trait AdjacentBound: Ord {
    /// Determines whether `self` and `other` are adjacent.
    fn is_adjacent(&self, other: &Self) -> bool {
        self.is_immediately_before(other) || self.is_immediately_after(other)
    }

    /// Determines whether `self` is immediately before `other`.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert!(5u32.is_immediately_before(&6));
    /// assert_eq!(5u32.is_immediately_before(&7), false);
    /// ```
    fn is_immediately_before(&self, other: &Self) -> bool;

    /// Determines whether `self` is immediately after `other`.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert!(6u32.is_immediately_after(&5));
    /// assert_eq!(7u32.is_immediately_after(&5), false);
    /// ```
    fn is_immediately_after(&self, other: &Self) -> bool;

    /// Returns a new value which is `self` incremented.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert_eq!(6u32.increment(), 7);
    /// ```
    fn increment(&self) -> Self;

    /// Returns a new value which is `self` decremented.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert_eq!(6u32.decrement(), 5);
    /// ```
    fn decrement(&self) -> Self;

    /// Increments `self` in place.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// let mut value = 6u32;
    /// value.increment_ref();
    /// assert_eq!(value, 7);
    /// ```
    fn increment_ref(&mut self);

    /// Decrements `self` in place.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// let mut value = 6u32;
    /// value.decrement_ref();
    /// assert_eq!(value, 5);
    /// ```
    fn decrement_ref(&mut self);
}

/// Implements `AdjacentBound` for a type using the specified value to
/// represent an increment of "one".
///
/// For numeric types $one should be 1, however for other types this
/// will be up the implementor, for dates $one may be a single day.
#[macro_export]
macro_rules! adjacent_bound_impl {
    ($type:ty, $one:expr) => {
        impl ::AdjacentBound for $type {
            fn is_immediately_before(&self, other: &Self) -> bool {
                *self == (*other - $one)
            }

            fn is_immediately_after(&self, other: &Self) -> bool {
                *self == (*other + $one)
            }

            fn increment(&self) -> Self {
                *self + $one
            }

            fn decrement(&self) -> Self {
                *self - $one
            }

            fn increment_ref(&mut self) {
                *self = *self + $one;
            }

            fn decrement_ref(&mut self) {
                *self = *self - $one;
            }
        }
    }
}

macro_rules! adjacent_bound_impl_and_wrapping {
    ($type:ty, $one:expr) => {
        adjacent_bound_impl!($type, $one);
        adjacent_bound_impl!(::std::num::Wrapping<$type>, ::std::num::Wrapping($one));
    }
}

adjacent_bound_impl_and_wrapping!(u8, 1u8);
adjacent_bound_impl_and_wrapping!(i8, 1i8);

adjacent_bound_impl_and_wrapping!(u16, 1u16);
adjacent_bound_impl_and_wrapping!(i16, 1i16);

adjacent_bound_impl_and_wrapping!(u32, 1u32);
adjacent_bound_impl_and_wrapping!(i32, 1i32);

adjacent_bound_impl_and_wrapping!(u64, 1u64);
adjacent_bound_impl_and_wrapping!(i64, 1i64);

adjacent_bound_impl_and_wrapping!(usize, 1usize);
adjacent_bound_impl_and_wrapping!(isize, 1isize);

#[cfg(test)]
mod tests {
    use std::num::Wrapping;
    use AdjacentBound;

    #[test]
    fn overflow_wrapping_tests() {
        assert!(Wrapping(u32::max_value()).is_immediately_before(&Wrapping(0)));
        assert!(Wrapping(0).is_immediately_after(&Wrapping(u32::max_value())));
    }
}

#[cfg(feature = "chrono")]
mod chrono_impl {
    use chrono::{Date, DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime,
                 NaiveTime, Utc};

    adjacent_bound_impl!(NaiveDate, Duration::days(1));
    adjacent_bound_impl!(NaiveDateTime, Duration::min_value());
    adjacent_bound_impl!(NaiveTime, Duration::min_value());

    adjacent_bound_impl!(Date<Utc>, Duration::days(1));
    adjacent_bound_impl!(Date<FixedOffset>, Duration::days(1));
    adjacent_bound_impl!(Date<Local>, Duration::days(1));

    adjacent_bound_impl!(DateTime<Utc>, Duration::min_value());
    adjacent_bound_impl!(DateTime<FixedOffset>, Duration::min_value());
    adjacent_bound_impl!(DateTime<Local>, Duration::min_value());

}

#[cfg(feature = "chrono")]
pub use self::chrono_impl::*;

#[cfg(feature = "extprim")]
mod extprim_impl {
    use extprim::i128::i128;
    use extprim::u128::u128;

    adjacent_bound_impl!(i128, i128::one());
    adjacent_bound_impl!(u128, u128::one());
}

#[cfg(feature = "extprim")]
pub use self::extprim_impl::*;

#[cfg(feature = "nightly")]
mod nightly_impl {
    adjacent_bound_impl_and_wrapping!(u128, 1u128);
    adjacent_bound_impl_and_wrapping!(i128, 1i128);
}

#[cfg(feature = "nightly")]
pub use self::nightly_impl::*;
<commit_msg>adjacent_bound_impl now works for all Cloneable types<commit_after>/// For types which have adjacent values.
pub trait AdjacentBound: Ord {
    /// Determines whether `self` and `other` are adjacent.
    fn is_adjacent(&self, other: &Self) -> bool {
        self.is_immediately_before(other) || self.is_immediately_after(other)
    }

    /// Determines whether `self` is immediately before `other`.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert!(5u32.is_immediately_before(&6));
    /// assert_eq!(5u32.is_immediately_before(&7), false);
    /// ```
    fn is_immediately_before(&self, other: &Self) -> bool;

    /// Determines whether `self` is immediately after `other`.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert!(6u32.is_immediately_after(&5));
    /// assert_eq!(7u32.is_immediately_after(&5), false);
    /// ```
    fn is_immediately_after(&self, other: &Self) -> bool;

    /// Returns a new value which is `self` incremented.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert_eq!(6u32.increment(), 7);
    /// ```
    fn increment(&self) -> Self;

    /// Returns a new value which is `self` decremented.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// assert_eq!(6u32.decrement(), 5);
    /// ```
    fn decrement(&self) -> Self;

    /// Increments `self` in place.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// let mut value = 6u32;
    /// value.increment_ref();
    /// assert_eq!(value, 7);
    /// ```
    fn increment_ref(&mut self);

    /// Decrements `self` in place.
    ///
    /// ```
    /// use lz_diet::AdjacentBound;
    ///
    /// let mut value = 6u32;
    /// value.decrement_ref();
    /// assert_eq!(value, 5);
    /// ```
    fn decrement_ref(&mut self);
}

/// Implements `AdjacentBound` for a type using the specified value to
/// represent an increment of "one".
///
/// For numeric types $one should be 1, however for other types this
/// will be up the implementor, for dates $one may be a single day.
#[macro_export]
macro_rules! adjacent_bound_impl {
    ($type:ty, $one:expr) => {
        impl ::AdjacentBound for $type {
            fn is_immediately_before(&self, other: &Self) -> bool {
                *self == other.decrement()
            }

            fn is_immediately_after(&self, other: &Self) -> bool {
                *self == other.increment()
            }

            fn increment(&self) -> Self {
                self.to_owned() + $one
            }

            fn decrement(&self) -> Self {
                self.to_owned() - $one
            }

            fn increment_ref(&mut self) {
                *self = self.increment();
            }

            fn decrement_ref(&mut self) {
                *self = self.decrement();
            }
        }
    }
}

macro_rules! adjacent_bound_impl_and_wrapping {
    ($type:ty, $one:expr) => {
        adjacent_bound_impl!($type, $one);
        adjacent_bound_impl!(::std::num::Wrapping<$type>, ::std::num::Wrapping($one));
    }
}

adjacent_bound_impl_and_wrapping!(u8, 1u8);
adjacent_bound_impl_and_wrapping!(i8, 1i8);

adjacent_bound_impl_and_wrapping!(u16, 1u16);
adjacent_bound_impl_and_wrapping!(i16, 1i16);

adjacent_bound_impl_and_wrapping!(u32, 1u32);
adjacent_bound_impl_and_wrapping!(i32, 1i32);

adjacent_bound_impl_and_wrapping!(u64, 1u64);
adjacent_bound_impl_and_wrapping!(i64, 1i64);

adjacent_bound_impl_and_wrapping!(usize, 1usize);
adjacent_bound_impl_and_wrapping!(isize, 1isize);

#[cfg(test)]
mod tests {
    use std::num::Wrapping;
    use AdjacentBound;

    #[test]
    fn overflow_wrapping_tests() {
        assert!(Wrapping(u32::max_value()).is_immediately_before(&Wrapping(0)));
        assert!(Wrapping(0).is_immediately_after(&Wrapping(u32::max_value())));
    }
}

#[cfg(feature = "chrono")]
mod chrono_impl {
    use chrono::{Date, DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime,
                 NaiveTime, Utc};

    adjacent_bound_impl!(NaiveDate, Duration::days(1));
    adjacent_bound_impl!(NaiveDateTime, Duration::min_value());
    adjacent_bound_impl!(NaiveTime, Duration::min_value());

    adjacent_bound_impl!(Date<Utc>, Duration::days(1));
    adjacent_bound_impl!(Date<FixedOffset>, Duration::days(1));
    adjacent_bound_impl!(Date<Local>, Duration::days(1));

    adjacent_bound_impl!(DateTime<Utc>, Duration::min_value());
    adjacent_bound_impl!(DateTime<FixedOffset>, Duration::min_value());
    adjacent_bound_impl!(DateTime<Local>, Duration::min_value());

}

#[cfg(feature = "chrono")]
pub use self::chrono_impl::*;

#[cfg(feature = "extprim")]
mod extprim_impl {
    use extprim::i128::i128;
    use extprim::u128::u128;

    adjacent_bound_impl!(i128, i128::one());
    adjacent_bound_impl!(u128, u128::one());
}

#[cfg(feature = "extprim")]
pub use self::extprim_impl::*;

#[cfg(feature = "nightly")]
mod nightly_impl {
    adjacent_bound_impl_and_wrapping!(u128, 1u128);
    adjacent_bound_impl_and_wrapping!(i128, 1i128);
}

#[cfg(feature = "nightly")]
pub use self::nightly_impl::*;
<|endoftext|>


<commit_before>use mio_uds::UnixStream;
use mio::{Poll,Ready};
use libc::{self,c_char,uint32_t,int32_t,pid_t};
use std::io;
use std::ffi::CString;
use std::iter::repeat;
use std::ptr::null_mut;
use std::process::Command;
use std::net::ToSocketAddrs;
use std::os::unix::process::CommandExt;
use std::os::unix::io::{AsRawFd,FromRawFd};
use nix;
use nix::unistd::*;
use nix::fcntl::{fcntl,FcntlArg,FdFlag,FD_CLOEXEC};

use sozu_command::config::Config;
use sozu_command::channel::Channel;
use sozu::network::session::Session;
use sozu_command::messages::{OrderMessage,OrderMessageAnswer};
use sozu::network::{http,tls};
use sozu::network::proxy::Server;

use logging;
use command::Worker;

pub fn start_workers(config: &Config) -> nix::Result<Vec<Worker>> {
  let mut workers = Vec::new();
  for index in 0..config.worker_count {
    match start_worker_process(&index.to_string(), config) {
      Ok((pid, command)) => {
        let w =  Worker::new(index as u32, pid, command, config);
        workers.push(w);
      },
      Err(e) => return Err(e)
    };
  }
  Ok(workers)
}

pub fn start_worker(id: u32, config: &Config) -> nix::Result<Worker> {
  match start_worker_process(&id.to_string(), config) {
    Ok((pid, command)) => {
      let w = Worker::new(id, pid, command, config);
      Ok(w)
    },
    Err(e) => Err(e)
  }
}

fn generate_channels() -> io::Result<(Channel<OrderMessage,OrderMessageAnswer>, Channel<OrderMessageAnswer,OrderMessage>)> {
  let (command,proxy) = try!(UnixStream::pair());
  //FIXME: configurable buffer size
  let proxy_channel   = Channel::new(proxy, 1_000_000, 2_000_000);
  let command_channel = Channel::new(command, 1_000_000, 2_000_000);
  Ok((command_channel, proxy_channel))
}

pub fn begin_worker_process(fd: i32, id: i32, channel_buffer_size: usize) {
  let mut command: Channel<OrderMessageAnswer,Config> = Channel::new(
    unsafe { UnixStream::from_raw_fd(fd) },
    channel_buffer_size,
    channel_buffer_size * 2
  );

  command.set_nonblocking(false);

  let proxy_config = command.read_message().expect("worker could not read configuration from socket");
  //println!("got message: {:?}", proxy_config);

  logging::setup(format!("{}-{:02}", "WRK", id), &proxy_config.log_level, &proxy_config.log_target);
  info!("worker {} starting...", id);

  command.set_nonblocking(true);
  let mut command: Channel<OrderMessageAnswer,OrderMessage> = command.into();

  if let Some(ref metrics) = proxy_config.metrics.as_ref() {
    metrics_set_up!(&metrics.address[..], metrics.port);
    gauge!("sozu.worker.TEST", 42);
  }

  let mut event_loop  = Poll::new().expect("could not create event loop");

  let http_session = proxy_config.http.and_then(|conf| conf.to_http()).and_then(|http_conf| {
    let max_connections = http_conf.max_connections;
    let max_listeners = 1;
    http::ServerConfiguration::new(http_conf, &mut event_loop, 1 + max_listeners).map(|configuration| {
      Session::new(1, max_connections, 0, configuration, &mut event_loop)
    }).ok()
  });

  let https_session = proxy_config.https.and_then(|conf| conf.to_tls()).and_then(|https_conf| {
    let max_connections = https_conf.max_connections;
    let max_listeners   = 1;
    tls::ServerConfiguration::new(https_conf, 6148914691236517205, &mut event_loop, 1 + max_listeners + 6148914691236517205).map(|configuration| {
      Session::new(max_listeners, max_connections, 6148914691236517205, configuration, &mut event_loop)
    }).ok()
  });
  //TODO: implement for TCP

  command.readiness.insert(Ready::readable());
  let mut server = Server::new(event_loop, command, http_session, https_session, None);
  info!("{} starting event loop", id);
  server.run();
  info!("{} ending event loop", id);
}

pub fn start_worker_process(id: &str, config: &Config) -> nix::Result<(pid_t, Channel<OrderMessage,OrderMessageAnswer>)> {
  trace!("parent({})", unsafe { libc::getpid() });

  let (server, client) = UnixStream::pair().unwrap();

  // FD_CLOEXEC is set by default on every fd in Rust standard lib,
  // so we need to remove the flag on the client, otherwise
  // it won't be accessible
  let cl_flags = fcntl(client.as_raw_fd(), FcntlArg::F_GETFD).unwrap();
  let mut new_cl_flags = FdFlag::from_bits(cl_flags).unwrap();
  new_cl_flags.remove(FD_CLOEXEC);
  fcntl(client.as_raw_fd(), FcntlArg::F_SETFD(new_cl_flags));

  let channel_buffer_size = config.channel_buffer_size;
  //FIXME
  let channel_max_buffer_size = config.channel_buffer_size * 2;

  let mut command: Channel<Config,OrderMessageAnswer> = Channel::new(
    server,
    channel_buffer_size,
    channel_max_buffer_size
  );
  command.set_nonblocking(false);

  let path = unsafe { get_executable_path() };

  info!("{} launching worker", id);
  debug!("executable path is {}", path);
  match fork() {
    Ok(ForkResult::Parent{ child }) => {
      info!("{} worker launched: {}", id, child);
      command.write_message(config);
      command.set_nonblocking(true);

      let command: Channel<OrderMessage,OrderMessageAnswer> = command.into();
      Ok((child, command))
    },
    Ok(ForkResult::Child) => {
      trace!("child({}):\twill spawn a child", unsafe { libc::getpid() });
      Command::new(path)
        .arg("worker")
        .arg("--fd")
        .arg(client.as_raw_fd().to_string())
        .arg("--id")
        .arg(id)
        .arg("--channel-buffer-size")
        .arg(channel_buffer_size.to_string())
        .exec();

      unreachable!();
    },
    Err(e) => {
      error!("Error during fork(): {}", e);
      Err(e)
    }
  }
}

#[cfg(target_os = "linux")]
pub unsafe fn get_executable_path() -> String {
  let path         = fs::read_link("/proc/self/exe").expect("/proc/self/exe doesn't exist");
  let mut path_str = path.into_os_string().into_string().expect("Failed to convert PathBuf to String");

  if path_str.ends_with(" (deleted)") {
    // The kernel appends " (deleted)" to the symlink when the original executable has been replaced
    let len = path_str.len();
    path_str.truncate(len - 10)
  }

  path_str
}

#[cfg(target_os = "macos")]
extern {
  pub fn _NSGetExecutablePath(buf: *mut c_char, size: *mut uint32_t) -> int32_t;
}

#[cfg(target_os = "macos")]
pub unsafe fn get_executable_path() -> String {
  let capacity = 2000;
  let mut temp:Vec<u8> = Vec::with_capacity(capacity);
  temp.extend(repeat(0).take(capacity));
  let pathbuf = CString::from_vec_unchecked(temp);
  let ptr = pathbuf.into_raw();

  let mut size:uint32_t = capacity as u32;
  if _NSGetExecutablePath(ptr, &mut size) == 0 {

    let mut temp2:Vec<u8> = Vec::with_capacity(capacity);
    temp2.extend(repeat(0).take(capacity));
    let pathbuf2 = CString::from_vec_unchecked(temp2);
    let ptr2 = pathbuf2.into_raw();

    if libc::realpath(ptr, ptr2) != null_mut() {
      let path = CString::from_raw(ptr2);
      path.to_str().expect("failed to convert CString to String").to_string()
    } else {
      panic!();
    }
  } else {
    panic!("buffer too small");
  }
}
<commit_msg>add missing import for linux<commit_after>use mio_uds::UnixStream;
use mio::{Poll,Ready};
use libc::{self,c_char,uint32_t,int32_t,pid_t};
use std::io;
use std::ffi::CString;
use std::iter::repeat;
use std::ptr::null_mut;
use std::process::Command;
use std::net::ToSocketAddrs;
use std::os::unix::process::CommandExt;
use std::os::unix::io::{AsRawFd,FromRawFd};
use nix;
use nix::unistd::*;
use nix::fcntl::{fcntl,FcntlArg,FdFlag,FD_CLOEXEC};

use sozu_command::config::Config;
use sozu_command::channel::Channel;
use sozu::network::session::Session;
use sozu_command::messages::{OrderMessage,OrderMessageAnswer};
use sozu::network::{http,tls};
use sozu::network::proxy::Server;

use logging;
use command::Worker;

pub fn start_workers(config: &Config) -> nix::Result<Vec<Worker>> {
  let mut workers = Vec::new();
  for index in 0..config.worker_count {
    match start_worker_process(&index.to_string(), config) {
      Ok((pid, command)) => {
        let w =  Worker::new(index as u32, pid, command, config);
        workers.push(w);
      },
      Err(e) => return Err(e)
    };
  }
  Ok(workers)
}

pub fn start_worker(id: u32, config: &Config) -> nix::Result<Worker> {
  match start_worker_process(&id.to_string(), config) {
    Ok((pid, command)) => {
      let w = Worker::new(id, pid, command, config);
      Ok(w)
    },
    Err(e) => Err(e)
  }
}

fn generate_channels() -> io::Result<(Channel<OrderMessage,OrderMessageAnswer>, Channel<OrderMessageAnswer,OrderMessage>)> {
  let (command,proxy) = try!(UnixStream::pair());
  //FIXME: configurable buffer size
  let proxy_channel   = Channel::new(proxy, 1_000_000, 2_000_000);
  let command_channel = Channel::new(command, 1_000_000, 2_000_000);
  Ok((command_channel, proxy_channel))
}

pub fn begin_worker_process(fd: i32, id: i32, channel_buffer_size: usize) {
  let mut command: Channel<OrderMessageAnswer,Config> = Channel::new(
    unsafe { UnixStream::from_raw_fd(fd) },
    channel_buffer_size,
    channel_buffer_size * 2
  );

  command.set_nonblocking(false);

  let proxy_config = command.read_message().expect("worker could not read configuration from socket");
  //println!("got message: {:?}", proxy_config);

  logging::setup(format!("{}-{:02}", "WRK", id), &proxy_config.log_level, &proxy_config.log_target);
  info!("worker {} starting...", id);

  command.set_nonblocking(true);
  let mut command: Channel<OrderMessageAnswer,OrderMessage> = command.into();

  if let Some(ref metrics) = proxy_config.metrics.as_ref() {
    metrics_set_up!(&metrics.address[..], metrics.port);
    gauge!("sozu.worker.TEST", 42);
  }

  let mut event_loop  = Poll::new().expect("could not create event loop");

  let http_session = proxy_config.http.and_then(|conf| conf.to_http()).and_then(|http_conf| {
    let max_connections = http_conf.max_connections;
    let max_listeners = 1;
    http::ServerConfiguration::new(http_conf, &mut event_loop, 1 + max_listeners).map(|configuration| {
      Session::new(1, max_connections, 0, configuration, &mut event_loop)
    }).ok()
  });

  let https_session = proxy_config.https.and_then(|conf| conf.to_tls()).and_then(|https_conf| {
    let max_connections = https_conf.max_connections;
    let max_listeners   = 1;
    tls::ServerConfiguration::new(https_conf, 6148914691236517205, &mut event_loop, 1 + max_listeners + 6148914691236517205).map(|configuration| {
      Session::new(max_listeners, max_connections, 6148914691236517205, configuration, &mut event_loop)
    }).ok()
  });
  //TODO: implement for TCP

  command.readiness.insert(Ready::readable());
  let mut server = Server::new(event_loop, command, http_session, https_session, None);
  info!("{} starting event loop", id);
  server.run();
  info!("{} ending event loop", id);
}

pub fn start_worker_process(id: &str, config: &Config) -> nix::Result<(pid_t, Channel<OrderMessage,OrderMessageAnswer>)> {
  trace!("parent({})", unsafe { libc::getpid() });

  let (server, client) = UnixStream::pair().unwrap();

  // FD_CLOEXEC is set by default on every fd in Rust standard lib,
  // so we need to remove the flag on the client, otherwise
  // it won't be accessible
  let cl_flags = fcntl(client.as_raw_fd(), FcntlArg::F_GETFD).unwrap();
  let mut new_cl_flags = FdFlag::from_bits(cl_flags).unwrap();
  new_cl_flags.remove(FD_CLOEXEC);
  fcntl(client.as_raw_fd(), FcntlArg::F_SETFD(new_cl_flags));

  let channel_buffer_size = config.channel_buffer_size;
  //FIXME
  let channel_max_buffer_size = config.channel_buffer_size * 2;

  let mut command: Channel<Config,OrderMessageAnswer> = Channel::new(
    server,
    channel_buffer_size,
    channel_max_buffer_size
  );
  command.set_nonblocking(false);

  let path = unsafe { get_executable_path() };

  info!("{} launching worker", id);
  debug!("executable path is {}", path);
  match fork() {
    Ok(ForkResult::Parent{ child }) => {
      info!("{} worker launched: {}", id, child);
      command.write_message(config);
      command.set_nonblocking(true);

      let command: Channel<OrderMessage,OrderMessageAnswer> = command.into();
      Ok((child, command))
    },
    Ok(ForkResult::Child) => {
      trace!("child({}):\twill spawn a child", unsafe { libc::getpid() });
      Command::new(path)
        .arg("worker")
        .arg("--fd")
        .arg(client.as_raw_fd().to_string())
        .arg("--id")
        .arg(id)
        .arg("--channel-buffer-size")
        .arg(channel_buffer_size.to_string())
        .exec();

      unreachable!();
    },
    Err(e) => {
      error!("Error during fork(): {}", e);
      Err(e)
    }
  }
}

#[cfg(target_os = "linux")]
pub unsafe fn get_executable_path() -> String {
  use std::fs;

  let path         = fs::read_link("/proc/self/exe").expect("/proc/self/exe doesn't exist");
  let mut path_str = path.into_os_string().into_string().expect("Failed to convert PathBuf to String");

  if path_str.ends_with(" (deleted)") {
    // The kernel appends " (deleted)" to the symlink when the original executable has been replaced
    let len = path_str.len();
    path_str.truncate(len - 10)
  }

  path_str
}

#[cfg(target_os = "macos")]
extern {
  pub fn _NSGetExecutablePath(buf: *mut c_char, size: *mut uint32_t) -> int32_t;
}

#[cfg(target_os = "macos")]
pub unsafe fn get_executable_path() -> String {
  let capacity = 2000;
  let mut temp:Vec<u8> = Vec::with_capacity(capacity);
  temp.extend(repeat(0).take(capacity));
  let pathbuf = CString::from_vec_unchecked(temp);
  let ptr = pathbuf.into_raw();

  let mut size:uint32_t = capacity as u32;
  if _NSGetExecutablePath(ptr, &mut size) == 0 {

    let mut temp2:Vec<u8> = Vec::with_capacity(capacity);
    temp2.extend(repeat(0).take(capacity));
    let pathbuf2 = CString::from_vec_unchecked(temp2);
    let ptr2 = pathbuf2.into_raw();

    if libc::realpath(ptr, ptr2) != null_mut() {
      let path = CString::from_raw(ptr2);
      path.to_str().expect("failed to convert CString to String").to_string()
    } else {
      panic!();
    }
  } else {
    panic!("buffer too small");
  }
}
<|endoftext|>


<commit_before>use serde_json::{json, Number, Value};

#[test]
fn number() {
    assert_eq!(format!("{:?}", Number::from(1)), "Number(1)");
    assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)");
    assert_eq!(
        format!("{:?}", Number::from_f64(1.0).unwrap()),
        "Number(1.0)"
    );
}

#[test]
fn value_null() {
    assert_eq!(format!("{:?}", json!(null)), "Null");
}

#[test]
fn value_bool() {
    assert_eq!(format!("{:?}", json!(true)), "Bool(true)");
    assert_eq!(format!("{:?}", json!(false)), "Bool(false)");
}

#[test]
fn value_number() {
    assert_eq!(format!("{:?}", json!(1)), "Number(1)");
    assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
    assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
}

#[test]
fn value_string() {
    assert_eq!(format!("{:?}", json!("s")), "String(\"s\")");
}

#[test]
fn value_array() {
    assert_eq!(format!("{:?}", json!([])), "Array([])");
}

#[test]
fn value_object() {
    assert_eq!(format!("{:?}", json!({})), "Object({})");
}

#[test]
fn error() {
    let err = serde_json::from_str::<Value>("{0}").unwrap_err();
    let expected = "Error(\"key must be a string\", line: 1, column: 2)";
    assert_eq!(format!("{:?}", err), expected);
}
<commit_msg>Add test for {:#?} format of Value<commit_after>use serde_json::{json, Number, Value};

#[test]
fn number() {
    assert_eq!(format!("{:?}", Number::from(1)), "Number(1)");
    assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)");
    assert_eq!(
        format!("{:?}", Number::from_f64(1.0).unwrap()),
        "Number(1.0)"
    );
}

#[test]
fn value_null() {
    assert_eq!(format!("{:?}", json!(null)), "Null");
}

#[test]
fn value_bool() {
    assert_eq!(format!("{:?}", json!(true)), "Bool(true)");
    assert_eq!(format!("{:?}", json!(false)), "Bool(false)");
}

#[test]
fn value_number() {
    assert_eq!(format!("{:?}", json!(1)), "Number(1)");
    assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
    assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
}

#[test]
fn value_string() {
    assert_eq!(format!("{:?}", json!("s")), "String(\"s\")");
}

#[test]
fn value_array() {
    assert_eq!(format!("{:?}", json!([])), "Array([])");
}

#[test]
fn value_object() {
    assert_eq!(format!("{:?}", json!({})), "Object({})");
}

#[test]
fn error() {
    let err = serde_json::from_str::<Value>("{0}").unwrap_err();
    let expected = "Error(\"key must be a string\", line: 1, column: 2)";
    assert_eq!(format!("{:?}", err), expected);
}

const INDENTED_EXPECTED: &str = r#"Object(
    {
        "array": Array(
            [
                Number(
                    0,
                ),
                Number(
                    1,
                ),
            ],
        ),
    },
)"#;

#[test]
fn indented() {
    let j = json!({ "array": [0, 1] });
    assert_eq!(format!("{:#?}", j), INDENTED_EXPECTED);
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate errno;

use self::libc::{uint32_t, c_int};

use std::{ptr, mem, env};
use std::fmt;

use libproc::proc_pid;

#[cfg(test)]
use std::io;
#[cfg(test)]
use std::io::Write;

// See https://opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/msgbuf.h
const MAX_MSG_BSIZE : c_int = (1*1024*1024);
const MSG_MAGIC : c_int = 0x063061;

// See /usr/include/sys/msgbuf.h on your Mac.
#[repr(C)]
struct MessageBuffer {
    pub msg_magic : c_int,
    pub msg_size : c_int,
    pub msg_bufx : c_int,      // write pointer
    pub msg_bufr : c_int,      // read pointer
    pub msg_bufc : * mut u8     // buffer
}

impl Default for MessageBuffer {
    fn default() -> MessageBuffer {
        MessageBuffer {
            msg_magic : 0,
            msg_size : 0,
            msg_bufx : 0,
            msg_bufr : 0,
            msg_bufc : ptr::null_mut() as * mut u8
        }
    }
}

impl fmt::Debug for MessageBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "MessageBuffer {{ magic: 0x{:x}, size: {}, bufx: {}}}", self.msg_magic, self.msg_size, self.msg_bufx)
    }
}

// this extern block links to the libproc library
// Original signatures of functions can be found at http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
#[link(name = "proc", kind = "dylib")]
extern {
    fn proc_kmsgbuf(buffer : *mut MessageBuffer, buffersize : uint32_t) -> c_int;
}

/// Get upto buffersize bytes from the the kernel message buffer - as used by dmesg
/// extern crate libproc;
/// extern crate libc;
///
/// use std::str;
/// use std::io::Write;
/// use libproc::libproc::kmesg_buffer;
///
/// fn main() {
///     if kmesg_buffer::am_root() {
///         match kmesg_buffer::kmsgbuf() {
///             Ok(message) => println!("{}", message),
///             Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
///         }
///     } else {
///         writeln!(&mut std::io::stderr(), "Must be run as root").unwrap()
///     }
// See http://opensource.apple.com//source/system_cmds/system_cmds-336.6/dmesg.tproj/dmesg.c
pub fn kmsgbuf() -> Result<String, String> {
    let mut message_buffer : MessageBuffer = Default::default();
    let ret: i32;

    unsafe {
        ret = proc_kmsgbuf(&mut message_buffer, mem::size_of::<MessageBuffer>() as u32);
    }

    if ret <= 0 {
        Err(proc_pid::get_errno_with_message(ret))
    } else
    {
        if message_buffer.msg_magic != MSG_MAGIC {
            println!("Message buffer: {:?}", message_buffer);
            Err(format!("The magic number 0x{:x} is incorrect", message_buffer.msg_magic))
        } else {
            // Avoid starting beyond the end of the buffer
            if message_buffer.msg_bufx >= MAX_MSG_BSIZE {
                message_buffer.msg_bufx = 0;
            }
            let mut output : Vec<u8> = Vec::new();

            // The message buffer is circular; start at the read pointer, and go to the write pointer - 1.
            unsafe {
                let mut ch : u8;
//                let newl : bool = false;
//                let skip : bool = false;
                let mut p : * mut u8 = message_buffer.msg_bufc.offset(message_buffer.msg_bufx as isize);
                let ep : * mut u8 = message_buffer.msg_bufc.offset((message_buffer.msg_bufx - 1) as isize);
//                let buf : [u8; 5];

                while p != ep {
                    // If at the end, then loop around to the start
                    // TODO should use actual size (from struct element) - not the max size??
                    if p == message_buffer.msg_bufc.offset(MAX_MSG_BSIZE as isize) {
                        p = message_buffer.msg_bufc;
                    }

                    ch = *p;

                    /* Skip "\n<.*>" syslog sequences.
                    if skip {
                        if ch == '>' {
                            newl = skip = false;
                        }
                        continue;
                    }

                    if newl && ch == '<' {
                        skip = true;
                        continue;
                    }

                    if ch == '\0' {
                        continue;
                    }

                    newl = ch == '\n';

//                    (void)vis(buf, ch, 0, 0);

                    if buf[1] == 0 {
                        output.append(buf[0]);
                    } else {
                        output.append("%s", buf);
                    }
                    */

                    output.push(ch);
                    p = p.offset(1);
                }

                Ok(String::from_utf8(output).unwrap())
            }
        }
    }
}

pub fn am_root() -> bool {
    libc::getuid() == 0
}

// If you want this test to actually test something, then you need to run as root 'sudo cargo test'
#[test]
fn kmessagebuffer_test() {
    if am_root() {
        match kmsgbuf() {
            Ok(buffer) => println!("Buffer: {:?}", buffer),
            Err(message) => assert!(false, message)
        }
    } else {
        writeln!(&mut io::stdout(), "test libproc::kmesg_buffer::kmessagebuffer_test ... skipped as it needs to be run as root").unwrap();
    }
}
<commit_msg>Fix PR#11<commit_after>extern crate libc;
extern crate errno;

use self::libc::{uint32_t, c_int};

use std::{ptr, mem, env};
use std::fmt;

use libproc::proc_pid;

#[cfg(test)]
use std::io;
#[cfg(test)]
use std::io::Write;

// See https://opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/msgbuf.h
const MAX_MSG_BSIZE : c_int = (1*1024*1024);
const MSG_MAGIC : c_int = 0x063061;

// See /usr/include/sys/msgbuf.h on your Mac.
#[repr(C)]
struct MessageBuffer {
    pub msg_magic : c_int,
    pub msg_size : c_int,
    pub msg_bufx : c_int,      // write pointer
    pub msg_bufr : c_int,      // read pointer
    pub msg_bufc : * mut u8     // buffer
}

impl Default for MessageBuffer {
    fn default() -> MessageBuffer {
        MessageBuffer {
            msg_magic : 0,
            msg_size : 0,
            msg_bufx : 0,
            msg_bufr : 0,
            msg_bufc : ptr::null_mut() as * mut u8
        }
    }
}

impl fmt::Debug for MessageBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "MessageBuffer {{ magic: 0x{:x}, size: {}, bufx: {}}}", self.msg_magic, self.msg_size, self.msg_bufx)
    }
}

// this extern block links to the libproc library
// Original signatures of functions can be found at http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
#[link(name = "proc", kind = "dylib")]
extern {
    fn proc_kmsgbuf(buffer : *mut MessageBuffer, buffersize : uint32_t) -> c_int;
}

/// Get upto buffersize bytes from the the kernel message buffer - as used by dmesg
/// extern crate libproc;
/// extern crate libc;
///
/// use std::str;
/// use std::io::Write;
/// use libproc::libproc::kmesg_buffer;
///
/// fn main() {
///     if kmesg_buffer::am_root() {
///         match kmesg_buffer::kmsgbuf() {
///             Ok(message) => println!("{}", message),
///             Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
///         }
///     } else {
///         writeln!(&mut std::io::stderr(), "Must be run as root").unwrap()
///     }
// See http://opensource.apple.com//source/system_cmds/system_cmds-336.6/dmesg.tproj/dmesg.c
pub fn kmsgbuf() -> Result<String, String> {
    let mut message_buffer : MessageBuffer = Default::default();
    let ret: i32;

    unsafe {
        ret = proc_kmsgbuf(&mut message_buffer, mem::size_of::<MessageBuffer>() as u32);
    }

    if ret <= 0 {
        Err(proc_pid::get_errno_with_message(ret))
    } else
    {
        if message_buffer.msg_magic != MSG_MAGIC {
            println!("Message buffer: {:?}", message_buffer);
            Err(format!("The magic number 0x{:x} is incorrect", message_buffer.msg_magic))
        } else {
            // Avoid starting beyond the end of the buffer
            if message_buffer.msg_bufx >= MAX_MSG_BSIZE {
                message_buffer.msg_bufx = 0;
            }
            let mut output : Vec<u8> = Vec::new();

            // The message buffer is circular; start at the read pointer, and go to the write pointer - 1.
            unsafe {
                let mut ch : u8;
//                let newl : bool = false;
//                let skip : bool = false;
                let mut p : * mut u8 = message_buffer.msg_bufc.offset(message_buffer.msg_bufx as isize);
                let ep : * mut u8 = message_buffer.msg_bufc.offset((message_buffer.msg_bufx - 1) as isize);
//                let buf : [u8; 5];

                while p != ep {
                    // If at the end, then loop around to the start
                    // TODO should use actual size (from struct element) - not the max size??
                    if p == message_buffer.msg_bufc.offset(MAX_MSG_BSIZE as isize) {
                        p = message_buffer.msg_bufc;
                    }

                    ch = *p;

                    /* Skip "\n<.*>" syslog sequences.
                    if skip {
                        if ch == '>' {
                            newl = skip = false;
                        }
                        continue;
                    }

                    if newl && ch == '<' {
                        skip = true;
                        continue;
                    }

                    if ch == '\0' {
                        continue;
                    }

                    newl = ch == '\n';

//                    (void)vis(buf, ch, 0, 0);

                    if buf[1] == 0 {
                        output.append(buf[0]);
                    } else {
                        output.append("%s", buf);
                    }
                    */

                    output.push(ch);
                    p = p.offset(1);
                }

                Ok(String::from_utf8(output).unwrap())
            }
        }
    }
}

pub fn am_root() -> bool {
    unsafe { libc::getuid() == 0 }
}

// If you want this test to actually test something, then you need to run as root 'sudo cargo test'
#[test]
fn kmessagebuffer_test() {
    if am_root() {
        match kmsgbuf() {
            Ok(buffer) => println!("Buffer: {:?}", buffer),
            Err(message) => assert!(false, message)
        }
    } else {
        writeln!(&mut io::stdout(), "test libproc::kmesg_buffer::kmessagebuffer_test ... skipped as it needs to be run as root").unwrap();
    }
}
<|endoftext|>


<commit_before>extern crate env_logger;
extern crate rustc_serialize;
extern crate handlebars;

use std::io::{self, Write};
use std::process;
use std::env;

use rustc_serialize::json::Json;

use handlebars::Handlebars;

fn usage() -> ! {
    writeln!(&mut io::stderr(), "{}",
        r#"Usage: ./render-cli template.hbs '{"json": "data"}'"#).ok();
    process::exit(1);
}

fn main() {
    env_logger::init().unwrap();

    let mut args = env::args();
    args.next(); // skip own filename
    let (filename, json) = match (args.next(), args.next()) {
        (Some(filename), Some(json)) => (filename, json),
        _ => usage(),
    };
    let data = match Json::from_str(&json) {
        Ok(json) => json,
        Err(_) => usage(),
    };

    let mut handlebars = Handlebars::new();

    handlebars.register_template_file(&filename, &filename)
              .ok()
              .unwrap();
    match handlebars.render(&filename, &data) {
        Ok(data) => {
            println!("{}", data);
        }
        Err(e) => {
            println!("Error rendering {}: {}", filename, e);
            process::exit(2);
        }
    }
}
<commit_msg>Trying to fix example in rust-nightly<commit_after>#![cfg_attr(all(feature="serde_type"), feature(custom_derive, plugin))]
#![cfg_attr(all(feature="serde_type"), plugin(serde_macros))]
extern crate env_logger;
#[cfg(all(feature = "rustc_ser_type", not(feature = "serde_type")))]
extern crate rustc_serialize;
extern crate handlebars;

#[cfg(feature = "serde_type")]
extern crate serde;
#[cfg(feature = "serde_type")]
extern crate serde_json;

use std::io::{self, Write};
use std::process;
use std::env;

use rustc_serialize::json::Json;

use handlebars::Handlebars;

fn usage() -> ! {
    writeln!(&mut io::stderr(), "{}",
        r#"Usage: ./render-cli template.hbs '{"json": "data"}'"#).ok();
    process::exit(1);
}

#[cfg(all(feature = "rustc_ser_type", not(feature = "serde_type")))]
fn parse_json(text: &str) -> Json {
    match Json::from_str(text) {
        Ok(json) => json,
        Err(_) => usage(),
    }
}
#[cfg(feature = "serde_type")]
fn parse_json(text: &str) -> Value {
    match serde_json::from_str(text) {
        Ok(json) => json,
        Err(_) => usage(),
    }
}

fn main() {
    env_logger::init().unwrap();

    let mut args = env::args();
    args.next(); // skip own filename
    let (filename, json) = match (args.next(), args.next()) {
        (Some(filename), Some(json)) => (filename, json),
        _ => usage(),
    };
    let data = parse_json(&json);

    let mut handlebars = Handlebars::new();

    handlebars.register_template_file(&filename, &filename)
              .ok()
              .unwrap();
    match handlebars.render(&filename, &data) {
        Ok(data) => {
            println!("{}", data);
        }
        Err(e) => {
            println!("Error rendering {}: {}", filename, e);
            process::exit(2);
        }
    }
}
<|endoftext|>


<commit_before>use clippy_utils::diagnostics::{multispan_sugg, span_lint, span_lint_and_then};
use clippy_utils::source::snippet;
use clippy_utils::ty::{implements_trait, is_copy};
use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, in_macro, is_expn_of};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for equal operands to comparison, logical and
    /// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
    /// `||`, `&`, `|`, `^`, `-` and `/`).
    ///
    /// **Why is this bad?** This is usually just a typo or a copy and paste error.
    ///
    /// **Known problems:** False negatives: We had some false positives regarding
    /// calls (notably [racer](https://github.com/phildawes/racer) had one instance
    /// of `x.pop() && x.pop()`), so we removed matching any function or method
    /// calls. We may introduce a list of known pure functions in the future.
    ///
    /// **Example:**
    /// ```rust
    /// # let x = 1;
    /// if x + 1 == x + 1 {}
    /// ```
    /// or
    /// ```rust
    /// # let a = 3;
    /// # let b = 4;
    /// assert_eq!(a, a);
    /// ```
    pub EQ_OP,
    correctness,
    "equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)"
}

declare_clippy_lint! {
    /// **What it does:** Checks for arguments to `==` which have their address
    /// taken to satisfy a bound
    /// and suggests to dereference the other argument instead
    ///
    /// **Why is this bad?** It is more idiomatic to dereference the other argument.
    ///
    /// **Known problems:** None
    ///
    /// **Example:**
    /// ```ignore
    /// // Bad
    /// &x == y
    ///
    /// // Good
    /// x == *y
    /// ```
    pub OP_REF,
    style,
    "taking a reference to satisfy the type constraints on `==`"
}

declare_lint_pass!(EqOp => [EQ_OP, OP_REF]);

const ASSERT_MACRO_NAMES: [&str; 4] = ["assert_eq", "assert_ne", "debug_assert_eq", "debug_assert_ne"];

impl<'tcx> LateLintPass<'tcx> for EqOp {
    #[allow(clippy::similar_names, clippy::too_many_lines)]
    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
        if let ExprKind::Block(block, _) = e.kind {
            for stmt in block.stmts {
                for amn in &ASSERT_MACRO_NAMES {
                    if_chain! {
                        if is_expn_of(stmt.span, amn).is_some();
                        if let StmtKind::Semi(matchexpr) = stmt.kind;
                        if let Some(macro_args) = higher::extract_assert_macro_args(matchexpr);
                        if macro_args.len() == 2;
                        let (lhs, rhs) = (macro_args[0], macro_args[1]);
                        if eq_expr_value(cx, lhs, rhs);

                        then {
                            span_lint(
                                cx,
                                EQ_OP,
                                lhs.span.to(rhs.span),
                                &format!("identical args used in this `{}!` macro call", amn),
                            );
                        }
                    }
                }
            }
        }
        if let ExprKind::Binary(op, left, right) = e.kind {
            if e.span.from_expansion() {
                return;
            }
            let macro_with_not_op = |expr_kind: &ExprKind<'_>| {
                if let ExprKind::Unary(_, expr) = *expr_kind {
                    in_macro(expr.span)
                } else {
                    false
                }
            };
            if macro_with_not_op(&left.kind) || macro_with_not_op(&right.kind) {
                return;
            }
            if is_useless_with_eq_exprs(higher::binop(op.node)) && eq_expr_value(cx, left, right) {
                span_lint(
                    cx,
                    EQ_OP,
                    e.span,
                    &format!("equal expressions as operands to `{}`", op.node.as_str()),
                );
                return;
            }
            let (trait_id, requires_ref) = match op.node {
                BinOpKind::Add => (cx.tcx.lang_items().add_trait(), false),
                BinOpKind::Sub => (cx.tcx.lang_items().sub_trait(), false),
                BinOpKind::Mul => (cx.tcx.lang_items().mul_trait(), false),
                BinOpKind::Div => (cx.tcx.lang_items().div_trait(), false),
                BinOpKind::Rem => (cx.tcx.lang_items().rem_trait(), false),
                // don't lint short circuiting ops
                BinOpKind::And | BinOpKind::Or => return,
                BinOpKind::BitXor => (cx.tcx.lang_items().bitxor_trait(), false),
                BinOpKind::BitAnd => (cx.tcx.lang_items().bitand_trait(), false),
                BinOpKind::BitOr => (cx.tcx.lang_items().bitor_trait(), false),
                BinOpKind::Shl => (cx.tcx.lang_items().shl_trait(), false),
                BinOpKind::Shr => (cx.tcx.lang_items().shr_trait(), false),
                BinOpKind::Ne | BinOpKind::Eq => (cx.tcx.lang_items().eq_trait(), true),
                BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ge | BinOpKind::Gt => {
                    (cx.tcx.lang_items().partial_ord_trait(), true)
                },
            };
            if let Some(trait_id) = trait_id {
                #[allow(clippy::match_same_arms)]
                match (&left.kind, &right.kind) {
                    // do not suggest to dereference literals
                    (&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},
                    // &foo == &bar
                    (&ExprKind::AddrOf(BorrowKind::Ref, _, l), &ExprKind::AddrOf(BorrowKind::Ref, _, r)) => {
                        let lty = cx.typeck_results().expr_ty(l);
                        let rty = cx.typeck_results().expr_ty(r);
                        let lcpy = is_copy(cx, lty);
                        let rcpy = is_copy(cx, rty);
                        // either operator autorefs or both args are copyable
                        if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty.into()]) {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of both operands",
                                |diag| {
                                    let lsnip = snippet(cx, l.span, "...").to_string();
                                    let rsnip = snippet(cx, r.span, "...").to_string();
                                    multispan_sugg(
                                        diag,
                                        "use the values directly",
                                        vec![(left.span, lsnip), (right.span, rsnip)],
                                    );
                                },
                            );
                        } else if lcpy
                            && !rcpy
                            && implements_trait(cx, lty, trait_id, &[cx.typeck_results().expr_ty(right).into()])
                        {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of left operand",
                                |diag| {
                                    let lsnip = snippet(cx, l.span, "...").to_string();
                                    diag.span_suggestion(
                                        left.span,
                                        "use the left value directly",
                                        lsnip,
                                        Applicability::MaybeIncorrect, // FIXME #2597
                                    );
                                },
                            );
                        } else if !lcpy
                            && rcpy
                            && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])
                        {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of right operand",
                                |diag| {
                                    let rsnip = snippet(cx, r.span, "...").to_string();
                                    diag.span_suggestion(
                                        right.span,
                                        "use the right value directly",
                                        rsnip,
                                        Applicability::MaybeIncorrect, // FIXME #2597
                                    );
                                },
                            );
                        }
                    },
                    // &foo == bar
                    (&ExprKind::AddrOf(BorrowKind::Ref, _, l), _) => {
                        let lty = cx.typeck_results().expr_ty(l);
                        let lcpy = is_copy(cx, lty);
                        if (requires_ref || lcpy)
                            && implements_trait(cx, lty, trait_id, &[cx.typeck_results().expr_ty(right).into()])
                        {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of left operand",
                                |diag| {
                                    let lsnip = snippet(cx, l.span, "...").to_string();
                                    diag.span_suggestion(
                                        left.span,
                                        "use the left value directly",
                                        lsnip,
                                        Applicability::MaybeIncorrect, // FIXME #2597
                                    );
                                },
                            );
                        }
                   },
                    // foo == &bar
                    (_, &ExprKind::AddrOf(BorrowKind::Ref, _, r)) => {
                        let rty = cx.typeck_results().expr_ty(r);
                        let rcpy = is_copy(cx, rty);
                        if (requires_ref || rcpy)
                            && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])
                        {
                            span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |diag| {
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                diag.span_suggestion(
                                    right.span,
                                    "use the right value directly",
                                    rsnip,
                                    Applicability::MaybeIncorrect, // FIXME #2597
                                );
                            });
                        }
                    },
                    _ => {},
                }
            }
        }
    }
}
<commit_msg>Run `cargo fmt`<commit_after>use clippy_utils::diagnostics::{multispan_sugg, span_lint, span_lint_and_then};
use clippy_utils::source::snippet;
use clippy_utils::ty::{implements_trait, is_copy};
use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, in_macro, is_expn_of};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for equal operands to comparison, logical and
    /// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
    /// `||`, `&`, `|`, `^`, `-` and `/`).
    ///
    /// **Why is this bad?** This is usually just a typo or a copy and paste error.
    ///
    /// **Known problems:** False negatives: We had some false positives regarding
    /// calls (notably [racer](https://github.com/phildawes/racer) had one instance
    /// of `x.pop() && x.pop()`), so we removed matching any function or method
    /// calls. We may introduce a list of known pure functions in the future.
    ///
    /// **Example:**
    /// ```rust
    /// # let x = 1;
    /// if x + 1 == x + 1 {}
    /// ```
    /// or
    /// ```rust
    /// # let a = 3;
    /// # let b = 4;
    /// assert_eq!(a, a);
    /// ```
    pub EQ_OP,
    correctness,
    "equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)"
}

declare_clippy_lint! {
    /// **What it does:** Checks for arguments to `==` which have their address
    /// taken to satisfy a bound
    /// and suggests to dereference the other argument instead
    ///
    /// **Why is this bad?** It is more idiomatic to dereference the other argument.
    ///
    /// **Known problems:** None
    ///
    /// **Example:**
    /// ```ignore
    /// // Bad
    /// &x == y
    ///
    /// // Good
    /// x == *y
    /// ```
    pub OP_REF,
    style,
    "taking a reference to satisfy the type constraints on `==`"
}

declare_lint_pass!(EqOp => [EQ_OP, OP_REF]);

const ASSERT_MACRO_NAMES: [&str; 4] = ["assert_eq", "assert_ne", "debug_assert_eq", "debug_assert_ne"];

impl<'tcx> LateLintPass<'tcx> for EqOp {
    #[allow(clippy::similar_names, clippy::too_many_lines)]
    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
        if let ExprKind::Block(block, _) = e.kind {
            for stmt in block.stmts {
                for amn in &ASSERT_MACRO_NAMES {
                    if_chain! {
                        if is_expn_of(stmt.span, amn).is_some();
                        if let StmtKind::Semi(matchexpr) = stmt.kind;
                        if let Some(macro_args) = higher::extract_assert_macro_args(matchexpr);
                        if macro_args.len() == 2;
                        let (lhs, rhs) = (macro_args[0], macro_args[1]);
                        if eq_expr_value(cx, lhs, rhs);

                        then {
                            span_lint(
                                cx,
                                EQ_OP,
                                lhs.span.to(rhs.span),
                                &format!("identical args used in this `{}!` macro call", amn),
                            );
                        }
                    }
                }
            }
        }
        if let ExprKind::Binary(op, left, right) = e.kind {
            if e.span.from_expansion() {
                return;
            }
            let macro_with_not_op = |expr_kind: &ExprKind<'_>| {
                if let ExprKind::Unary(_, expr) = *expr_kind {
                    in_macro(expr.span)
                } else {
                    false
                }
            };
            if macro_with_not_op(&left.kind) || macro_with_not_op(&right.kind) {
                return;
            }
            if is_useless_with_eq_exprs(higher::binop(op.node)) && eq_expr_value(cx, left, right) {
                span_lint(
                    cx,
                    EQ_OP,
                    e.span,
                    &format!("equal expressions as operands to `{}`", op.node.as_str()),
                );
                return;
            }
            let (trait_id, requires_ref) = match op.node {
                BinOpKind::Add => (cx.tcx.lang_items().add_trait(), false),
                BinOpKind::Sub => (cx.tcx.lang_items().sub_trait(), false),
                BinOpKind::Mul => (cx.tcx.lang_items().mul_trait(), false),
                BinOpKind::Div => (cx.tcx.lang_items().div_trait(), false),
                BinOpKind::Rem => (cx.tcx.lang_items().rem_trait(), false),
                // don't lint short circuiting ops
                BinOpKind::And | BinOpKind::Or => return,
                BinOpKind::BitXor => (cx.tcx.lang_items().bitxor_trait(), false),
                BinOpKind::BitAnd => (cx.tcx.lang_items().bitand_trait(), false),
                BinOpKind::BitOr => (cx.tcx.lang_items().bitor_trait(), false),
                BinOpKind::Shl => (cx.tcx.lang_items().shl_trait(), false),
                BinOpKind::Shr => (cx.tcx.lang_items().shr_trait(), false),
                BinOpKind::Ne | BinOpKind::Eq => (cx.tcx.lang_items().eq_trait(), true),
                BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ge | BinOpKind::Gt => {
                    (cx.tcx.lang_items().partial_ord_trait(), true)
                },
            };
            if let Some(trait_id) = trait_id {
                #[allow(clippy::match_same_arms)]
                match (&left.kind, &right.kind) {
                    // do not suggest to dereference literals
                    (&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},
                    // &foo == &bar
                    (&ExprKind::AddrOf(BorrowKind::Ref, _, l), &ExprKind::AddrOf(BorrowKind::Ref, _, r)) => {
                        let lty = cx.typeck_results().expr_ty(l);
                        let rty = cx.typeck_results().expr_ty(r);
                        let lcpy = is_copy(cx, lty);
                        let rcpy = is_copy(cx, rty);
                        // either operator autorefs or both args are copyable
                        if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty.into()]) {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of both operands",
                                |diag| {
                                    let lsnip = snippet(cx, l.span, "...").to_string();
                                    let rsnip = snippet(cx, r.span, "...").to_string();
                                    multispan_sugg(
                                        diag,
                                        "use the values directly",
                                        vec![(left.span, lsnip), (right.span, rsnip)],
                                    );
                                },
                            );
                        } else if lcpy
                            && !rcpy
                            && implements_trait(cx, lty, trait_id, &[cx.typeck_results().expr_ty(right).into()])
                        {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of left operand",
                                |diag| {
                                    let lsnip = snippet(cx, l.span, "...").to_string();
                                    diag.span_suggestion(
                                        left.span,
                                        "use the left value directly",
                                        lsnip,
                                        Applicability::MaybeIncorrect, // FIXME #2597
                                    );
                                },
                            );
                        } else if !lcpy
                            && rcpy
                            && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])
                        {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of right operand",
                                |diag| {
                                    let rsnip = snippet(cx, r.span, "...").to_string();
                                    diag.span_suggestion(
                                        right.span,
                                        "use the right value directly",
                                        rsnip,
                                        Applicability::MaybeIncorrect, // FIXME #2597
                                    );
                                },
                            );
                        }
                    },
                    // &foo == bar
                    (&ExprKind::AddrOf(BorrowKind::Ref, _, l), _) => {
                        let lty = cx.typeck_results().expr_ty(l);
                        let lcpy = is_copy(cx, lty);
                        if (requires_ref || lcpy)
                            && implements_trait(cx, lty, trait_id, &[cx.typeck_results().expr_ty(right).into()])
                        {
                            span_lint_and_then(
                                cx,
                                OP_REF,
                                e.span,
                                "needlessly taken reference of left operand",
                                |diag| {
                                    let lsnip = snippet(cx, l.span, "...").to_string();
                                    diag.span_suggestion(
                                        left.span,
                                        "use the left value directly",
                                        lsnip,
                                        Applicability::MaybeIncorrect, // FIXME #2597
                                    );
                                },
                            );
                        }
                    },
                    // foo == &bar
                    (_, &ExprKind::AddrOf(BorrowKind::Ref, _, r)) => {
                        let rty = cx.typeck_results().expr_ty(r);
                        let rcpy = is_copy(cx, rty);
                        if (requires_ref || rcpy)
                            && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])
                        {
                            span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |diag| {
                                let rsnip = snippet(cx, r.span, "...").to_string();
                                diag.span_suggestion(
                                    right.span,
                                    "use the right value directly",
                                    rsnip,
                                    Applicability::MaybeIncorrect, // FIXME #2597
                                );
                            });
                        }
                    },
                    _ => {},
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::common::util::*;

#[test]
fn test_to_upper() {
    new_ucmd!()
        .args(&["a-z", "A-Z"])
        .pipe_in("!abcd!")
        .run()
        .stdout_is("!ABCD!");
}

#[test]
fn test_small_set2() {
    new_ucmd!()
        .args(&["0-9", "X"])
        .pipe_in("@0123456789")
        .run()
        .stdout_is("@XXXXXXXXXX");
}

#[test]
fn test_unicode() {
    new_ucmd!()
        .args(&[", ┬─┬", "╯︵┻━┻"])
        .pipe_in("(,°□°）, ┬─┬")
        .run()
        .stdout_is("(╯°□°）╯︵┻━┻");
}

#[test]
fn test_delete() {
    new_ucmd!()
        .args(&["-d", "a-z"])
        .pipe_in("aBcD")
        .run()
        .stdout_is("BD");
}

#[test]
fn test_delete_complement() {
    new_ucmd!()
        .args(&["-d", "-c", "a-z"])
        .pipe_in("aBcD")
        .run()
        .stdout_is("ac");
}

#[test]
fn test_delete_complement_2() {
    new_ucmd!()
        .args(&["-d", "-C", "0-9"])
        .pipe_in("Phone: 01234 567890")
        .succeeds()
        .stdout_is("01234567890");
    new_ucmd!()
        .args(&["-d", "--complement", "0-9"])
        .pipe_in("Phone: 01234 567890")
        .succeeds()
        .stdout_is("01234567890");
}

#[test]
fn test_complement1() {
    new_ucmd!()
        .args(&["-c", "a", "X"])
        .pipe_in("ab")
        .run()
        .stdout_is("aX");
}

#[test]
fn test_complement2() {
    new_ucmd!()
        .args(&["-c", "0-9", "x"])
        .pipe_in("Phone: 01234 567890")
        .run()
        .stdout_is("xxxxxxx01234x567890");
}

#[test]
fn test_complement3() {
    new_ucmd!()
        .args(&["-c", "abcdefgh", "123"]) // spell-checker:disable-line
        .pipe_in("the cat and the bat")
        .run()
        .stdout_is("3he3ca33a3d33he3ba3"); // spell-checker:disable-line
}

#[test]
fn test_complement4() {
    // $ echo -n '0x1y2z3' | tr -c '0-@' '*-~'
    // 0~1~2~3
    new_ucmd!()
        .args(&["-c", "0-@", "*-~"])
        .pipe_in("0x1y2z3")
        .run()
        .stdout_is("0~1~2~3");
}

#[test]
fn test_complement5() {
    // $ echo -n '0x1y2z3' | tr -c '\0-@' '*-~'
    // 0a1b2c3
    new_ucmd!()
        .args(&["-c", "\\0-@", "*-~"])
        .pipe_in("0x1y2z3")
        .run()
        .stdout_is("0a1b2c3");
}

#[test]
fn test_squeeze() {
    new_ucmd!()
        .args(&["-s", "a-z"])
        .pipe_in("aaBBcDcc")
        .run()
        .stdout_is("aBBcDc");
}

#[test]
fn test_squeeze_complement() {
    new_ucmd!()
        .args(&["-sc", "a-z"])
        .pipe_in("aaBBcDcc")
        .run()
        .stdout_is("aaBcDcc");
}

#[test]
fn test_squeeze_complement_two_sets() {
    new_ucmd!()
        .args(&["-sc", "a", "_"])
        .pipe_in("test a aa with 3 ___ spaaaces +++") // spell-checker:disable-line
        .run()
        .stdout_is("_a_aa_aaa_");
}

#[test]
fn test_translate_and_squeeze() {
    new_ucmd!()
        .args(&["-s", "x", "y"])
        .pipe_in("xx")
        .run()
        .stdout_is("y");
}

#[test]
fn test_translate_and_squeeze_multiple_lines() {
    new_ucmd!()
        .args(&["-s", "x", "y"])
        .pipe_in("xxaax\nxaaxx") // spell-checker:disable-line
        .run()
        .stdout_is("yaay\nyaay"); // spell-checker:disable-line
}

#[test]
fn test_delete_and_squeeze() {
    new_ucmd!()
        .args(&["-ds", "a-z", "A-Z"])
        .pipe_in("abBcB")
        .run()
        .stdout_is("B");
}

#[test]
fn test_delete_and_squeeze_complement() {
    new_ucmd!()
        .args(&["-dsc", "a-z", "A-Z"])
        .pipe_in("abBcB")
        .run()
        .stdout_is("abc");
}

#[test]
fn test_set1_longer_than_set2() {
    new_ucmd!()
        .args(&["abc", "xy"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xyyde"); // spell-checker:disable-line
}

#[test]
fn test_set1_shorter_than_set2() {
    new_ucmd!()
        .args(&["ab", "xyz"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xycde"); // spell-checker:disable-line
}

#[test]
fn test_truncate() {
    new_ucmd!()
        .args(&["-t", "abc", "xy"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xycde"); // spell-checker:disable-line
}

#[test]
fn test_truncate_with_set1_shorter_than_set2() {
    new_ucmd!()
        .args(&["-t", "ab", "xyz"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xycde"); // spell-checker:disable-line
}

#[test]
fn missing_args_fails() {
    let (_, mut ucmd) = at_and_ucmd!();
    ucmd.fails().stderr_contains("missing operand");
}

#[test]
fn missing_required_second_arg_fails() {
    let (_, mut ucmd) = at_and_ucmd!();
    ucmd.args(&["foo"])
        .fails()
        .stderr_contains("missing operand after");
}

#[test]
fn test_interpret_backslash_escapes() {
    new_ucmd!()
        .args(&["abfnrtv", r"\a\b\f\n\r\t\v"]) // spell-checker:disable-line
        .pipe_in("abfnrtv") // spell-checker:disable-line
        .succeeds()
        .stdout_is("\u{7}\u{8}\u{c}\n\r\t\u{b}");
}

#[test]
fn test_interpret_unrecognized_backslash_escape_as_character() {
    new_ucmd!()
        .args(&["qcz+=~-", r"\q\c\z\+\=\~\-"])
        .pipe_in("qcz+=~-")
        .succeeds()
        .stdout_is("qcz+=~-");
}

#[test]
fn test_interpret_single_octal_escape() {
    new_ucmd!()
        .args(&["X", r"\015"])
        .pipe_in("X")
        .succeeds()
        .stdout_is("\r");
}

#[test]
fn test_interpret_one_and_two_digit_octal_escape() {
    new_ucmd!()
        .args(&["XYZ", r"\0\11\77"])
        .pipe_in("XYZ")
        .succeeds()
        .stdout_is("\0\t?");
}

#[test]
fn test_octal_escape_is_at_most_three_digits() {
    new_ucmd!()
        .args(&["XY", r"\0156"])
        .pipe_in("XY")
        .succeeds()
        .stdout_is("\r6");
}

#[test]
fn test_non_octal_digit_ends_escape() {
    new_ucmd!()
        .args(&["rust", r"\08\11956"])
        .pipe_in("rust")
        .succeeds()
        .stdout_is("\08\t9");
}

#[test]
fn test_interpret_backslash_at_eol_literally() {
    new_ucmd!()
        .args(&["X", r"\"])
        .pipe_in("X")
        .succeeds()
        .stdout_is("\\");
}

#[test]
fn test_more_than_2_sets() {
    new_ucmd!()
        .args(&["'abcdefgh'", "'a", "'b'"])
        .pipe_in("hello world")
        .fails();
}

#[test]
fn basic_translation_works() {
    // echo -n "abcdefabcdef" | tr "dabcdef"  "xyz"
    new_ucmd!()
        .args(&["abcdef", "xyz"])
        .pipe_in("abcdefabcdef")
        .succeeds()
        .stdout_is("xyzzzzxyzzzz");
}

#[test]
fn alnum_overrides_translation_to_fallback_1() {
    // echo -n "abcdefghijklmnopqrstuvwxyz" | tr "abc[:alpha:]" "xyz"
    new_ucmd!()
        .args(&["abc[:alpha:]", "xyz"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("zzzzzzzzzzzzzzzzzzzzzzzzzz");
}

#[test]
fn alnum_overrides_translation_to_fallback_2() {
    // echo -n "abcdefghijklmnopqrstuvwxyz" | tr "[:alpha:]abc" "xyz"
    new_ucmd!()
        .args(&["[:alpha:]abc", "xyz"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("zzzzzzzzzzzzzzzzzzzzzzzzzz");
}

#[test]
fn overrides_translation_pair_if_repeats() {
    // echo -n 'aaa' | tr "aaa" "xyz"
    new_ucmd!()
        .args(&["aaa", "xyz"])
        .pipe_in("aaa")
        .succeeds()
        .stdout_is("zzz");
}

#[test]
fn uppercase_conversion_works_1() {
    // echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    new_ucmd!()
        .args(&["abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

#[test]
fn uppercase_conversion_works_2() {
    // echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "a-z" "A-Z"
    new_ucmd!()
        .args(&["a-z", "A-Z"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

#[test]
fn uppercase_conversion_works_3() {
    // echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "[:lower:]" "[:upper:]"
    new_ucmd!()
        .args(&["[:lower:]", "[:upper:]"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

#[test]
fn translate_complement_set_in_order() {
    // echo -n '01234' | tr -c '@-~' ' -^'
    new_ucmd!()
        .args(&["-c", "@-~", " -^"])
        .pipe_in("01234")
        .succeeds()
        .stdout_is("PQRST");
}

#[test]
fn alpha_expands_uppercase_lowercase() {
    // echo -n "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alpha:]" " -_"
    new_ucmd!()
        .args(&["[:alpha:]", " -_"])
        .pipe_in("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is(r##" !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS"##);
}

#[test]
fn alnum_expands_number_uppercase_lowercase() {
    // echo -n "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alnum:]" " -_"
    new_ucmd!()
        .args(&["[:alnum:]", " -_"])
        .pipe_in("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is(r##" !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]"##);
}

#[test]
#[ignore = "not expected to fully pass -- any help appreciated!"]
fn check_against_gnu_tr_tests() {
    // echo -n "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alnum:]" " -_"
    new_ucmd!()
        .args(&["abcd", "[]*]"])
        .pipe_in("abcd")
        .succeeds()
        .stdout_is("]]]]");
    new_ucmd!()
        .args(&["abc", "[%*]xyz"])
        .pipe_in("abc")
        .succeeds()
        .stdout_is("xyz");
    new_ucmd!()
        .args(&["", "[.*]"])
        .pipe_in("abc")
        .succeeds()
        .stdout_is("abc");
    new_ucmd!()
        .args(&["-t", "abcd", "xy"])
        .pipe_in("abcde")
        .succeeds()
        .stdout_is("xycde");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
    new_ucmd!().args(&[""]).pipe_in("").succeeds().stdout_is("");
}
<commit_msg>Removed useless tests that were supposed to be filled with tests from GNU tr<commit_after>use crate::common::util::*;

#[test]
fn test_to_upper() {
    new_ucmd!()
        .args(&["a-z", "A-Z"])
        .pipe_in("!abcd!")
        .run()
        .stdout_is("!ABCD!");
}

#[test]
fn test_small_set2() {
    new_ucmd!()
        .args(&["0-9", "X"])
        .pipe_in("@0123456789")
        .run()
        .stdout_is("@XXXXXXXXXX");
}

#[test]
fn test_unicode() {
    new_ucmd!()
        .args(&[", ┬─┬", "╯︵┻━┻"])
        .pipe_in("(,°□°）, ┬─┬")
        .run()
        .stdout_is("(╯°□°）╯︵┻━┻");
}

#[test]
fn test_delete() {
    new_ucmd!()
        .args(&["-d", "a-z"])
        .pipe_in("aBcD")
        .run()
        .stdout_is("BD");
}

#[test]
fn test_delete_complement() {
    new_ucmd!()
        .args(&["-d", "-c", "a-z"])
        .pipe_in("aBcD")
        .run()
        .stdout_is("ac");
}

#[test]
fn test_delete_complement_2() {
    new_ucmd!()
        .args(&["-d", "-C", "0-9"])
        .pipe_in("Phone: 01234 567890")
        .succeeds()
        .stdout_is("01234567890");
    new_ucmd!()
        .args(&["-d", "--complement", "0-9"])
        .pipe_in("Phone: 01234 567890")
        .succeeds()
        .stdout_is("01234567890");
}

#[test]
fn test_complement1() {
    new_ucmd!()
        .args(&["-c", "a", "X"])
        .pipe_in("ab")
        .run()
        .stdout_is("aX");
}

#[test]
fn test_complement2() {
    new_ucmd!()
        .args(&["-c", "0-9", "x"])
        .pipe_in("Phone: 01234 567890")
        .run()
        .stdout_is("xxxxxxx01234x567890");
}

#[test]
fn test_complement3() {
    new_ucmd!()
        .args(&["-c", "abcdefgh", "123"]) // spell-checker:disable-line
        .pipe_in("the cat and the bat")
        .run()
        .stdout_is("3he3ca33a3d33he3ba3"); // spell-checker:disable-line
}

#[test]
fn test_complement4() {
    // $ echo -n '0x1y2z3' | tr -c '0-@' '*-~'
    // 0~1~2~3
    new_ucmd!()
        .args(&["-c", "0-@", "*-~"])
        .pipe_in("0x1y2z3")
        .run()
        .stdout_is("0~1~2~3");
}

#[test]
fn test_complement5() {
    // $ echo -n '0x1y2z3' | tr -c '\0-@' '*-~'
    // 0a1b2c3
    new_ucmd!()
        .args(&["-c", "\\0-@", "*-~"])
        .pipe_in("0x1y2z3")
        .run()
        .stdout_is("0a1b2c3");
}

#[test]
fn test_squeeze() {
    new_ucmd!()
        .args(&["-s", "a-z"])
        .pipe_in("aaBBcDcc")
        .run()
        .stdout_is("aBBcDc");
}

#[test]
fn test_squeeze_complement() {
    new_ucmd!()
        .args(&["-sc", "a-z"])
        .pipe_in("aaBBcDcc")
        .run()
        .stdout_is("aaBcDcc");
}

#[test]
fn test_squeeze_complement_two_sets() {
    new_ucmd!()
        .args(&["-sc", "a", "_"])
        .pipe_in("test a aa with 3 ___ spaaaces +++") // spell-checker:disable-line
        .run()
        .stdout_is("_a_aa_aaa_");
}

#[test]
fn test_translate_and_squeeze() {
    new_ucmd!()
        .args(&["-s", "x", "y"])
        .pipe_in("xx")
        .run()
        .stdout_is("y");
}

#[test]
fn test_translate_and_squeeze_multiple_lines() {
    new_ucmd!()
        .args(&["-s", "x", "y"])
        .pipe_in("xxaax\nxaaxx") // spell-checker:disable-line
        .run()
        .stdout_is("yaay\nyaay"); // spell-checker:disable-line
}

#[test]
fn test_delete_and_squeeze() {
    new_ucmd!()
        .args(&["-ds", "a-z", "A-Z"])
        .pipe_in("abBcB")
        .run()
        .stdout_is("B");
}

#[test]
fn test_delete_and_squeeze_complement() {
    new_ucmd!()
        .args(&["-dsc", "a-z", "A-Z"])
        .pipe_in("abBcB")
        .run()
        .stdout_is("abc");
}

#[test]
fn test_set1_longer_than_set2() {
    new_ucmd!()
        .args(&["abc", "xy"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xyyde"); // spell-checker:disable-line
}

#[test]
fn test_set1_shorter_than_set2() {
    new_ucmd!()
        .args(&["ab", "xyz"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xycde"); // spell-checker:disable-line
}

#[test]
fn test_truncate() {
    new_ucmd!()
        .args(&["-t", "abc", "xy"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xycde"); // spell-checker:disable-line
}

#[test]
fn test_truncate_with_set1_shorter_than_set2() {
    new_ucmd!()
        .args(&["-t", "ab", "xyz"])
        .pipe_in("abcde")
        .run()
        .stdout_is("xycde"); // spell-checker:disable-line
}

#[test]
fn missing_args_fails() {
    let (_, mut ucmd) = at_and_ucmd!();
    ucmd.fails().stderr_contains("missing operand");
}

#[test]
fn missing_required_second_arg_fails() {
    let (_, mut ucmd) = at_and_ucmd!();
    ucmd.args(&["foo"])
        .fails()
        .stderr_contains("missing operand after");
}

#[test]
fn test_interpret_backslash_escapes() {
    new_ucmd!()
        .args(&["abfnrtv", r"\a\b\f\n\r\t\v"]) // spell-checker:disable-line
        .pipe_in("abfnrtv") // spell-checker:disable-line
        .succeeds()
        .stdout_is("\u{7}\u{8}\u{c}\n\r\t\u{b}");
}

#[test]
fn test_interpret_unrecognized_backslash_escape_as_character() {
    new_ucmd!()
        .args(&["qcz+=~-", r"\q\c\z\+\=\~\-"])
        .pipe_in("qcz+=~-")
        .succeeds()
        .stdout_is("qcz+=~-");
}

#[test]
fn test_interpret_single_octal_escape() {
    new_ucmd!()
        .args(&["X", r"\015"])
        .pipe_in("X")
        .succeeds()
        .stdout_is("\r");
}

#[test]
fn test_interpret_one_and_two_digit_octal_escape() {
    new_ucmd!()
        .args(&["XYZ", r"\0\11\77"])
        .pipe_in("XYZ")
        .succeeds()
        .stdout_is("\0\t?");
}

#[test]
fn test_octal_escape_is_at_most_three_digits() {
    new_ucmd!()
        .args(&["XY", r"\0156"])
        .pipe_in("XY")
        .succeeds()
        .stdout_is("\r6");
}

#[test]
fn test_non_octal_digit_ends_escape() {
    new_ucmd!()
        .args(&["rust", r"\08\11956"])
        .pipe_in("rust")
        .succeeds()
        .stdout_is("\08\t9");
}

#[test]
fn test_interpret_backslash_at_eol_literally() {
    new_ucmd!()
        .args(&["X", r"\"])
        .pipe_in("X")
        .succeeds()
        .stdout_is("\\");
}

#[test]
fn test_more_than_2_sets() {
    new_ucmd!()
        .args(&["'abcdefgh'", "'a", "'b'"])
        .pipe_in("hello world")
        .fails();
}

#[test]
fn basic_translation_works() {
    // echo -n "abcdefabcdef" | tr "dabcdef"  "xyz"
    new_ucmd!()
        .args(&["abcdef", "xyz"])
        .pipe_in("abcdefabcdef")
        .succeeds()
        .stdout_is("xyzzzzxyzzzz");
}

#[test]
fn alnum_overrides_translation_to_fallback_1() {
    // echo -n "abcdefghijklmnopqrstuvwxyz" | tr "abc[:alpha:]" "xyz"
    new_ucmd!()
        .args(&["abc[:alpha:]", "xyz"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("zzzzzzzzzzzzzzzzzzzzzzzzzz");
}

#[test]
fn alnum_overrides_translation_to_fallback_2() {
    // echo -n "abcdefghijklmnopqrstuvwxyz" | tr "[:alpha:]abc" "xyz"
    new_ucmd!()
        .args(&["[:alpha:]abc", "xyz"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("zzzzzzzzzzzzzzzzzzzzzzzzzz");
}

#[test]
fn overrides_translation_pair_if_repeats() {
    // echo -n 'aaa' | tr "aaa" "xyz"
    new_ucmd!()
        .args(&["aaa", "xyz"])
        .pipe_in("aaa")
        .succeeds()
        .stdout_is("zzz");
}

#[test]
fn uppercase_conversion_works_1() {
    // echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    new_ucmd!()
        .args(&["abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

#[test]
fn uppercase_conversion_works_2() {
    // echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "a-z" "A-Z"
    new_ucmd!()
        .args(&["a-z", "A-Z"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

#[test]
fn uppercase_conversion_works_3() {
    // echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "[:lower:]" "[:upper:]"
    new_ucmd!()
        .args(&["[:lower:]", "[:upper:]"])
        .pipe_in("abcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

#[test]
fn translate_complement_set_in_order() {
    // echo -n '01234' | tr -c '@-~' ' -^'
    new_ucmd!()
        .args(&["-c", "@-~", " -^"])
        .pipe_in("01234")
        .succeeds()
        .stdout_is("PQRST");
}

#[test]
fn alpha_expands_uppercase_lowercase() {
    // echo -n "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alpha:]" " -_"
    new_ucmd!()
        .args(&["[:alpha:]", " -_"])
        .pipe_in("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is(r##" !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS"##);
}

#[test]
fn alnum_expands_number_uppercase_lowercase() {
    // echo -n "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alnum:]" " -_"
    new_ucmd!()
        .args(&["[:alnum:]", " -_"])
        .pipe_in("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
        .succeeds()
        .stdout_is(r##" !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]"##);
}

#[test]
#[ignore = "not expected to fully pass -- any help appreciated!"]
fn check_against_gnu_tr_tests() {
    // echo -n "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alnum:]" " -_"
    new_ucmd!()
        .args(&["abcd", "[]*]"])
        .pipe_in("abcd")
        .succeeds()
        .stdout_is("]]]]");
    new_ucmd!()
        .args(&["abc", "[%*]xyz"])
        .pipe_in("abc")
        .succeeds()
        .stdout_is("xyz");
    new_ucmd!()
        .args(&["", "[.*]"])
        .pipe_in("abc")
        .succeeds()
        .stdout_is("abc");
    new_ucmd!()
        .args(&["-t", "abcd", "xy"])
        .pipe_in("abcde")
        .succeeds()
        .stdout_is("xycde");
}
<|endoftext|>


<commit_before>#[macro_use] extern crate conv;

use conv::TryFrom;

#[derive(Debug, PartialEq)]
enum Get { Up, Down, AllAround }

TryFrom! { (u8)
    enum Get {
        Up,
        /// And
        Down,
        /** And */
        AllAround
    }
}

#[derive(Debug, PartialEq)]
enum GottaGo { GetAway, Fast = 9000, Faster = 9001 }

TryFrom! { (u16)
    enum GottaGo {
        GetAway,
        Fast = 9000,
        /// This show was stupid.
        Faster = 9001
    }
}

#[test]
fn test_try_from() {
    assert_eq!(Get::try_from(0u8), Ok(Get::Up));
    assert_eq!(Get::try_from(1u8), Ok(Get::Down));
    assert_eq!(Get::try_from(2u8), Ok(Get::AllAround));
    assert_eq!(Get::try_from(3u8), Err(3u8));

    assert_eq!(GottaGo::try_from(0u16), Ok(GottaGo::GetAway));
    assert_eq!(GottaGo::try_from(1u16), Err(1u16));
    assert_eq!(GottaGo::try_from(2u16), Err(2u16));
    assert_eq!(GottaGo::try_from(3u16), Err(3u16));
    assert_eq!(GottaGo::try_from(8999u16), Err(8999u16));
    assert_eq!(GottaGo::try_from(9000u16), Ok(GottaGo::Fast));
    assert_eq!(GottaGo::try_from(9001u16), Ok(GottaGo::Faster));
    assert_eq!(GottaGo::try_from(9002u16), Err(8999u16));
}
<commit_msg>Fixed borked TryFrom test.<commit_after>#[macro_use] extern crate conv;

use conv::TryFrom;

#[derive(Debug, PartialEq)]
enum Get { Up, Down, AllAround }

TryFrom! { (u8)
    enum Get {
        Up,
        /// And
        Down,
        /** And */
        AllAround
    }
}

#[derive(Debug, PartialEq)]
enum GottaGo { GetAway, Fast = 9000, Faster = 9001 }

TryFrom! { (u16)
    enum GottaGo {
        GetAway,
        Fast = 9000,
        /// This show was stupid.
        Faster = 9001
    }
}

#[test]
fn test_try_from() {
    assert_eq!(Get::try_from(0u8), Ok(Get::Up));
    assert_eq!(Get::try_from(1u8), Ok(Get::Down));
    assert_eq!(Get::try_from(2u8), Ok(Get::AllAround));
    assert_eq!(Get::try_from(3u8), Err(3u8));

    assert_eq!(GottaGo::try_from(0u16), Ok(GottaGo::GetAway));
    assert_eq!(GottaGo::try_from(1u16), Err(1u16));
    assert_eq!(GottaGo::try_from(2u16), Err(2u16));
    assert_eq!(GottaGo::try_from(3u16), Err(3u16));
    assert_eq!(GottaGo::try_from(8999u16), Err(8999u16));
    assert_eq!(GottaGo::try_from(9000u16), Ok(GottaGo::Fast));
    assert_eq!(GottaGo::try_from(9001u16), Ok(GottaGo::Faster));
    assert_eq!(GottaGo::try_from(9002u16), Err(9002u16));
}
<|endoftext|>


<commit_before>//! Defines basic types and constants like squares, pieces, moves,
//! value.

pub mod board;
pub mod castling;
pub mod moves;
pub mod squares;
pub mod files;
pub mod ranks;

pub use self::board::*;
pub use self::castling::*;
pub use self::moves::*;

/// Represents a notation error.
pub struct NotationError;
<commit_msg>make some modules in chesstypes private<commit_after>//! Defines basic types and constants like squares, pieces, moves,
//! value.

mod board;
mod castling;
mod moves;
pub mod squares;
pub mod files;
pub mod ranks;

pub use self::board::*;
pub use self::castling::*;
pub use self::moves::*;

/// Represents a notation error.
pub struct NotationError;
<|endoftext|>


<commit_before>extern crate rand_core;
extern crate rand_xorshift;
#[cfg(all(feature="serde1", test))] extern crate bincode;

use rand_core::{RngCore, SeedableRng};
use rand_xorshift::XorShiftRng;

#[test]
fn test_xorshift_construction() {
    // Test that various construction techniques produce a working RNG.
    let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
    let mut rng1 = XorShiftRng::from_seed(seed);
    assert_eq!(rng1.next_u64(), 4325440999699518727);

    let _rng2 = XorShiftRng::from_rng(rng1).unwrap();
    // Note: we cannot test the state of _rng2 because from_rng does not
    // fix Endianness. This is allowed in the trait specification.
}

#[test]
fn test_xorshift_true_values() {
    let seed = [16,15,14,13, 12,11,10,9, 8,7,6,5, 4,3,2,1];
    let mut rng = XorShiftRng::from_seed(seed);

    let mut results = [0u32; 9];
    for i in results.iter_mut() { *i = rng.next_u32(); }
    let expected: [u32; 9] = [
        2081028795, 620940381, 269070770, 16943764, 854422573, 29242889,
        1550291885, 1227154591, 271695242];
    assert_eq!(results, expected);

    let mut results = [0u64; 9];
    for i in results.iter_mut() { *i = rng.next_u64(); }
    let expected: [u64; 9] = [
        9247529084182843387, 8321512596129439293, 14104136531997710878,
        6848554330849612046, 343577296533772213, 17828467390962600268,
        9847333257685787782, 7717352744383350108, 1133407547287910111];
    assert_eq!(results, expected);

    let mut results = [0u8; 32];
    rng.fill_bytes(&mut results);
    let expected = [102, 57, 212, 16, 233, 130, 49, 183,
                    158, 187, 44, 203, 63, 149, 45, 17,
                    117, 129, 131, 160, 70, 121, 158, 155,
                    224, 209, 192, 53, 10, 62, 57, 72];
    assert_eq!(results, expected);
}

#[test]
fn test_xorshift_zero_seed() {
    // Xorshift does not work with an all zero seed.
    // Assert it does not panic.
    let seed = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
    let mut rng = XorShiftRng::from_seed(seed);
    let a = rng.next_u64();
    let b = rng.next_u64();
    assert!(a != 0);
    assert!(b != a);
}

#[test]
fn test_xorshift_clone() {
    let seed = [1,2,3,4, 5,5,7,8, 8,7,6,5, 4,3,2,1];
    let mut rng1 = XorShiftRng::from_seed(seed);
    let mut rng2 = rng1.clone();
    for _ in 0..16 {
        assert_eq!(rng1.next_u64(), rng2.next_u64());
    }
}

#[cfg(feature="serde1")]
#[test]
fn test_xorshift_serde() {
    use bincode;
    use std::io::{BufWriter, BufReader};

    let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
    let mut rng = XorShiftRng::from_seed(seed);

    let buf: Vec<u8> = Vec::new();
    let mut buf = BufWriter::new(buf);
    bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");

    let buf = buf.into_inner().unwrap();
    let mut read = BufReader::new(&buf[..]);
    let mut deserialized: XorShiftRng = bincode::deserialize_from(&mut read)
        .expect("Could not deserialize");

    for _ in 0..16 {
        assert_eq!(rng.next_u64(), deserialized.next_u64());
    }
}
<commit_msg>Update XorShiftRng::from_rng test<commit_after>extern crate rand_core;
extern crate rand_xorshift;
#[cfg(all(feature="serde1", test))] extern crate bincode;

use rand_core::{RngCore, SeedableRng};
use rand_xorshift::XorShiftRng;

#[test]
fn test_xorshift_construction() {
    // Test that various construction techniques produce a working RNG.
    let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
    let mut rng1 = XorShiftRng::from_seed(seed);
    assert_eq!(rng1.next_u64(), 4325440999699518727);

    let mut rng2 = XorShiftRng::from_rng(&mut rng1).unwrap();
    // Yes, this makes rng2 a clone of rng1!
    assert_eq!(rng1.next_u64(), 15614385950550801700);
    assert_eq!(rng2.next_u64(), 15614385950550801700);
}

#[test]
fn test_xorshift_true_values() {
    let seed = [16,15,14,13, 12,11,10,9, 8,7,6,5, 4,3,2,1];
    let mut rng = XorShiftRng::from_seed(seed);

    let mut results = [0u32; 9];
    for i in results.iter_mut() { *i = rng.next_u32(); }
    let expected: [u32; 9] = [
        2081028795, 620940381, 269070770, 16943764, 854422573, 29242889,
        1550291885, 1227154591, 271695242];
    assert_eq!(results, expected);

    let mut results = [0u64; 9];
    for i in results.iter_mut() { *i = rng.next_u64(); }
    let expected: [u64; 9] = [
        9247529084182843387, 8321512596129439293, 14104136531997710878,
        6848554330849612046, 343577296533772213, 17828467390962600268,
        9847333257685787782, 7717352744383350108, 1133407547287910111];
    assert_eq!(results, expected);

    let mut results = [0u8; 32];
    rng.fill_bytes(&mut results);
    let expected = [102, 57, 212, 16, 233, 130, 49, 183,
                    158, 187, 44, 203, 63, 149, 45, 17,
                    117, 129, 131, 160, 70, 121, 158, 155,
                    224, 209, 192, 53, 10, 62, 57, 72];
    assert_eq!(results, expected);
}

#[test]
fn test_xorshift_zero_seed() {
    // Xorshift does not work with an all zero seed.
    // Assert it does not panic.
    let seed = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
    let mut rng = XorShiftRng::from_seed(seed);
    let a = rng.next_u64();
    let b = rng.next_u64();
    assert!(a != 0);
    assert!(b != a);
}

#[test]
fn test_xorshift_clone() {
    let seed = [1,2,3,4, 5,5,7,8, 8,7,6,5, 4,3,2,1];
    let mut rng1 = XorShiftRng::from_seed(seed);
    let mut rng2 = rng1.clone();
    for _ in 0..16 {
        assert_eq!(rng1.next_u64(), rng2.next_u64());
    }
}

#[cfg(feature="serde1")]
#[test]
fn test_xorshift_serde() {
    use bincode;
    use std::io::{BufWriter, BufReader};

    let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
    let mut rng = XorShiftRng::from_seed(seed);

    let buf: Vec<u8> = Vec::new();
    let mut buf = BufWriter::new(buf);
    bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");

    let buf = buf.into_inner().unwrap();
    let mut read = BufReader::new(&buf[..]);
    let mut deserialized: XorShiftRng = bincode::deserialize_from(&mut read)
        .expect("Could not deserialize");

    for _ in 0..16 {
        assert_eq!(rng.next_u64(), deserialized.next_u64());
    }
}
<|endoftext|>