<commit_before>/*
 * Copyright (c) 2013-2014, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

#![feature(globs)]

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

extern crate capnp;

pub mod schema_capnp;
pub mod codegen;

pub fn compile(prefix : Path, files : &[Path]) {

    let out_dir = ::std::os::getenv("OUT_DIR").unwrap();

    let mut command = ::std::io::Command::new("capnp");
    command
        .arg("compile")
        .arg(format!("-o/bin/cat:{}", out_dir))
        .arg(format!("--src-prefix={}", prefix.display()));

    for file in files.iter() {
        command.arg(format!("{}", prefix.join(file).display()));
    }

    command.stdout(::std::io::process::CreatePipe(false, true));

    match command.spawn() {
        Ok(ref mut p) =>  {
            let mut child_stdout = p.stdout.take().unwrap();
            ::codegen::main(&mut child_stdout).unwrap();
        }
        Err(e) => {
            println!("could not start process: {}", e);
        }
    }

}

<commit_msg>don't join the prefix<commit_after>/*
 * Copyright (c) 2013-2014, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

#![feature(globs)]

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

extern crate capnp;

pub mod schema_capnp;
pub mod codegen;

pub fn compile(prefix : Path, files : &[Path]) {

    let out_dir = ::std::os::getenv("OUT_DIR").unwrap();

    let mut command = ::std::io::Command::new("capnp");
    command
        .arg("compile")
        .arg(format!("-o/bin/cat:{}", out_dir))
        .arg(format!("--src-prefix={}", prefix.display()));

    for file in files.iter() {
        command.arg(format!("{}", file.display()));
    }

    command.stdout(::std::io::process::CreatePipe(false, true));

    match command.spawn() {
        Ok(ref mut p) =>  {
            let mut child_stdout = p.stdout.take().unwrap();
            ::codegen::main(&mut child_stdout).unwrap();
        }
        Err(e) => {
            println!("could not start process: {}", e);
        }
    }

}

<|endoftext|>


<commit_before>#![crate_id = "graphics"]
#![deny(missing_doc)]

//! A library for 2D graphics that works with multiple back-ends.
//!
//! To implement your own back-end, use the BackEnd trait.
//!
//! ## Usage
//!
//! To draw to the back-end, you need a context.
//! The context contains the information necessary to perform the drawing.
//! Unlike other graphics libraries, this library is not bound to the back-end.
//! You do not have to specify which back-end to use before doing the actual drawing.
//!
//! For example, assuming we have a back-end called `back_end`:
//!
//! ```
//! Context::new().rect(x, y, w, h).rgba(r, g, b, a).fill(&mut back_end);
//! ```
//!
//! ## Important!
//!
//! Because the context is built using borrowed pointers,
//! it is not possible to do two or more steps at a time and assign it to a variable:
//!
//! ```
//! // ERROR: Borrowed value does not live long enough
//! let rect = Context::new().rect(x, y, w, h);
//! ```
//!
//! This is because the lifetime of the first step only lives inside the expression.
//! To solve this problem, break the statement into two parts, one for each step:
//!
//! ```
//! let c = Context::new();
//! let rect = c.rect(x, y, w, h);
//! ```
//!
//! This is only the case when you are assigning the context to a variable.

pub use Context = context::Context;
pub use BackEnd = back_end::BackEnd;
pub use Transform2d = transform2d::Transform2d;
pub use AddColor = add_color::AddColor;
pub use AddEllipse = add_ellipse::AddEllipse;
pub use AddRectangle = add_rectangle::AddRectangle;
pub use Fill = fill::Fill;
pub use Clear = clear::Clear;
pub use ColorContext = color_context::ColorContext;
pub use EllipseContext = ellipse_context::EllipseContext;
pub use EllipseColorContext = ellipse_color_context::EllipseColorContext;
pub use LineContext = line_context::LineContext;
pub use RectangleContext = rectangle_context::RectangleContext;
pub use RectangleColorContext = rectangle_color_context::RectangleColorContext;
pub use RoundRectangleContext = round_rectangle_context::RoundRectangleContext;

mod context;
mod back_end;
mod transform2d;
mod add_color;
mod add_ellipse;
mod add_rectangle;
mod fill;
mod clear;
mod color_context;
mod ellipse_context;
mod ellipse_color_context;
mod line_context;
mod rectangle_context;
mod rectangle_color_context;
mod round_rectangle_context;
pub mod vecmath;
pub mod triangulation;
pub mod interpolation;

pub type Color = [f32, ..4];
pub type Line = [f64, ..4];
pub type Matrix2d = [f64, ..6];
pub type Rectangle = [f64, ..4];
pub type RoundRectangle = [f64, ..5];

/// A structure that might contain a value or a borrowed value.
/// This is to used as building block to create data structure
/// that is partially based on an existing structure.
pub enum Field<'a, T> {
    /// Contains a value.
    Value(T),
    /// Contains a borrowed pointer.
    Borrowed(&'a T),
}

impl<'a, T> Field<'a, T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&'a self) -> &'a T {
        match *self {
            Value(ref val) => val,
            Borrowed(rval) => rval,
        }
    }
}

<commit_msg>Added InfiniteLine<commit_after>#![crate_id = "graphics"]
#![deny(missing_doc)]

//! A library for 2D graphics that works with multiple back-ends.
//!
//! To implement your own back-end, use the BackEnd trait.
//!
//! ## Usage
//!
//! To draw to the back-end, you need a context.
//! The context contains the information necessary to perform the drawing.
//! Unlike other graphics libraries, this library is not bound to the back-end.
//! You do not have to specify which back-end to use before doing the actual drawing.
//!
//! For example, assuming we have a back-end called `back_end`:
//!
//! ```
//! Context::new().rect(x, y, w, h).rgba(r, g, b, a).fill(&mut back_end);
//! ```
//!
//! ## Important!
//!
//! Because the context is built using borrowed pointers,
//! it is not possible to do two or more steps at a time and assign it to a variable:
//!
//! ```
//! // ERROR: Borrowed value does not live long enough
//! let rect = Context::new().rect(x, y, w, h);
//! ```
//!
//! This is because the lifetime of the first step only lives inside the expression.
//! To solve this problem, break the statement into two parts, one for each step:
//!
//! ```
//! let c = Context::new();
//! let rect = c.rect(x, y, w, h);
//! ```
//!
//! This is only the case when you are assigning the context to a variable.

pub use Context = context::Context;
pub use BackEnd = back_end::BackEnd;
pub use Transform2d = transform2d::Transform2d;
pub use AddColor = add_color::AddColor;
pub use AddEllipse = add_ellipse::AddEllipse;
pub use AddRectangle = add_rectangle::AddRectangle;
pub use Fill = fill::Fill;
pub use Clear = clear::Clear;
pub use ColorContext = color_context::ColorContext;
pub use EllipseContext = ellipse_context::EllipseContext;
pub use EllipseColorContext = ellipse_color_context::EllipseColorContext;
pub use LineContext = line_context::LineContext;
pub use RectangleContext = rectangle_context::RectangleContext;
pub use RectangleColorContext = rectangle_color_context::RectangleColorContext;
pub use RoundRectangleContext = round_rectangle_context::RoundRectangleContext;

mod context;
mod back_end;
mod transform2d;
mod add_color;
mod add_ellipse;
mod add_rectangle;
mod fill;
mod clear;
mod color_context;
mod ellipse_context;
mod ellipse_color_context;
mod line_context;
mod rectangle_context;
mod rectangle_color_context;
mod round_rectangle_context;
pub mod vecmath;
pub mod triangulation;
pub mod interpolation;

pub type Color = [f32, ..4];
pub type Line = [f64, ..4];
pub type InfiniteLine = [f64, ..4];
pub type Matrix2d = [f64, ..6];
pub type Rectangle = [f64, ..4];
pub type RoundRectangle = [f64, ..5];

/// A structure that might contain a value or a borrowed value.
/// This is to used as building block to create data structure
/// that is partially based on an existing structure.
pub enum Field<'a, T> {
    /// Contains a value.
    Value(T),
    /// Contains a borrowed pointer.
    Borrowed(&'a T),
}

impl<'a, T> Field<'a, T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&'a self) -> &'a T {
        match *self {
            Value(ref val) => val,
            Borrowed(rval) => rval,
        }
    }
}

<|endoftext|>


<commit_before>//! Lettre is an email library that allows creating and sending messages. It provides:
//!
//! * An easy to use email builder
//! * Pluggable email transports
//! * Unicode support
//! * Secure defaults
//!
//! Lettre requires Rust 1.40 or newer.
//!
//! ## Optional features
//!
//! * **builder**: Message builder
//! * **file-transport**: Transport that write messages into a file
//! * **smtp-transport**: Transport over SMTP
//! * **sendmail-transport**: Transport over SMTP
//! * **rustls-tls**: TLS support with the `rustls` crate
//! * **native-tls**: TLS support with the `native-tls` crate
//! * **r2d2**: Connection pool for SMTP transport
//! * **tracing**: Logging using the `tracing` crate
//! * **serde**: Serialization/Deserialization of entities
//! * **hostname**: Ability to try to use actual hostname in SMTP transaction

#![doc(html_root_url = "https://docs.rs/lettre/0.10.0")]
#![doc(html_favicon_url = "https://lettre.at/favicon.png")]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/15113230?v=4")]
#![deny(
    missing_copy_implementations,
    trivial_casts,
    trivial_numeric_casts,
    unstable_features,
    unused_import_braces,
    unsafe_code
)]

pub mod address;
pub mod error;
#[cfg(feature = "builder")]
pub mod message;
pub mod transport;

use crate::error::Error;
#[cfg(feature = "builder")]
pub use crate::message::{
    header::{self, Headers},
    EmailFormat, Mailbox, Mailboxes, Message,
};
#[cfg(feature = "file-transport")]
pub use crate::transport::file::FileTransport;
#[cfg(feature = "sendmail-transport")]
pub use crate::transport::sendmail::SendmailTransport;
#[cfg(all(feature = "smtp-transport", feature = "connection-pool"))]
pub use crate::transport::smtp::r2d2::SmtpConnectionManager;
#[cfg(feature = "smtp-transport")]
pub use crate::transport::smtp::SmtpTransport;
#[cfg(all(feature = "smtp-transport", feature = "tokio02"))]
pub use crate::transport::smtp::{AsyncSmtpTransport, Tokio02Connector};
pub use crate::{address::Address, transport::stub::StubTransport};
#[cfg(any(feature = "async-std1", feature = "tokio02"))]
use async_trait::async_trait;
#[cfg(feature = "builder")]
use std::convert::TryFrom;
use std::{error::Error as StdError, fmt};

/// Simple email envelope representation
///
/// We only accept mailboxes, and do not support source routes (as per RFC).
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Envelope {
    /// The envelope recipients' addresses
    ///
    /// This can not be empty.
    forward_path: Vec<Address>,
    /// The envelope sender address
    reverse_path: Option<Address>,
}

impl Envelope {
    /// Creates a new envelope, which may fail if `to` is empty.
    pub fn new(from: Option<Address>, to: Vec<Address>) -> Result<Envelope, Error> {
        if to.is_empty() {
            return Err(Error::MissingTo);
        }
        Ok(Envelope {
            forward_path: to,
            reverse_path: from,
        })
    }

    /// Destination addresses of the envelope
    pub fn to(&self) -> &[Address] {
        self.forward_path.as_slice()
    }

    /// Source address of the envelope
    pub fn from(&self) -> Option<&Address> {
        self.reverse_path.as_ref()
    }
}

impl TryFrom<&Headers> for Envelope {
    type Error = Error;

    fn try_from(headers: &Headers) -> Result<Self, Self::Error> {
        let from = match headers.get::<header::Sender>() {
            // If there is a Sender, use it
            Some(header::Sender(a)) => Some(a.email.clone()),
            // ... else try From
            None => match headers.get::<header::From>() {
                Some(header::From(a)) => {
                    let from: Vec<Mailbox> = a.clone().into();
                    if from.len() > 1 {
                        return Err(Error::TooManyFrom);
                    }
                    Some(from[0].email.clone())
                }
                None => None,
            },
        };

        fn add_addresses_from_mailboxes(
            addresses: &mut Vec<Address>,
            mailboxes: Option<&Mailboxes>,
        ) {
            if let Some(mailboxes) = mailboxes {
                for mailbox in mailboxes.iter() {
                    addresses.push(mailbox.email.clone());
                }
            }
        }
        let mut to = vec![];
        add_addresses_from_mailboxes(&mut to, headers.get::<header::To>().map(|h| &h.0));
        add_addresses_from_mailboxes(&mut to, headers.get::<header::Cc>().map(|h| &h.0));
        add_addresses_from_mailboxes(&mut to, headers.get::<header::Bcc>().map(|h| &h.0));

        Self::new(from, to)
    }
}

/// Blocking Transport method for emails
pub trait Transport {
    /// Result types for the transport
    type Ok: fmt::Debug;
    type Error: StdError;

    /// Sends the email
    #[cfg(feature = "builder")]
    fn send(&self, message: &Message) -> Result<Self::Ok, Self::Error> {
        let raw = message.formatted();
        self.send_raw(message.envelope(), &raw)
    }

    fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error>;
}

/// async-std 1.x based Transport method for emails
#[cfg(feature = "async-std1")]
#[async_trait]
pub trait AsyncStd1Transport {
    /// Result types for the transport
    type Ok: fmt::Debug;
    type Error: StdError;

    /// Sends the email
    #[cfg(feature = "builder")]
    // TODO take &Message
    async fn send(&self, message: Message) -> Result<Self::Ok, Self::Error> {
        let raw = message.formatted();
        let envelope = message.envelope();
        self.send_raw(&envelope, &raw).await
    }

    async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error>;
}

/// tokio 0.2.x based Transport method for emails
#[cfg(feature = "tokio02")]
#[async_trait]
pub trait Tokio02Transport {
    /// Result types for the transport
    type Ok: fmt::Debug;
    type Error: StdError;

    /// Sends the email
    #[cfg(feature = "builder")]
    // TODO take &Message
    async fn send(&self, message: Message) -> Result<Self::Ok, Self::Error> {
        let raw = message.formatted();
        let envelope = message.envelope();
        self.send_raw(&envelope, &raw).await
    }

    async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error>;
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::message::{header, Mailbox, Mailboxes};
    use hyperx::header::Headers;

    #[test]
    fn envelope_from_headers() {
        let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
        let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());

        let mut headers = Headers::new();
        headers.set(header::From(from));
        headers.set(header::To(to));

        assert_eq!(
            Envelope::try_from(&headers).unwrap(),
            Envelope::new(
                Some(Address::new("kayo", "example.com").unwrap()),
                vec![Address::new("amousset", "example.com").unwrap()]
            )
            .unwrap()
        );
    }

    #[test]
    fn envelope_from_headers_sender() {
        let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
        let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());
        let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());

        let mut headers = Headers::new();
        headers.set(header::From(from));
        headers.set(header::Sender(sender));
        headers.set(header::To(to));

        assert_eq!(
            Envelope::try_from(&headers).unwrap(),
            Envelope::new(
                Some(Address::new("kayo2", "example.com").unwrap()),
                vec![Address::new("amousset", "example.com").unwrap()]
            )
            .unwrap()
        );
    }

    #[test]
    fn envelope_from_headers_no_to() {
        let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
        let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());

        let mut headers = Headers::new();
        headers.set(header::From(from));
        headers.set(header::Sender(sender));

        assert!(Envelope::try_from(&headers).is_err(),);
    }
}
<commit_msg>Don't require Transport::{Ok, Error} to inherit specific traits<commit_after>//! Lettre is an email library that allows creating and sending messages. It provides:
//!
//! * An easy to use email builder
//! * Pluggable email transports
//! * Unicode support
//! * Secure defaults
//!
//! Lettre requires Rust 1.40 or newer.
//!
//! ## Optional features
//!
//! * **builder**: Message builder
//! * **file-transport**: Transport that write messages into a file
//! * **smtp-transport**: Transport over SMTP
//! * **sendmail-transport**: Transport over SMTP
//! * **rustls-tls**: TLS support with the `rustls` crate
//! * **native-tls**: TLS support with the `native-tls` crate
//! * **r2d2**: Connection pool for SMTP transport
//! * **tracing**: Logging using the `tracing` crate
//! * **serde**: Serialization/Deserialization of entities
//! * **hostname**: Ability to try to use actual hostname in SMTP transaction

#![doc(html_root_url = "https://docs.rs/lettre/0.10.0")]
#![doc(html_favicon_url = "https://lettre.at/favicon.png")]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/15113230?v=4")]
#![deny(
    missing_copy_implementations,
    trivial_casts,
    trivial_numeric_casts,
    unstable_features,
    unused_import_braces,
    unsafe_code
)]

pub mod address;
pub mod error;
#[cfg(feature = "builder")]
pub mod message;
pub mod transport;

use crate::error::Error;
#[cfg(feature = "builder")]
pub use crate::message::{
    header::{self, Headers},
    EmailFormat, Mailbox, Mailboxes, Message,
};
#[cfg(feature = "file-transport")]
pub use crate::transport::file::FileTransport;
#[cfg(feature = "sendmail-transport")]
pub use crate::transport::sendmail::SendmailTransport;
#[cfg(all(feature = "smtp-transport", feature = "connection-pool"))]
pub use crate::transport::smtp::r2d2::SmtpConnectionManager;
#[cfg(feature = "smtp-transport")]
pub use crate::transport::smtp::SmtpTransport;
#[cfg(all(feature = "smtp-transport", feature = "tokio02"))]
pub use crate::transport::smtp::{AsyncSmtpTransport, Tokio02Connector};
pub use crate::{address::Address, transport::stub::StubTransport};
#[cfg(any(feature = "async-std1", feature = "tokio02"))]
use async_trait::async_trait;
#[cfg(feature = "builder")]
use std::convert::TryFrom;

/// Simple email envelope representation
///
/// We only accept mailboxes, and do not support source routes (as per RFC).
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Envelope {
    /// The envelope recipients' addresses
    ///
    /// This can not be empty.
    forward_path: Vec<Address>,
    /// The envelope sender address
    reverse_path: Option<Address>,
}

impl Envelope {
    /// Creates a new envelope, which may fail if `to` is empty.
    pub fn new(from: Option<Address>, to: Vec<Address>) -> Result<Envelope, Error> {
        if to.is_empty() {
            return Err(Error::MissingTo);
        }
        Ok(Envelope {
            forward_path: to,
            reverse_path: from,
        })
    }

    /// Destination addresses of the envelope
    pub fn to(&self) -> &[Address] {
        self.forward_path.as_slice()
    }

    /// Source address of the envelope
    pub fn from(&self) -> Option<&Address> {
        self.reverse_path.as_ref()
    }
}

impl TryFrom<&Headers> for Envelope {
    type Error = Error;

    fn try_from(headers: &Headers) -> Result<Self, Self::Error> {
        let from = match headers.get::<header::Sender>() {
            // If there is a Sender, use it
            Some(header::Sender(a)) => Some(a.email.clone()),
            // ... else try From
            None => match headers.get::<header::From>() {
                Some(header::From(a)) => {
                    let from: Vec<Mailbox> = a.clone().into();
                    if from.len() > 1 {
                        return Err(Error::TooManyFrom);
                    }
                    Some(from[0].email.clone())
                }
                None => None,
            },
        };

        fn add_addresses_from_mailboxes(
            addresses: &mut Vec<Address>,
            mailboxes: Option<&Mailboxes>,
        ) {
            if let Some(mailboxes) = mailboxes {
                for mailbox in mailboxes.iter() {
                    addresses.push(mailbox.email.clone());
                }
            }
        }
        let mut to = vec![];
        add_addresses_from_mailboxes(&mut to, headers.get::<header::To>().map(|h| &h.0));
        add_addresses_from_mailboxes(&mut to, headers.get::<header::Cc>().map(|h| &h.0));
        add_addresses_from_mailboxes(&mut to, headers.get::<header::Bcc>().map(|h| &h.0));

        Self::new(from, to)
    }
}

/// Blocking Transport method for emails
pub trait Transport {
    /// Response produced by the Transport
    type Ok;
    /// Error produced by the Transport
    type Error;

    /// Sends the email
    #[cfg(feature = "builder")]
    fn send(&self, message: &Message) -> Result<Self::Ok, Self::Error> {
        let raw = message.formatted();
        self.send_raw(message.envelope(), &raw)
    }

    fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error>;
}

/// async-std 1.x based Transport method for emails
#[cfg(feature = "async-std1")]
#[async_trait]
pub trait AsyncStd1Transport {
    /// Response produced by the Transport
    type Ok;
    /// Error produced by the Transport
    type Error;

    /// Sends the email
    #[cfg(feature = "builder")]
    // TODO take &Message
    async fn send(&self, message: Message) -> Result<Self::Ok, Self::Error> {
        let raw = message.formatted();
        let envelope = message.envelope();
        self.send_raw(&envelope, &raw).await
    }

    async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error>;
}

/// tokio 0.2.x based Transport method for emails
#[cfg(feature = "tokio02")]
#[async_trait]
pub trait Tokio02Transport {
    /// Response produced by the Transport
    type Ok;
    /// Error produced by the Transport
    type Error;

    /// Sends the email
    #[cfg(feature = "builder")]
    // TODO take &Message
    async fn send(&self, message: Message) -> Result<Self::Ok, Self::Error> {
        let raw = message.formatted();
        let envelope = message.envelope();
        self.send_raw(&envelope, &raw).await
    }

    async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error>;
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::message::{header, Mailbox, Mailboxes};
    use hyperx::header::Headers;

    #[test]
    fn envelope_from_headers() {
        let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
        let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());

        let mut headers = Headers::new();
        headers.set(header::From(from));
        headers.set(header::To(to));

        assert_eq!(
            Envelope::try_from(&headers).unwrap(),
            Envelope::new(
                Some(Address::new("kayo", "example.com").unwrap()),
                vec![Address::new("amousset", "example.com").unwrap()]
            )
            .unwrap()
        );
    }

    #[test]
    fn envelope_from_headers_sender() {
        let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
        let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());
        let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());

        let mut headers = Headers::new();
        headers.set(header::From(from));
        headers.set(header::Sender(sender));
        headers.set(header::To(to));

        assert_eq!(
            Envelope::try_from(&headers).unwrap(),
            Envelope::new(
                Some(Address::new("kayo2", "example.com").unwrap()),
                vec![Address::new("amousset", "example.com").unwrap()]
            )
            .unwrap()
        );
    }

    #[test]
    fn envelope_from_headers_no_to() {
        let from = Mailboxes::new().with("kayo@example.com".parse().unwrap());
        let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());

        let mut headers = Headers::new();
        headers.set(header::From(from));
        headers.set(header::Sender(sender));

        assert!(Envelope::try_from(&headers).is_err(),);
    }
}
<|endoftext|>


<commit_before>//! Read available data from file descriptors without blocking
//!
//! Useful for nonblocking reads from sockets, named pipes, and child stdout/stderr
//!
//! # Example
//!
//! ```no_run
//! use std::io::Read;
//! use std::process::{Command, Stdio};
//! use std::time::Duration;
//! use nonblock::NonBlockingReader;
//!
//! let mut child = Command::new("some-executable")
//!                         .stdout(Stdio::piped())
//!                         .spawn().unwrap();
//! let stdout = child.stdout.take().unwrap();
//! let mut noblock_stdout = NonBlockingReader::from_fd(stdout).unwrap();
//! while !noblock_stdout.is_eof() {
//!     let mut buf = String::new();
//!     noblock_stdout.read_available_to_string(&mut buf).unwrap();
//!     std::thread::sleep(Duration::from_secs(5));
//! }
extern crate libc;
use std::os::unix::io::{RawFd, AsRawFd};
use std::io::{self, Read, ErrorKind};
use libc::{F_GETFL, F_SETFL, fcntl, O_NONBLOCK};

/// Simple non-blocking wrapper for reader types that implement AsRawFd
pub struct NonBlockingReader<R: AsRawFd + Read> {
    eof: bool,
    reader: R,
}

impl<R: AsRawFd + Read> NonBlockingReader<R> {
    /// Initialize a NonBlockingReader from the reader's file descriptor.
    ///
    /// The reader will be managed internally,
    ///   and O_NONBLOCK will be set the file descriptor.
    pub fn from_fd(reader: R) -> io::Result<NonBlockingReader<R>> {
        let fd = reader.as_raw_fd();
        try!(set_blocking(fd, false));
        Ok(NonBlockingReader {
            reader: reader,
            eof: false,
        })
    }

    /// Consume this NonBlockingReader and return the blocking version
    ///   of the interanally managed reader.
    ///
    /// This will disable O_NONBLOCK on the file descriptor,
    ///   and any data read from the NonBlockingReader before calling `into_blocking`
    ///   will already have been consumed from the reader.
    pub fn into_blocking(self) -> io::Result<R> {
        let fd = self.reader.as_raw_fd();
        try!(set_blocking(fd, true));
        Ok(self.reader)
    }

    /// Indicates if EOF has been reached for the reader.
    ///
    /// Currently this defaults to false until one of the `read_available` methods is called,
    ///   but this may change in the future if I stumble on a compelling way
    ///   to check for EOF without consuming any of the internal reader.
    pub fn is_eof(&self) -> bool {
        self.eof
    }

    /// Reads any available data from the reader without blocking, placing them into `buf`.
    ///
    /// If successful, this function will return the total number of bytes read.
    ///  0 bytes read may indicate the EOF has been reached or that reading
    ///  would block because there is not any data immediately available.
    ///  Call `is_eof()` after this method to determine if EOF was reached.
    ///
    /// ## Errors
    ///
    /// If this function encounters an error of the kind ErrorKind::Interrupted
    ///   then the error is ignored and the operation will continue.
    ///   If it encounters ErrorKind::WouldBlock, then this function immediately returns
    ///   the total number of bytes read so far.
    ///
    /// If any other read error is encountered then this function immediately returns.
    ///   Any bytes which have already been read will be appended to buf.
    pub fn read_available(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        let mut buf_len = 0;
        loop {
            let mut bytes = [0u8; 1024];
            match self.reader.read(&mut bytes[..]) {
                // EOF
                Ok(0) => {
                    self.eof = true;
                    break;
                }
                // Not EOF, but no more data currently available
                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {
                    self.eof = false;
                    break;
                }
                // Ignore interruptions, continue reading
                Err(ref err) if err.kind() == ErrorKind::Interrupted => {}
                // bytes available
                Ok(len) => {
                    buf_len += len;
                    buf.append(&mut bytes[0..(len)].to_owned())
                }
                // IO Error encountered
                Err(err) => {
                    return Err(err);
                }
            }
        }
        Ok(buf_len)
    }

    /// Reads any available data from the reader without blocking, placing them into `buf`.
    ///
    /// If successful, this function returns the number of bytes which were read and appended to buf.
    ///
    /// This function calls `read_available()` and attempts to convert the data read to a UTF-8 string.
    ///   If the any data read is parsed successfully as a UTF-8 string  it is appended to `buf`.
    ///   If it cannot be parsed as UTF-8, then `buf` will remain unmodified, returning `ErrorKind::InvalidData`
    ///   with the `FromUtf8Error` containing any data that was read.
    ///
    /// In theory, since this function only reads immediately available data,
    ///   There may not be any guarantee that the data immediately available ends
    ///   on a UTF-8 alignment, so it might be worth a bufferred wrapper
    ///   that manages the captures a final non-UTF-8 character and prepends it to the next call,
    ///   but in practice, this has worked as expected.
    pub fn read_available_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        let mut byte_buf: Vec<u8> = Vec::with_capacity(1024);
        let res = self.read_available(&mut byte_buf);
        match String::from_utf8(byte_buf) {
            Ok(utf8_buf) => {
                // append any read data before returning the `read_available` result
                buf.push_str(&utf8_buf);
                res
            }
            Err(err) => {
                // check for read error before returning the UTF8 Error
                let _ = try!(res);
                Err(io::Error::new(ErrorKind::InvalidData, err))
            }
        }
    }
}

fn set_blocking(fd: RawFd, blocking: bool) -> io::Result<()> {
    let flags = unsafe { fcntl(fd, F_GETFL, 0) };
    if flags < 0 {
        return Err(io::Error::last_os_error());
    }

    let flags = if blocking {
        flags & !O_NONBLOCK
    } else {
        flags | O_NONBLOCK
    };
    let res = unsafe { fcntl(fd, F_SETFL, flags) };
    if res != 0 {
        return Err(io::Error::last_os_error());
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::NonBlockingReader;
    use std::sync::mpsc::channel;
    use std::net::{TcpListener, TcpStream};
    use std::thread;
    use std::io::Write;

    #[test]
    fn it_works() {
        let server = TcpListener::bind("127.0.0.1:34254").unwrap();
        let (tx, rx) = channel();

        thread::spawn(move || {
            let (stream, _) = server.accept().unwrap();
            tx.send(stream).unwrap();
        });

        let client = TcpStream::connect("127.0.0.1:34254").unwrap();;
        let mut stream = rx.recv().unwrap();

        let mut nonblocking = NonBlockingReader::from_fd(client).unwrap();
        let mut buf = Vec::new();

        assert_eq!(nonblocking.read_available(&mut buf).unwrap(), 0);
        assert_eq!(buf, b"");

        stream.write(b"foo").unwrap();
        assert_eq!(nonblocking.read_available(&mut buf).unwrap(), 3);
        assert_eq!(buf, b"foo");
    }
}
<commit_msg>Improve docs<commit_after>//! Read available data from file descriptors without blocking
//!
//! Useful for nonblocking reads from sockets, named pipes, and child stdout/stderr
//!
//! # Example
//!
//! ```no_run
//! use std::io::Read;
//! use std::process::{Command, Stdio};
//! use std::time::Duration;
//! use nonblock::NonBlockingReader;
//!
//! let mut child = Command::new("some-executable")
//!                         .stdout(Stdio::piped())
//!                         .spawn().unwrap();
//! let stdout = child.stdout.take().unwrap();
//! let mut noblock_stdout = NonBlockingReader::from_fd(stdout).unwrap();
//! while !noblock_stdout.is_eof() {
//!     let mut buf = String::new();
//!     noblock_stdout.read_available_to_string(&mut buf).unwrap();
//!     std::thread::sleep(Duration::from_secs(5));
//! }
//! ```
extern crate libc;
use std::os::unix::io::{RawFd, AsRawFd};
use std::io::{self, Read, ErrorKind};
use libc::{F_GETFL, F_SETFL, fcntl, O_NONBLOCK};

/// Simple non-blocking wrapper for reader types that implement AsRawFd
pub struct NonBlockingReader<R: AsRawFd + Read> {
    eof: bool,
    reader: R,
}

impl<R: AsRawFd + Read> NonBlockingReader<R> {
    /// Initialize a NonBlockingReader from the reader's file descriptor.
    ///
    /// The reader will be managed internally,
    ///   and O_NONBLOCK will be set the file descriptor.
    pub fn from_fd(reader: R) -> io::Result<NonBlockingReader<R>> {
        let fd = reader.as_raw_fd();
        try!(set_blocking(fd, false));
        Ok(NonBlockingReader {
            reader: reader,
            eof: false,
        })
    }

    /// Consume this NonBlockingReader and return the blocking version
    ///   of the internally managed reader.
    ///
    /// This will disable O_NONBLOCK on the file descriptor,
    ///   and any data read from the NonBlockingReader before calling `into_blocking`
    ///   will already have been consumed from the reader.
    pub fn into_blocking(self) -> io::Result<R> {
        let fd = self.reader.as_raw_fd();
        try!(set_blocking(fd, true));
        Ok(self.reader)
    }

    /// Indicates if EOF has been reached for the reader.
    ///
    /// Currently this defaults to false until one of the `read_available` methods is called,
    ///   but this may change in the future if I stumble on a compelling way
    ///   to check for EOF without consuming any of the internal reader.
    pub fn is_eof(&self) -> bool {
        self.eof
    }

    /// Reads any available data from the reader without blocking, placing them into `buf`.
    ///
    /// If successful, this function will return the total number of bytes read.
    ///  0 bytes read may indicate the EOF has been reached or that reading
    ///  would block because there is not any data immediately available.
    ///  Call `is_eof()` after this method to determine if EOF was reached.
    ///
    /// ## Errors
    ///
    /// If this function encounters an error of the kind `ErrorKind::Interrupted`
    ///   then the error is ignored and the operation will continue.
    ///   If it encounters `ErrorKind::WouldBlock`, then this function immediately returns
    ///   the total number of bytes read so far.
    ///
    /// If any other read error is encountered then this function immediately returns.
    ///   Any bytes which have already been read will be appended to buf.
    ///
    /// ## Examples
    /// ```no_run
    /// # use std::io::Read;
    /// # use std::net::TcpStream;
    /// # use std::time::Duration;
    /// # use nonblock::NonBlockingReader;
    /// #
    /// let client = TcpStream::connect("127.0.0.1:34567").unwrap();
    /// let mut noblock_stdout = NonBlockingReader::from_fd(client).unwrap();
    /// let mut buf = Vec::new();
    /// noblock_stdout.read_available(&mut buf).unwrap();
    /// ```

    pub fn read_available(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        let mut buf_len = 0;
        loop {
            let mut bytes = [0u8; 1024];
            match self.reader.read(&mut bytes[..]) {
                // EOF
                Ok(0) => {
                    self.eof = true;
                    break;
                }
                // Not EOF, but no more data currently available
                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {
                    self.eof = false;
                    break;
                }
                // Ignore interruptions, continue reading
                Err(ref err) if err.kind() == ErrorKind::Interrupted => {}
                // bytes available
                Ok(len) => {
                    buf_len += len;
                    buf.append(&mut bytes[0..(len)].to_owned())
                }
                // IO Error encountered
                Err(err) => {
                    return Err(err);
                }
            }
        }
        Ok(buf_len)
    }

    /// Reads any available data from the reader without blocking, placing them into `buf`.
    ///
    /// If successful, this function returns the number of bytes which were read and appended to buf.
    ///
    /// ## Errors
    ///
    /// This function inherits all the possible errors of `read_available()`.
    ///   In the case of errors that occur after successfully reading some data,
    ///   the successfully read data will still be parsed and appended to `buf`.
    ///
    /// Additionally, if the read data cannot be parsed as UTF-8,
    ///   then `buf` will remain unmodified, and this method will return `ErrorKind::InvalidData`
    ///   with the `FromUtf8Error` containing any data that was read.
    ///
    /// ## Examples
    /// ```no_run
    /// # use std::io::Read;
    /// # use std::process::{Command, Stdio};
    /// # use std::time::Duration;
    /// # use nonblock::NonBlockingReader;
    /// #
    /// let mut child = Command::new("foo").stdout(Stdio::piped()).spawn().unwrap();
    /// let stdout = child.stdout.take().unwrap();
    /// let mut noblock_stdout = NonBlockingReader::from_fd(stdout).unwrap();
    /// let mut buf = String::new();
    /// noblock_stdout.read_available_to_string(&mut buf).unwrap();
    /// ```
    ///
    /// In theory, since this function only reads immediately available data,
    ///   There may not be any guarantee that the data immediately available ends
    ///   on a UTF-8 alignment, so it might be worth a bufferred wrapper
    ///   that manages the captures a final non-UTF-8 character and prepends it to the next call,
    ///   but in practice, this has worked as expected.
    pub fn read_available_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        let mut byte_buf: Vec<u8> = Vec::with_capacity(1024);
        let res = self.read_available(&mut byte_buf);
        match String::from_utf8(byte_buf) {
            Ok(utf8_buf) => {
                // append any read data before returning the `read_available` result
                buf.push_str(&utf8_buf);
                res
            }
            Err(err) => {
                // check for read error before returning the UTF8 Error
                let _ = try!(res);
                Err(io::Error::new(ErrorKind::InvalidData, err))
            }
        }
    }
}

fn set_blocking(fd: RawFd, blocking: bool) -> io::Result<()> {
    let flags = unsafe { fcntl(fd, F_GETFL, 0) };
    if flags < 0 {
        return Err(io::Error::last_os_error());
    }

    let flags = if blocking {
        flags & !O_NONBLOCK
    } else {
        flags | O_NONBLOCK
    };
    let res = unsafe { fcntl(fd, F_SETFL, flags) };
    if res != 0 {
        return Err(io::Error::last_os_error());
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::NonBlockingReader;
    use std::sync::mpsc::channel;
    use std::net::{TcpListener, TcpStream};
    use std::thread;
    use std::io::Write;

    #[test]
    fn it_works() {
        let server = TcpListener::bind("127.0.0.1:34567").unwrap();
        let (tx, rx) = channel();

        thread::spawn(move || {
            let (stream, _) = server.accept().unwrap();
            tx.send(stream).unwrap();
        });

        let client = TcpStream::connect("127.0.0.1:34567").unwrap();
        let mut stream = rx.recv().unwrap();

        let mut nonblocking = NonBlockingReader::from_fd(client).unwrap();
        let mut buf = Vec::new();

        assert_eq!(nonblocking.read_available(&mut buf).unwrap(), 0);
        assert_eq!(buf, b"");

        stream.write(b"foo").unwrap();
        assert_eq!(nonblocking.read_available(&mut buf).unwrap(), 3);
        assert_eq!(buf, b"foo");
    }
}
<|endoftext|>


<commit_before>#[cfg(not(test))] pub const WIDTH: usize = 5;
#[cfg(not(test))] pub const HEIGHT: usize = 5;
#[cfg(not(test))] pub const X_ROW: usize = 4;

#[cfg(test)] pub const WIDTH: usize = 4;
#[cfg(test)] pub const HEIGHT: usize = 3;
#[cfg(test)] pub const X_ROW: usize = 2;

pub struct Game {
    turns: u32,
    current_turn: Player,
    winner: Option<Player>,
    field: Field,
}

impl Game {
    pub fn new() -> Game {
        Game {
            turns: 0,
            current_turn: Player::Red,
            winner : None,
		    field: Field::new(),
		}
    }

    pub fn current_turn(&self) -> Player {
        self.current_turn
    }

    pub fn winner(&self) -> Option<Player> {
        self.winner
    }

    pub fn is_full(&self) -> bool {
        self.turns as usize == WIDTH * HEIGHT
    }

    pub fn make_turn(&mut self, column: usize) -> Result<(), GameError> {
        if self.winner.is_some() { return Err(GameError::AlreadyEnded); }
        try!(self.field.throw_token(column, self.current_turn));
        self.winner = self.field.win_check();
        self.turns += 1;
        self.current_turn = self.current_turn.next();
        Ok(())
    }

    pub fn current_state(&self) -> &[Option<Player>; WIDTH * HEIGHT] {
        &self.field.cells
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GameError {
    NoSuchColumn,
    ColumnIsFull,
    AlreadyEnded,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Player {
    Red,
    Blue,
}

impl Player {
    fn next(self) -> Player {
        match self {
            Player::Red => Player::Blue,
            Player::Blue => Player::Red,
        }
    }
}

pub struct Field {
    cells: [Option<Player>; WIDTH * HEIGHT],
}

impl Field {

    pub fn with_cells(cells: [Option<Player>; WIDTH * HEIGHT]) -> Field {
        Field {
            cells: cells,
        }
    }

    pub fn free_columns(&self) -> Option<Vec<usize>> {
        let mut res = Vec::new();

        for (index, Column { cells }) in self.columns().enumerate() {
            if cells.iter().any(|x| x.is_none()) {
                res.push(index);
            }
        }

        if res.is_empty() { None } else { Some(res) }
    }

    fn new() -> Field {
        Field {
		    cells: [None; (WIDTH * HEIGHT) as usize],
		}
    }

    fn throw_token(&mut self, column_index: usize, player: Player) -> Result<(), GameError> {
        if column_index > WIDTH { return Err(GameError::NoSuchColumn); }
        let Column { cells } = Columns::index(&self.cells, column_index).next().unwrap();
        let row_index = try!( cells.iter().position(|x| x.is_none() ).ok_or(GameError::ColumnIsFull) );
        let position = row_index * WIDTH + column_index;
        self.cells[position] = Some(player);
        Ok(())
    }

    fn win_check(&self) -> Option<Player> {
        for Row { cells } in self.rows() {
            match Field::max_series(&cells[..]) {
                (Some(player), length) => {
                	if length >= X_ROW {
                	    return Some(player);
                	}
                },
                _ => {}
            }
        }

        for Column { cells } in self.columns() {
            match Field::max_series(&cells[..]) {
                (Some(player), length) => {
                	if length >= X_ROW {
                	    return Some(player);
                	}
                },
                _ => {}
            }
        }

        for Diagonal { cells, length } in self.diagonals() {
            match Field::max_series(&cells[0..length]) {
                (Some(player), length) => {
                	if length >= X_ROW {
                	    return Some(player);
                	}
                },
                _ => {}
            }
        }

        None
    }

    fn rows<'a>(&'a self) -> Rows<'a>{
        Rows::new(&self.cells)
    }

    fn columns<'a, 'b>(&'a self) -> Columns<'a> {
        Columns::new(&self.cells)
    }

    fn diagonals<'a>(&'a self) -> Diagonals<'a> {
        Diagonals::new(&self.cells)
    }

    fn max_series(cells: &[Option<Player>]) -> (Option<Player>, usize) {
        const RED: Option<Player> = Some(Player::Red);
        const BLUE: Option<Player> = Some(Player::Blue);
        let mut red_max = 0;
        let mut blue_max = 0;
        let mut prev_player = None;
        let mut series = 0;

        for curr_player in cells.iter() {
            match (*curr_player, prev_player) {
                (Some(_), None) => { series = 1; },
                (RED, RED) | (BLUE, BLUE) => { series += 1; },
                (None, RED) | (BLUE, RED) => {
					if series > red_max { red_max = series; }
					series = 1;
				},
                (None, BLUE) | (RED, BLUE) => {
					if series > blue_max { blue_max = series; }
					series = 1;
				},
                _ => {}
            }
            prev_player = *curr_player;
        }

        match prev_player {
            BLUE => if series > blue_max { blue_max = series; },
            RED  => if series > red_max { red_max = series; },
            _ => {},
        }

        if red_max == blue_max { return (None, red_max); }
        if red_max > blue_max { return (RED, red_max); } else { return (BLUE, blue_max); }
    }
}

struct Rows<'a> {
    field: &'a [Option<Player>; WIDTH * HEIGHT],
    current_row: usize,
}

impl<'a> Rows<'a> {
    fn new(field: &'a [Option<Player>; WIDTH * HEIGHT]) -> Rows<'a> {
        Rows {
		    field: field,
		    current_row: 0,
		}
    }

    fn index(field: &'a [Option<Player>; WIDTH * HEIGHT], index: usize) -> Rows<'a> {
        Rows {
		    field: field,
		    current_row: index,
		}
    }
}

impl<'a> Iterator for Rows<'a> {
    type Item = Row;

    fn next(&mut self) -> Option<Row> {
        if self.current_row < HEIGHT {
            let from = self.current_row * WIDTH;
            let to = from + WIDTH;
            let mut cells = [None; WIDTH];
            for (val, index) in (&self.field[from .. to]).iter().zip(0..WIDTH) {
                cells[index] = *val;
            }
            self.current_row += 1;
            Some( Row { cells: cells} )
        } else {
            None
        }
    }
}

struct Row {
    cells: [Option<Player>; WIDTH],
}

struct Columns<'a> {
    field: &'a [Option<Player>; WIDTH * HEIGHT],
    current_column: usize,
}

impl<'a> Columns<'a> {
    fn new(field: &'a [Option<Player>; WIDTH * HEIGHT]) -> Columns<'a> {
        Columns {
		    field: field,
			current_column: 0,
		}
    }

    fn index(field: &'a [Option<Player>; WIDTH * HEIGHT], index: usize) -> Columns<'a> {
        Columns {
            field: field,
            current_column: index,
		}
    }
}

impl<'a> Iterator for Columns<'a> {
    type Item = Column;

    fn next(&mut self) -> Option<Column> {
        if self.current_column < WIDTH {
            let mut cells = [None; HEIGHT];
            for i in 0..HEIGHT {
                let index: usize = (i * WIDTH as usize) + self.current_column as usize;
                cells[i] = self.field[index];
            }
            self.current_column += 1;
            Some( Column { cells: cells} )
        } else {
            None
        }
    }
}

struct Column {
    cells: [Option<Player>; HEIGHT],
}

struct Diagonals<'a> {
    field: &'a [Option<Player>; WIDTH * HEIGHT],
    current_diagonal : usize,
    total_diagonals: usize,
}

impl<'a> Diagonals<'a> {
    fn new(field: &'a [Option<Player>; WIDTH * HEIGHT]) -> Diagonals<'a> {
        Diagonals {
		    field: field,
		    current_diagonal: 0,
		    total_diagonals: WIDTH + HEIGHT - 3,
		}
    }
}

impl<'a> Iterator for Diagonals<'a> {
    type Item = Diagonal;

    fn next(&mut self) -> Option<Diagonal> {
        if WIDTH == 1 || HEIGHT == 1 { return None; }
        if self.total_diagonals >= self.current_diagonal { return None; }
        None
    }
}

struct Diagonal {
    cells: [Option<Player>; WIDTH + HEIGHT],
    length: usize,
}

#[test]
fn test_diagonal_win() {
    let mut game = Game::new();
    game.make_turn(0).unwrap();
    println!("");
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    assert_eq!(game.win_check(), Some(Player::Red) );
    assert_eq!(game.make_turn(0), Err(GameError::AlreadyEnded) );
}

#[test]
fn test_row_win() {
    let mut game = Game::new();
    game.make_turn(0).unwrap();
    println!("");
    println!("{:?}", &game.field.cells);
    game.make_turn(0).unwrap();
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    assert_eq!(game.win_check(), Some(Player::Red) );
    assert_eq!(game.make_turn(0), Err(GameError::AlreadyEnded) );
}

#[test]
fn test_column_win() {
    let mut game = Game::new();
    game.make_turn(0).unwrap();
    println!("");
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    game.make_turn(0).unwrap();
    println!("{:?}", &game.field.cells);
    assert_eq!(game.win_check(), Some(Player::Red) );
    assert_eq!(game.make_turn(0), Err(GameError::AlreadyEnded) );
}

#[test]
fn test_max_series() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    assert_eq!(Field::max_series(&[]), (None, 0));
    assert_eq!(Field::max_series(&[None, None]), (None, 0));
    assert_eq!(Field::max_series(&[red]), (red, 1));
    assert_eq!(Field::max_series(&[blue]), (blue, 1));
    assert_eq!(Field::max_series(&[red, blue]), (None, 1));
    assert_eq!(Field::max_series(&[red, red, blue]), (red, 2));
    assert_eq!(Field::max_series(&[red, red, None, red, red, red]), (red, 3));
    assert_eq!(Field::max_series(&[blue, blue, None, red, red, red]), (red, 3));
    assert_eq!(Field::max_series(&[blue, blue, None, red, red, red, blue, blue, blue]), (None, 3));
}

#[test]
fn test_rows_iterator() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    let cells = &[red,  None, blue, None,
    			  None, red,  blue, red,
    			  None, None, None, None,];
    let mut rows = Rows::new(cells);
    let row1 = rows.next().unwrap();
    let row2 = rows.next().unwrap();
    let row3 = rows.next().unwrap();
    assert!(rows.next().is_none());

    assert_eq!(row1.cells, [red,  None, blue, None] );
    assert_eq!(row2.cells, [None, red,  blue, red] );
    assert_eq!(row3.cells, [None, None, None, None] );
}

#[test]
fn test_columns_iterator() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    let cells = &[red,  None, blue, None,
    			  None, red,  blue, red,
    			  None, None, None, None,];

    let mut columns = Columns::new(&cells);
    let column1 = columns.next().unwrap();
    let column2 = columns.next().unwrap();
    let column3 = columns.next().unwrap();
    let column4 = columns.next().unwrap();
    assert!(columns.next().is_none());

    assert_eq!(column1.cells, [red,  None, None] );
    assert_eq!(column2.cells, [None, red,  None] );
    assert_eq!(column3.cells, [blue, blue, None] );
    assert_eq!(column4.cells, [None, red,  None] );
}

#[test]
fn test_diagonal_iterator() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    let cells = &[red,  None, blue, None,
    			  None, red,  blue, red,
    			  None, None, None, None,];

	let mut diagonals = Diagonals::new(&cells);
	let d1 = diagonals.next().unwrap();
	let d2 = diagonals.next().unwrap();
	let d3 = diagonals.next().unwrap();
	let d4 = diagonals.next().unwrap();

	let d5 = diagonals.next().unwrap();
	let d6 = diagonals.next().unwrap();
	let d7 = diagonals.next().unwrap();
	let d8 = diagonals.next().unwrap();

	assert!( diagonals.next().is_none() );

	fn check(d: Diagonal, cells: [Option<Player>; WIDTH + HEIGHT], length: usize) {
	    assert_eq!((d.cells, d.length), (cells, length) );
	}

	check(d1, [None, None, None, None, None, None, None], 2);
	check(d2, [blue, red, None, None, None, None, None], 3);
	check(d3, [None, blue, None, None, None, None, None], 3);
	check(d4, [red, None, None, None, None, None, None], 2);

	check(d5, [None, None, None, None, None, None, None], 2);
	check(d6, [red, red, None, None, None, None, None], 3);
	check(d7, [None, blue, None, None, None, None, None], 3);
	check(d8, [blue, red, None, None, None, None, None], 2);

}
<commit_msg>tests adjustments<commit_after>#[cfg(not(test))] pub const WIDTH: usize = 5;
#[cfg(not(test))] pub const HEIGHT: usize = 5;
#[cfg(not(test))] pub const X_ROW: usize = 4;

#[cfg(test)] pub const WIDTH: usize = 4;
#[cfg(test)] pub const HEIGHT: usize = 3;
#[cfg(test)] pub const X_ROW: usize = 2;

pub struct Game {
    turns: u32,
    current_turn: Player,
    winner: Option<Player>,
    field: Field,
}

impl Game {
    pub fn new() -> Game {
        Game {
            turns: 0,
            current_turn: Player::Red,
            winner : None,
		    field: Field::new(),
		}
    }

    pub fn current_turn(&self) -> Player {
        self.current_turn
    }

    pub fn winner(&self) -> Option<Player> {
        self.winner
    }

    pub fn is_full(&self) -> bool {
        self.turns as usize == WIDTH * HEIGHT
    }

    pub fn make_turn(&mut self, column: usize) -> Result<(), GameError> {
        if self.winner.is_some() { return Err(GameError::AlreadyEnded); }
        try!(self.field.throw_token(column, self.current_turn));
        self.winner = self.field.win_check();
        self.turns += 1;
        self.current_turn = self.current_turn.next();
        Ok(())
    }

    pub fn current_state(&self) -> &[Option<Player>; WIDTH * HEIGHT] {
        &self.field.cells
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GameError {
    NoSuchColumn,
    ColumnIsFull,
    AlreadyEnded,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Player {
    Red,
    Blue,
}

impl Player {
    fn next(self) -> Player {
        match self {
            Player::Red => Player::Blue,
            Player::Blue => Player::Red,
        }
    }
}

pub struct Field {
    cells: [Option<Player>; WIDTH * HEIGHT],
}

impl Field {

    pub fn with_cells(cells: [Option<Player>; WIDTH * HEIGHT]) -> Field {
        Field {
            cells: cells,
        }
    }

    pub fn free_columns(&self) -> Option<Vec<usize>> {
        let mut res = Vec::new();

        for (index, Column { cells }) in self.columns().enumerate() {
            if cells.iter().any(|x| x.is_none()) {
                res.push(index);
            }
        }

        if res.is_empty() { None } else { Some(res) }
    }

    fn new() -> Field {
        Field {
		    cells: [None; (WIDTH * HEIGHT) as usize],
		}
    }

    fn throw_token(&mut self, column_index: usize, player: Player) -> Result<(), GameError> {
        if column_index > WIDTH { return Err(GameError::NoSuchColumn); }
        let Column { cells } = Columns::index(&self.cells, column_index).next().unwrap();
        let row_index = try!( cells.iter().position(|x| x.is_none() ).ok_or(GameError::ColumnIsFull) );
        let position = row_index * WIDTH + column_index;
        self.cells[position] = Some(player);
        Ok(())
    }

    fn win_check(&self) -> Option<Player> {
        for Row { cells } in self.rows() {
            match Field::max_series(&cells[..]) {
                (Some(player), length) => {
                	if length >= X_ROW {
                	    return Some(player);
                	}
                },
                _ => {}
            }
        }

        for Column { cells } in self.columns() {
            match Field::max_series(&cells[..]) {
                (Some(player), length) => {
                	if length >= X_ROW {
                	    return Some(player);
                	}
                },
                _ => {}
            }
        }

        for Diagonal { cells, length } in self.diagonals() {
            match Field::max_series(&cells[0..length]) {
                (Some(player), length) => {
                	if length >= X_ROW {
                	    return Some(player);
                	}
                },
                _ => {}
            }
        }

        None
    }

    fn rows<'a>(&'a self) -> Rows<'a>{
        Rows::new(&self.cells)
    }

    fn columns<'a, 'b>(&'a self) -> Columns<'a> {
        Columns::new(&self.cells)
    }

    fn diagonals<'a>(&'a self) -> Diagonals<'a> {
        Diagonals::new(&self.cells)
    }

    fn max_series(cells: &[Option<Player>]) -> (Option<Player>, usize) {
        const RED: Option<Player> = Some(Player::Red);
        const BLUE: Option<Player> = Some(Player::Blue);
        let mut red_max = 0;
        let mut blue_max = 0;
        let mut prev_player = None;
        let mut series = 0;

        for curr_player in cells.iter() {
            match (*curr_player, prev_player) {
                (Some(_), None) => { series = 1; },
                (RED, RED) | (BLUE, BLUE) => { series += 1; },
                (None, RED) | (BLUE, RED) => {
					if series > red_max { red_max = series; }
					series = 1;
				},
                (None, BLUE) | (RED, BLUE) => {
					if series > blue_max { blue_max = series; }
					series = 1;
				},
                _ => {}
            }
            prev_player = *curr_player;
        }

        match prev_player {
            BLUE => if series > blue_max { blue_max = series; },
            RED  => if series > red_max { red_max = series; },
            _ => {},
        }

        if red_max == blue_max { return (None, red_max); }
        if red_max > blue_max { return (RED, red_max); } else { return (BLUE, blue_max); }
    }
}

struct Rows<'a> {
    field: &'a [Option<Player>; WIDTH * HEIGHT],
    current_row: usize,
}

impl<'a> Rows<'a> {
    fn new(field: &'a [Option<Player>; WIDTH * HEIGHT]) -> Rows<'a> {
        Rows {
		    field: field,
		    current_row: 0,
		}
    }

    fn index(field: &'a [Option<Player>; WIDTH * HEIGHT], index: usize) -> Rows<'a> {
        Rows {
		    field: field,
		    current_row: index,
		}
    }
}

impl<'a> Iterator for Rows<'a> {
    type Item = Row;

    fn next(&mut self) -> Option<Row> {
        if self.current_row < HEIGHT {
            let from = self.current_row * WIDTH;
            let to = from + WIDTH;
            let mut cells = [None; WIDTH];
            for (val, index) in (&self.field[from .. to]).iter().zip(0..WIDTH) {
                cells[index] = *val;
            }
            self.current_row += 1;
            Some( Row { cells: cells} )
        } else {
            None
        }
    }
}

struct Row {
    cells: [Option<Player>; WIDTH],
}

struct Columns<'a> {
    field: &'a [Option<Player>; WIDTH * HEIGHT],
    current_column: usize,
}

impl<'a> Columns<'a> {
    fn new(field: &'a [Option<Player>; WIDTH * HEIGHT]) -> Columns<'a> {
        Columns {
		    field: field,
			current_column: 0,
		}
    }

    fn index(field: &'a [Option<Player>; WIDTH * HEIGHT], index: usize) -> Columns<'a> {
        Columns {
            field: field,
            current_column: index,
		}
    }
}

impl<'a> Iterator for Columns<'a> {
    type Item = Column;

    fn next(&mut self) -> Option<Column> {
        if self.current_column < WIDTH {
            let mut cells = [None; HEIGHT];
            for i in 0..HEIGHT {
                let index: usize = (i * WIDTH as usize) + self.current_column as usize;
                cells[i] = self.field[index];
            }
            self.current_column += 1;
            Some( Column { cells: cells} )
        } else {
            None
        }
    }
}

struct Column {
    cells: [Option<Player>; HEIGHT],
}

struct Diagonals<'a> {
    field: &'a [Option<Player>; WIDTH * HEIGHT],
    current_diagonal : usize,
    total_diagonals: usize,
}

impl<'a> Diagonals<'a> {
    fn new(field: &'a [Option<Player>; WIDTH * HEIGHT]) -> Diagonals<'a> {
        Diagonals {
		    field: field,
		    current_diagonal: 0,
		    total_diagonals: WIDTH + HEIGHT - 3,
		}
    }
}

impl<'a> Iterator for Diagonals<'a> {
    type Item = Diagonal;

    fn next(&mut self) -> Option<Diagonal> {
        if WIDTH == 1 || HEIGHT == 1 { return None; }
        if self.total_diagonals >= self.current_diagonal { return None; }
        None
    }
}

struct Diagonal {
    cells: [Option<Player>; WIDTH + HEIGHT],
    length: usize,
}

#[test]
fn test_diagonal_win() {
    let mut game = Game::new();
    game.make_turn(0).unwrap();
    println!("");
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    assert_eq!(game.winner(), Some(Player::Red) );
    assert_eq!(game.make_turn(0), Err(GameError::AlreadyEnded) );
}

#[test]
fn test_row_win() {
    let mut game = Game::new();
    game.make_turn(0).unwrap();
    println!("");
    println!("{:?}", &game.field.cells);
    game.make_turn(0).unwrap();
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    assert_eq!(game.winner(), Some(Player::Red) );
    assert_eq!(game.make_turn(0), Err(GameError::AlreadyEnded) );
}

#[test]
fn test_column_win() {
    let mut game = Game::new();
    game.make_turn(0).unwrap();
    println!("");
    println!("{:?}", &game.field.cells);
    game.make_turn(1).unwrap();
    println!("{:?}", &game.field.cells);
    game.make_turn(0).unwrap();
    println!("{:?}", &game.field.cells);
    assert_eq!(game.winner(), Some(Player::Red) );
    assert_eq!(game.make_turn(0), Err(GameError::AlreadyEnded) );
}

#[test]
fn test_max_series() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    assert_eq!(Field::max_series(&[]), (None, 0));
    assert_eq!(Field::max_series(&[None, None]), (None, 0));
    assert_eq!(Field::max_series(&[red]), (red, 1));
    assert_eq!(Field::max_series(&[blue]), (blue, 1));
    assert_eq!(Field::max_series(&[red, blue]), (None, 1));
    assert_eq!(Field::max_series(&[red, red, blue]), (red, 2));
    assert_eq!(Field::max_series(&[red, red, None, red, red, red]), (red, 3));
    assert_eq!(Field::max_series(&[blue, blue, None, red, red, red]), (red, 3));
    assert_eq!(Field::max_series(&[blue, blue, None, red, red, red, blue, blue, blue]), (None, 3));
}

#[test]
fn test_rows_iterator() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    let cells = &[red,  None, blue, None,
    			  None, red,  blue, red,
    			  None, None, None, None,];
    let mut rows = Rows::new(cells);
    let row1 = rows.next().unwrap();
    let row2 = rows.next().unwrap();
    let row3 = rows.next().unwrap();
    assert!(rows.next().is_none());

    assert_eq!(row1.cells, [red,  None, blue, None] );
    assert_eq!(row2.cells, [None, red,  blue, red] );
    assert_eq!(row3.cells, [None, None, None, None] );
}

#[test]
fn test_columns_iterator() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    let cells = &[red,  None, blue, None,
    			  None, red,  blue, red,
    			  None, None, None, None,];

    let mut columns = Columns::new(&cells);
    let column1 = columns.next().unwrap();
    let column2 = columns.next().unwrap();
    let column3 = columns.next().unwrap();
    let column4 = columns.next().unwrap();
    assert!(columns.next().is_none());

    assert_eq!(column1.cells, [red,  None, None] );
    assert_eq!(column2.cells, [None, red,  None] );
    assert_eq!(column3.cells, [blue, blue, None] );
    assert_eq!(column4.cells, [None, red,  None] );
}

#[test]
fn test_diagonal_iterator() {
    let red = Some(Player::Red);
    let blue = Some(Player::Blue);
    let cells = &[red,  None, blue, None,
    			  None, red,  blue, red,
    			  None, None, None, None,];

	let mut diagonals = Diagonals::new(&cells);
	let d1 = diagonals.next().unwrap();
	let d2 = diagonals.next().unwrap();
	let d3 = diagonals.next().unwrap();
	let d4 = diagonals.next().unwrap();

	let d5 = diagonals.next().unwrap();
	let d6 = diagonals.next().unwrap();
	let d7 = diagonals.next().unwrap();
	let d8 = diagonals.next().unwrap();

	assert!( diagonals.next().is_none() );

	fn check(d: Diagonal, cells: [Option<Player>; WIDTH + HEIGHT], length: usize) {
	    assert_eq!((d.cells, d.length), (cells, length) );
	}

	check(d1, [None, None, None, None, None, None, None], 2);
	check(d2, [blue, red, None, None, None, None, None], 3);
	check(d3, [None, blue, None, None, None, None, None], 3);
	check(d4, [red, None, None, None, None, None, None], 2);

	check(d5, [None, None, None, None, None, None, None], 2);
	check(d6, [red, red, None, None, None, None, None], 3);
	check(d7, [None, blue, None, None, None, None, None], 3);
	check(d8, [blue, red, None, None, None, None, None], 2);

}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![warn(dead_code)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate libc;
#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_device_gl;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
#[cfg(feature = "include_opengl")]
extern crate opengl_graphics;
#[cfg(feature = "include_sdl2")]
extern crate sdl2;
#[cfg(feature = "include_sdl2")]
extern crate sdl2_window;
#[cfg(feature = "include_glfw")]
extern crate glfw;
#[cfg(feature = "include_glfw")]
extern crate glfw_window;
#[cfg(feature = "include_glutin")]
extern crate glutin;
#[cfg(feature = "include_glutin")]
extern crate glutin_window;
extern crate graphics;
extern crate fps_counter;
extern crate current;
extern crate shader_version;

extern crate piston;

#[cfg(feature = "include_sdl2")]
pub use sdl2_window::Sdl2Window as WindowBackEnd;
#[cfg(feature = "include_glfw")]
pub use glfw_window::GlfwWindow as WindowBackEnd;
#[cfg(feature = "include_glutin")]
pub use glutin_window::GlutinWindow as WindowBackEnd;

#[cfg(feature = "include_gfx")]
use gfx_graphics::Gfx2d;
#[cfg(feature = "include_gfx")]
use gfx_device_gl::{ Device, Resources, CommandBuffer, Output };

#[cfg(feature = "include_opengl")]
use opengl_graphics::GlGraphics;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;

use piston::window::WindowSettings;
use current::{ Current, CurrentGuard };

fn start_window<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    #[cfg(feature = "include_sdl2")]
    fn disable_vsync() { sdl2::video::gl_set_swap_interval(0); }

    #[cfg(not(feature = "include_sdl2"))]
    fn disable_vsync() {}

    disable_vsync();

    let window_guard = CurrentGuard::new(&mut window);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_opengl")]
fn start_opengl<F>(opengl: shader_version::OpenGL, mut f: F)
    where
        F: FnMut()
{
    let mut gl = Rc::new(RefCell::new(GlGraphics::new(opengl)));

    let gl_guard = CurrentGuard::new(&mut gl);

    f();

    drop(gl_guard);
}

#[cfg(not(feature = "include_opengl"))]
fn start_opengl<F>(_opengl: shader_version::OpenGL, mut f: F)
    where
        F: FnMut()
{
    f();
}

#[cfg(feature = "include_gfx")]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    use piston::window::Window;
    use gfx::render::RenderFactory;

    let window = current_window();

    let (device, mut factory) = gfx_device_gl::create(|s| {
        #[cfg(feature = "include_sdl2")]
        fn get_proc_address(_: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            unsafe { std::mem::transmute(sdl2::video::gl_get_proc_address(s)) }
        }

        #[cfg(feature = "include_glfw")]
        fn get_proc_address(window: &mut WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        #[cfg(feature = "include_glutin")]
        fn get_proc_address(window: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        get_proc_address(&mut *window.borrow_mut(), s)
    });
    let mut renderer: Rc<RefCell<
        gfx::Renderer<gfx_device_gl::Resources,
        <gfx_device_gl::Device as gfx::Device>::CommandBuffer
    >>> =
        Rc::new(RefCell::new(factory.create_renderer()));
    let mut device = Rc::new(RefCell::new(device));
    let factory = Rc::new(RefCell::new(factory));
    let mut g2d = Rc::new(RefCell::new(Gfx2d::new(&mut *device.borrow_mut(), &mut *factory.borrow_mut())));
    let size = window.borrow().size();
    let mut output = Rc::new(RefCell::new(factory.borrow_mut().make_fake_output(
        size.width as u16, size.height as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let output_guard = CurrentGuard::new(&mut output);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(output_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    f();
}

/// Initializes window and sets up current objects.
pub fn start<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    start_window(opengl, window_settings, || {
        start_opengl(opengl, || {
            if cfg!(feature = "include_gfx") {
                start_gfx(|| f());
            } else {
                f();
            }
        })
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<Device>> {
    unsafe {
        Current::<Rc<RefCell<Device>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
#[cfg(feature = "include_opengl")]
pub fn current_gl() -> Rc<RefCell<GlGraphics>> {
    unsafe {
        Current::<Rc<RefCell<GlGraphics>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<Gfx2d<Resources>>> {
    unsafe {
        Current::<Rc<RefCell<Gfx2d<Resources>>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<Resources, CommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<Resources, CommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_output() -> Rc<RefCell<Output>> {
    unsafe {
        Current::<Rc<RefCell<Output>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events() -> piston::event::events::Events<WindowBackEnd, piston::event::Event> {
    use piston::event::Events;

    current_window().events()
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> usize {
    let fps_counter = current_fps_counter();
    let mut fps_counter = fps_counter.borrow_mut();
    fps_counter.tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    use piston::window::AdvancedWindow;

    let window = current_window();
    let mut window = window.borrow_mut();
    window.set_title(text);
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use piston::window::Window;

    let window = current_window();
    let window = window.borrow();
    window.should_close()
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context,
            &mut gfx_graphics::GfxGraphics<Resources, CommandBuffer, Output>)
{
    use gfx::Device;
    use piston::window::Window;
    use graphics::Viewport;

    let window = current_window();
    let window = window.borrow();
    let size = window.size();
    let draw_size = window.draw_size();
    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = &mut *renderer;
    let gfx = current_g2d();
    let mut gfx = gfx.borrow_mut();
    let output = current_output();
    let output = output.borrow();
    gfx.draw(
        renderer,
        &*output,
        Viewport {
            rect: [0, 0, draw_size.width as i32, draw_size.height as i32],
            draw_size: [draw_size.width, draw_size.height],
            window_size: [size.width, size.height],
        },
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    let gfx_device = current_gfx_device();
    let mut gfx_device = gfx_device.borrow_mut();
    gfx_device.submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
#[cfg(feature = "include_opengl")]
pub fn render_2d_opengl<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context, &mut opengl_graphics::GlGraphics)
{
    use piston::window::Window;
    use graphics::Viewport;

    let window = current_window();
    let window = window.borrow();
    let size = window.size();
    let draw_size = window.draw_size();
    let gl = current_gl();
    let mut gl = gl.borrow_mut();
    gl.draw(Viewport {
        rect: [0, 0, draw_size.width as i32, draw_size.height as i32],
        draw_size: [draw_size.width, draw_size.height],
        window_size: [size.width, size.height]
    }, |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<commit_msg>Upgraded to latest piston<commit_after>#![deny(missing_docs)]
#![warn(dead_code)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate libc;
#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_device_gl;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
#[cfg(feature = "include_opengl")]
extern crate opengl_graphics;
#[cfg(feature = "include_sdl2")]
extern crate sdl2;
#[cfg(feature = "include_sdl2")]
extern crate sdl2_window;
#[cfg(feature = "include_glfw")]
extern crate glfw;
#[cfg(feature = "include_glfw")]
extern crate glfw_window;
#[cfg(feature = "include_glutin")]
extern crate glutin;
#[cfg(feature = "include_glutin")]
extern crate glutin_window;
extern crate graphics;
extern crate fps_counter;
extern crate current;
extern crate shader_version;

extern crate piston;

#[cfg(feature = "include_sdl2")]
pub use sdl2_window::Sdl2Window as WindowBackEnd;
#[cfg(feature = "include_glfw")]
pub use glfw_window::GlfwWindow as WindowBackEnd;
#[cfg(feature = "include_glutin")]
pub use glutin_window::GlutinWindow as WindowBackEnd;

#[cfg(feature = "include_gfx")]
use gfx_graphics::Gfx2d;
#[cfg(feature = "include_gfx")]
use gfx_device_gl::{ Device, Resources, CommandBuffer, Output };

#[cfg(feature = "include_opengl")]
use opengl_graphics::GlGraphics;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;

use piston::window::WindowSettings;
use current::{ Current, CurrentGuard };

fn start_window<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    #[cfg(feature = "include_sdl2")]
    fn disable_vsync() { sdl2::video::gl_set_swap_interval(0); }

    #[cfg(not(feature = "include_sdl2"))]
    fn disable_vsync() {}

    disable_vsync();

    let window_guard = CurrentGuard::new(&mut window);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_opengl")]
fn start_opengl<F>(opengl: shader_version::OpenGL, mut f: F)
    where
        F: FnMut()
{
    let mut gl = Rc::new(RefCell::new(GlGraphics::new(opengl)));

    let gl_guard = CurrentGuard::new(&mut gl);

    f();

    drop(gl_guard);
}

#[cfg(not(feature = "include_opengl"))]
fn start_opengl<F>(_opengl: shader_version::OpenGL, mut f: F)
    where
        F: FnMut()
{
    f();
}

#[cfg(feature = "include_gfx")]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    use piston::window::Window;
    use gfx::render::RenderFactory;

    let window = current_window();

    let (device, mut factory) = gfx_device_gl::create(|s| {
        #[cfg(feature = "include_sdl2")]
        fn get_proc_address(_: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            unsafe { std::mem::transmute(sdl2::video::gl_get_proc_address(s)) }
        }

        #[cfg(feature = "include_glfw")]
        fn get_proc_address(window: &mut WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        #[cfg(feature = "include_glutin")]
        fn get_proc_address(window: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        get_proc_address(&mut *window.borrow_mut(), s)
    });
    let mut renderer: Rc<RefCell<
        gfx::Renderer<gfx_device_gl::Resources,
        <gfx_device_gl::Device as gfx::Device>::CommandBuffer
    >>> =
        Rc::new(RefCell::new(factory.create_renderer()));
    let mut device = Rc::new(RefCell::new(device));
    let factory = Rc::new(RefCell::new(factory));
    let mut g2d = Rc::new(RefCell::new(Gfx2d::new(&mut *device.borrow_mut(), &mut *factory.borrow_mut())));
    let size = window.borrow().size();
    let mut output = Rc::new(RefCell::new(factory.borrow_mut().make_fake_output(
        size.width as u16, size.height as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let output_guard = CurrentGuard::new(&mut output);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(output_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    f();
}

/// Initializes window and sets up current objects.
pub fn start<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    start_window(opengl, window_settings, || {
        start_opengl(opengl, || {
            if cfg!(feature = "include_gfx") {
                start_gfx(|| f());
            } else {
                f();
            }
        })
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<Device>> {
    unsafe {
        Current::<Rc<RefCell<Device>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
#[cfg(feature = "include_opengl")]
pub fn current_gl() -> Rc<RefCell<GlGraphics>> {
    unsafe {
        Current::<Rc<RefCell<GlGraphics>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<Gfx2d<Resources>>> {
    unsafe {
        Current::<Rc<RefCell<Gfx2d<Resources>>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<Resources, CommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<Resources, CommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_output() -> Rc<RefCell<Output>> {
    unsafe {
        Current::<Rc<RefCell<Output>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events() -> piston::event::WindowEvents<WindowBackEnd, piston::event::Event> {
    use piston::event::Events;

    current_window().events()
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> usize {
    let fps_counter = current_fps_counter();
    let mut fps_counter = fps_counter.borrow_mut();
    fps_counter.tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    use piston::window::AdvancedWindow;

    let window = current_window();
    let mut window = window.borrow_mut();
    window.set_title(text);
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use piston::window::Window;

    let window = current_window();
    let window = window.borrow();
    window.should_close()
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context,
            &mut gfx_graphics::GfxGraphics<Resources, CommandBuffer, Output>)
{
    use gfx::Device;
    use piston::window::Window;
    use graphics::Viewport;

    let window = current_window();
    let window = window.borrow();
    let size = window.size();
    let draw_size = window.draw_size();
    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = &mut *renderer;
    let gfx = current_g2d();
    let mut gfx = gfx.borrow_mut();
    let output = current_output();
    let output = output.borrow();
    gfx.draw(
        renderer,
        &*output,
        Viewport {
            rect: [0, 0, draw_size.width as i32, draw_size.height as i32],
            draw_size: [draw_size.width, draw_size.height],
            window_size: [size.width, size.height],
        },
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    let gfx_device = current_gfx_device();
    let mut gfx_device = gfx_device.borrow_mut();
    gfx_device.submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
#[cfg(feature = "include_opengl")]
pub fn render_2d_opengl<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context, &mut opengl_graphics::GlGraphics)
{
    use piston::window::Window;
    use graphics::Viewport;

    let window = current_window();
    let window = window.borrow();
    let size = window.size();
    let draw_size = window.draw_size();
    let gl = current_gl();
    let mut gl = gl.borrow_mut();
    gl.draw(Viewport {
        rect: [0, 0, draw_size.width as i32, draw_size.height as i32],
        draw_size: [draw_size.width, draw_size.height],
        window_size: [size.width, size.height]
    }, |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<|endoftext|>


<commit_before>#![feature(no_std)]
#![no_std]

extern crate num;

pub mod create;
pub use create::*;

pub mod set;
pub use set::*;

pub mod mul;
pub use mul::*;

pub mod sdiv;
pub use sdiv::*;

pub mod misc;
pub use misc::*;

pub mod transform;
pub use transform::*;
<commit_msg>updated to lastest rust nightly<commit_after>#![no_std]

extern crate num;

pub mod create;
pub use create::*;

pub mod set;
pub use set::*;

pub mod mul;
pub use mul::*;

pub mod sdiv;
pub use sdiv::*;

pub mod misc;
pub use misc::*;

pub mod transform;
pub use transform::*;
<|endoftext|>