<commit_before>use std::path::posix::Path;
use std::io::fs::PathExtensions;
use std::io::process::Command;

mod io;

static TEMPLATE: &'static str = include_str!("template.toml");

pub fn main(path: Path) {
    if !path.exists() {
        let filename = path.filename().unwrap();
        let template = modified_template(TEMPLATE, filename);

        try_or_err!(io::create(&path, template.as_slice()), "Failed to create project file");

        match is_default_editor_set() {
            true  => io::open(&path),
            false => println!("Default editor is not set. Your config has been created and can be found in ~/.muxed/. Please define $EDITOR in your ~/.bashrc or similar file.")
        }
    } else {
        println!("Project already exists.");
    }
}

/// Run `which $EDITOR` to see if a default editor is defined on the system.
fn is_default_editor_set() -> bool {
  let output = match Command::new("which").arg("$EDITOR").output() {
      Ok(output) => output.output.to_string(),
      Err(e)     => fail!("failed to execute process: {}", e),
  };

  !output.is_empty()
}

fn modified_template(template: &str, project_name: &[u8]) -> String {
    let name = String::from_utf8(project_name.to_vec()).unwrap();
    template.replace("{file_name}", name.as_slice())
}

#[test]
fn populates_template_values() {
    let name   = "muxed projects".as_bytes();
    let value  = modified_template(TEMPLATE, name);
    let result = value.as_slice().contains("muxed project");
    assert!(result);
}

#[test]
fn removes_template_placeholders() {
    let name   = "muxed projects".as_bytes();
    let value  = modified_template(TEMPLATE, name);
    let result = !value.as_slice().contains("{file_name}");
    assert!(result);
}

//#[test]
//fn create_copies_the_template_file() {
//    let muxed_dir = &root::muxed_dir();
//    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), random_name()));
//    let filename = project_filename(path);
//    create_project_file(path);
//    let data = File::open(path).read_to_end().unwrap();
//    let template_expectation = modified_template(TEMPLATE, filename.as_slice());
//    assert_eq!(data.as_slice(), template_expectation.as_bytes());
//
//    cleanup_dir(muxed_dir);
//}

//#[test]
//fn new_writes_file_to_muxed_dir() {
//    let name = random_name();
//    let muxed_dir = root::muxed_dir();
//    let path = &Path::new(format!("{}/{}", muxed_dir.display(), name));
//
//    println!("{}", path.display());
//
//    new(name.as_slice());
//    assert!(path.exists());
//
//    cleanup_dir(path);
//}
<commit_msg>Remove never-working integration tests.<commit_after>use std::path::posix::Path;
use std::io::fs::PathExtensions;
use std::io::process::Command;

mod io;

static TEMPLATE: &'static str = include_str!("template.toml");

pub fn main(path: Path) {
    if !path.exists() {
        let filename = path.filename().unwrap();
        let template = modified_template(TEMPLATE, filename);

        try_or_err!(io::create(&path, template.as_slice()), "Failed to create project file");

        match is_default_editor_set() {
            true  => io::open(&path),
            false => println!("Default editor is not set. Your config has been created and can be found in ~/.muxed/. Please define $EDITOR in your ~/.bashrc or similar file.")
        }
    } else {
        println!("Project already exists.");
    }
}

/// Run `which $EDITOR` to see if a default editor is defined on the system.
fn is_default_editor_set() -> bool {
  let output = match Command::new("which").arg("$EDITOR").output() {
      Ok(output) => output.output.to_string(),
      Err(e)     => fail!("failed to execute process: {}", e),
  };

  !output.is_empty()
}

fn modified_template(template: &str, project_name: &[u8]) -> String {
    let name = String::from_utf8(project_name.to_vec()).unwrap();
    template.replace("{file_name}", name.as_slice())
}

#[test]
fn populates_template_values() {
    let name   = "muxed projects".as_bytes();
    let value  = modified_template(TEMPLATE, name);
    let result = value.as_slice().contains("muxed project");
    assert!(result);
}

#[test]
fn removes_template_placeholders() {
    let name   = "muxed projects".as_bytes();
    let value  = modified_template(TEMPLATE, name);
    let result = !value.as_slice().contains("{file_name}");
    assert!(result);
}
//}
<|endoftext|>


<commit_before>use std::f32;

use num::{Complex, FromPrimitive, Signed, Zero};

use algorithm::FFTAlgorithm;
use butterflies::{butterfly_2, butterfly_3, butterfly_4, butterfly_5, butterfly};

pub struct CooleyTukey<T> {
    twiddles: Vec<Complex<T>>,
    factors: Vec<usize>,
    scratch: Vec<Complex<T>>,
    inverse: bool,
}

impl<T> CooleyTukey<T>
    where T: Signed + FromPrimitive + Copy
{
    pub fn new(len: usize, factors: &[(usize, usize)], inverse: bool) -> Self {
        let dir = if inverse {
            1
        } else {
            -1
        };
        let max_fft_len = factors.iter().map(|&(a, _)| a).max();
        let scratch = match max_fft_len {
            None | Some(0...5) => vec![Zero::zero(); 0],
            Some(l) => vec![Zero::zero(); l],
        };

        CooleyTukey {
            twiddles: (0..len)
                .map(|i| dir as f32 * i as f32 * 2.0 * f32::consts::PI / len as f32)
                .map(|phase| Complex::from_polar(&1.0, &phase))
                .map(|c| {
                    Complex {
                        re: FromPrimitive::from_f32(c.re).unwrap(),
                        im: FromPrimitive::from_f32(c.im).unwrap(),
                    }
                })
                .collect(),
            factors: CooleyTukey::<T>::expand_factors(factors),
            scratch: scratch,
            inverse: inverse,
        }
    }

    fn expand_factors(factors: &[(usize, usize)]) -> Vec<usize> {
        let count = factors.iter().map(|&(_, count)| count).sum();

        let mut expanded_factors = Vec::with_capacity(count);
        for &(factor, count) in factors {
            for _ in 0..count {
                expanded_factors.push(factor);
            }
        }

        expanded_factors
    }
}

impl<T> FFTAlgorithm<T> for CooleyTukey<T>
    where T: Signed + FromPrimitive + Copy
{
    /// Runs the FFT on the input `signal` array, placing the output in the 'spectrum' array
    fn process(&mut self, signal: &[Complex<T>], spectrum: &mut [Complex<T>]) {
        cooley_tukey(signal.len(), signal,
                     spectrum,
                     1,
                     self.twiddles.as_slice(),
                     self.factors.as_slice(),
                     self.scratch.as_mut_slice(),
                     self.inverse);
    }
}

fn cooley_tukey<T>(size: usize,
                   signal: &[Complex<T>],
                   spectrum: &mut [Complex<T>],
                   stride: usize,
                   twiddles: &[Complex<T>],
                   factors: &[usize],
                   scratch: &mut [Complex<T>],
                   inverse: bool)
    where T: Signed + FromPrimitive + Copy
{
    if let Some(&n1) = factors.first() {
        let n2 = size / n1;
        if n2 == 1 {
            // we theoretically need to compute n1 ffts of size n2
            // but n2 is 1, and a fft of size 1 is just a copy
            copy_data(signal, spectrum, stride);
        } else {
            // Recursive call to perform n1 ffts of length n2
            for i in 0..n1 {
                cooley_tukey(n2,
                             &signal[i * stride..],
                             &mut spectrum[i * n2..],
                             stride * n1,
                             twiddles,
                             &factors[1..],
                             scratch,
                             inverse);
            }
        }

        match n1 {
            5 => unsafe { butterfly_5(spectrum, stride, twiddles, n2) },
            4 => unsafe { butterfly_4(spectrum, stride, twiddles, n2, inverse) },
            3 => unsafe { butterfly_3(spectrum, stride, twiddles, n2) },
            2 => unsafe { butterfly_2(spectrum, stride, twiddles, n2) },
            _ => butterfly(spectrum, stride, twiddles, n2, n1, &mut scratch[..n1]),
        }
    }
}

fn copy_data<T: Copy>(signal: &[Complex<T>], spectrum: &mut [Complex<T>], stride: usize) {
    let mut spectrum_idx = 0usize;
    let mut signal_idx = 0usize;
    while signal_idx < signal.len() {
        unsafe {
            *spectrum.get_unchecked_mut(spectrum_idx) = *signal.get_unchecked(signal_idx);
        }
        spectrum_idx += 1;
        signal_idx += stride;
    }
}
<commit_msg>replaced unstable 'sum' call with 'fold'<commit_after>use std::f32;

use num::{Complex, FromPrimitive, Signed, Zero};

use algorithm::FFTAlgorithm;
use butterflies::{butterfly_2, butterfly_3, butterfly_4, butterfly_5, butterfly};

pub struct CooleyTukey<T> {
    twiddles: Vec<Complex<T>>,
    factors: Vec<usize>,
    scratch: Vec<Complex<T>>,
    inverse: bool,
}

impl<T> CooleyTukey<T>
    where T: Signed + FromPrimitive + Copy
{
    pub fn new(len: usize, factors: &[(usize, usize)], inverse: bool) -> Self {
        let dir = if inverse {
            1
        } else {
            -1
        };
        let max_fft_len = factors.iter().map(|&(a, _)| a).max();
        let scratch = match max_fft_len {
            None | Some(0...5) => vec![Zero::zero(); 0],
            Some(l) => vec![Zero::zero(); l],
        };

        CooleyTukey {
            twiddles: (0..len)
                .map(|i| dir as f32 * i as f32 * 2.0 * f32::consts::PI / len as f32)
                .map(|phase| Complex::from_polar(&1.0, &phase))
                .map(|c| {
                    Complex {
                        re: FromPrimitive::from_f32(c.re).unwrap(),
                        im: FromPrimitive::from_f32(c.im).unwrap(),
                    }
                })
                .collect(),
            factors: CooleyTukey::<T>::expand_factors(factors),
            scratch: scratch,
            inverse: inverse,
        }
    }

    fn expand_factors(factors: &[(usize, usize)]) -> Vec<usize> {
        let count = factors.iter().map(|&(_, count)| count).fold(0, |acc, x| acc + x);

        let mut expanded_factors = Vec::with_capacity(count);
        for &(factor, count) in factors {
            for _ in 0..count {
                expanded_factors.push(factor);
            }
        }

        expanded_factors
    }
}

impl<T> FFTAlgorithm<T> for CooleyTukey<T>
    where T: Signed + FromPrimitive + Copy
{
    /// Runs the FFT on the input `signal` array, placing the output in the 'spectrum' array
    fn process(&mut self, signal: &[Complex<T>], spectrum: &mut [Complex<T>]) {
        cooley_tukey(signal.len(), signal,
                     spectrum,
                     1,
                     self.twiddles.as_slice(),
                     self.factors.as_slice(),
                     self.scratch.as_mut_slice(),
                     self.inverse);
    }
}

fn cooley_tukey<T>(size: usize,
                   signal: &[Complex<T>],
                   spectrum: &mut [Complex<T>],
                   stride: usize,
                   twiddles: &[Complex<T>],
                   factors: &[usize],
                   scratch: &mut [Complex<T>],
                   inverse: bool)
    where T: Signed + FromPrimitive + Copy
{
    if let Some(&n1) = factors.first() {
        let n2 = size / n1;
        if n2 == 1 {
            // we theoretically need to compute n1 ffts of size n2
            // but n2 is 1, and a fft of size 1 is just a copy
            copy_data(signal, spectrum, stride);
        } else {
            // Recursive call to perform n1 ffts of length n2
            for i in 0..n1 {
                cooley_tukey(n2,
                             &signal[i * stride..],
                             &mut spectrum[i * n2..],
                             stride * n1,
                             twiddles,
                             &factors[1..],
                             scratch,
                             inverse);
            }
        }

        match n1 {
            5 => unsafe { butterfly_5(spectrum, stride, twiddles, n2) },
            4 => unsafe { butterfly_4(spectrum, stride, twiddles, n2, inverse) },
            3 => unsafe { butterfly_3(spectrum, stride, twiddles, n2) },
            2 => unsafe { butterfly_2(spectrum, stride, twiddles, n2) },
            _ => butterfly(spectrum, stride, twiddles, n2, n1, &mut scratch[..n1]),
        }
    }
}

fn copy_data<T: Copy>(signal: &[Complex<T>], spectrum: &mut [Complex<T>], stride: usize) {
    let mut spectrum_idx = 0usize;
    let mut signal_idx = 0usize;
    while signal_idx < signal.len() {
        unsafe {
            *spectrum.get_unchecked_mut(spectrum_idx) = *signal.get_unchecked(signal_idx);
        }
        spectrum_idx += 1;
        signal_idx += stride;
    }
}
<|endoftext|>


<commit_before>
///
/// Systems are a set of event handlers and optionally some associated state.
///
/// The event handlers are invoked with a list of event data and have access to component
/// lists. This access can be immutable or mutable which is made explicit so that
/// the event handler scheduler might parallelize handler invocations.
///
/// To properly enforce this I guess the scheduler would acquire the locks on the component
/// lists.
///
/// So the context of the handler function would consist of:
///
///   The handler state
///   The event data list
///   Immutable components lists
///   Mutable components lists
///
/// For example the following invocation:
///
/// system! my_system {
///   state! { i: i64 }
///   on!(event_name, { positions: Position}, { descriptions: Description }) {
///     state.i += 1;
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
/// }
///
/// Expands to:
///
/// pub mod my_system {
///   struct State { i: i64 }
///
///   pub fn event_name(state: &mut State, data: &Vec<event_name::Data>, positions: &Vec<Position>, descriptions: &mut Vec<Description> ) {
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
///
///   pub fn register() {
///      events::register_handler(event_name); // etc..
///   }
/// }
///
/// How are we going to register this handler at the event loop?
///
/// Ideally we would have just one 'register' call per system. But to have that the register call should enable
/// all nested handlers. We could also just have one handler per system. That would make things easier..
/// Maybe there's some scheme using recursive macros that we could use to generate a register_system that collects
/// all on! calls. Ok this is definitely a possibility. We could simply match the on! macro in the system! macro
/// and use that to populate the register function.
///
/// How are we going to store/invoke these handlers.
///
/// To invoke the handler it will require the state, the components and the data list passed in the right order.
/// we could have a separate invoker function that invokes event_name with the arguments passed in. Its arguments
/// would be the component lists in two vecs, as well as the event data list.
///
/// This could work!
///

#[macro_export]
macro_rules! system {
	( $system_name:ident { $($contents:tt)* } ) => {
		pub mod $system_name {
			use std::collections::HashMap;
			use std::any::Any;
			use shared_mutex::{ SharedMutex, MappedSharedMutexReadGuard };

			system_contents!{ ( $($contents)* ) [ ] }
		}
	}
}

#[macro_export]
macro_rules! system_contents {
	// Consume on! invocations
	(
		(
			on! (
				$event_name:ident, $($event_declaration:tt)*
			) $_self:ident, $_data:ident => $event_body:block $($rest:tt)*
		) [
			$($event_decls:tt)*
		]
	) => (
		on! { ($event_name, $( $event_declaration)* ) $_self , $_data => $event_body }

		system_contents!{( $($rest)* ) [ ( $event_name, $($event_declaration)* ) , $($event_decls)* ] }
	);

	(
		(
			state! { $($state_declaration:tt)* } $($rest:tt)*
		) [ $($event_decls:tt)* ]
	) => (
		state! { $($state_declaration)* }

		system_contents!{( $($rest)* ) [ $($event_decls)* ] }
	);

	// When all content has been consumed emit register macro
	(
		() [ $($event_decls:tt)* ]
	) => (
		system_register!{ $($event_decls)* }
	)
}

#[macro_export]
macro_rules! on {
	( ($event_name:ident, { $( $mut_name:ident : $mut_typ:ty )* } , { $($name:ident : $typ:ty)* } )
		$_self:ident, $_data:ident => $event_body:block ) => (

		use super::$event_name;

		impl State {
			pub fn $event_name(&mut $_self,
				$_data: Vec<$event_name::Data>,
				$( $name : &Vec<$typ>),*
				$( $mut_name : &Vec<$mut_typ> ),* ) $event_body

		}

		pub fn $event_name(data: Vec<$event_name::Data>, components: Vec<&Any>, mut mut_components: Vec<&mut Any>) {
			let mut components_iter = components.iter();
			let mut mut_components_iter = mut_components.iter_mut();

			$(
				let $name : &Vec<$typ> = components_iter
					.next().expect("Event components list too short.")
					.downcast_ref().expect("Event component not of expected type.");
			)*

			$(
				let $mut_name: &mut Vec<$mut_typ> = mut_components_iter
					.next().expect("Event mut_components list too short.")
					.downcast_mut().expect("Event component not of expected type.");
			)*

			state.write().expect("Event state corrupted").$event_name(
				data,
				$($name),*
				$($mut_name),*
			);
		}
	)
}

#[macro_export]
macro_rules! state {
	( $( $name:ident : $field:ty )* ) => (
		#[derive(Default)]
		pub struct State {
			pub $($name : $field),*
		}

		lazy_static! {
			pub static ref state: SharedMutex<State> = SharedMutex::new(State::default());
		}
	)
}

#[macro_export]
macro_rules! system_register {
	( $($event_decls:tt)* )=> (
		pub fn register() {
		}
	)
}
<commit_msg>fix error with comma in system contents macro<commit_after>
///
/// Systems are a set of event handlers and optionally some associated state.
///
/// The event handlers are invoked with a list of event data and have access to component
/// lists. This access can be immutable or mutable which is made explicit so that
/// the event handler scheduler might parallelize handler invocations.
///
/// To properly enforce this I guess the scheduler would acquire the locks on the component
/// lists.
///
/// So the context of the handler function would consist of:
///
///   The handler state
///   The event data list
///   Immutable components lists
///   Mutable components lists
///
/// For example the following invocation:
///
/// system! my_system {
///   state! { i: i64 }
///   on!(event_name, { positions: Position}, { descriptions: Description }) {
///     state.i += 1;
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
/// }
///
/// Expands to:
///
/// pub mod my_system {
///   struct State { i: i64 }
///
///   pub fn event_name(state: &mut State, data: &Vec<event_name::Data>, positions: &Vec<Position>, descriptions: &mut Vec<Description> ) {
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
///
///   pub fn register() {
///      events::register_handler(event_name); // etc..
///   }
/// }
///
/// How are we going to register this handler at the event loop?
///
/// Ideally we would have just one 'register' call per system. But to have that the register call should enable
/// all nested handlers. We could also just have one handler per system. That would make things easier..
/// Maybe there's some scheme using recursive macros that we could use to generate a register_system that collects
/// all on! calls. Ok this is definitely a possibility. We could simply match the on! macro in the system! macro
/// and use that to populate the register function.
///
/// How are we going to store/invoke these handlers.
///
/// To invoke the handler it will require the state, the components and the data list passed in the right order.
/// we could have a separate invoker function that invokes event_name with the arguments passed in. Its arguments
/// would be the component lists in two vecs, as well as the event data list.
///
/// This could work!
///

#[macro_export]
macro_rules! system {
	( $system_name:ident { $($contents:tt)* } ) => {
		pub mod $system_name {
			use std::collections::HashMap;
			use std::any::Any;
			use shared_mutex::{ SharedMutex, MappedSharedMutexReadGuard };

			system_contents!{ ( $($contents)* ) [ ] }
		}
	}
}

#[macro_export]
macro_rules! system_contents {
	// Consume on! invocations
	(
		(
			on! (
				$event_name:ident, $($event_declaration:tt)*
			) $_self:ident, $_data:ident => $event_body:block $($rest:tt)*
		) [
			$( $saved_decl:ident ),*
		]
	) => (
		on! { ($event_name, $( $event_declaration)* ) $_self , $_data => $event_body }

		system_contents!{
			( $($rest)* )
			[ $event_name $(, $saved_decl)* ]
		}
	);

	(
		(
			state! { $($state_declaration:tt)* } $($rest:tt)*
		) [
			$( $event_decl:ident ),*
		]
	) => (
		state! { $($state_declaration)* }

		system_contents!{
			( $($rest)* )
			[ $( $event_decl ),* ]
		}
	);

	// When all content has been consumed emit register macro
	(
		() [ $($event_name:ident),* ]
	) => (
		system_register!{ $( $event_name ),* }
	)
}

#[macro_export]
macro_rules! on {
	( ($event_name:ident, { $( $mut_name:ident : $mut_typ:ty )* } , { $($name:ident : $typ:ty)* } )
		$_self:ident, $_data:ident => $event_body:block ) => (

		use super::$event_name;

		impl State {
			pub fn $event_name(&mut $_self,
				$_data: Vec<$event_name::Data>,
				$( $name : &Vec<$typ>),*
				$( $mut_name : &Vec<$mut_typ> ),* ) $event_body

		}

		pub fn $event_name(data: Vec<$event_name::Data>, components: Vec<&Any>, mut mut_components: Vec<&mut Any>) {
			let mut components_iter = components.iter();
			let mut mut_components_iter = mut_components.iter_mut();

			$(
				let $name : &Vec<$typ> = components_iter
					.next().expect("Event components list too short.")
					.downcast_ref().expect("Event component not of expected type.");
			)*

			$(
				let $mut_name: &mut Vec<$mut_typ> = mut_components_iter
					.next().expect("Event mut_components list too short.")
					.downcast_mut().expect("Event component not of expected type.");
			)*

			state.write().expect("Event state corrupted").$event_name(
				data,
				$($name),*
				$($mut_name),*
			);
		}
	)
}

#[macro_export]
macro_rules! state {
	( $( $name:ident : $field:ty )* ) => (
		#[derive(Default)]
		pub struct State {
			pub $($name : $field),*
		}

		lazy_static! {
			pub static ref state: SharedMutex<State> = SharedMutex::new(State::default());
		}
	)
}

#[macro_export]
macro_rules! system_register {
	( $( $event_name:ident ),* ) => (
		pub fn register() {
			$(
				super::$event_name.register_handler($event_name)
			)*
		}
	)
}
<|endoftext|>


<commit_before>
/// Implemented by contexts that can transform.
pub trait Transform2d<'a> {
    /// Translate x and y.
    fn trans(&'a self, x: f64, y: f64) -> Self;

    /// Rotates degrees.
    #[inline(always)]
    fn rot_deg(&'a self, angle: f64) -> Self {
        let pi: f64 = Float::pi();
        self.rot_rad(angle * pi / 180.0)
    }

    /// Rotate radians.
    fn rot_rad(&'a self, angle: f64) -> Self;
    /// Scale.
    fn scale(&'a self, sx: f64, sy: f64) -> Self;
    /// Shear.
    fn shear(&'a self, sx: f64, sy: f64) -> Self;
}
<commit_msg>Add `zoom`<commit_after>
/// Implemented by contexts that can transform.
pub trait Transform2d<'a> {
    /// Translate x and y.
    fn trans(&'a self, x: f64, y: f64) -> Self;

    /// Rotates degrees.
    #[inline(always)]
    fn rot_deg(&'a self, angle: f64) -> Self {
        let pi: f64 = Float::pi();
        self.rot_rad(angle * pi / 180.0)
    }

    /// Rotate radians.
    fn rot_rad(&'a self, angle: f64) -> Self;
    /// Scale.
    fn scale(&'a self, sx: f64, sy: f64) -> Self;

    /// Scales in both directions.
    #[inline(always)]
    fn zoom(&'a self, s: f64) -> Self {
        self.scale(s, s)
    }

    /// Shear.
    fn shear(&'a self, sx: f64, sy: f64) -> Self;
}
<|endoftext|>


<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Anthony Deschamps <anthony.j.deschamps@gmail.com>
// (c) Sylvestre Ledru <sylvestre@debian.org>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (format) MMDDhhmm
// spell-checker:ignore (ToDO) DATEFILE

#[macro_use]
extern crate uucore;

use chrono::{DateTime, FixedOffset, Local, Offset, Utc};
#[cfg(windows)]
use chrono::{Datelike, Timelike};
use clap::{App, Arg};
#[cfg(all(unix, not(target_os = "macos")))]
use libc::{clock_settime, timespec, CLOCK_REALTIME};
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
#[cfg(windows)]
use winapi::{
    shared::minwindef::WORD,
    um::{minwinbase::SYSTEMTIME, sysinfoapi::SetSystemTime},
};

// Options
const DATE: &str = "date";
const HOURS: &str = "hours";
const MINUTES: &str = "minutes";
const SECONDS: &str = "seconds";
const HOUR: &str = "hour";
const MINUTE: &str = "minute";
const SECOND: &str = "second";
const NS: &str = "ns";

const NAME: &str = "date";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const ABOUT: &str = "print or set the system date and time";

const OPT_DATE: &str = "date";
const OPT_FORMAT: &str = "format";
const OPT_FILE: &str = "file";
const OPT_DEBUG: &str = "debug";
const OPT_ISO_8601: &str = "iso-8601";
const OPT_RFC_EMAIL: &str = "rfc-email";
const OPT_RFC_3339: &str = "rfc-3339";
const OPT_SET: &str = "set";
const OPT_REFERENCE: &str = "reference";
const OPT_UNIVERSAL: &str = "universal";
const OPT_UNIVERSAL_2: &str = "utc";

// Help strings

static ISO_8601_HELP_STRING: &str = "output date/time in ISO 8601 format.
 FMT='date' for date only (the default),
 'hours', 'minutes', 'seconds', or 'ns'
 for date and time to the indicated precision.
 Example: 2006-08-14T02:34:56-06:00";

static RFC_5322_HELP_STRING: &str = "output date and time in RFC 5322 format.
 Example: Mon, 14 Aug 2006 02:34:56 -0600";

static RFC_3339_HELP_STRING: &str = "output date/time in RFC 3339 format.
 FMT='date', 'seconds', or 'ns'
 for date and time to the indicated precision.
 Example: 2006-08-14 02:34:56-06:00";

#[cfg(not(target_os = "macos"))]
static OPT_SET_HELP_STRING: &str = "set time described by STRING";
#[cfg(target_os = "macos")]
static OPT_SET_HELP_STRING: &str = "set time described by STRING (not available on mac yet)";

/// Settings for this program, parsed from the command line
struct Settings {
    utc: bool,
    format: Format,
    date_source: DateSource,
    set_to: Option<DateTime<FixedOffset>>,
}

/// Various ways of displaying the date
enum Format {
    Iso8601(Iso8601Format),
    Rfc5322,
    Rfc3339(Rfc3339Format),
    Custom(String),
    Default,
}

/// Various places that dates can come from
enum DateSource {
    Now,
    Custom(String),
    File(PathBuf),
}

enum Iso8601Format {
    Date,
    Hours,
    Minutes,
    Seconds,
    Ns,
}

impl<'a> From<&'a str> for Iso8601Format {
    fn from(s: &str) -> Self {
        match s {
            HOURS | HOUR => Iso8601Format::Hours,
            MINUTES | MINUTE => Iso8601Format::Minutes,
            SECONDS | SECOND => Iso8601Format::Seconds,
            NS => Iso8601Format::Ns,
            DATE => Iso8601Format::Date,
            // Should be caught by clap
            _ => panic!("Invalid format: {}", s),
        }
    }
}

enum Rfc3339Format {
    Date,
    Seconds,
    Ns,
}

impl<'a> From<&'a str> for Rfc3339Format {
    fn from(s: &str) -> Self {
        match s {
            DATE => Rfc3339Format::Date,
            SECONDS | SECOND => Rfc3339Format::Seconds,
            NS => Rfc3339Format::Ns,
            // Should be caught by clap
            _ => panic!("Invalid format: {}", s),
        }
    }
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let syntax = format!(
        "{0} [OPTION]... [+FORMAT]...
 {0} [OPTION]... [MMDDhhmm[[CC]YY][.ss]]",
        NAME
    );
    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&syntax[..])
        .arg(
            Arg::with_name(OPT_DATE)
                .short("d")
                .long(OPT_DATE)
                .takes_value(true)
                .help("display time described by STRING, not 'now'"),
        )
        .arg(
            Arg::with_name(OPT_FILE)
                .short("f")
                .long(OPT_FILE)
                .takes_value(true)
                .help("like --date; once for each line of DATEFILE"),
        )
        .arg(
            Arg::with_name(OPT_ISO_8601)
                .short("I")
                .long(OPT_ISO_8601)
                .takes_value(true)
                .help(ISO_8601_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_RFC_EMAIL)
                .short("R")
                .long(OPT_RFC_EMAIL)
                .help(RFC_5322_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_RFC_3339)
                .long(OPT_RFC_3339)
                .takes_value(true)
                .help(RFC_3339_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_DEBUG)
                .long(OPT_DEBUG)
                .help("annotate the parsed date, and warn about questionable usage to stderr"),
        )
        .arg(
            Arg::with_name(OPT_REFERENCE)
                .short("r")
                .long(OPT_REFERENCE)
                .takes_value(true)
                .help("display the last modification time of FILE"),
        )
        .arg(
            Arg::with_name(OPT_SET)
                .short("s")
                .long(OPT_SET)
                .takes_value(true)
                .help(OPT_SET_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_UNIVERSAL)
                .short("u")
                .long(OPT_UNIVERSAL)
                .alias(OPT_UNIVERSAL_2)
                .help("print or set Coordinated Universal Time (UTC)"),
        )
        .arg(Arg::with_name(OPT_FORMAT).multiple(true))
        .get_matches_from(args);

    let format = if let Some(form) = matches.value_of(OPT_FORMAT) {
        let form = form[1..].into();
        Format::Custom(form)
    } else if let Some(fmt) = matches
        .values_of(OPT_ISO_8601)
        .map(|mut iter| iter.next().unwrap_or(DATE).into())
    {
        Format::Iso8601(fmt)
    } else if matches.is_present(OPT_RFC_EMAIL) {
        Format::Rfc5322
    } else if let Some(fmt) = matches.value_of(OPT_RFC_3339).map(Into::into) {
        Format::Rfc3339(fmt)
    } else {
        Format::Default
    };

    let date_source = if let Some(date) = matches.value_of(OPT_DATE) {
        DateSource::Custom(date.into())
    } else if let Some(file) = matches.value_of(OPT_FILE) {
        DateSource::File(file.into())
    } else {
        DateSource::Now
    };

    let set_to = match matches.value_of(OPT_SET).map(parse_date) {
        None => None,
        Some(Err((input, _err))) => {
            eprintln!("date: invalid date '{}'", input);
            return 1;
        }
        Some(Ok(date)) => Some(date),
    };

    let settings = Settings {
        utc: matches.is_present(OPT_UNIVERSAL),
        format,
        date_source,
        set_to,
    };

    if let Some(date) = settings.set_to {
        // All set time functions expect UTC datetimes.
        let date: DateTime<Utc> = if settings.utc {
            date.with_timezone(&Utc)
        } else {
            date.into()
        };

        return set_system_datetime(date);
    } else {
        // Declare a file here because it needs to outlive the `dates` iterator.
        let file: File;

        // Get the current time, either in the local time zone or UTC.
        let now: DateTime<FixedOffset> = if settings.utc {
            let now = Utc::now();
            now.with_timezone(&now.offset().fix())
        } else {
            let now = Local::now();
            now.with_timezone(now.offset())
        };

        // Iterate over all dates - whether it's a single date or a file.
        let dates: Box<dyn Iterator<Item = _>> = match settings.date_source {
            DateSource::Custom(ref input) => {
                let date = parse_date(input.clone());
                let iter = std::iter::once(date);
                Box::new(iter)
            }
            DateSource::File(ref path) => {
                file = File::open(path).unwrap();
                let lines = BufReader::new(file).lines();
                let iter = lines.filter_map(Result::ok).map(parse_date);
                Box::new(iter)
            }
            DateSource::Now => {
                let iter = std::iter::once(Ok(now));
                Box::new(iter)
            }
        };

        let format_string = make_format_string(&settings);

        // Format all the dates
        for date in dates {
            match date {
                Ok(date) => {
                    let formatted = date.format(format_string);
                    println!("{}", formatted);
                }
                Err((input, _err)) => {
                    println!("date: invalid date '{}'", input);
                }
            }
        }
    }

    0
}

/// Return the appropriate format string for the given settings.
fn make_format_string(settings: &Settings) -> &str {
    match settings.format {
        Format::Iso8601(ref fmt) => match *fmt {
            Iso8601Format::Date => "%F",
            Iso8601Format::Hours => "%FT%H%:z",
            Iso8601Format::Minutes => "%FT%H:%M%:z",
            Iso8601Format::Seconds => "%FT%T%:z",
            Iso8601Format::Ns => "%FT%T,%f%:z",
        },
        Format::Rfc5322 => "%a, %d %h %Y %T %z",
        Format::Rfc3339(ref fmt) => match *fmt {
            Rfc3339Format::Date => "%F",
            Rfc3339Format::Seconds => "%F %T%:z",
            Rfc3339Format::Ns => "%F %T.%f%:z",
        },
        Format::Custom(ref fmt) => fmt,
        Format::Default => "%c",
    }
}

/// Parse a `String` into a `DateTime`.
/// If it fails, return a tuple of the `String` along with its `ParseError`.
fn parse_date<S: AsRef<str> + Clone>(
    s: S,
) -> Result<DateTime<FixedOffset>, (String, chrono::format::ParseError)> {
    // TODO: The GNU date command can parse a wide variety of inputs.
    s.as_ref().parse().map_err(|e| (s.as_ref().into(), e))
}

#[cfg(not(any(unix, windows)))]
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
    unimplemented!("setting date not implemented (unsupported target)");
}

#[cfg(target_os = "macos")]
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
    eprintln!("date: setting the date is not supported by macOS");
    return 1;
}

#[cfg(all(unix, not(target_os = "macos")))]
/// System call to set date (unix).
/// See here for more:
/// https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html
/// https://linux.die.net/man/3/clock_settime
/// https://www.gnu.org/software/libc/manual/html_node/Time-Types.html
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
    let timespec = timespec {
        tv_sec: date.timestamp() as _,
        tv_nsec: date.timestamp_subsec_nanos() as _,
    };

    let result = unsafe { clock_settime(CLOCK_REALTIME, &timespec) };

    if result != 0 {
        let error = std::io::Error::last_os_error();
        eprintln!("date: cannot set date: {}", error);
        error.raw_os_error().unwrap()
    } else {
        0
    }
}

#[cfg(windows)]
/// System call to set date (Windows).
/// See here for more:
/// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-setsystemtime
/// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
    let system_time = SYSTEMTIME {
        wYear: date.year() as WORD,
        wMonth: date.month() as WORD,
        // Ignored
        wDayOfWeek: 0,
        wDay: date.day() as WORD,
        wHour: date.hour() as WORD,
        wMinute: date.minute() as WORD,
        wSecond: date.second() as WORD,
        // TODO: be careful of leap seconds - valid range is [0, 999] - how to handle?
        wMilliseconds: ((date.nanosecond() / 1_000_000) % 1000) as WORD,
    };

    let result = unsafe { SetSystemTime(&system_time) };

    if result == 0 {
        let error = std::io::Error::last_os_error();
        eprintln!("date: cannot set date: {}", error);
        error.raw_os_error().unwrap()
    } else {
        0
    }
}
<commit_msg>date: unneeded 'return' statement<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Anthony Deschamps <anthony.j.deschamps@gmail.com>
// (c) Sylvestre Ledru <sylvestre@debian.org>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (format) MMDDhhmm
// spell-checker:ignore (ToDO) DATEFILE

#[macro_use]
extern crate uucore;

use chrono::{DateTime, FixedOffset, Local, Offset, Utc};
#[cfg(windows)]
use chrono::{Datelike, Timelike};
use clap::{App, Arg};
#[cfg(all(unix, not(target_os = "macos")))]
use libc::{clock_settime, timespec, CLOCK_REALTIME};
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
#[cfg(windows)]
use winapi::{
    shared::minwindef::WORD,
    um::{minwinbase::SYSTEMTIME, sysinfoapi::SetSystemTime},
};

// Options
const DATE: &str = "date";
const HOURS: &str = "hours";
const MINUTES: &str = "minutes";
const SECONDS: &str = "seconds";
const HOUR: &str = "hour";
const MINUTE: &str = "minute";
const SECOND: &str = "second";
const NS: &str = "ns";

const NAME: &str = "date";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const ABOUT: &str = "print or set the system date and time";

const OPT_DATE: &str = "date";
const OPT_FORMAT: &str = "format";
const OPT_FILE: &str = "file";
const OPT_DEBUG: &str = "debug";
const OPT_ISO_8601: &str = "iso-8601";
const OPT_RFC_EMAIL: &str = "rfc-email";
const OPT_RFC_3339: &str = "rfc-3339";
const OPT_SET: &str = "set";
const OPT_REFERENCE: &str = "reference";
const OPT_UNIVERSAL: &str = "universal";
const OPT_UNIVERSAL_2: &str = "utc";

// Help strings

static ISO_8601_HELP_STRING: &str = "output date/time in ISO 8601 format.
 FMT='date' for date only (the default),
 'hours', 'minutes', 'seconds', or 'ns'
 for date and time to the indicated precision.
 Example: 2006-08-14T02:34:56-06:00";

static RFC_5322_HELP_STRING: &str = "output date and time in RFC 5322 format.
 Example: Mon, 14 Aug 2006 02:34:56 -0600";

static RFC_3339_HELP_STRING: &str = "output date/time in RFC 3339 format.
 FMT='date', 'seconds', or 'ns'
 for date and time to the indicated precision.
 Example: 2006-08-14 02:34:56-06:00";

#[cfg(not(target_os = "macos"))]
static OPT_SET_HELP_STRING: &str = "set time described by STRING";
#[cfg(target_os = "macos")]
static OPT_SET_HELP_STRING: &str = "set time described by STRING (not available on mac yet)";

/// Settings for this program, parsed from the command line
struct Settings {
    utc: bool,
    format: Format,
    date_source: DateSource,
    set_to: Option<DateTime<FixedOffset>>,
}

/// Various ways of displaying the date
enum Format {
    Iso8601(Iso8601Format),
    Rfc5322,
    Rfc3339(Rfc3339Format),
    Custom(String),
    Default,
}

/// Various places that dates can come from
enum DateSource {
    Now,
    Custom(String),
    File(PathBuf),
}

enum Iso8601Format {
    Date,
    Hours,
    Minutes,
    Seconds,
    Ns,
}

impl<'a> From<&'a str> for Iso8601Format {
    fn from(s: &str) -> Self {
        match s {
            HOURS | HOUR => Iso8601Format::Hours,
            MINUTES | MINUTE => Iso8601Format::Minutes,
            SECONDS | SECOND => Iso8601Format::Seconds,
            NS => Iso8601Format::Ns,
            DATE => Iso8601Format::Date,
            // Should be caught by clap
            _ => panic!("Invalid format: {}", s),
        }
    }
}

enum Rfc3339Format {
    Date,
    Seconds,
    Ns,
}

impl<'a> From<&'a str> for Rfc3339Format {
    fn from(s: &str) -> Self {
        match s {
            DATE => Rfc3339Format::Date,
            SECONDS | SECOND => Rfc3339Format::Seconds,
            NS => Rfc3339Format::Ns,
            // Should be caught by clap
            _ => panic!("Invalid format: {}", s),
        }
    }
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let syntax = format!(
        "{0} [OPTION]... [+FORMAT]...
 {0} [OPTION]... [MMDDhhmm[[CC]YY][.ss]]",
        NAME
    );
    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&syntax[..])
        .arg(
            Arg::with_name(OPT_DATE)
                .short("d")
                .long(OPT_DATE)
                .takes_value(true)
                .help("display time described by STRING, not 'now'"),
        )
        .arg(
            Arg::with_name(OPT_FILE)
                .short("f")
                .long(OPT_FILE)
                .takes_value(true)
                .help("like --date; once for each line of DATEFILE"),
        )
        .arg(
            Arg::with_name(OPT_ISO_8601)
                .short("I")
                .long(OPT_ISO_8601)
                .takes_value(true)
                .help(ISO_8601_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_RFC_EMAIL)
                .short("R")
                .long(OPT_RFC_EMAIL)
                .help(RFC_5322_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_RFC_3339)
                .long(OPT_RFC_3339)
                .takes_value(true)
                .help(RFC_3339_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_DEBUG)
                .long(OPT_DEBUG)
                .help("annotate the parsed date, and warn about questionable usage to stderr"),
        )
        .arg(
            Arg::with_name(OPT_REFERENCE)
                .short("r")
                .long(OPT_REFERENCE)
                .takes_value(true)
                .help("display the last modification time of FILE"),
        )
        .arg(
            Arg::with_name(OPT_SET)
                .short("s")
                .long(OPT_SET)
                .takes_value(true)
                .help(OPT_SET_HELP_STRING),
        )
        .arg(
            Arg::with_name(OPT_UNIVERSAL)
                .short("u")
                .long(OPT_UNIVERSAL)
                .alias(OPT_UNIVERSAL_2)
                .help("print or set Coordinated Universal Time (UTC)"),
        )
        .arg(Arg::with_name(OPT_FORMAT).multiple(true))
        .get_matches_from(args);

    let format = if let Some(form) = matches.value_of(OPT_FORMAT) {
        let form = form[1..].into();
        Format::Custom(form)
    } else if let Some(fmt) = matches
        .values_of(OPT_ISO_8601)
        .map(|mut iter| iter.next().unwrap_or(DATE).into())
    {
        Format::Iso8601(fmt)
    } else if matches.is_present(OPT_RFC_EMAIL) {
        Format::Rfc5322
    } else if let Some(fmt) = matches.value_of(OPT_RFC_3339).map(Into::into) {
        Format::Rfc3339(fmt)
    } else {
        Format::Default
    };

    let date_source = if let Some(date) = matches.value_of(OPT_DATE) {
        DateSource::Custom(date.into())
    } else if let Some(file) = matches.value_of(OPT_FILE) {
        DateSource::File(file.into())
    } else {
        DateSource::Now
    };

    let set_to = match matches.value_of(OPT_SET).map(parse_date) {
        None => None,
        Some(Err((input, _err))) => {
            eprintln!("date: invalid date '{}'", input);
            return 1;
        }
        Some(Ok(date)) => Some(date),
    };

    let settings = Settings {
        utc: matches.is_present(OPT_UNIVERSAL),
        format,
        date_source,
        set_to,
    };

    if let Some(date) = settings.set_to {
        // All set time functions expect UTC datetimes.
        let date: DateTime<Utc> = if settings.utc {
            date.with_timezone(&Utc)
        } else {
            date.into()
        };

        return set_system_datetime(date);
    } else {
        // Declare a file here because it needs to outlive the `dates` iterator.
        let file: File;

        // Get the current time, either in the local time zone or UTC.
        let now: DateTime<FixedOffset> = if settings.utc {
            let now = Utc::now();
            now.with_timezone(&now.offset().fix())
        } else {
            let now = Local::now();
            now.with_timezone(now.offset())
        };

        // Iterate over all dates - whether it's a single date or a file.
        let dates: Box<dyn Iterator<Item = _>> = match settings.date_source {
            DateSource::Custom(ref input) => {
                let date = parse_date(input.clone());
                let iter = std::iter::once(date);
                Box::new(iter)
            }
            DateSource::File(ref path) => {
                file = File::open(path).unwrap();
                let lines = BufReader::new(file).lines();
                let iter = lines.filter_map(Result::ok).map(parse_date);
                Box::new(iter)
            }
            DateSource::Now => {
                let iter = std::iter::once(Ok(now));
                Box::new(iter)
            }
        };

        let format_string = make_format_string(&settings);

        // Format all the dates
        for date in dates {
            match date {
                Ok(date) => {
                    let formatted = date.format(format_string);
                    println!("{}", formatted);
                }
                Err((input, _err)) => {
                    println!("date: invalid date '{}'", input);
                }
            }
        }
    }

    0
}

/// Return the appropriate format string for the given settings.
fn make_format_string(settings: &Settings) -> &str {
    match settings.format {
        Format::Iso8601(ref fmt) => match *fmt {
            Iso8601Format::Date => "%F",
            Iso8601Format::Hours => "%FT%H%:z",
            Iso8601Format::Minutes => "%FT%H:%M%:z",
            Iso8601Format::Seconds => "%FT%T%:z",
            Iso8601Format::Ns => "%FT%T,%f%:z",
        },
        Format::Rfc5322 => "%a, %d %h %Y %T %z",
        Format::Rfc3339(ref fmt) => match *fmt {
            Rfc3339Format::Date => "%F",
            Rfc3339Format::Seconds => "%F %T%:z",
            Rfc3339Format::Ns => "%F %T.%f%:z",
        },
        Format::Custom(ref fmt) => fmt,
        Format::Default => "%c",
    }
}

/// Parse a `String` into a `DateTime`.
/// If it fails, return a tuple of the `String` along with its `ParseError`.
fn parse_date<S: AsRef<str> + Clone>(
    s: S,
) -> Result<DateTime<FixedOffset>, (String, chrono::format::ParseError)> {
    // TODO: The GNU date command can parse a wide variety of inputs.
    s.as_ref().parse().map_err(|e| (s.as_ref().into(), e))
}

#[cfg(not(any(unix, windows)))]
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
    unimplemented!("setting date not implemented (unsupported target)");
}

#[cfg(target_os = "macos")]
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
    eprintln!("date: setting the date is not supported by macOS");
    1
}

#[cfg(all(unix, not(target_os = "macos")))]
/// System call to set date (unix).
/// See here for more:
/// https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html
/// https://linux.die.net/man/3/clock_settime
/// https://www.gnu.org/software/libc/manual/html_node/Time-Types.html
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
    let timespec = timespec {
        tv_sec: date.timestamp() as _,
        tv_nsec: date.timestamp_subsec_nanos() as _,
    };

    let result = unsafe { clock_settime(CLOCK_REALTIME, &timespec) };

    if result != 0 {
        let error = std::io::Error::last_os_error();
        eprintln!("date: cannot set date: {}", error);
        error.raw_os_error().unwrap()
    } else {
        0
    }
}

#[cfg(windows)]
/// System call to set date (Windows).
/// See here for more:
/// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-setsystemtime
/// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
    let system_time = SYSTEMTIME {
        wYear: date.year() as WORD,
        wMonth: date.month() as WORD,
        // Ignored
        wDayOfWeek: 0,
        wDay: date.day() as WORD,
        wHour: date.hour() as WORD,
        wMinute: date.minute() as WORD,
        wSecond: date.second() as WORD,
        // TODO: be careful of leap seconds - valid range is [0, 999] - how to handle?
        wMilliseconds: ((date.nanosecond() / 1_000_000) % 1000) as WORD,
    };

    let result = unsafe { SetSystemTime(&system_time) };

    if result == 0 {
        let error = std::io::Error::last_os_error();
        eprintln!("date: cannot set date: {}", error);
        error.raw_os_error().unwrap()
    } else {
        0
    }
}
<|endoftext|>


<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Jordi Boggiano <j.boggiano@seld.be>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

use clap::App;
use uucore::executable;

pub fn uumain(args: impl uucore::Args) -> i32 {
    uu_app().get_matches_from(args);
    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(executable!())
}
<commit_msg>true: added uresult<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Jordi Boggiano <j.boggiano@seld.be>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
#![allow(clippy::nonstandard_macro_braces)]

#[macro_use]
extern crate uucore;

use clap::App;
use uucore::error::UResult;
use uucore::executable;

#[uucore_procs::gen_uumain]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    uu_app().get_matches_from(args);
    Ok(())
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(executable!())
}
<|endoftext|>


<commit_before>use std::char;
use std::cell::Cell;

#[derive(Debug)]
pub enum Value {
    Int(String),
    Str(String),
}

#[derive(Debug, PartialEq)]
pub enum TokenType {
    ILLEGAL,
    EOF,
    IDENT,
    INT,
    ASSIGN,
    PLUS,
    MINUS,
    COMMA,
    SEMICOLON,
    LPAREN,
    RPAREN,
    LBRACE,
    RBRACE,
    FUNCTION,
    LET,
}

impl TokenType {
    pub fn from_string(s: String) -> TokenType {
        match s.trim().as_ref() {
            "\n" => TokenType::EOF,
            "=" => TokenType::ASSIGN,
            "(" => TokenType::LPAREN,
            ")" => TokenType::RPAREN,
            "let" => TokenType::LET,
            "+" => TokenType::PLUS,
            "-" => TokenType::MINUS,
            "," => TokenType::COMMA,
            ";" => TokenType::SEMICOLON,
            "{" => TokenType::LBRACE,
            "}" => TokenType::RBRACE,
            "func" => TokenType::FUNCTION,
            c => TokenType::ILLEGAL
        }
    }
}

#[derive(Debug)]
pub struct Token {
    pub token_type: TokenType,
    pub value: Option<Value>,
}

pub struct Lexer {
    input: String,
    position: Cell<usize>,
    read_position: Cell<usize>,
}

impl Lexer {
    pub fn new(input: String) -> Lexer {
        return Lexer {
            input: input,
            position: Cell::new(0),
            read_position: Cell::new(0),
        };
    }

    pub fn read_char(&self) -> char {
        if self.read_position.get() >= self.input.len() {
            return '0';
        } else {
            let c = self.input.chars().nth(self.read_position.get()).unwrap();
            self.position.set(self.read_position.get());
            self.read_position.set(self.read_position.get() + 1);
            return c;
        }
    }

    pub fn next_token(&self) -> Token {
        let c = self.read_char();
        let token_type = TokenType::from_string(c.to_string());
        return Token {
            token_type: token_type,
            value: Some(Value::Str(c.to_string()))
        };
    }

    pub fn peek_char(&self) -> char {
        if self.read_position.get() >= self.input.len() {
            return '0';
        } else {
            return self.input.chars().nth(self.read_position.get()).unwrap();
        }
    }

    pub fn read_number(&self) {
        let ch = self.peek_char();
        while is_digit(ch) {
            self.read_char();
        }
        // 途中まで実装
//        return self.input.chars().nth(self.position.get()).unwrap();
    }

    pub fn skip_white_space(&self) {
        let ch = self.peek_char();
        while ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' {
            self.read_char();
        }
    }
}

fn is_letter(ch: char) -> bool {
    return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_'
}

fn is_digit(ch: char) -> bool {
    return '0' <= ch && ch <= '9';
}

#[test]
fn read_char() {
    let input = String::from("=!");
    let l = &Lexer::new(input);
    assert_eq!('=', l.read_char());
    assert_eq!('!', l.read_char());
    assert_eq!('0', l.read_char());
}

#[test]
fn peek_char() {
    let input = String::from("!=");
    let l = &Lexer::new(input);
    assert_eq!('!', l.peek_char());
    assert_eq!('!', l.peek_char());
}

#[test]
fn next_token() {
    let input = String::from("=()");
    let l = &Lexer::new(input);
    assert_eq!(l.next_token().token_type, TokenType::ASSIGN);
    assert_eq!(l.next_token().token_type, TokenType::LPAREN);
    assert_eq!(l.next_token().token_type, TokenType::RPAREN);
}

#[test]
fn from_string() {
    assert_eq!(TokenType::from_string(String::from("=")), TokenType::ASSIGN);
    assert_eq!(TokenType::from_string(String::from("(")), TokenType::LPAREN);
}
<commit_msg>add code<commit_after>use std::char;
use std::cell::Cell;

#[derive(Debug)]
pub enum Value {
    Int(String),
    Str(String),
}

#[derive(Debug, PartialEq)]
pub enum TokenType {
    ILLEGAL,
    EOF,
    IDENT,
    INT,
    ASSIGN,
    PLUS,
    MINUS,
    COMMA,
    SEMICOLON,
    LPAREN,
    RPAREN,
    LBRACE,
    RBRACE,
    FUNCTION,
    LET,
}

impl TokenType {
    pub fn from_string(s: String) -> TokenType {
        match s.trim().as_ref() {
            "\n" => TokenType::EOF,
            "=" => TokenType::ASSIGN,
            "(" => TokenType::LPAREN,
            ")" => TokenType::RPAREN,
            "let" => TokenType::LET,
            "+" => TokenType::PLUS,
            "-" => TokenType::MINUS,
            "," => TokenType::COMMA,
            ";" => TokenType::SEMICOLON,
            "{" => TokenType::LBRACE,
            "}" => TokenType::RBRACE,
            "func" => TokenType::FUNCTION,
            c => TokenType::ILLEGAL
        }
    }
}

#[derive(Debug)]
pub struct Token {
    pub token_type: TokenType,
    pub value: Option<Value>,
}

pub struct Lexer {
    input: String,
    position: Cell<usize>,
    read_position: Cell<usize>,
}

impl Lexer {
    pub fn new(input: String) -> Lexer {
        return Lexer {
            input: input,
            position: Cell::new(0),
            read_position: Cell::new(0),
        };
    }

    pub fn read_char(&self) -> char {
        if self.read_position.get() >= self.input.len() {
            return '0';
        } else {
            let c = self.input.chars().nth(self.read_position.get()).unwrap();
            self.position.set(self.read_position.get());
            self.read_position.set(self.read_position.get() + 1);
            return c;
        }
    }

    pub fn next_token(&self) -> Token {
        let c = self.read_char();
        let token_type = TokenType::from_string(c.to_string());
        return Token {
            token_type: token_type,
            value: Some(Value::Str(c.to_string()))
        };
    }

    pub fn peek_char(&self) -> char {
        if self.read_position.get() >= self.input.len() {
            return '0';
        } else {
            return self.input.chars().nth(self.read_position.get()).unwrap();
        }
    }

    pub unsafe fn read_identifier(&self) -> String {
        let start_position = self.position.get();
        let ch = self.peek_char();
        while is_letter(ch) {
            self.read_char();
        }
        let end_position = self.position.get();
        let s = self.input.slice_unchecked(start_position, end_position);
        return s.to_string();
    }

    pub unsafe fn read_number(&self) -> String {
        let start_position = self.position.get();
        let ch = self.peek_char();
        while is_digit(ch) {
            self.read_char();
        }
        let end_position = self.position.get();
        let s = self.input.slice_unchecked(start_position, end_position);
        return s.to_string();
    }

    pub fn skip_white_space(&self) {
        let ch = self.peek_char();
        while ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' {
            self.read_char();
        }
    }
}

fn is_letter(ch: char) -> bool {
    return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_'
}

fn is_digit(ch: char) -> bool {
    return '0' <= ch && ch <= '9';
}

#[test]
fn read_char() {
    let input = String::from("=!");
    let l = &Lexer::new(input);
    assert_eq!('=', l.read_char());
    assert_eq!('!', l.read_char());
    assert_eq!('0', l.read_char());
}

#[test]
fn peek_char() {
    let input = String::from("!=");
    let l = &Lexer::new(input);
    assert_eq!('!', l.peek_char());
    assert_eq!('!', l.peek_char());
}

#[test]
fn next_token() {
    let input = String::from("=()");
    let l = &Lexer::new(input);
    assert_eq!(l.next_token().token_type, TokenType::ASSIGN);
    assert_eq!(l.next_token().token_type, TokenType::LPAREN);
    assert_eq!(l.next_token().token_type, TokenType::RPAREN);
}

#[test]
fn from_string() {
    assert_eq!(TokenType::from_string(String::from("=")), TokenType::ASSIGN);
    assert_eq!(TokenType::from_string(String::from("(")), TokenType::LPAREN);
}
<|endoftext|>


<commit_before>//! Simple hashed wheel timer with bounded interval.
//!
//! Relevant:
//! http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf

#![unstable]
#![feature(core)]

use std::mem;
use std::ops::IndexMut;

/// A simple wheel timer implementation with a fixed ring size.
pub struct WheelTimer<T> {
  max_interval: usize,
  current_tick: usize,
  size: usize,

  ring: Vec<Vec<T>>
}

/// Iterator implementation allows for using the wheel timer in a for loop.
///
/// # Example
///
/// ```
/// use wheel_timer::WheelTimer;
///
/// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
/// for result in timer {
///   // result is a vector of the values at that step
/// }
/// ```
impl<T> Iterator for WheelTimer<T> {
  type Item = Vec<T>;

  fn next(&mut self) -> Option<Vec<T>> {
    let size = self.size();
    return if size > 0 {
      Some(self.tick())
    } else {
      None
    };
  }
}

impl<T> WheelTimer<T> {

  /// Creates a new timer with the specified max interval.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// ```
  pub fn new(max_interval: usize) -> WheelTimer<T> {
    // Initialize the ring with Nil values
    let mut ring = Vec::with_capacity(max_interval);
    for _ in range(0, max_interval) {
      ring.push(Vec::new())
    }

    return WheelTimer{
      max_interval: max_interval,
      current_tick: 0,
      ring: ring,
      size: 0,
    }
  }

  /// Returns the number of items currently scheduled.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(4, 1);
  /// timer.schedule(7, 1);
  /// timer.schedule(1, 1);
  /// assert_eq!(timer.size(), 3);
  /// ```
  pub fn size(&self) -> usize {
    self.size
  }

  /// Schedules a new value, available after `ticks` have passed.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(4, 7); // schedule value 7 for 4 ticks
  /// ```
  pub fn schedule(&mut self, ticks: usize, value: T) {
    // Compute the scheduled position in the wheel
    let index = (self.current_tick + ticks) % self.max_interval;

    // Get the current node at `index` in the wheel and append the new node
    self.ring.index_mut(&index).push(value);

    // Increment the size counter
    self.size = self.size + 1;
  }

  /// Tick the timer, returning the node at the current tick.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(3, 4); // schedule value 4 for 3 ticks
  /// timer.tick();
  /// timer.tick();
  /// timer.tick();
  /// let result = timer.tick(); // vec![4]
  /// assert_eq!(result.len(), 1);
  /// ```
  pub fn tick(&mut self) -> Vec<T> {
    // Get the node at the current tick in the wheel
    let node = mem::replace(self.ring.index_mut(&self.current_tick), Vec::new());

    // Increment the timer
    self.current_tick = (self.current_tick + 1) % self.max_interval;

    // Reduce the size by the length of the removed node
    self.size = self.size - node.len();

    // Return the node that was in that spot
    return node
  }
}
<commit_msg>Updating for rust 1.0<commit_after>//! Simple hashed wheel timer with bounded interval.
//!
//! Relevant:
//! http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf

use std::mem;
use std::ops::IndexMut;

/// A simple wheel timer implementation with a fixed ring size.
pub struct WheelTimer<T> {
  max_interval: usize,
  current_tick: usize,
  size: usize,

  ring: Vec<Vec<T>>
}

/// Iterator implementation allows for using the wheel timer in a for loop.
///
/// # Example
///
/// ```
/// use wheel_timer::WheelTimer;
///
/// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
/// for result in timer {
///   // result is a vector of the values at that step
/// }
/// ```
impl<T> Iterator for WheelTimer<T> {
  type Item = Vec<T>;

  fn next(&mut self) -> Option<Vec<T>> {
    let size = self.size();
    return if size > 0 {
      Some(self.tick())
    } else {
      None
    };
  }
}

impl<T> WheelTimer<T> {

  /// Creates a new timer with the specified max interval.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// ```
  pub fn new(max_interval: usize) -> WheelTimer<T> {
    // Initialize the ring with Nil values
    let mut ring = Vec::with_capacity(max_interval);
    for _ in 0..max_interval {
      ring.push(Vec::new())
    }

    return WheelTimer{
      max_interval: max_interval,
      current_tick: 0,
      ring: ring,
      size: 0,
    }
  }

  /// Returns the number of items currently scheduled.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(4, 1);
  /// timer.schedule(7, 1);
  /// timer.schedule(1, 1);
  /// assert_eq!(timer.size(), 3);
  /// ```
  pub fn size(&self) -> usize {
    self.size
  }

  /// Schedules a new value, available after `ticks` have passed.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(4, 7); // schedule value 7 for 4 ticks
  /// ```
  pub fn schedule(&mut self, ticks: usize, value: T) {
    // Compute the scheduled position in the wheel
    let index = (self.current_tick + ticks) % self.max_interval;

    // Get the current node at `index` in the wheel and append the new node
    self.ring.index_mut(index).push(value);

    // Increment the size counter
    self.size = self.size + 1;
  }

  /// Tick the timer, returning the node at the current tick.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(3, 4); // schedule value 4 for 3 ticks
  /// timer.tick();
  /// timer.tick();
  /// timer.tick();
  /// let result = timer.tick(); // vec![4]
  /// assert_eq!(result.len(), 1);
  /// ```
  pub fn tick(&mut self) -> Vec<T> {
    // Get the node at the current tick in the wheel
    let node = mem::replace(self.ring.index_mut(self.current_tick), Vec::new());

    // Increment the timer
    self.current_tick = (self.current_tick + 1) % self.max_interval;

    // Reduce the size by the length of the removed node
    self.size = self.size - node.len();

    // Return the node that was in that spot
    return node
  }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! States elements can be in.

bitflags! {
    /// Event-based element states.
    ///
    /// NB: Is important for this to remain in sync with Gecko's
    /// dom/events/EventStates.h.
    ///
    /// Please keep in that order in order for this to be easily auditable.
    ///
    /// TODO(emilio): We really really want to use the NS_EVENT_STATE bindings
    /// for this.
    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
    pub flags ElementState: u64 {
        /// The mouse is down on this element.
        /// https://html.spec.whatwg.org/multipage/#selector-active
        /// FIXME(#7333): set/unset this when appropriate
        const IN_ACTIVE_STATE = 1 << 0,
        /// This element has focus.
        /// https://html.spec.whatwg.org/multipage/#selector-focus
        const IN_FOCUS_STATE = 1 << 1,
        /// The mouse is hovering over this element.
        /// https://html.spec.whatwg.org/multipage/#selector-hover
        const IN_HOVER_STATE = 1 << 2,
        /// Content is enabled (and can be disabled).
        /// http://www.whatwg.org/html/#selector-enabled
        const IN_ENABLED_STATE = 1 << 3,
        /// Content is disabled.
        /// http://www.whatwg.org/html/#selector-disabled
        const IN_DISABLED_STATE = 1 << 4,
        /// Content is checked.
        /// https://html.spec.whatwg.org/multipage/#selector-checked
        const IN_CHECKED_STATE = 1 << 5,
        /// https://html.spec.whatwg.org/multipage/#selector-indeterminate
        const IN_INDETERMINATE_STATE = 1 << 6,
        /// https://html.spec.whatwg.org/multipage/#selector-placeholder-shown
        const IN_PLACEHOLDER_SHOWN_STATE = 1 << 7,
        /// https://html.spec.whatwg.org/multipage/#selector-target
        const IN_TARGET_STATE = 1 << 8,
        /// https://fullscreen.spec.whatwg.org/#%3Afullscreen-pseudo-class
        const IN_FULLSCREEN_STATE = 1 << 9,
        /// https://html.spec.whatwg.org/multipage/#selector-valid
        const IN_VALID_STATE = 1 << 10,
        /// https://html.spec.whatwg.org/multipage/#selector-invalid
        const IN_INVALID_STATE = 1 << 11,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-valid
        const IN_MOZ_UI_VALID_STATE = 1 << 12,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-invalid
        const IN_MOZ_UI_INVALID_STATE = 1 << 13,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-broken
        const IN_BROKEN_STATE = 1 << 14,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-user-disabled
        const IN_USER_DISABLED_STATE = 1 << 15,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-suppressed
        const IN_SUPPRESSED_STATE = 1 << 16,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-loading
        const IN_LOADING_STATE = 1 << 18,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-blocked
        const IN_HANDLER_BLOCKED_STATE = 1 << 18,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-disabled
        const IN_HANDLER_DISABLED_STATE = 1 << 19,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-crashed
        const IN_HANDLER_CRASHED_STATE = 1 << 20,
        /// https://html.spec.whatwg.org/multipage/#selector-required
        const IN_REQUIRED_STATE = 1 << 21,
        /// https://html.spec.whatwg.org/multipage/#selector-optional
        const IN_OPTIONAL_STATE = 1 << 22,
        /// https://html.spec.whatwg.org/multipage/#selector-read-write
        const IN_READ_WRITE_STATE = 1 << 22,
        /// Non-standard: Older custom-elements spec.
        const IN_UNRESOLVED_STATE = 1 << 23,
        /// https://html.spec.whatwg.org/multipage/#selector-visited
        const IN_VISITED_STATE = 1 << 24,
        /// https://html.spec.whatwg.org/multipage/#selector-link
        const IN_UNVISITED_STATE = 1 << 25,
        /// https://drafts.csswg.org/selectors-4/#the-any-link-pseudo
        const IN_VISITED_OR_UNVISITED_STATE = IN_VISITED_STATE.bits | IN_UNVISITED_STATE.bits,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-drag-over
        const IN_DRAGOVER_STATE = 1 << 26,
        /// https://html.spec.whatwg.org/multipage/#selector-in-range
        const IN_INRANGE_STATE = 1 << 27,
        /// https://html.spec.whatwg.org/multipage/#selector-out-of-range
        const IN_OUTOFRANGE_STATE = 1 << 28,
        /// https://html.spec.whatwg.org/multipage/#selector-read-only
        const IN_MOZ_READONLY_STATE = 1 << 29,
        /// https://html.spec.whatwg.org/multipage/#selector-read-write
        const IN_MOZ_READWRITE_STATE = 1 << 30,
        /// https://html.spec.whatwg.org/multipage/#selector-default
        const IN_DEFAULT_STATE = 1 << 31,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-submit-invalid
        const IN_MOZ_SUBMITINVALID_STATE = 1 << 32,
        /// Non-standard & undocumented.
        const IN_OPTIMUM_STATE = 1 << 33,
        /// Non-standard & undocumented.
        const IN_SUB_OPTIMUM_STATE = 1 << 34,
        /// Non-standard & undocumented.
        const IN_SUB_SUB_OPTIMUM_STATE = 1 << 35,
        /// Non-standard & undocumented.
        const IN_DEVTOOLS_HIGHLIGHTED_STATE = 1 << 36,
        /// Non-standard & undocumented.
        const IN_STYLEEDITOR_TRANSITIONING_STATE = 1 << 37,
        /// Non-standard & undocumented.
        const IN_INCREMENT_SCRIPT_LEVEL_STATE = 1 << 38,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-focusring
        const IN_FOCUSRING_STATE = 1 << 39,
        /// Non-standard & undocumented.
        const IN_HANDLER_CLICK_TO_PLAY_STATE = 1 << 40,
        /// Non-standard & undocumented.
        const IN_HANDLER_VULNERABLE_UPDATABLE_STATE = 1 << 41,
        /// Non-standard & undocumented.
        const IN_HANDLER_VULNERABLE_NO_UPDATE_STATE = 1 << 42,
        /// https://drafts.csswg.org/selectors-4/#the-focus-within-pseudo
        const IN_FOCUS_WITHIN_STATE = 1 << 43,
    }
}
<commit_msg>style: Fix IN_LOADING_STATE value.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! States elements can be in.

bitflags! {
    /// Event-based element states.
    ///
    /// NB: Is important for this to remain in sync with Gecko's
    /// dom/events/EventStates.h.
    ///
    /// Please keep in that order in order for this to be easily auditable.
    ///
    /// TODO(emilio): We really really want to use the NS_EVENT_STATE bindings
    /// for this.
    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
    pub flags ElementState: u64 {
        /// The mouse is down on this element.
        /// https://html.spec.whatwg.org/multipage/#selector-active
        /// FIXME(#7333): set/unset this when appropriate
        const IN_ACTIVE_STATE = 1 << 0,
        /// This element has focus.
        /// https://html.spec.whatwg.org/multipage/#selector-focus
        const IN_FOCUS_STATE = 1 << 1,
        /// The mouse is hovering over this element.
        /// https://html.spec.whatwg.org/multipage/#selector-hover
        const IN_HOVER_STATE = 1 << 2,
        /// Content is enabled (and can be disabled).
        /// http://www.whatwg.org/html/#selector-enabled
        const IN_ENABLED_STATE = 1 << 3,
        /// Content is disabled.
        /// http://www.whatwg.org/html/#selector-disabled
        const IN_DISABLED_STATE = 1 << 4,
        /// Content is checked.
        /// https://html.spec.whatwg.org/multipage/#selector-checked
        const IN_CHECKED_STATE = 1 << 5,
        /// https://html.spec.whatwg.org/multipage/#selector-indeterminate
        const IN_INDETERMINATE_STATE = 1 << 6,
        /// https://html.spec.whatwg.org/multipage/#selector-placeholder-shown
        const IN_PLACEHOLDER_SHOWN_STATE = 1 << 7,
        /// https://html.spec.whatwg.org/multipage/#selector-target
        const IN_TARGET_STATE = 1 << 8,
        /// https://fullscreen.spec.whatwg.org/#%3Afullscreen-pseudo-class
        const IN_FULLSCREEN_STATE = 1 << 9,
        /// https://html.spec.whatwg.org/multipage/#selector-valid
        const IN_VALID_STATE = 1 << 10,
        /// https://html.spec.whatwg.org/multipage/#selector-invalid
        const IN_INVALID_STATE = 1 << 11,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-valid
        const IN_MOZ_UI_VALID_STATE = 1 << 12,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-invalid
        const IN_MOZ_UI_INVALID_STATE = 1 << 13,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-broken
        const IN_BROKEN_STATE = 1 << 14,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-user-disabled
        const IN_USER_DISABLED_STATE = 1 << 15,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-suppressed
        const IN_SUPPRESSED_STATE = 1 << 16,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-loading
        const IN_LOADING_STATE = 1 << 17,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-blocked
        const IN_HANDLER_BLOCKED_STATE = 1 << 18,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-disabled
        const IN_HANDLER_DISABLED_STATE = 1 << 19,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-crashed
        const IN_HANDLER_CRASHED_STATE = 1 << 20,
        /// https://html.spec.whatwg.org/multipage/#selector-required
        const IN_REQUIRED_STATE = 1 << 21,
        /// https://html.spec.whatwg.org/multipage/#selector-optional
        const IN_OPTIONAL_STATE = 1 << 22,
        /// https://html.spec.whatwg.org/multipage/#selector-read-write
        const IN_READ_WRITE_STATE = 1 << 22,
        /// Non-standard: Older custom-elements spec.
        const IN_UNRESOLVED_STATE = 1 << 23,
        /// https://html.spec.whatwg.org/multipage/#selector-visited
        const IN_VISITED_STATE = 1 << 24,
        /// https://html.spec.whatwg.org/multipage/#selector-link
        const IN_UNVISITED_STATE = 1 << 25,
        /// https://drafts.csswg.org/selectors-4/#the-any-link-pseudo
        const IN_VISITED_OR_UNVISITED_STATE = IN_VISITED_STATE.bits | IN_UNVISITED_STATE.bits,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-drag-over
        const IN_DRAGOVER_STATE = 1 << 26,
        /// https://html.spec.whatwg.org/multipage/#selector-in-range
        const IN_INRANGE_STATE = 1 << 27,
        /// https://html.spec.whatwg.org/multipage/#selector-out-of-range
        const IN_OUTOFRANGE_STATE = 1 << 28,
        /// https://html.spec.whatwg.org/multipage/#selector-read-only
        const IN_MOZ_READONLY_STATE = 1 << 29,
        /// https://html.spec.whatwg.org/multipage/#selector-read-write
        const IN_MOZ_READWRITE_STATE = 1 << 30,
        /// https://html.spec.whatwg.org/multipage/#selector-default
        const IN_DEFAULT_STATE = 1 << 31,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-submit-invalid
        const IN_MOZ_SUBMITINVALID_STATE = 1 << 32,
        /// Non-standard & undocumented.
        const IN_OPTIMUM_STATE = 1 << 33,
        /// Non-standard & undocumented.
        const IN_SUB_OPTIMUM_STATE = 1 << 34,
        /// Non-standard & undocumented.
        const IN_SUB_SUB_OPTIMUM_STATE = 1 << 35,
        /// Non-standard & undocumented.
        const IN_DEVTOOLS_HIGHLIGHTED_STATE = 1 << 36,
        /// Non-standard & undocumented.
        const IN_STYLEEDITOR_TRANSITIONING_STATE = 1 << 37,
        /// Non-standard & undocumented.
        const IN_INCREMENT_SCRIPT_LEVEL_STATE = 1 << 38,
        /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-focusring
        const IN_FOCUSRING_STATE = 1 << 39,
        /// Non-standard & undocumented.
        const IN_HANDLER_CLICK_TO_PLAY_STATE = 1 << 40,
        /// Non-standard & undocumented.
        const IN_HANDLER_VULNERABLE_UPDATABLE_STATE = 1 << 41,
        /// Non-standard & undocumented.
        const IN_HANDLER_VULNERABLE_NO_UPDATE_STATE = 1 << 42,
        /// https://drafts.csswg.org/selectors-4/#the-focus-within-pseudo
        const IN_FOCUS_WITHIN_STATE = 1 << 43,
    }
}
<|endoftext|>


<commit_before>use core::mem::PinMut;
use futures_core::TryFuture;
use futures_core::task::{Context, Poll};

#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
crate enum TryChain<Fut1, Fut2, Data> {
    First(Fut1, Option<Data>),
    Second(Fut2),
    Empty,
}

crate enum TryChainAction<Fut2>
    where Fut2: TryFuture,
{
    Future(Fut2),
    Output(Result<Fut2::Item, Fut2::Error>),
}

impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
    where Fut1: TryFuture,
          Fut2: TryFuture,
{
    pub fn new(fut1: Fut1, data: Data) -> TryChain<Fut1, Fut2, Data> {
        TryChain::First(fut1, Some(data))
    }

    pub fn poll<F>(
        self: PinMut<Self>,
        cx: &mut Context,
        async_op: F,
    ) -> Poll<Result<Fut2::Item, Fut2::Error>>
        where F: FnOnce(Result<Fut1::Item, Fut1::Error>, Data) -> TryChainAction<Fut2>,
    {
        let mut async_op = Some(async_op);

        // Safe to call `get_mut_unchecked` because we won't move the futures.
        let this = unsafe { PinMut::get_mut_unchecked(self) };

        loop {
            let (output, data) = match this {
                TryChain::First(fut1, data) => {
                    // Poll the first future
                    match unsafe { PinMut::new_unchecked(fut1) }.try_poll(cx) {
                        Poll::Pending => return Poll::Pending,
                        Poll::Ready(output) => (output, data.take().unwrap()),
                    }
                }
                TryChain::Second(fut2) => {
                    // Poll the second future
                    return unsafe { PinMut::new_unchecked(fut2) }.try_poll(cx)
                }
                TryChain::Empty => {
                    panic!("future must not be polled after it returned `Poll::Ready`");
                }
            };

            *this = TryChain::Empty; // Drop fut1
            let async_op = async_op.take().unwrap();
            match async_op(output, data) {
                TryChainAction::Future(fut2) => *this = TryChain::Second(fut2),
                TryChainAction::Output(output) => return Poll::Ready(output),
            }
        }
    }
}
<commit_msg>Name `TryChain` callback `op` becaue it is not always async<commit_after>use core::mem::PinMut;
use futures_core::TryFuture;
use futures_core::task::{Context, Poll};

#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
crate enum TryChain<Fut1, Fut2, Data> {
    First(Fut1, Option<Data>),
    Second(Fut2),
    Empty,
}

crate enum TryChainAction<Fut2>
    where Fut2: TryFuture,
{
    Future(Fut2),
    Output(Result<Fut2::Item, Fut2::Error>),
}

impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
    where Fut1: TryFuture,
          Fut2: TryFuture,
{
    pub fn new(fut1: Fut1, data: Data) -> TryChain<Fut1, Fut2, Data> {
        TryChain::First(fut1, Some(data))
    }

    pub fn poll<F>(
        self: PinMut<Self>,
        cx: &mut Context,
        op: F,
    ) -> Poll<Result<Fut2::Item, Fut2::Error>>
        where F: FnOnce(Result<Fut1::Item, Fut1::Error>, Data) -> TryChainAction<Fut2>,
    {
        let mut op = Some(op);

        // Safe to call `get_mut_unchecked` because we won't move the futures.
        let this = unsafe { PinMut::get_mut_unchecked(self) };

        loop {
            let (output, data) = match this {
                TryChain::First(fut1, data) => {
                    // Poll the first future
                    match unsafe { PinMut::new_unchecked(fut1) }.try_poll(cx) {
                        Poll::Pending => return Poll::Pending,
                        Poll::Ready(output) => (output, data.take().unwrap()),
                    }
                }
                TryChain::Second(fut2) => {
                    // Poll the second future
                    return unsafe { PinMut::new_unchecked(fut2) }.try_poll(cx)
                }
                TryChain::Empty => {
                    panic!("future must not be polled after it returned `Poll::Ready`");
                }
            };

            *this = TryChain::Empty; // Drop fut1
            let op = op.take().unwrap();
            match op(output, data) {
                TryChainAction::Future(fut2) => *this = TryChain::Second(fut2),
                TryChainAction::Output(output) => return Poll::Ready(output),
            }
        }
    }
}
<|endoftext|>


<commit_before>use rustc_serialize::{Encodable, Decodable};
use super::master::{self, Master, MasterResult};
use super::slave::Slave;
use super::error::ServerError;
use super::value::Topic;
use super::naming::{self, Resolver};
use super::resolve;
use tcpros::{Client, Message, PublisherStream, ServicePair};
use rosxmlrpc::serde::XmlRpcValue;

pub struct Ros {
    master: Master,
    slave: Slave,
    hostname: String,
    resolver: Resolver,
    name: String,
}

impl Ros {
    pub fn new(name: &str) -> Result<Ros, ServerError> {
        let namespace = resolve::namespace();
        let master_uri = resolve::master();
        let hostname = resolve::hostname();
        let name = resolve::name(name);
        let mut ros = Ros::new_raw(&master_uri, &hostname, &namespace, &name)?;
        for (src, dest) in resolve::mappings() {
            ros.map(&src, &dest)?;
        }
        Ok(ros)
    }

    pub fn new_raw(master_uri: &str,
                   hostname: &str,
                   namespace: &str,
                   name: &str)
                   -> Result<Ros, ServerError> {
        let namespace = namespace.trim_right_matches("/");

        if name.contains("/") {
            return Err(ServerError::Naming(naming::Error::IllegalPath));
        }

        let name = format!("{}/{}", namespace, name);
        let resolver = Resolver::new(&name)?;

        let slave = Slave::new(&master_uri, &hostname, 0, &name)?;
        let master = Master::new(&master_uri, &name, &slave.uri());
        Ok(Ros {
            master: master,
            slave: slave,
            hostname: String::from(hostname),
            resolver: resolver,
            name: name,
        })
    }

    pub fn map(&mut self, source: &str, destination: &str) -> Result<(), ServerError> {
        self.resolver.map(source, destination).map_err(|v| ServerError::Naming(v))
    }

    pub fn node_uri(&self) -> &str {
        return self.slave.uri();
    }

    pub fn param<'a, 'b>(&'a self, name: &'b str) -> Option<Parameter<'a>> {
        self.resolver.translate(name).ok().map(|v| {
            Parameter {
                master: &self.master,
                name: v,
            }
        })
    }

    pub fn parameters(&self) -> MasterResult<Vec<String>> {
        self.master.get_param_names()
    }

    pub fn state(&self) -> MasterResult<master::SystemState> {
        self.master.get_system_state()
    }

    pub fn topics(&self) -> MasterResult<Vec<Topic>> {
        self.master.get_topic_types()
    }

    pub fn client<T: ServicePair>(&self, service: &str) -> Result<Client<T>, ServerError> {
        let name = self.resolver.translate(service)?;
        let uri = self.master.lookup_service(&name)?;
        Ok(Client::new(&self.name, &uri, &name))
    }

    pub fn service<T, F>(&mut self, service: &str, handler: F) -> Result<(), ServerError>
        where T: ServicePair,
              F: Fn(T::Request) -> T::Response + Send + Sync + 'static
    {
        let name = self.resolver.translate(service)?;
        let api = self.slave.add_service::<T, F>(&self.hostname, &name, handler)?;

        if let Err(err) = self.master.register_service(&name, &api) {
            self.slave.remove_service(&name);
            self.master.unregister_service(&name, &api)?;
            Err(ServerError::from(err))
        } else {
            Ok(())
        }
    }

    pub fn subscribe<T, F>(&mut self, topic: &str, callback: F) -> Result<(), ServerError>
        where T: Message,
              F: Fn(T) -> () + Send + 'static
    {
        let name = self.resolver.translate(topic)?;
        self.slave.add_subscription::<T, F>(&name, callback)?;

        match self.master.register_subscriber(&name, &T::msg_type()) {
            Ok(publishers) => {
                if let Err(err) = self.slave
                    .add_publishers_to_subscription(&name, publishers.into_iter()) {
                    error!("Failed to subscribe to all publishers of topic '{}': {}",
                           name,
                           err);
                }
                Ok(())
            }
            Err(err) => {
                self.slave.remove_subscription(&name);
                self.master.unregister_subscriber(&name)?;
                Err(ServerError::from(err))
            }
        }
    }

    pub fn publish<T>(&mut self, topic: &str) -> Result<PublisherStream<T>, ServerError>
        where T: Message
    {
        let name = self.resolver.translate(topic)?;
        let stream = self.slave.add_publication::<T>(&self.hostname, &name)?;
        match self.master.register_publisher(&name, &T::msg_type()) {
            Ok(_) => Ok(stream),
            Err(error) => {
                error!("Failed to register publisher for topic '{}': {}",
                       name,
                       error);
                self.slave.remove_publication(&name);
                self.master.unregister_publisher(&name)?;
                Err(ServerError::from(error))
            }
        }
    }
}

pub struct Parameter<'a> {
    master: &'a Master,
    name: String,
}

impl<'a> Parameter<'a> {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn get<T: Decodable>(&self) -> MasterResult<T> {
        self.master.get_param::<T>(&self.name)
    }

    pub fn get_raw(&self) -> MasterResult<XmlRpcValue> {
        self.master.get_param_any(&self.name)
    }

    pub fn set<T: Encodable>(&self, value: &T) -> MasterResult<()> {
        self.master.set_param::<T>(&self.name, value).and(Ok(()))
    }

    pub fn delete(&self) -> MasterResult<()> {
        self.master.delete_param(&self.name).and(Ok(()))
    }

    pub fn exists(&self) -> MasterResult<bool> {
        self.master.has_param(&self.name)
    }

    pub fn search(&self) -> MasterResult<String> {
        self.master.search_param(&self.name)
    }
}
<commit_msg>Limit setup and remapping to standard ways<commit_after>use rustc_serialize::{Encodable, Decodable};
use super::master::{self, Master, MasterResult};
use super::slave::Slave;
use super::error::ServerError;
use super::value::Topic;
use super::naming::{self, Resolver};
use super::resolve;
use tcpros::{Client, Message, PublisherStream, ServicePair};
use rosxmlrpc::serde::XmlRpcValue;

pub struct Ros {
    master: Master,
    slave: Slave,
    hostname: String,
    resolver: Resolver,
    name: String,
}

impl Ros {
    pub fn new(name: &str) -> Result<Ros, ServerError> {
        let namespace = resolve::namespace();
        let master_uri = resolve::master();
        let hostname = resolve::hostname();
        let name = resolve::name(name);
        let mut ros = Ros::new_raw(&master_uri, &hostname, &namespace, &name)?;
        for (src, dest) in resolve::mappings() {
            ros.map(&src, &dest)?;
        }
        Ok(ros)
    }

    fn new_raw(master_uri: &str,
               hostname: &str,
               namespace: &str,
               name: &str)
               -> Result<Ros, ServerError> {
        let namespace = namespace.trim_right_matches("/");

        if name.contains("/") {
            return Err(ServerError::Naming(naming::Error::IllegalPath));
        }

        let name = format!("{}/{}", namespace, name);
        let resolver = Resolver::new(&name)?;

        let slave = Slave::new(&master_uri, &hostname, 0, &name)?;
        let master = Master::new(&master_uri, &name, &slave.uri());
        Ok(Ros {
            master: master,
            slave: slave,
            hostname: String::from(hostname),
            resolver: resolver,
            name: name,
        })
    }

    fn map(&mut self, source: &str, destination: &str) -> Result<(), ServerError> {
        self.resolver.map(source, destination).map_err(|v| ServerError::Naming(v))
    }

    pub fn uri(&self) -> &str {
        return self.slave.uri();
    }

    pub fn param<'a, 'b>(&'a self, name: &'b str) -> Option<Parameter<'a>> {
        self.resolver.translate(name).ok().map(|v| {
            Parameter {
                master: &self.master,
                name: v,
            }
        })
    }

    pub fn parameters(&self) -> MasterResult<Vec<String>> {
        self.master.get_param_names()
    }

    pub fn state(&self) -> MasterResult<master::SystemState> {
        self.master.get_system_state()
    }

    pub fn topics(&self) -> MasterResult<Vec<Topic>> {
        self.master.get_topic_types()
    }

    pub fn client<T: ServicePair>(&self, service: &str) -> Result<Client<T>, ServerError> {
        let name = self.resolver.translate(service)?;
        let uri = self.master.lookup_service(&name)?;
        Ok(Client::new(&self.name, &uri, &name))
    }

    pub fn service<T, F>(&mut self, service: &str, handler: F) -> Result<(), ServerError>
        where T: ServicePair,
              F: Fn(T::Request) -> T::Response + Send + Sync + 'static
    {
        let name = self.resolver.translate(service)?;
        let api = self.slave.add_service::<T, F>(&self.hostname, &name, handler)?;

        if let Err(err) = self.master.register_service(&name, &api) {
            self.slave.remove_service(&name);
            self.master.unregister_service(&name, &api)?;
            Err(ServerError::from(err))
        } else {
            Ok(())
        }
    }

    pub fn subscribe<T, F>(&mut self, topic: &str, callback: F) -> Result<(), ServerError>
        where T: Message,
              F: Fn(T) -> () + Send + 'static
    {
        let name = self.resolver.translate(topic)?;
        self.slave.add_subscription::<T, F>(&name, callback)?;

        match self.master.register_subscriber(&name, &T::msg_type()) {
            Ok(publishers) => {
                if let Err(err) = self.slave
                    .add_publishers_to_subscription(&name, publishers.into_iter()) {
                    error!("Failed to subscribe to all publishers of topic '{}': {}",
                           name,
                           err);
                }
                Ok(())
            }
            Err(err) => {
                self.slave.remove_subscription(&name);
                self.master.unregister_subscriber(&name)?;
                Err(ServerError::from(err))
            }
        }
    }

    pub fn publish<T>(&mut self, topic: &str) -> Result<PublisherStream<T>, ServerError>
        where T: Message
    {
        let name = self.resolver.translate(topic)?;
        let stream = self.slave.add_publication::<T>(&self.hostname, &name)?;
        match self.master.register_publisher(&name, &T::msg_type()) {
            Ok(_) => Ok(stream),
            Err(error) => {
                error!("Failed to register publisher for topic '{}': {}",
                       name,
                       error);
                self.slave.remove_publication(&name);
                self.master.unregister_publisher(&name)?;
                Err(ServerError::from(error))
            }
        }
    }
}

pub struct Parameter<'a> {
    master: &'a Master,
    name: String,
}

impl<'a> Parameter<'a> {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn get<T: Decodable>(&self) -> MasterResult<T> {
        self.master.get_param::<T>(&self.name)
    }

    pub fn get_raw(&self) -> MasterResult<XmlRpcValue> {
        self.master.get_param_any(&self.name)
    }

    pub fn set<T: Encodable>(&self, value: &T) -> MasterResult<()> {
        self.master.set_param::<T>(&self.name, value).and(Ok(()))
    }

    pub fn delete(&self) -> MasterResult<()> {
        self.master.delete_param(&self.name).and(Ok(()))
    }

    pub fn exists(&self) -> MasterResult<bool> {
        self.master.has_param(&self.name)
    }

    pub fn search(&self) -> MasterResult<String> {
        self.master.search_param(&self.name)
    }
}
<|endoftext|>