<commit_before>use hyper::{Body, Headers, HttpVersion, Method, Uri};
use std::{fmt, net};
use tokio_core::reactor::Handle;
use recognizer::Params;
use anymap::AnyMap;
use serde_json::{self, from_slice, from_value};
use hyper::Chunk;
use serde::de::DeserializeOwned;
use queryst_prime::{self, parse};

/// The Request Struct, This is passed to Middlewares and route handlers.
///
pub struct Request {
	pub(crate) uri: Uri,
	pub(crate) handle: Option<Handle>,
	pub(crate) body: Option<Body>,
	pub(crate) version: HttpVersion,
	pub(crate) headers: Headers,
	pub(crate) remote: Option<net::SocketAddr>,
	pub(crate) method: Method,
	pub(crate) anyMap: AnyMap,
}

#[derive(Debug)]
pub enum JsonError {
	None,
	Err(serde_json::Error),
}

#[derive(Debug)]
pub enum QueryParseError {
	SerdeError(serde_json::Error),
	ParseError(queryst_prime::ParseError),
	None,
}

impl Request {
	pub(crate) fn new(
		method: Method,
		uri: Uri,
		version: HttpVersion,
		headers: Headers,
		body: Body,
	) -> Self {
		Self {
			method,
			uri,
			version,
			headers,
			body: Some(body),
			remote: None,
			anyMap: AnyMap::new(),
			handle: None,
		}
	}

	pub fn reactor_handle(&self) -> Handle {
		self.handle.clone().unwrap()
	}

	/// returns a reference to the request's HttpVersion
	#[inline]
	pub fn version(&self) -> &HttpVersion {
		&self.version
	}

	/// returns a reference to the request's headers
	#[inline]
	pub fn headers(&self) -> &Headers {
		&self.headers
	}

	/// returns a reference to the request's method
	#[inline]
	pub fn method(&self) -> &Method {
		&self.method
	}

	/// returns a request to the request's Uri
	#[inline]
	pub fn uri(&self) -> &Uri {
		&self.uri
	}

	/// returns the query path
	#[inline]
	pub fn path(&self) -> &str {
		self.uri.path()
	}

	/// returns the IP of the connected client.
	#[inline]
	pub fn remote_ip(&self) -> net::SocketAddr {
		self.remote.unwrap()
	}

	/// Serializes the query string into a struct via serde.
	///
	///  # Examples
	///
	/// ```rust,ignore
	/// [derive(Serialize, Deserialize)]
	/// truct AccessToken {
	/// token: String,
	/// 	}
	///
	/// ub fn login(req: Request, _res: Response) {
	/// if let AccessToken { token } = req.query::<AccessToken>() {
	/// 	// do something with the token here.
	/// }
	/// 	}
	/// ```
	/// returns `None` if the query could not be serialized.
	/// Ideally this should return a `Result<T, serde_json::Error>`
	/// It would be corrected in a later version.
	///

	#[inline]
	pub fn query<T>(&self) -> Result<T, QueryParseError>
	where
		T: DeserializeOwned,
	{
		self
			.uri
			.query()
			.ok_or(QueryParseError::None)
			.and_then(|query| parse(query).map_err(|err| QueryParseError::ParseError(err)))
			.and_then(|value| from_value::<T>(value).map_err(|err| QueryParseError::SerdeError(err)))
	}

	/// Get the url params for the request
	///
	/// e.g `/profile/:id`
	///
	/// ```rust,ignore
	/// [service]
	/// ub fn ProfileService(req: Request, res: Response) {
	/// let profileId = req.params().unwrap()["id"];
	/// // Its safe to unwrap here as this woute would never be matched without the `id`
	/// 	}
	/// ```
	pub fn params(&self) -> Option<&Params> {
		self.anyMap.get::<Params>()
	}

	/// The request struct constains an `AnyMap` so that middlewares can append additional
	/// information.
	///
	/// you can get values out of the `AnyMap` by using this method.
	///
	/// # Examples
	///
	/// ```rust,ignore
	/// [derive(Serialize, Deserialize)]
	/// truct AccessToken {
	/// token: String,
	/// 	}
	///
	/// truct User {
	/// name: String,
	/// 	}
	///
	/// [middleware(Request)]
	/// ub fn AssertAuth(req: Request) {
	/// if let AccessToken { token } = req.query::<AccessToken>() {
	/// 	if let user = db::fetchUser::<User>(token) {
	/// 		// pseudo code
	/// 		req.set::<User>(user); // Set the user
	/// 	} else {
	/// 		return Err((404, "User Not Found!").into());
	/// 	}
	/// } else {
	/// 	return Err((401, "Unauthorized!").into());
	/// }
	/// 	}
	///
	/// [service]
	/// ub fn ProfileService(req: Request, res: Response) {
	/// let user = req.get::<User>().unwrap();
	/// // Its safe to unwrap here, because if user isn't set this service will never
	/// // be called.
	/// 	}
	/// ```
	pub fn get<T: 'static>(&self) -> Option<&T> {
		self.anyMap.get::<T>()
	}

	pub fn get_owned<T: 'static>(&mut self) -> Option<T> {
		self.anyMap.remove::<T>()
	}

	/// same as above.
	pub fn set<T: 'static>(&mut self, value: T) -> Option<T> {
		self.anyMap.insert::<T>(value)
	}

	/// move the request body. note that this takes ownership of `self`, use
	/// wisely.
	#[inline]
	pub fn body(self) -> Body {
		self.body.unwrap_or_default()
	}

	/// serialize the request's json value into a struct
	///
	/// Note that the json value needs to have been previously set on the request by a middleware.
	/// otherwise this would return `Err(JsonError::None)`
	pub fn json<T>(&self) -> Result<T, JsonError>
	where
		T: DeserializeOwned,
	{
		match self.get::<Chunk>() {
			Some(ref slice) => from_slice::<T>(slice).map_err(JsonError::Err),
			_ => Err(JsonError::None),
		}
	}

	/// get a reference to the body
	#[inline]
	pub fn body_ref(&self) -> Option<&Body> {
		self.body.as_ref()
	}

	/// set the request body
	pub fn set_body(&mut self, body: Body) {
		self.body = Some(body)
	}

	/// Decontruct this request.
	pub fn deconstruct(self) -> (Method, Uri, HttpVersion, Headers, Body) {
		(
			self.method,
			self.uri,
			self.version,
			self.headers,
			self.body.unwrap_or_default(),
		)
	}
}

impl fmt::Debug for Request {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.debug_struct("Request")
			.field("method", &self.method)
			.field("uri", &self.uri)
			.field("version", &self.version)
			.field("remote", &self.remote)
			.field("headers", &self.headers)
			.finish()
	}
}
<commit_msg>fixed documentation<commit_after>use hyper::{Body, Headers, HttpVersion, Method, Uri};
use std::{fmt, net};
use tokio_core::reactor::Handle;
use recognizer::Params;
use anymap::AnyMap;
use serde_json::{self, from_slice, from_value};
use hyper::Chunk;
use serde::de::DeserializeOwned;
use queryst_prime::{self, parse};

/// The Request Struct, This is passed to Middlewares and route handlers.
///
pub struct Request {
	pub(crate) uri: Uri,
	pub(crate) handle: Option<Handle>,
	pub(crate) body: Option<Body>,
	pub(crate) version: HttpVersion,
	pub(crate) headers: Headers,
	pub(crate) remote: Option<net::SocketAddr>,
	pub(crate) method: Method,
	pub(crate) anyMap: AnyMap,
}

#[derive(Debug)]
pub enum JsonError {
	None,
	Err(serde_json::Error),
}

#[derive(Debug)]
pub enum QueryParseError {
	SerdeError(serde_json::Error),
	ParseError(queryst_prime::ParseError),
	None,
}

impl Request {
	pub(crate) fn new(
		method: Method,
		uri: Uri,
		version: HttpVersion,
		headers: Headers,
		body: Body,
	) -> Self {
		Self {
			method,
			uri,
			version,
			headers,
			body: Some(body),
			remote: None,
			anyMap: AnyMap::new(),
			handle: None,
		}
	}

	pub fn reactor_handle(&self) -> Handle {
		self.handle.clone().unwrap()
	}

	/// returns a reference to the request's HttpVersion
	#[inline]
	pub fn version(&self) -> &HttpVersion {
		&self.version
	}

	/// returns a reference to the request's headers
	#[inline]
	pub fn headers(&self) -> &Headers {
		&self.headers
	}

	/// returns a reference to the request's method
	#[inline]
	pub fn method(&self) -> &Method {
		&self.method
	}

	/// returns a request to the request's Uri
	#[inline]
	pub fn uri(&self) -> &Uri {
		&self.uri
	}

	/// returns the query path
	#[inline]
	pub fn path(&self) -> &str {
		self.uri.path()
	}

	/// returns the IP of the connected client.
	#[inline]
	pub fn remote_ip(&self) -> net::SocketAddr {
		self.remote.unwrap()
	}

	/// Serializes the query string into a struct via serde.
	///
	///  # Examples
	///
	/// ```rust,ignore
	/// [derive(Serialize, Deserialize)]
	/// struct AccessToken {
	/// 	token: String,
	/// }
	///
	/// pub fn login(req: Request, _res: Response) {
	/// 	if let AccessToken { token } = req.query::<AccessToken>() {
	/// 		// do something with the token here.
	/// 	}
	/// }
	/// ```
	/// returns `None` if the query could not be serialized.
	/// Ideally this should return a `Result<T, serde_json::Error>`
	/// It would be corrected in a later version.
	///

	#[inline]
	pub fn query<T>(&self) -> Result<T, QueryParseError>
	where
		T: DeserializeOwned,
	{
		self
			.uri
			.query()
			.ok_or(QueryParseError::None)
			.and_then(|query| parse(query).map_err(QueryParseError::ParseError))
			.and_then(|value| from_value::<T>(value).map_err(QueryParseError::SerdeError))
	}

	/// Get the url params for the request
	///
	/// e.g `/profile/:id`
	///
	/// ```rust,ignore
	/// [service]
	/// pub fn ProfileService(req: Request, res: Response) {
	/// 	let profileId = req.params().unwrap()["id"];
	/// 	// Its safe to unwrap here as this woute would never be matched without the `id`
	/// }
	/// ```
	pub fn params(&self) -> Option<&Params> {
		self.anyMap.get::<Params>()
	}

	/// The request struct constains an `AnyMap` so that middlewares can append additional
	/// information.
	///
	/// you can get values out of the `AnyMap` by using this method.
	///
	/// # Examples
	///
	/// ```rust,ignore
	/// [derive(Serialize, Deserialize)]
	/// struct AccessToken {
	/// 	token: String,
	/// }
	///
	/// struct User {
	/// 	name: String,
	/// }
	///
	/// [middleware(Request)]
	/// pub fn AssertAuth(req: Request) {
	/// 	if let AccessToken { token } = req.query::<AccessToken>() {
	/// 		if let user = db::fetchUser::<User>(token) {
	/// 			// pseudo code
	/// 			req.set::<User>(user); // Set the user
	/// 		} else {
	/// 			return Err((404, "User Not Found!").into());
	/// 		}
	/// 	} else {
	/// 		return Err((401, "Unauthorized!").into());
	/// 	}
	/// }
	///
	/// [service]
	/// pub fn ProfileService(req: Request, res: Response) {
	/// 	let user = req.get::<User>().unwrap();
	/// 	// Its safe to unwrap here, because if user isn't set this service will never
	/// 	// be called.
	/// }
	/// ```
	pub fn get<T: 'static>(&self) -> Option<&T> {
		self.anyMap.get::<T>()
	}

	pub fn get_owned<T: 'static>(&mut self) -> Option<T> {
		self.anyMap.remove::<T>()
	}

	/// same as above.
	pub fn set<T: 'static>(&mut self, value: T) -> Option<T> {
		self.anyMap.insert::<T>(value)
	}

	/// move the request body. note that this takes ownership of `self`, use
	/// wisely.
	#[inline]
	pub fn body(self) -> Body {
		self.body.unwrap_or_default()
	}

	/// serialize the request's json value into a struct
	///
	/// Note that the json value needs to have been previously set on the request by a middleware.
	/// otherwise this would return `Err(JsonError::None)`
	pub fn json<T>(&self) -> Result<T, JsonError>
	where
		T: DeserializeOwned,
	{
		match self.get::<Chunk>() {
			Some(ref slice) => from_slice::<T>(slice).map_err(JsonError::Err),
			_ => Err(JsonError::None),
		}
	}

	/// get a reference to the body
	#[inline]
	pub fn body_ref(&self) -> Option<&Body> {
		self.body.as_ref()
	}

	/// set the request body
	pub fn set_body(&mut self, body: Body) {
		self.body = Some(body)
	}

	/// Decontruct this request.
	pub fn deconstruct(self) -> (Method, Uri, HttpVersion, Headers, Body) {
		(
			self.method,
			self.uri,
			self.version,
			self.headers,
			self.body.unwrap_or_default(),
		)
	}
}

impl fmt::Debug for Request {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.debug_struct("Request")
			.field("method", &self.method)
			.field("uri", &self.uri)
			.field("version", &self.version)
			.field("remote", &self.remote)
			.field("headers", &self.headers)
			.finish()
	}
}
<|endoftext|>


<commit_before>extern crate image;
extern crate num_traits;
extern crate palette;

use image::{GenericImage, RgbImage};

use palette::{LinSrgb, Mix, Pixel, Srgb};
#[cfg(feature = "std")]
use palette::Gradient;

mod color_spaces {
    use palette::{Hue, Lch, LinSrgb, Srgb};
    use display_colors;

    pub fn run() {
        let lch_color: Lch = Srgb::new(0.8, 0.2, 0.1).into();
        let new_color = LinSrgb::from(lch_color.shift_hue(180.0));

        display_colors(
            "examples/readme_color_spaces.png",
            &[
                ::palette::Srgb::new(0.8, 0.2, 0.1).into_format(),
                Srgb::from_linear(new_color.into()).into_format(),
            ],
        );
    }
}

mod manipulation {
    use palette::{Color, Saturate, Shade, Srgb};
    use display_colors;

    pub fn run() {
        let color: Color = Srgb::new(0.8, 0.2, 0.1).into_linear().into();
        let lighter = color.lighten(0.1);
        let desaturated = color.desaturate(0.5);

        display_colors(
            "examples/readme_manipulation.png",
            &[
                Srgb::from_linear(color.into()).into_format(),
                Srgb::from_linear(lighter.into()).into_format(),
                Srgb::from_linear(desaturated.into()).into_format(),
            ],
        );
    }
}

#[cfg(feature = "std")]
mod gradients {
    use palette::{Gradient, Hsv, LinSrgb};
    use display_gradients;

    pub fn run() {
        let grad1 = Gradient::new(vec![
            LinSrgb::new(1.0, 0.1, 0.1),
            LinSrgb::new(0.1, 1.0, 1.0),
        ]);

        let grad2 = Gradient::new(vec![
            Hsv::from(LinSrgb::new(1.0, 0.1, 0.1)),
            Hsv::from(LinSrgb::new(0.1, 1.0, 1.0)),
        ]);

        display_gradients("examples/readme_gradients.png", grad1, grad2);
    }
}

fn display_colors(filename: &str, colors: &[Srgb<u8>]) {
    let mut image = RgbImage::new(colors.len() as u32 * 64, 64);
    for (i, &color) in colors.iter().enumerate() {
        let mut sub_image = image.sub_image(i as u32 * 64, 0, 64, 64);
        let (width, height) = sub_image.dimensions();
        for x in 0..width {
            for y in 0..height {
                sub_image.put_pixel(x, y, image::Rgb { data: *color.as_raw() });
            }
        }
    }

    match image.save(filename) {
        Ok(()) => println!("see '{}' for the result", filename),
        Err(e) => println!("failed to write '{}': {}", filename, e),
    }
}

#[cfg(feature = "std")]
fn display_gradients<A: Mix<Scalar = f32> + Clone, B: Mix<Scalar = f32> + Clone>(
    filename: &str,
    grad1: Gradient<A>,
    grad2: Gradient<B>,
) where
    LinSrgb: From<A>,
    LinSrgb: From<B>,
{
    let mut image = RgbImage::new(256, 64);
    {
        let mut sub_image = image.sub_image(0, 0, 256, 32);
        let (width, height) = sub_image.dimensions();
        for x in 0..width {
            for y in 0..height {
                sub_image.put_pixel(x, y, image::Rgb {
                    data: Srgb::from_linear(grad1.get(x as f32 / 255.0).into())
                        .into_format()
                        .into_raw()
                });
            }
        }
    }

    {
        let mut sub_image = image.sub_image(0, 32, 256, 32);
        let (width, height) = sub_image.dimensions();
        for x in 0..width {
            for y in 0..height {
                sub_image.put_pixel(x, y, image::Rgb {
                    data: Srgb::from_linear(grad2.get(x as f32 / 255.0).into())
                        .into_format()
                        .into_raw()
                });
            }
        }
    }

    match image.save(filename) {
        Ok(()) => println!("see '{}' for the result", filename),
        Err(e) => println!("failed to write '{}': {}", filename, e),
    }
}

fn main() {
    color_spaces::run();
    manipulation::run();
    #[cfg(feature = "std")]
    gradients::run();
}
<commit_msg>Fix "unused import" warnings in palette/examples/readme_examples.rs with "std" disabled<commit_after>extern crate image;
extern crate num_traits;
extern crate palette;

use image::{GenericImage, RgbImage};

use palette::{Pixel, Srgb};
#[cfg(feature = "std")]
use palette::{Gradient, LinSrgb, Mix};

mod color_spaces {
    use palette::{Hue, Lch, LinSrgb, Srgb};
    use display_colors;

    pub fn run() {
        let lch_color: Lch = Srgb::new(0.8, 0.2, 0.1).into();
        let new_color = LinSrgb::from(lch_color.shift_hue(180.0));

        display_colors(
            "examples/readme_color_spaces.png",
            &[
                ::palette::Srgb::new(0.8, 0.2, 0.1).into_format(),
                Srgb::from_linear(new_color.into()).into_format(),
            ],
        );
    }
}

mod manipulation {
    use palette::{Color, Saturate, Shade, Srgb};
    use display_colors;

    pub fn run() {
        let color: Color = Srgb::new(0.8, 0.2, 0.1).into_linear().into();
        let lighter = color.lighten(0.1);
        let desaturated = color.desaturate(0.5);

        display_colors(
            "examples/readme_manipulation.png",
            &[
                Srgb::from_linear(color.into()).into_format(),
                Srgb::from_linear(lighter.into()).into_format(),
                Srgb::from_linear(desaturated.into()).into_format(),
            ],
        );
    }
}

#[cfg(feature = "std")]
mod gradients {
    use palette::{Gradient, Hsv, LinSrgb};
    use display_gradients;

    pub fn run() {
        let grad1 = Gradient::new(vec![
            LinSrgb::new(1.0, 0.1, 0.1),
            LinSrgb::new(0.1, 1.0, 1.0),
        ]);

        let grad2 = Gradient::new(vec![
            Hsv::from(LinSrgb::new(1.0, 0.1, 0.1)),
            Hsv::from(LinSrgb::new(0.1, 1.0, 1.0)),
        ]);

        display_gradients("examples/readme_gradients.png", grad1, grad2);
    }
}

fn display_colors(filename: &str, colors: &[Srgb<u8>]) {
    let mut image = RgbImage::new(colors.len() as u32 * 64, 64);
    for (i, &color) in colors.iter().enumerate() {
        let mut sub_image = image.sub_image(i as u32 * 64, 0, 64, 64);
        let (width, height) = sub_image.dimensions();
        for x in 0..width {
            for y in 0..height {
                sub_image.put_pixel(x, y, image::Rgb { data: *color.as_raw() });
            }
        }
    }

    match image.save(filename) {
        Ok(()) => println!("see '{}' for the result", filename),
        Err(e) => println!("failed to write '{}': {}", filename, e),
    }
}

#[cfg(feature = "std")]
fn display_gradients<A: Mix<Scalar = f32> + Clone, B: Mix<Scalar = f32> + Clone>(
    filename: &str,
    grad1: Gradient<A>,
    grad2: Gradient<B>,
) where
    LinSrgb: From<A>,
    LinSrgb: From<B>,
{
    let mut image = RgbImage::new(256, 64);
    {
        let mut sub_image = image.sub_image(0, 0, 256, 32);
        let (width, height) = sub_image.dimensions();
        for x in 0..width {
            for y in 0..height {
                sub_image.put_pixel(x, y, image::Rgb {
                    data: Srgb::from_linear(grad1.get(x as f32 / 255.0).into())
                        .into_format()
                        .into_raw()
                });
            }
        }
    }

    {
        let mut sub_image = image.sub_image(0, 32, 256, 32);
        let (width, height) = sub_image.dimensions();
        for x in 0..width {
            for y in 0..height {
                sub_image.put_pixel(x, y, image::Rgb {
                    data: Srgb::from_linear(grad2.get(x as f32 / 255.0).into())
                        .into_format()
                        .into_raw()
                });
            }
        }
    }

    match image.save(filename) {
        Ok(()) => println!("see '{}' for the result", filename),
        Err(e) => println!("failed to write '{}': {}", filename, e),
    }
}

fn main() {
    color_spaces::run();
    manipulation::run();
    #[cfg(feature = "std")]
    gradients::run();
}
<|endoftext|>


<commit_before>use core::ops::{Div, Rem};

pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
    /// Calculates Euclidean division, the matching method for `rem_euclid`.
    ///
    /// This computes the integer `n` such that
    /// `self = n * v + self.rem_euclid(v)`.
    /// In other words, the result is `self / v` rounded to the integer `n`
    /// such that `self >= n * v`.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::Euclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(Euclid::div_euclid(&a, &b), 1); // 7 > 4 * 1
    /// assert_eq!(Euclid::div_euclid(&-a, &b), -2); // -7 >= 4 * -2
    /// assert_eq!(Euclid::div_euclid(&a, &-b), -1); // 7 >= -4 * -1
    /// assert_eq!(Euclid::div_euclid(&-a, &-b), 2); // -7 >= -4 * 2
    /// ```
    fn div_euclid(&self, v: &Self) -> Self;

    /// Calculates the least nonnegative remainder of `self (mod v)`.
    ///
    /// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
    /// most cases. However, due to a floating point round-off error it can
    /// result in `r == v.abs()`, violating the mathematical definition, if
    /// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
    /// This result is not an element of the function's codomain, but it is the
    /// closest floating point number in the real numbers and thus fulfills the
    /// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
    /// approximatively.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::Euclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(Euclid::rem_euclid(&a, &b), 3);
    /// assert_eq!(Euclid::rem_euclid(&-a, &b), 1);
    /// assert_eq!(Euclid::rem_euclid(&a, &-b), 3);
    /// assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
    /// ```
    fn rem_euclid(&self, v: &Self) -> Self;
}

macro_rules! euclid_int_impl {
    ($($t:ty)*) => {$(
        impl Euclid for $t {
            #[inline]
            fn div_euclid(&self, v: &$t) -> Self {
                let q = self / v;
                if self % v < 0 {
                    return if *v > 0 { q - 1 } else { q + 1 }
                }
                q
            }

            #[inline]
            fn rem_euclid(&self, v: &$t) -> Self {
                let r = self % v;
                if r < 0 {
                    if *v < 0 {
                        r - v
                    } else {
                        r + v
                    }
                } else {
                    r
                }
            }
        }
    )*}
}

macro_rules! euclid_uint_impl {
    ($($t:ty)*) => {$(
        impl Euclid for $t {
            #[inline]
            fn div_euclid(&self, v: &$t) -> Self {
                self / v
            }

            #[inline]
            fn rem_euclid(&self, v: &$t) -> Self {
                self % v
            }
        }
    )*}
}

euclid_int_impl!(isize i8 i16 i32 i64);
euclid_uint_impl!(usize u8 u16 u32 u64);
#[cfg(has_i128)]
euclid_int_impl!(i128);
#[cfg(has_i128)]
euclid_uint_impl!(u128);

impl Euclid for f32 {
    #[inline]
    fn div_euclid(&self, v: &f32) -> f32 {
        let q = <f32 as ::float::FloatCore>::trunc(self / v);
        if self % v < 0.0 {
            return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }

    #[inline]
    fn rem_euclid(&self, v: &f32) -> f32 {
        let r = self % v;
        if r < 0.0 {
            r + <f32 as ::float::FloatCore>::abs(*v)
        } else {
            r
        }
    }
}

impl Euclid for f64 {
    #[inline]
    fn div_euclid(&self, v: &f64) -> f64 {
        let q = <f64 as ::float::FloatCore>::trunc(self / v);
        if self % v < 0.0 {
            return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }

    #[inline]
    fn rem_euclid(&self, v: &f64) -> f64 {
        let r = self % v;
        if r < 0.0 {
            r + <f64 as ::float::FloatCore>::abs(*v)
        } else {
            r
        }
    }
}

pub trait CheckedEuclid: Euclid {
    /// Performs euclid division that returns `None` instead of panicking on division by zero
    /// and instead of wrapping around on underflow and overflow.
    fn checked_div_euclid(&self, v: &Self) -> Option<Self>;

    /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
    /// division by zero. If any of that happens, `None` is returned.
    fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
}

macro_rules! checked_euclid_int_impl {
    ($($t:ty)*) => {$(
        impl CheckedEuclid for $t {
            #[inline]
            fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 || (*self == Self::min_value() && *v == -1) {
                    None
                } else {
                    Some(Euclid::div_euclid(self, v))
                }
            }

            #[inline]
            fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 || (*self == Self::min_value() && *v == -1) {
                    None
                } else {
                    Some(Euclid::rem_euclid(self, v))
                }
            }
        }
    )*}
}

macro_rules! checked_euclid_uint_impl {
    ($($t:ty)*) => {$(
        impl CheckedEuclid for $t {
            #[inline]
            fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 {
                    None
                } else {
                    Some(Euclid::div_euclid(self, v))
                }
            }

            #[inline]
            fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 {
                    None
                } else {
                    Some(Euclid::rem_euclid(self, v))
                }
            }
        }
    )*}
}

checked_euclid_int_impl!(isize i8 i16 i32 i64);
checked_euclid_uint_impl!(usize u8 u16 u32 u64);
#[cfg(has_i128)]
checked_euclid_int_impl!(i128);
#[cfg(has_i128)]
checked_euclid_uint_impl!(u128);

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

    #[test]
    fn euclid_unsigned() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = 3;
                        assert_eq!(Euclid::div_euclid(&x, &y), 3);
                        assert_eq!(Euclid::rem_euclid(&x, &y), 1);
                    }
                )+
            };
        }

        test_euclid!(usize u8 u16 u32 u64 isize);
    }

    #[test]
    fn euclid_signed() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = -3;
                        assert_eq!(Euclid::div_euclid(&x, &y), -3);
                        assert_eq!(Euclid::div_euclid(&-x, &y), 4);
                        assert_eq!(Euclid::rem_euclid(&x, &y), 1);
                        assert_eq!(Euclid::rem_euclid(&-x, &y), 2);
                        let x: $t = $t::min_value() + 1;
                        let y: $t = -1;
                        assert_eq!(Euclid::div_euclid(&x, &y), $t::max_value());
                    }
                )+
            };
        }

        test_euclid!(i8 i16 i32 i64);
    }

    #[test]
    fn euclid_float() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 12.1;
                        let y: $t = 3.2;
                        assert!(Euclid::div_euclid(&x, &y) * y + Euclid::rem_euclid(&x, &y) - x
                        <=46.4 * <$t as ::float::FloatCore>::epsilon());
                        assert!(Euclid::div_euclid(&x, &-y) * -y + Euclid::rem_euclid(&x, &-y) - x
                        <= 46.4 * <$t as ::float::FloatCore>::epsilon());
                        assert!(Euclid::div_euclid(&-x, &y) * y + Euclid::rem_euclid(&-x, &y) + x
                        <= 46.4 * <$t as ::float::FloatCore>::epsilon());
                        assert!(Euclid::div_euclid(&-x, &-y) * -y + Euclid::rem_euclid(&-x, &-y) + x
                        <= 46.4 * <$t as ::float::FloatCore>::epsilon());
                    }
                )+
            };
        }

        test_euclid!(f32 f64);
    }

    #[test]
    fn euclid_checked() {
        macro_rules! test_euclid_checked {
            ($($t:ident)+) => {
                $(
                    {
                        assert_eq!(CheckedEuclid::checked_div_euclid(&$t::min_value(), &-1), None);
                        assert_eq!(CheckedEuclid::checked_rem_euclid(&$t::min_value(), &-1), None);
                        assert_eq!(CheckedEuclid::checked_div_euclid(&1, &0), None);
                        assert_eq!(CheckedEuclid::checked_rem_euclid(&1, &0), None);
                    }
                )+
            };
        }

        test_euclid_checked!(i8 i16 i32 i64);
    }
}
<commit_msg>tweak euclid tests<commit_after>use core::ops::{Div, Rem};

pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
    /// Calculates Euclidean division, the matching method for `rem_euclid`.
    ///
    /// This computes the integer `n` such that
    /// `self = n * v + self.rem_euclid(v)`.
    /// In other words, the result is `self / v` rounded to the integer `n`
    /// such that `self >= n * v`.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::Euclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(Euclid::div_euclid(&a, &b), 1); // 7 > 4 * 1
    /// assert_eq!(Euclid::div_euclid(&-a, &b), -2); // -7 >= 4 * -2
    /// assert_eq!(Euclid::div_euclid(&a, &-b), -1); // 7 >= -4 * -1
    /// assert_eq!(Euclid::div_euclid(&-a, &-b), 2); // -7 >= -4 * 2
    /// ```
    fn div_euclid(&self, v: &Self) -> Self;

    /// Calculates the least nonnegative remainder of `self (mod v)`.
    ///
    /// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
    /// most cases. However, due to a floating point round-off error it can
    /// result in `r == v.abs()`, violating the mathematical definition, if
    /// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
    /// This result is not an element of the function's codomain, but it is the
    /// closest floating point number in the real numbers and thus fulfills the
    /// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
    /// approximatively.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::Euclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(Euclid::rem_euclid(&a, &b), 3);
    /// assert_eq!(Euclid::rem_euclid(&-a, &b), 1);
    /// assert_eq!(Euclid::rem_euclid(&a, &-b), 3);
    /// assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
    /// ```
    fn rem_euclid(&self, v: &Self) -> Self;
}

macro_rules! euclid_int_impl {
    ($($t:ty)*) => {$(
        impl Euclid for $t {
            #[inline]
            fn div_euclid(&self, v: &$t) -> Self {
                let q = self / v;
                if self % v < 0 {
                    return if *v > 0 { q - 1 } else { q + 1 }
                }
                q
            }

            #[inline]
            fn rem_euclid(&self, v: &$t) -> Self {
                let r = self % v;
                if r < 0 {
                    if *v < 0 {
                        r - v
                    } else {
                        r + v
                    }
                } else {
                    r
                }
            }
        }
    )*}
}

macro_rules! euclid_uint_impl {
    ($($t:ty)*) => {$(
        impl Euclid for $t {
            #[inline]
            fn div_euclid(&self, v: &$t) -> Self {
                self / v
            }

            #[inline]
            fn rem_euclid(&self, v: &$t) -> Self {
                self % v
            }
        }
    )*}
}

euclid_int_impl!(isize i8 i16 i32 i64);
euclid_uint_impl!(usize u8 u16 u32 u64);
#[cfg(has_i128)]
euclid_int_impl!(i128);
#[cfg(has_i128)]
euclid_uint_impl!(u128);

impl Euclid for f32 {
    #[inline]
    fn div_euclid(&self, v: &f32) -> f32 {
        let q = <f32 as ::float::FloatCore>::trunc(self / v);
        if self % v < 0.0 {
            return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }

    #[inline]
    fn rem_euclid(&self, v: &f32) -> f32 {
        let r = self % v;
        if r < 0.0 {
            r + <f32 as ::float::FloatCore>::abs(*v)
        } else {
            r
        }
    }
}

impl Euclid for f64 {
    #[inline]
    fn div_euclid(&self, v: &f64) -> f64 {
        let q = <f64 as ::float::FloatCore>::trunc(self / v);
        if self % v < 0.0 {
            return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }

    #[inline]
    fn rem_euclid(&self, v: &f64) -> f64 {
        let r = self % v;
        if r < 0.0 {
            r + <f64 as ::float::FloatCore>::abs(*v)
        } else {
            r
        }
    }
}

pub trait CheckedEuclid: Euclid {
    /// Performs euclid division that returns `None` instead of panicking on division by zero
    /// and instead of wrapping around on underflow and overflow.
    fn checked_div_euclid(&self, v: &Self) -> Option<Self>;

    /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
    /// division by zero. If any of that happens, `None` is returned.
    fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
}

macro_rules! checked_euclid_int_impl {
    ($($t:ty)*) => {$(
        impl CheckedEuclid for $t {
            #[inline]
            fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 || (*self == Self::min_value() && *v == -1) {
                    None
                } else {
                    Some(Euclid::div_euclid(self, v))
                }
            }

            #[inline]
            fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 || (*self == Self::min_value() && *v == -1) {
                    None
                } else {
                    Some(Euclid::rem_euclid(self, v))
                }
            }
        }
    )*}
}

macro_rules! checked_euclid_uint_impl {
    ($($t:ty)*) => {$(
        impl CheckedEuclid for $t {
            #[inline]
            fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 {
                    None
                } else {
                    Some(Euclid::div_euclid(self, v))
                }
            }

            #[inline]
            fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
                if *v == 0 {
                    None
                } else {
                    Some(Euclid::rem_euclid(self, v))
                }
            }
        }
    )*}
}

checked_euclid_int_impl!(isize i8 i16 i32 i64);
checked_euclid_uint_impl!(usize u8 u16 u32 u64);
#[cfg(has_i128)]
checked_euclid_int_impl!(i128);
#[cfg(has_i128)]
checked_euclid_uint_impl!(u128);

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

    #[test]
    fn euclid_unsigned() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = 3;
                        assert_eq!(Euclid::div_euclid(&x, &y), 3);
                        assert_eq!(Euclid::rem_euclid(&x, &y), 1);
                    }
                )+
            };
        }

        test_euclid!(usize u8 u16 u32 u64);
    }

    #[test]
    fn euclid_signed() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = -3;
                        assert_eq!(Euclid::div_euclid(&x, &y), -3);
                        assert_eq!(Euclid::div_euclid(&-x, &y), 4);
                        assert_eq!(Euclid::rem_euclid(&x, &y), 1);
                        assert_eq!(Euclid::rem_euclid(&-x, &y), 2);
                        let x: $t = $t::min_value() + 1;
                        let y: $t = -1;
                        assert_eq!(Euclid::div_euclid(&x, &y), $t::max_value());
                    }
                )+
            };
        }

        test_euclid!(isize i8 i16 i32 i64);
    }

    #[test]
    fn euclid_float() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 12.1;
                        let y: $t = 3.2;
                        assert!(Euclid::div_euclid(&x, &y) * y + Euclid::rem_euclid(&x, &y) - x
                        <= 46.4 * <$t as ::float::FloatCore>::epsilon());
                        assert!(Euclid::div_euclid(&x, &-y) * -y + Euclid::rem_euclid(&x, &-y) - x
                        <= 46.4 * <$t as ::float::FloatCore>::epsilon());
                        assert!(Euclid::div_euclid(&-x, &y) * y + Euclid::rem_euclid(&-x, &y) + x
                        <= 46.4 * <$t as ::float::FloatCore>::epsilon());
                        assert!(Euclid::div_euclid(&-x, &-y) * -y + Euclid::rem_euclid(&-x, &-y) + x
                        <= 46.4 * <$t as ::float::FloatCore>::epsilon());
                    }
                )+
            };
        }

        test_euclid!(f32 f64);
    }

    #[test]
    fn euclid_checked() {
        macro_rules! test_euclid_checked {
            ($($t:ident)+) => {
                $(
                    {
                        assert_eq!(CheckedEuclid::checked_div_euclid(&$t::min_value(), &-1), None);
                        assert_eq!(CheckedEuclid::checked_rem_euclid(&$t::min_value(), &-1), None);
                        assert_eq!(CheckedEuclid::checked_div_euclid(&1, &0), None);
                        assert_eq!(CheckedEuclid::checked_rem_euclid(&1, &0), None);
                    }
                )+
            };
        }

        test_euclid_checked!(isize i8 i16 i32 i64);
    }
}
<|endoftext|>


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

use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::fs::{self, File};
use std::path::PathBuf;
use std::io::Read;
use std::env;

use serde_json;
use antidote::Mutex;
use failure::{ResultExt, Error};
use failure::SyncFailure;
use rust_sysroot;
use rust_sysroot::git::Commit as GitCommit;
use chrono::{Duration, Utc};

use util;
use git;
use collector::Date;

pub use collector::{Commit, CommitData, ArtifactData, Patch, Run, Stat};

#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct CurrentState {
    pub commit: Commit,
    pub benchmarks: Vec<String>,
}

#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct Persistent {
    pub try_commits: Vec<String>,
    pub current: Option<CurrentState>,
}

impl Persistent {
    pub fn write(&self) -> Result<(), Error> {
        let s = serde_json::to_string(self)?;
        fs::write("persistent.json", &s).with_context(|_| format!("failed to write persistent DB"))?;
        Ok(())
    }

    fn load() -> Persistent {
        Persistent::load_().unwrap_or_else(|| Persistent {
            try_commits: Vec::new(),
            current: None,
        })
    }

    fn load_() -> Option<Persistent> {
        let s = fs::read_to_string("persistent.json").ok()?;
        let persistent: Persistent = serde_json::from_str(&s).ok()?;

        Some(persistent)
    }
}

#[derive(Debug)]
pub struct InputData {
    /// A set containing all crate names of the bootstrap kind.
    pub crate_list: BTreeSet<String>,

    /// All known statistics gathered for crates
    pub stats_list: BTreeSet<String>,

    /// The last date that was seen while loading files. The DateTime variant is
    /// used here since the date may or may not contain a time. Since the
    /// timezone is not important, it isn't stored, hence the Naive variant.
    pub last_date: Date,

    pub data: BTreeMap<Commit, CommitData>,

    pub artifact_data: BTreeMap<String, ArtifactData>,

    pub commits: Vec<GitCommit>,

    pub persistent: Mutex<Persistent>,
}

impl InputData {
    /// Initialize `InputData from the file system.
    pub fn from_fs(repo_loc: &str) -> Result<InputData, Error> {
        let repo_loc = PathBuf::from(repo_loc);
        let mut skipped = 0;
        let mut artifact_data = BTreeMap::new();
        let mut data = BTreeMap::new();

        if !repo_loc.exists() {
            // If the repository doesn't yet exist, simplify clone it to the given location.
            info!(
                "cloning repository into {}, since it doesn't exist before",
                repo_loc.display()
            );
            git::execute_command(
                &env::current_dir()?,
                &[
                    "clone",
                    "https://github.com/rust-lang-nursery/rustc-timing.git",
                    repo_loc.to_str().unwrap(),
                ],
            )?;
        }

        // Read all files from repo_loc/processed
        let mut file_count = 0;
        for entry in fs::read_dir(repo_loc.join("times"))? {
            let entry = entry?;
            if entry.file_type()?.is_dir() {
                continue;
            }
            file_count += 1;

            let filename = entry.file_name();
            let filename = filename.to_str().unwrap();
            let mut file = File::open(entry.path())?;
            let mut file_contents = String::new();
            // Skip files whose size is 0.
            if file.read_to_string(&mut file_contents)? == 0 {
                warn!("Skipping empty file: {}", filename);
                skipped += 1;
                continue;
            }

            if filename.starts_with("artifact-") {
                let contents: ArtifactData = match serde_json::from_str(&file_contents) {
                    Ok(j) => j,
                    Err(err) => {
                        error!("Failed to parse JSON for {}: {:?}", filename, err);
                        skipped += 1;
                        continue;
                    }
                };
                if contents.benchmarks.is_empty() {
                    warn!("empty benchmarks hash for {}", filename);
                    skipped += 1;
                    continue;
                }

                artifact_data.insert(contents.id.clone(), contents);
            } else {
                let contents: CommitData = match serde_json::from_str(&file_contents) {
                    Ok(json) => json,
                    Err(err) => {
                        error!("Failed to parse JSON for {}: {:?}", filename, err);
                        skipped += 1;
                        continue;
                    }
                };
                if contents.benchmarks.is_empty() {
                    warn!("empty benchmarks hash for {}", filename);
                    skipped += 1;
                    continue;
                }

                data.insert(contents.commit.clone(), contents);
            }
        }

        info!("{} total files", file_count);
        info!("{} skipped files", skipped);
        info!("{} measured", data.len());

        InputData::new(data, artifact_data)
    }

    pub fn new(
        data: BTreeMap<Commit, CommitData>,
        artifact_data: BTreeMap<String, ArtifactData>,
    ) -> Result<InputData, Error> {
        let mut last_date = None;
        let mut crate_list = BTreeSet::new();
        let mut stats_list = BTreeSet::new();

        for commit_data in data.values() {
            if last_date.is_none() || last_date.as_ref().unwrap() < &commit_data.commit.date {
                last_date = Some(commit_data.commit.date);
            }

            let benchmarks = commit_data
                .benchmarks
                .values()
                .filter_map(|v| v.as_ref().ok());
            for benchmark in benchmarks {
                for run in &benchmark.runs {
                    let run_name = benchmark.name.clone() + &run.name();
                    crate_list.insert(run_name);
                    for stat in &run.stats {
                        stats_list.insert(stat.name.clone());
                    }
                }
            }
        }

        let last_date = last_date.expect("No dates found");
        let commits = rust_sysroot::get_commits(rust_sysroot::EPOCH_COMMIT, "master").map_err(SyncFailure::new)?;

        Ok(InputData {
            crate_list: crate_list,
            stats_list: stats_list,
            last_date: last_date,
            data: data,
            artifact_data,
            commits,
            persistent: Mutex::new(Persistent::load()),
        })
    }

    pub fn missing_commits(&self) -> Result<Vec<Commit>, Error> {
        let known_benchmarks = self.data.values()
            .rev()
            .take(10)
            .flat_map(|v| v.benchmarks.keys())
            .collect::<HashSet<_>>();
        let have = self.data.iter().map(|(key, value)| (key.sha.clone(), value))
            .collect::<HashMap<_, _>>();
        let mut missing = self.commits
            .iter()
            .map(|commit| Commit { sha: commit.sha.clone(), date: Date(commit.date.clone()) })
            .filter(|c| Utc::now().signed_duration_since(c.date.0) < Duration::days(29))
            .filter(|c| {
                if let Some(cd) = have.get(&c.sha) {
                    // If we've missed any benchmark, we also want this commit
                    known_benchmarks
                        .iter()
                        .any(|b| !cd.benchmarks.contains_key(&**b))
                } else {
                    true
                }
            })
            .collect::<Vec<_>>();
        missing.reverse();
        Ok(self.persistent.lock().try_commits.iter()
            .map(|sha| Commit { sha: sha.clone(), date: Date::ymd_hms(2001, 01, 01, 0, 0, 0) })
            .filter(|c| !have.contains_key(&c.sha)) // we may have not updated the try-commits file
            .chain(missing)
            .collect())
    }
}

/// One decimal place rounded percent
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub struct Percent(#[serde(with = "util::round_float")] pub f64);
<commit_msg>Write out persistent on load<commit_after>// Copyright 2016 The rustc-perf Project Developers. See the COPYRIGHT
// file at the top-level directory.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::fs::{self, File};
use std::path::PathBuf;
use std::io::Read;
use std::env;

use serde_json;
use antidote::Mutex;
use failure::{ResultExt, Error};
use failure::SyncFailure;
use rust_sysroot;
use rust_sysroot::git::Commit as GitCommit;
use chrono::{Duration, Utc};

use util;
use git;
use collector::Date;

pub use collector::{Commit, CommitData, ArtifactData, Patch, Run, Stat};

#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct CurrentState {
    pub commit: Commit,
    pub benchmarks: Vec<String>,
}

#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct Persistent {
    pub try_commits: Vec<String>,
    pub current: Option<CurrentState>,
}

impl Persistent {
    pub fn write(&self) -> Result<(), Error> {
        let s = serde_json::to_string(self)?;
        fs::write("persistent.json", &s).with_context(|_| format!("failed to write persistent DB"))?;
        Ok(())
    }

    fn load() -> Persistent {
        let p = Persistent::load_().unwrap_or_else(|| Persistent {
            try_commits: Vec::new(),
            current: None,
        });
        p.write().unwrap();
        p
    }

    fn load_() -> Option<Persistent> {
        let s = fs::read_to_string("persistent.json").ok()?;
        let persistent: Persistent = serde_json::from_str(&s).ok()?;

        Some(persistent)
    }
}

#[derive(Debug)]
pub struct InputData {
    /// A set containing all crate names of the bootstrap kind.
    pub crate_list: BTreeSet<String>,

    /// All known statistics gathered for crates
    pub stats_list: BTreeSet<String>,

    /// The last date that was seen while loading files. The DateTime variant is
    /// used here since the date may or may not contain a time. Since the
    /// timezone is not important, it isn't stored, hence the Naive variant.
    pub last_date: Date,

    pub data: BTreeMap<Commit, CommitData>,

    pub artifact_data: BTreeMap<String, ArtifactData>,

    pub commits: Vec<GitCommit>,

    pub persistent: Mutex<Persistent>,
}

impl InputData {
    /// Initialize `InputData from the file system.
    pub fn from_fs(repo_loc: &str) -> Result<InputData, Error> {
        let repo_loc = PathBuf::from(repo_loc);
        let mut skipped = 0;
        let mut artifact_data = BTreeMap::new();
        let mut data = BTreeMap::new();

        if !repo_loc.exists() {
            // If the repository doesn't yet exist, simplify clone it to the given location.
            info!(
                "cloning repository into {}, since it doesn't exist before",
                repo_loc.display()
            );
            git::execute_command(
                &env::current_dir()?,
                &[
                    "clone",
                    "https://github.com/rust-lang-nursery/rustc-timing.git",
                    repo_loc.to_str().unwrap(),
                ],
            )?;
        }

        // Read all files from repo_loc/processed
        let mut file_count = 0;
        for entry in fs::read_dir(repo_loc.join("times"))? {
            let entry = entry?;
            if entry.file_type()?.is_dir() {
                continue;
            }
            file_count += 1;

            let filename = entry.file_name();
            let filename = filename.to_str().unwrap();
            let mut file = File::open(entry.path())?;
            let mut file_contents = String::new();
            // Skip files whose size is 0.
            if file.read_to_string(&mut file_contents)? == 0 {
                warn!("Skipping empty file: {}", filename);
                skipped += 1;
                continue;
            }

            if filename.starts_with("artifact-") {
                let contents: ArtifactData = match serde_json::from_str(&file_contents) {
                    Ok(j) => j,
                    Err(err) => {
                        error!("Failed to parse JSON for {}: {:?}", filename, err);
                        skipped += 1;
                        continue;
                    }
                };
                if contents.benchmarks.is_empty() {
                    warn!("empty benchmarks hash for {}", filename);
                    skipped += 1;
                    continue;
                }

                artifact_data.insert(contents.id.clone(), contents);
            } else {
                let contents: CommitData = match serde_json::from_str(&file_contents) {
                    Ok(json) => json,
                    Err(err) => {
                        error!("Failed to parse JSON for {}: {:?}", filename, err);
                        skipped += 1;
                        continue;
                    }
                };
                if contents.benchmarks.is_empty() {
                    warn!("empty benchmarks hash for {}", filename);
                    skipped += 1;
                    continue;
                }

                data.insert(contents.commit.clone(), contents);
            }
        }

        info!("{} total files", file_count);
        info!("{} skipped files", skipped);
        info!("{} measured", data.len());

        InputData::new(data, artifact_data)
    }

    pub fn new(
        data: BTreeMap<Commit, CommitData>,
        artifact_data: BTreeMap<String, ArtifactData>,
    ) -> Result<InputData, Error> {
        let mut last_date = None;
        let mut crate_list = BTreeSet::new();
        let mut stats_list = BTreeSet::new();

        for commit_data in data.values() {
            if last_date.is_none() || last_date.as_ref().unwrap() < &commit_data.commit.date {
                last_date = Some(commit_data.commit.date);
            }

            let benchmarks = commit_data
                .benchmarks
                .values()
                .filter_map(|v| v.as_ref().ok());
            for benchmark in benchmarks {
                for run in &benchmark.runs {
                    let run_name = benchmark.name.clone() + &run.name();
                    crate_list.insert(run_name);
                    for stat in &run.stats {
                        stats_list.insert(stat.name.clone());
                    }
                }
            }
        }

        let last_date = last_date.expect("No dates found");
        let commits = rust_sysroot::get_commits(rust_sysroot::EPOCH_COMMIT, "master").map_err(SyncFailure::new)?;

        Ok(InputData {
            crate_list: crate_list,
            stats_list: stats_list,
            last_date: last_date,
            data: data,
            artifact_data,
            commits,
            persistent: Mutex::new(Persistent::load()),
        })
    }

    pub fn missing_commits(&self) -> Result<Vec<Commit>, Error> {
        let known_benchmarks = self.data.values()
            .rev()
            .take(10)
            .flat_map(|v| v.benchmarks.keys())
            .collect::<HashSet<_>>();
        let have = self.data.iter().map(|(key, value)| (key.sha.clone(), value))
            .collect::<HashMap<_, _>>();
        let mut missing = self.commits
            .iter()
            .map(|commit| Commit { sha: commit.sha.clone(), date: Date(commit.date.clone()) })
            .filter(|c| Utc::now().signed_duration_since(c.date.0) < Duration::days(29))
            .filter(|c| {
                if let Some(cd) = have.get(&c.sha) {
                    // If we've missed any benchmark, we also want this commit
                    known_benchmarks
                        .iter()
                        .any(|b| !cd.benchmarks.contains_key(&**b))
                } else {
                    true
                }
            })
            .collect::<Vec<_>>();
        missing.reverse();
        Ok(self.persistent.lock().try_commits.iter()
            .map(|sha| Commit { sha: sha.clone(), date: Date::ymd_hms(2001, 01, 01, 0, 0, 0) })
            .filter(|c| !have.contains_key(&c.sha)) // we may have not updated the try-commits file
            .chain(missing)
            .collect())
    }
}

/// One decimal place rounded percent
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub struct Percent(#[serde(with = "util::round_float")] pub f64);
<|endoftext|>


<commit_before>extern crate ansi_term;
extern crate rand;

use ansi_term::Colour::*;
use rand::Rng;
use std::io;

enum Card {
    ClubsAce,      //  0
    ClubsTen,      //  1
    ClubsKing,     //  2
    ClubsQueen,    //  3
    ClubsJack,     //  4
    ClubsNine,     //  5
    ClubsEight,    //  6
    ClubsSeven,    //  7
    SpadesAce,     //  8
    SpadesTen,     //  9
    SpadesKing,    // 10
    SpadesQueen,   // 11
    SpadesJack,    // 12
    SpadesNine,    // 13
    SpadesEight,   // 14
    SpadesSeven,   // 15
    HeartsAce,     // 16
    HeartsTen,     // 17
    HeartsKing,    // 18
    HeartsQueen,   // 19
    HeartsJack,    // 20
    HeartsNine,    // 21
    HeartsEight,   // 22
    HeartsSeven,   // 23
    DiamondsAce,   // 24
    DiamondsTen,   // 25
    DiamondsKing,  // 26
    DiamondsQueen, // 27
    DiamondsJack,  // 28
    DiamondsNine,  // 29
    DiamondsEight, // 30
    DiamondsSeven, // 31
}

enum Game {
    Suit,
    Grand,
    Null,
}

enum PlayerId {
    A,
    B,
    C,
}

struct Player {
    id: u8,
    cards: Vec<u8>,
}

impl Player {
    fn print_cards(&self) {
        match self.id {
            0 => println!("player A:"),
            1 => println!("player B:"),
            2 => println!("player C:"),
            _ => panic!("Unknown player {}", self.id),
            }
        for index in 0..10 {
            print!("{}:", index);
            print_card(self.cards[index]);
        }
    }
    fn sort_cards(&mut self) {
        let mut sorted: Vec<u8> = Vec::new();
        let mut clubs: Vec<u8> = Vec::new();
        let mut spades: Vec<u8> = Vec::new();
        let mut hearts: Vec<u8> = Vec::new();
        let mut diamonds: Vec<u8> = Vec::new();
        // first find Jacks
        for n in 0..10 {
            match self.cards[n] {
                // ClubsJack
                4 => sorted.push(self.cards[n]),
                // SpadesJack
                12 => sorted.push(self.cards[n]),
                // HeartsJack
                20 => sorted.push(self.cards[n]),
                // DiamondsJack
                28 => sorted.push(self.cards[n]),
                // Clubs
                0 ... 7 => clubs.push(self.cards[n]),
                // Spades
                8 ... 15 => spades.push(self.cards[n]),
                // Hearts
                16 ... 23 => hearts.push(self.cards[n]),
                // Diamonds
                24 ... 31 => diamonds.push(self.cards[n]),
                _ => panic!("Unknown card"),
            }
        }
        clubs.sort();
        //clubs.reverse();
        spades.sort();
        //spades.reverse();
        hearts.sort();
        //hearts.reverse();
        diamonds.sort();
        //diamonds.reverse();
        // then add the suit with the highest count
        let empty: Vec<u8> = Vec::new();
        let mut highest: &Vec<u8> = ∅
        let mut max: u8 = 0u8;
        if clubs.len() > max as usize {
            max = clubs.len() as u8;
            highest = ♣
        }
        if spades.len() > max as usize {
            max = spades.len() as u8;
            highest = ♠
        }
        if hearts.len() > max as usize {
            max = hearts.len() as u8;
            highest = ♥
        }
        if diamonds.len() > max as usize {
            max = diamonds.len() as u8;
            highest = &diamonds;
        }
        // append highest
        if highest == &clubs {
            // append clubs
            for n in 0..clubs.len() {
                sorted.push(clubs[n]);
            }
        }
        if highest == &spades {
            // append spades
            for n in 0..spades.len() {
                sorted.push(spades[n]);
            }
        }
        if highest == &hearts {
            // append hearts
            for n in 0..hearts.len() {
                sorted.push(hearts[n]);
            }
        }
        if highest == &diamonds {
            // append diamonds
            for n in 0..diamonds.len() {
                sorted.push(diamonds[n]);
            }
        }
        // append others
        if highest != &clubs {
            // append clubs
            for n in 0..clubs.len() {
                sorted.push(clubs[n]);
            }
        }
        if highest != &spades {
            // append spades
            for n in 0..spades.len() {
                sorted.push(spades[n]);
            }
        }
        if highest != &hearts {
            // append hearts
            for n in 0..hearts.len() {
                sorted.push(hearts[n]);
            }
        }
        if highest != &diamonds {
            // append diamonds
            for n in 0..diamonds.len() {
                sorted.push(diamonds[n]);
            }
        }
        self.cards = sorted;
    }
}

struct PlayerBuilder {
    id: u8,
    cards: Vec<u8>,
}

impl PlayerBuilder {
    fn new() -> PlayerBuilder {
        PlayerBuilder { cards: Vec::new(), id: 3, }
    }

    fn add(&mut self, newCard: u8) -> &mut PlayerBuilder {
        self.cards.push(newCard);
        self
    }

    fn id(&mut self, newId: u8) -> &mut PlayerBuilder {
        self.id = newId;
        self
    }

    fn finalize(&self) -> Player {
        Player { id: self.id, cards: self.cards.to_vec(), }
    }
}

fn announce(player: u8) -> Game {
    Game::Suit
}

fn bid(dealer: u8) -> (u8, u8) {
    let winner: u8 = dealer;
    let highest: u8 = 18;
    // TODO
    (winner, highest)
}

fn deal(dealerId: u8) -> (Player, Player, Player) {
    let mut cards: Vec<u8> = (0..32).collect();
    // shuffle cards
    let mut upper: u8 = 32;
    let mut shuffled: Vec<u8> = Vec::new();
    for n in 0..32 {
        // randomly select card
        let pile_index: u8 = rand::thread_rng().gen_range(0, upper - n);
        // remove selected card from old pile
        let card = cards.remove(pile_index as usize);
        // add selected card to new pile
        shuffled.push(card);
    }
    // create dealer with the first 10 cards
    let mut dealer = PlayerBuilder::new()
        .id(dealerId)
        .add(shuffled[0])
        .add(shuffled[1])
        .add(shuffled[2])
        .add(shuffled[3])
        .add(shuffled[4])
        .add(shuffled[5])
        .add(shuffled[6])
        .add(shuffled[7])
        .add(shuffled[8])
        .add(shuffled[9])
        .finalize();
    // let the dealer print his own cards
    dealer.sort_cards();
    println!("");
    dealer.print_cards();
    println!("");
    // create the left player (will play first card)
    let mut left = PlayerBuilder::new()
        .id((dealerId + 1) % 3)
        .add(shuffled[10])
        .add(shuffled[11])
        .add(shuffled[12])
        .add(shuffled[13])
        .add(shuffled[14])
        .add(shuffled[15])
        .add(shuffled[16])
        .add(shuffled[17])
        .add(shuffled[18])
        .add(shuffled[19])
        .finalize();
    left.sort_cards();
    println!("");
    left.print_cards();
    println!("");
    // create the right player (will play bid first)
    let mut right = PlayerBuilder::new()
        .id((dealerId + 2) % 3)
        .add(shuffled[20])
        .add(shuffled[21])
        .add(shuffled[22])
        .add(shuffled[23])
        .add(shuffled[24])
        .add(shuffled[25])
        .add(shuffled[26])
        .add(shuffled[27])
        .add(shuffled[28])
        .add(shuffled[29])
        .finalize();
    right.sort_cards();
    println!("");
    right.print_cards();
    println!("");
    // Skat
    println!("Skat:");
    for n in 30..32 {
        print_card(shuffled[n]);
    };
    println!("");
    (dealer, left, right)
}

fn print_card(card: u8) {
    let club    = "♣";
    let spade   = "♠";
    let heart   = "♥";
    let diamond = "♦";
    match card {
        0 => {
            let mut ace = " A".to_string();
            ace.push_str(club);
            print!("{} ", Black.bold().paint(&ace));
        },
        1 => {
            let mut ten = "10".to_string();
            ten.push_str(club);
            print!("{} ", Black.bold().paint(&ten));
        },
        2 => {
            let mut king = " K".to_string();
            king.push_str(club);
            print!("{} ", Black.bold().paint(&king));
        },
        3 => {
            let mut queen = " Q".to_string();
            queen.push_str(club);
            print!("{} ", Black.bold().paint(&queen));
        },
        4 => {
            let mut jack = " J".to_string();
            jack.push_str(club);
            print!("{} ", Black.bold().paint(&jack));
        },
        5 => {
            let mut nine = " 9".to_string();
            nine.push_str(club);
            print!("{} ", Black.bold().paint(&nine));
        },
        6 => {
            let mut eight = " 8".to_string();
            eight.push_str(club);
            print!("{} ", Black.bold().paint(&eight));
        },
        7 => {
            let mut seven = " 7".to_string();
            seven.push_str(club);
            print!("{} ", Black.bold().paint(&seven));
        },
        8 => {
            let mut ace = " A".to_string();
            ace.push_str(spade);
            print!("{} ", Green.bold().paint(&ace));
        },
        9 => {
            let mut ten = "10".to_string();
            ten.push_str(spade);
            print!("{} ", Green.bold().paint(&ten));
        },
        10 => {
            let mut king = " K".to_string();
            king.push_str(spade);
            print!("{} ", Green.bold().paint(&king));
        },
        11 => {
            let mut queen = " Q".to_string();
            queen.push_str(spade);
            print!("{} ", Green.bold().paint(&queen));
        },
        12 => {
            let mut jack = " J".to_string();
            jack.push_str(spade);
            print!("{} ", Green.bold().paint(&jack));
        },
        13 => {
            let mut nine = " 9".to_string();
            nine.push_str(spade);
            print!("{} ", Green.bold().paint(&nine));
        },
        14 => {
            let mut eight = " 8".to_string();
            eight.push_str(spade);
            print!("{} ", Green.bold().paint(&eight));
        },
        15 => {
            let mut seven = " 7".to_string();
            seven.push_str(spade);
            print!("{} ", Green.bold().paint(&seven));
        },
        16 => {
            let mut ace = " A".to_string();
            ace.push_str(heart);
            print!("{} ", Red.bold().paint(&ace));
        },
        17 => {
            let mut ten = "10".to_string();
            ten.push_str(heart);
            print!("{} ", Red.bold().paint(&ten));
        },
        18 => {
            let mut king = " K".to_string();
            king.push_str(heart);
            print!("{} ", Red.bold().paint(&king));
        },
        19 => {
            let mut queen = " Q".to_string();
            queen.push_str(heart);
            print!("{} ", Red.bold().paint(&queen));
        },
        20 => {
            let mut jack = " J".to_string();
            jack.push_str(heart);
            print!("{} ", Red.bold().paint(&jack));
        },
        21 => {
            let mut nine = " 9".to_string();
            nine.push_str(heart);
            print!("{} ", Red.bold().paint(&nine));
        },
        22 => {
            let mut eight = " 8".to_string();
            eight.push_str(heart);
            print!("{} ", Red.bold().paint(&eight));
        },
        23 => {
            let mut seven = " 7".to_string();
            seven.push_str(heart);
            print!("{} ", Red.bold().paint(&seven));
        },
        24 => {
            let mut ace = " A".to_string();
            ace.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&ace));
        },
        25 => {
            let mut ten = "10".to_string();
            ten.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&ten));
        },
        26 => {
            let mut king = " K".to_string();
            king.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&king));
        },
        27 => {
            let mut queen = " Q".to_string();
            queen.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&queen));
        },
        28 => {
            let mut jack = " J".to_string();
            jack.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&jack));
        },
        29 => {
            let mut nine = " 9".to_string();
            nine.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&nine));
        },
        30 => {
            let mut eight = " 8".to_string();
            eight.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&eight));
        },
        31 => {
            let mut seven = " 7".to_string();
            seven.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&seven));
        },
        _ => panic!("Unknown card"),
    }
}

fn main() {
    // randomly select player
    let player_id: u8 = rand::thread_rng().gen_range(0, 3);
    loop {
        // player with player_id is dealing
        let (dealer,
             responder,
             bidder) = deal(player_id);
        // bid
        let (player, bid) = bid(player_id);
        // announce
        let game = announce(player);
        // play 10 tricks in a row
        for trick in 0..10 {
            println!("trick #{}:", trick);
            // ask for input
            let mut input = String::new();
            io::stdin().read_line(&mut input)
                .ok()
                .expect("failed to read line");
            let input: u8 = match input.trim().parse() {
                Ok(num) => num,
                Err(_) => break,
            };
            // is input valid?
        };
        println!("New game?");
        let mut input = String::new();
        io::stdin().read_line(&mut input)
            .ok()
            .expect("failed to read line");
        let input: u8 = match input.trim().parse() {
            Ok(num) => num,
            Err(_) => break,
        };
        println!("your input: {}", input);
        if input != 1 {
            break;
        }
    }
}
<commit_msg>Change the signature of bid() function.<commit_after>extern crate ansi_term;
extern crate rand;

use ansi_term::Colour::*;
use rand::Rng;
use std::io;

enum Card {
    ClubsAce,      //  0
    ClubsTen,      //  1
    ClubsKing,     //  2
    ClubsQueen,    //  3
    ClubsJack,     //  4
    ClubsNine,     //  5
    ClubsEight,    //  6
    ClubsSeven,    //  7
    SpadesAce,     //  8
    SpadesTen,     //  9
    SpadesKing,    // 10
    SpadesQueen,   // 11
    SpadesJack,    // 12
    SpadesNine,    // 13
    SpadesEight,   // 14
    SpadesSeven,   // 15
    HeartsAce,     // 16
    HeartsTen,     // 17
    HeartsKing,    // 18
    HeartsQueen,   // 19
    HeartsJack,    // 20
    HeartsNine,    // 21
    HeartsEight,   // 22
    HeartsSeven,   // 23
    DiamondsAce,   // 24
    DiamondsTen,   // 25
    DiamondsKing,  // 26
    DiamondsQueen, // 27
    DiamondsJack,  // 28
    DiamondsNine,  // 29
    DiamondsEight, // 30
    DiamondsSeven, // 31
}

enum Game {
    Suit,
    Grand,
    Null,
}

enum PlayerId {
    A,
    B,
    C,
}

struct Player {
    id: u8,
    cards: Vec<u8>,
}

impl Player {
    fn print_cards(&self) {
        match self.id {
            0 => println!("player A:"),
            1 => println!("player B:"),
            2 => println!("player C:"),
            _ => panic!("Unknown player {}", self.id),
            }
        for index in 0..10 {
            print!("{}:", index);
            print_card(self.cards[index]);
        }
    }
    fn sort_cards(&mut self) {
        let mut sorted: Vec<u8> = Vec::new();
        let mut clubs: Vec<u8> = Vec::new();
        let mut spades: Vec<u8> = Vec::new();
        let mut hearts: Vec<u8> = Vec::new();
        let mut diamonds: Vec<u8> = Vec::new();
        // first find Jacks
        for n in 0..10 {
            match self.cards[n] {
                // ClubsJack
                4 => sorted.push(self.cards[n]),
                // SpadesJack
                12 => sorted.push(self.cards[n]),
                // HeartsJack
                20 => sorted.push(self.cards[n]),
                // DiamondsJack
                28 => sorted.push(self.cards[n]),
                // Clubs
                0 ... 7 => clubs.push(self.cards[n]),
                // Spades
                8 ... 15 => spades.push(self.cards[n]),
                // Hearts
                16 ... 23 => hearts.push(self.cards[n]),
                // Diamonds
                24 ... 31 => diamonds.push(self.cards[n]),
                _ => panic!("Unknown card"),
            }
        }
        clubs.sort();
        //clubs.reverse();
        spades.sort();
        //spades.reverse();
        hearts.sort();
        //hearts.reverse();
        diamonds.sort();
        //diamonds.reverse();
        // then add the suit with the highest count
        let empty: Vec<u8> = Vec::new();
        let mut highest: &Vec<u8> = ∅
        let mut max: u8 = 0u8;
        if clubs.len() > max as usize {
            max = clubs.len() as u8;
            highest = ♣
        }
        if spades.len() > max as usize {
            max = spades.len() as u8;
            highest = ♠
        }
        if hearts.len() > max as usize {
            max = hearts.len() as u8;
            highest = ♥
        }
        if diamonds.len() > max as usize {
            max = diamonds.len() as u8;
            highest = &diamonds;
        }
        // append highest
        if highest == &clubs {
            // append clubs
            for n in 0..clubs.len() {
                sorted.push(clubs[n]);
            }
        }
        if highest == &spades {
            // append spades
            for n in 0..spades.len() {
                sorted.push(spades[n]);
            }
        }
        if highest == &hearts {
            // append hearts
            for n in 0..hearts.len() {
                sorted.push(hearts[n]);
            }
        }
        if highest == &diamonds {
            // append diamonds
            for n in 0..diamonds.len() {
                sorted.push(diamonds[n]);
            }
        }
        // append others
        if highest != &clubs {
            // append clubs
            for n in 0..clubs.len() {
                sorted.push(clubs[n]);
            }
        }
        if highest != &spades {
            // append spades
            for n in 0..spades.len() {
                sorted.push(spades[n]);
            }
        }
        if highest != &hearts {
            // append hearts
            for n in 0..hearts.len() {
                sorted.push(hearts[n]);
            }
        }
        if highest != &diamonds {
            // append diamonds
            for n in 0..diamonds.len() {
                sorted.push(diamonds[n]);
            }
        }
        self.cards = sorted;
    }
}

struct PlayerBuilder {
    id: u8,
    cards: Vec<u8>,
}

impl PlayerBuilder {
    fn new() -> PlayerBuilder {
        PlayerBuilder { cards: Vec::new(), id: 3, }
    }

    fn add(&mut self, newCard: u8) -> &mut PlayerBuilder {
        self.cards.push(newCard);
        self
    }

    fn id(&mut self, newId: u8) -> &mut PlayerBuilder {
        self.id = newId;
        self
    }

    fn finalize(&self) -> Player {
        Player { id: self.id, cards: self.cards.to_vec(), }
    }
}

fn announce(player: u8) -> Game {
    Game::Suit
}

fn bid(dealer: &Player,
       responder: &Player,
       bidder: &Player) -> (u8, u8) {
    let winner: u8 = dealer.id;
    let highest: u8 = 18;
    // TODO
    (winner, highest)
}

fn deal(dealerId: u8) -> (Player, Player, Player) {
    let mut cards: Vec<u8> = (0..32).collect();
    // shuffle cards
    let mut upper: u8 = 32;
    let mut shuffled: Vec<u8> = Vec::new();
    for n in 0..32 {
        // randomly select card
        let pile_index: u8 = rand::thread_rng().gen_range(0, upper - n);
        // remove selected card from old pile
        let card = cards.remove(pile_index as usize);
        // add selected card to new pile
        shuffled.push(card);
    }
    // create dealer with the first 10 cards
    let mut dealer = PlayerBuilder::new()
        .id(dealerId)
        .add(shuffled[0])
        .add(shuffled[1])
        .add(shuffled[2])
        .add(shuffled[3])
        .add(shuffled[4])
        .add(shuffled[5])
        .add(shuffled[6])
        .add(shuffled[7])
        .add(shuffled[8])
        .add(shuffled[9])
        .finalize();
    // let the dealer print his own cards
    dealer.sort_cards();
    println!("");
    dealer.print_cards();
    println!("");
    // create the left player (will play first card)
    let mut left = PlayerBuilder::new()
        .id((dealerId + 1) % 3)
        .add(shuffled[10])
        .add(shuffled[11])
        .add(shuffled[12])
        .add(shuffled[13])
        .add(shuffled[14])
        .add(shuffled[15])
        .add(shuffled[16])
        .add(shuffled[17])
        .add(shuffled[18])
        .add(shuffled[19])
        .finalize();
    left.sort_cards();
    println!("");
    left.print_cards();
    println!("");
    // create the right player (will play bid first)
    let mut right = PlayerBuilder::new()
        .id((dealerId + 2) % 3)
        .add(shuffled[20])
        .add(shuffled[21])
        .add(shuffled[22])
        .add(shuffled[23])
        .add(shuffled[24])
        .add(shuffled[25])
        .add(shuffled[26])
        .add(shuffled[27])
        .add(shuffled[28])
        .add(shuffled[29])
        .finalize();
    right.sort_cards();
    println!("");
    right.print_cards();
    println!("");
    // Skat
    println!("Skat:");
    for n in 30..32 {
        print_card(shuffled[n]);
    };
    println!("");
    (dealer, left, right)
}

fn print_card(card: u8) {
    let club    = "♣";
    let spade   = "♠";
    let heart   = "♥";
    let diamond = "♦";
    match card {
        0 => {
            let mut ace = " A".to_string();
            ace.push_str(club);
            print!("{} ", Black.bold().paint(&ace));
        },
        1 => {
            let mut ten = "10".to_string();
            ten.push_str(club);
            print!("{} ", Black.bold().paint(&ten));
        },
        2 => {
            let mut king = " K".to_string();
            king.push_str(club);
            print!("{} ", Black.bold().paint(&king));
        },
        3 => {
            let mut queen = " Q".to_string();
            queen.push_str(club);
            print!("{} ", Black.bold().paint(&queen));
        },
        4 => {
            let mut jack = " J".to_string();
            jack.push_str(club);
            print!("{} ", Black.bold().paint(&jack));
        },
        5 => {
            let mut nine = " 9".to_string();
            nine.push_str(club);
            print!("{} ", Black.bold().paint(&nine));
        },
        6 => {
            let mut eight = " 8".to_string();
            eight.push_str(club);
            print!("{} ", Black.bold().paint(&eight));
        },
        7 => {
            let mut seven = " 7".to_string();
            seven.push_str(club);
            print!("{} ", Black.bold().paint(&seven));
        },
        8 => {
            let mut ace = " A".to_string();
            ace.push_str(spade);
            print!("{} ", Green.bold().paint(&ace));
        },
        9 => {
            let mut ten = "10".to_string();
            ten.push_str(spade);
            print!("{} ", Green.bold().paint(&ten));
        },
        10 => {
            let mut king = " K".to_string();
            king.push_str(spade);
            print!("{} ", Green.bold().paint(&king));
        },
        11 => {
            let mut queen = " Q".to_string();
            queen.push_str(spade);
            print!("{} ", Green.bold().paint(&queen));
        },
        12 => {
            let mut jack = " J".to_string();
            jack.push_str(spade);
            print!("{} ", Green.bold().paint(&jack));
        },
        13 => {
            let mut nine = " 9".to_string();
            nine.push_str(spade);
            print!("{} ", Green.bold().paint(&nine));
        },
        14 => {
            let mut eight = " 8".to_string();
            eight.push_str(spade);
            print!("{} ", Green.bold().paint(&eight));
        },
        15 => {
            let mut seven = " 7".to_string();
            seven.push_str(spade);
            print!("{} ", Green.bold().paint(&seven));
        },
        16 => {
            let mut ace = " A".to_string();
            ace.push_str(heart);
            print!("{} ", Red.bold().paint(&ace));
        },
        17 => {
            let mut ten = "10".to_string();
            ten.push_str(heart);
            print!("{} ", Red.bold().paint(&ten));
        },
        18 => {
            let mut king = " K".to_string();
            king.push_str(heart);
            print!("{} ", Red.bold().paint(&king));
        },
        19 => {
            let mut queen = " Q".to_string();
            queen.push_str(heart);
            print!("{} ", Red.bold().paint(&queen));
        },
        20 => {
            let mut jack = " J".to_string();
            jack.push_str(heart);
            print!("{} ", Red.bold().paint(&jack));
        },
        21 => {
            let mut nine = " 9".to_string();
            nine.push_str(heart);
            print!("{} ", Red.bold().paint(&nine));
        },
        22 => {
            let mut eight = " 8".to_string();
            eight.push_str(heart);
            print!("{} ", Red.bold().paint(&eight));
        },
        23 => {
            let mut seven = " 7".to_string();
            seven.push_str(heart);
            print!("{} ", Red.bold().paint(&seven));
        },
        24 => {
            let mut ace = " A".to_string();
            ace.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&ace));
        },
        25 => {
            let mut ten = "10".to_string();
            ten.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&ten));
        },
        26 => {
            let mut king = " K".to_string();
            king.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&king));
        },
        27 => {
            let mut queen = " Q".to_string();
            queen.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&queen));
        },
        28 => {
            let mut jack = " J".to_string();
            jack.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&jack));
        },
        29 => {
            let mut nine = " 9".to_string();
            nine.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&nine));
        },
        30 => {
            let mut eight = " 8".to_string();
            eight.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&eight));
        },
        31 => {
            let mut seven = " 7".to_string();
            seven.push_str(diamond);
            print!("{} ", Yellow.bold().paint(&seven));
        },
        _ => panic!("Unknown card"),
    }
}

fn main() {
    // randomly select player
    let player_id: u8 = rand::thread_rng().gen_range(0, 3);
    loop {
        // player with player_id is dealing
        let (dealer,
             responder,
             bidder) = deal(player_id);
        // bid
        let (declarer_id, game_value) = bid(&dealer,
                                            &responder,
                                            &bidder);
        // announce
        let game = announce(declarer_id);
        // play 10 tricks in a row
        for trick in 0..10 {
            println!("trick #{}:", trick);
            // ask for input
            let mut input = String::new();
            io::stdin().read_line(&mut input)
                .ok()
                .expect("failed to read line");
            let input: u8 = match input.trim().parse() {
                Ok(num) => num,
                Err(_) => break,
            };
            // is input valid?
        };
        println!("New game?");
        let mut input = String::new();
        io::stdin().read_line(&mut input)
            .ok()
            .expect("failed to read line");
        let input: u8 = match input.trim().parse() {
            Ok(num) => num,
            Err(_) => break,
        };
        println!("your input: {}", input);
        if input != 1 {
            break;
        }
    }
}
<|endoftext|>


<commit_before>use cbor::decoder::*;
use cbor::cbor::CborType;

const COSE_SIGN_TAG: u64 = 98;

#[derive(Debug)]
#[derive(PartialEq)]
pub enum CoseSignatureType {
    ES256,
    ES384,
    ES512,
}

#[derive(Debug)]
pub struct CoseSignature {
    pub signature_type: CoseSignatureType,
    pub signature: Vec<u8>,
    pub signer_cert: Vec<u8>,
    pub certs: Vec<u8>,
    pub to_verify: Vec<u8>,
}

/// COSE_Sign = [
///     Headers,
///     payload : bstr / nil,
///     signatures : [+ COSE_Signature]
/// ]
///
/// Headers = (
///     protected : empty_or_serialized_map,
///     unprotected : header_map
/// )
///
/// This syntax is a little unintuitive. Taken together, the two previous definitions essentially
/// mean:
///
/// COSE_Sign = [
///     protected : empty_or_serialized_map,
///     unprotected : header_map
///     payload : bstr / nil,
///     signatures : [+ COSE_Signature]
/// ]
///
/// (COSE_Sign is an array. The first element is an empty or serialized map (in our case, it is
/// never expected to be empty). The second element is a map (it is expected to be empty. The third
/// element is a bstr or nil (it is expected to be nil). The fourth element is an array of
/// COSE_Signature.)
///
/// COSE_Signature =  [
///     Headers,
///     signature : bstr
/// ]
///
/// but again, unpacking this:
///
/// COSE_Signature =  [
///     protected : empty_or_serialized_map,
///     unprotected : header_map
///     signature : bstr
/// ]

pub fn decode_signature(bytes: Vec<u8>, payload: &[u8]) -> Result<Vec<CoseSignature>, &'static str> {
    // This has to be a COSE_Sign object, which is a tagged array.
    let tagged_cose_sign = decode(bytes)?;
    let cose_sign_array = match tagged_cose_sign {
        CborType::Tag(tag, cose_sign) => {
            if tag != COSE_SIGN_TAG {
                return Err("This is not a COSE_Sign object 0");
            }
            match *cose_sign {
                CborType::Array(values) => values,
                _ => return Err("This is not a COSE_Sign object 1"),
            }
        },
        _ => return Err("This is not a COSE_Sign object 2"),
    };
    if cose_sign_array.len() != 4 {
        return Err("This is not a valid COSE signature object 3.");
    }
    let signatures = &cose_sign_array[3];
    let signatures = unpack!(Array, signatures);

    // Take the first signature.
    if signatures.len() < 1 {
        return Err("This is not a valid COSE Signature. Couldn't find a signature object.");
    }
    let cose_signature = &signatures[0];
    let cose_signature = unpack!(Array, cose_signature);
    if cose_signature.len() != 3 {
        return Err("This is not a valid COSE Signature. Too short.");
    }
    let protected_signature_header_bytes = &cose_signature[0];
    let protected_signature_header_bytes = unpack!(Bytes, protected_signature_header_bytes).clone();

    // Parse the protected signature header.
    let protected_signature_header = decode(protected_signature_header_bytes.clone())?;
    // TODO: This isn't quite right due to order... (it's a map)
    let signature_algorithm_value = match protected_signature_header {
        CborType::Map(values) => {
            if values.len() < 1 {
                return Err("This is not a valid COSE signature object. Protected header is empty.");
            }
            let val = values.get(&CborType::Integer(1));
            match val {
                Some(x) => x.clone(),
                _ => return Err("Invalid COSE signature: expected alg header key (1)."),
            }
        },
        _ => return Err("Invalid COSE signature object: protected header is not a map."),
    };
    match signature_algorithm_value {
        CborType::SignedInteger(val) => {
            if val != -7 {
                return Err("Invalid COSE signature: expected ES256 (-7).");
            }
        },
        _ => return Err("Invalid COSE signature: alg value is not a signed integer."),
    };
    let signature_algorithm = CoseSignatureType::ES256;

    // Read the key ID from the unprotected header.
    let unprotected_signature_header = &cose_signature[1];
    let (key_id_key, key_id_value) = match unprotected_signature_header {
        &CborType::Map(ref value) => {
            if value.len() < 1 {
                return Err("Invalid COSE signature: unprotected header is empty.");
            }
            let mut tmp = value.iter();
            tmp.next().clone().unwrap()
        },
        _ => return Err("Invalid COSE signature: unprotected header is not a map."),
    };
    match key_id_key {
        &CborType::Integer(ref val) => {
            if val != &4 {
                return Err("Invalid COSE signature: expected kid header key (4).");
            }
        },
        _ => return Err("Invalid COSE signature: header key is not an integer."),
    };
    let key_id_bytes = &key_id_value.clone();
    let key_id = unpack!(Bytes, key_id_bytes);

    // Read the signature bytes.
    let signature_bytes = &cose_signature[2];
    let signature_bytes = unpack!(Bytes, signature_bytes).clone();
    let mut bytes_to_verify:Vec<u8> = Vec::new();
    // XXX: Use encoder for this.
    bytes_to_verify.push(0x69);
    bytes_to_verify.extend_from_slice(b"Signature");
    // XXX: Add protected body header when present.
    bytes_to_verify.push(0x40);
    if protected_signature_header_bytes.len() > 23 {
        // XXX: fix this.
        return Err("Sorry, this is not implemented for protected headers that are longer than 23.");
    }
    let tmp:u8 = ((2 << 5) as u8) + protected_signature_header_bytes.len() as u8;
    bytes_to_verify.push(tmp);
    bytes_to_verify.append(&mut protected_signature_header_bytes.clone());
    bytes_to_verify.push(0x40);
    if payload.len() > 23 {
        // XXX: fix this.
        return Err("Sorry, this is not implemented for payloads that are longer than 23.");
    }
    let tmp:u8 = ((2 << 5) as u8) + payload.len() as u8;
    bytes_to_verify.push(tmp);
    bytes_to_verify.extend_from_slice(payload);
    // Add CBOR array stuff.
    bytes_to_verify.insert(0, 0x85);

    let signature = CoseSignature {
        signature_type: signature_algorithm,
        signature: signature_bytes,
        signer_cert: key_id.clone(),
        certs: Vec::new(),
        to_verify: bytes_to_verify,
    };
    let mut result = Vec::new();
    result.push(signature);
    Ok(result)
}
<commit_msg>refactor map usage in cose decoder<commit_after>use cbor::decoder::*;
use cbor::cbor::CborType;

const COSE_SIGN_TAG: u64 = 98;

#[derive(Debug)]
#[derive(PartialEq)]
pub enum CoseSignatureType {
    ES256,
    ES384,
    ES512,
}

#[derive(Debug)]
pub struct CoseSignature {
    pub signature_type: CoseSignatureType,
    pub signature: Vec<u8>,
    pub signer_cert: Vec<u8>,
    pub certs: Vec<u8>,
    pub to_verify: Vec<u8>,
}

fn get_map_value(map: &CborType, key: &CborType) -> Result<CborType, &'static str> {
    match map {
        &CborType::Map(ref values) => {
            if values.is_empty() {
                return Err("This map is empty.");
            }
            let val = values.get(key);
            match val {
                Some(x) => return Ok(x.clone()),
                _ => return Err("Couldn't retrieve value for the provided key."),
            }
        }
        _ => return Err("This is not a CborType::Map."),
    };
}

/// COSE_Sign = [
///     Headers,
///     payload : bstr / nil,
///     signatures : [+ COSE_Signature]
/// ]
///
/// Headers = (
///     protected : empty_or_serialized_map,
///     unprotected : header_map
/// )
///
/// This syntax is a little unintuitive. Taken together, the two previous definitions essentially
/// mean:
///
/// COSE_Sign = [
///     protected : empty_or_serialized_map,
///     unprotected : header_map
///     payload : bstr / nil,
///     signatures : [+ COSE_Signature]
/// ]
///
/// (COSE_Sign is an array. The first element is an empty or serialized map (in our case, it is
/// never expected to be empty). The second element is a map (it is expected to be empty. The third
/// element is a bstr or nil (it is expected to be nil). The fourth element is an array of
/// COSE_Signature.)
///
/// COSE_Signature =  [
///     Headers,
///     signature : bstr
/// ]
///
/// but again, unpacking this:
///
/// COSE_Signature =  [
///     protected : empty_or_serialized_map,
///     unprotected : header_map
///     signature : bstr
/// ]

pub fn decode_signature(
    bytes: Vec<u8>,
    payload: &[u8],
) -> Result<Vec<CoseSignature>, &'static str> {
    // This has to be a COSE_Sign object, which is a tagged array.
    let tagged_cose_sign = decode(bytes)?;
    let cose_sign_array = match tagged_cose_sign {
        CborType::Tag(tag, cose_sign) => {
            if tag != COSE_SIGN_TAG {
                return Err("This is not a COSE_Sign object 0");
            }
            match *cose_sign {
                CborType::Array(values) => values,
                _ => return Err("This is not a COSE_Sign object 1"),
            }
        }
        _ => return Err("This is not a COSE_Sign object 2"),
    };
    if cose_sign_array.len() != 4 {
        return Err("This is not a valid COSE signature object 3.");
    }
    let signatures = &cose_sign_array[3];
    let signatures = unpack!(Array, signatures);

    // Take the first signature.
    if signatures.len() < 1 {
        return Err(
            "This is not a valid COSE Signature. Couldn't find a signature object.",
        );
    }
    let cose_signature = &signatures[0];
    let cose_signature = unpack!(Array, cose_signature);
    if cose_signature.len() != 3 {
        return Err("This is not a valid COSE Signature. Too short.");
    }
    let protected_signature_header_bytes = &cose_signature[0];
    let protected_signature_header_bytes = unpack!(Bytes, protected_signature_header_bytes).clone();

    // Parse the protected signature header.
    let protected_signature_header = decode(protected_signature_header_bytes.clone())?;
    // TODO: This isn't quite right due to order... (it's a map)
    let signature_algorithm = get_map_value(&protected_signature_header, &CborType::Integer(1))?;
    match signature_algorithm {
        CborType::SignedInteger(val) => {
            if val != -7 {
                return Err("Invalid COSE signature: expected ES256 (-7).");
            }
        }
        _ => return Err("Invalid COSE signature: alg value is not a signed integer."),
    };
    let signature_algorithm = CoseSignatureType::ES256;

    // Read the key ID from the unprotected header.
    let unprotected_signature_header = &cose_signature[1];
    let key_id = &get_map_value(unprotected_signature_header, &CborType::Integer(4))?;
    let key_id = unpack!(Bytes, key_id);

    // Read the signature bytes.
    let signature_bytes = &cose_signature[2];
    let signature_bytes = unpack!(Bytes, signature_bytes).clone();
    let mut bytes_to_verify: Vec<u8> = Vec::new();
    // XXX: Use encoder for this.
    bytes_to_verify.push(0x69);
    bytes_to_verify.extend_from_slice(b"Signature");
    // XXX: Add protected body header when present.
    bytes_to_verify.push(0x40);
    if protected_signature_header_bytes.len() > 23 {
        // XXX: fix this.
        return Err(
            "Sorry, this is not implemented for protected headers that are longer than 23.",
        );
    }
    let tmp: u8 = ((2 << 5) as u8) + protected_signature_header_bytes.len() as u8;
    bytes_to_verify.push(tmp);
    bytes_to_verify.append(&mut protected_signature_header_bytes.clone());
    bytes_to_verify.push(0x40);
    if payload.len() > 23 {
        // XXX: fix this.
        return Err(
            "Sorry, this is not implemented for payloads that are longer than 23.",
        );
    }
    let tmp: u8 = ((2 << 5) as u8) + payload.len() as u8;
    bytes_to_verify.push(tmp);
    bytes_to_verify.extend_from_slice(payload);
    // Add CBOR array stuff.
    bytes_to_verify.insert(0, 0x85);

    let signature = CoseSignature {
        signature_type: signature_algorithm,
        signature: signature_bytes,
        signer_cert: key_id.clone(),
        certs: Vec::new(),
        to_verify: bytes_to_verify,
    };
    let mut result = Vec::new();
    result.push(signature);
    Ok(result)
}
<|endoftext|>