<commit_before>use combine::{eof, satisfy, skip_many, none_of, token, between, optional, many, many1, choice,
              try, Parser, Stream, ParseError};
use combine::char::{string, spaces, digit, char};

#[derive(Clone, Debug, PartialEq)]
pub enum Tokens {
    ACCELERATOR,
    ACTIVETRANSFORM,
    ALL,
    AREALIGHTSOURCE,
    ATTRIBUTEBEGIN,
    ATTRIBUTEEND,
    CAMERA,
    CONCATTRANSFORM,
    COORDINATESYSTEM,
    COORDSYSTRANSFORM,
    ENDTIME,
    FILM,
    IDENTITY,
    INCLUDE,
    LIGHTSOURCE,
    LOOKAT,
    MAKENAMEDMEDIUM,
    MAKENAMEDMATERIAL,
    MATERIAL,
    MEDIUMINTERFACE,
    NAMEDMATERIAL,
    OBJECTBEGIN,
    OBJECTEND,
    OBJECTINSTANCE,
    PIXELFILTER,
    REVERSEORIENTATION,
    ROTATE,
    SAMPLER,
    SCALE,
    SHAPE,
    STARTTIME,
    INTEGRATOR,
    TEXTURE,
    TRANSFORMBEGIN,
    TRANSFORMEND,
    TRANSFORMTIMES,
    TRANSFORM,
    TRANSLATE,
    WORLDBEGIN,
    WORLDEND,
    STR(String),
    NUMBER(f32),
    LBRACK,
    RBRACK,
    COMMENT,
}

pub fn tokenize<'a>(input: &'a str) -> Result<(Vec<Tokens>, &'a str), ParseError<&'a str>> {

    // parsers for keywords
    let mut parsers = vec![token_parser("Accelerator", Tokens::ACCELERATOR),
                           token_parser("ActiveTransform", Tokens::ACTIVETRANSFORM),
                           token_parser("All", Tokens::ALL),
                           token_parser("AreaLightSource", Tokens::AREALIGHTSOURCE),
                           token_parser("AttributeBegin", Tokens::ATTRIBUTEBEGIN),
                           token_parser("AttributeEnd", Tokens::ATTRIBUTEEND),
                           token_parser("Camera", Tokens::CAMERA),
                           token_parser("ConcatTransform", Tokens::CONCATTRANSFORM),
                           token_parser("CoordinateSystem", Tokens::COORDINATESYSTEM),
                           token_parser("CoordSysTransform", Tokens::COORDSYSTRANSFORM),
                           token_parser("EndTime", Tokens::ENDTIME),
                           token_parser("Film", Tokens::FILM),
                           token_parser("Identity", Tokens::IDENTITY),
                           token_parser("Include", Tokens::INCLUDE),
                           token_parser("LightSource", Tokens::LIGHTSOURCE),
                           token_parser("LookAt", Tokens::LOOKAT),
                           token_parser("MakeNamedMedium", Tokens::MAKENAMEDMEDIUM),
                           token_parser("MakeNamedMaterial", Tokens::MAKENAMEDMATERIAL),
                           token_parser("Material", Tokens::MATERIAL),
                           token_parser("MediumInterface", Tokens::MEDIUMINTERFACE),
                           token_parser("NamedMaterial", Tokens::NAMEDMATERIAL),
                           token_parser("ObjectBegin", Tokens::OBJECTBEGIN),
                           token_parser("ObjectEnd", Tokens::OBJECTEND),
                           token_parser("ObjectInstance", Tokens::OBJECTINSTANCE),
                           token_parser("PixelFilter", Tokens::PIXELFILTER),
                           token_parser("ReverseOrientation", Tokens::REVERSEORIENTATION),
                           token_parser("Rotate", Tokens::ROTATE),
                           token_parser("Sampler", Tokens::SAMPLER),
                           token_parser("Scale", Tokens::SCALE),
                           token_parser("Shape", Tokens::SHAPE),
                           token_parser("StartTime", Tokens::STARTTIME),
                           token_parser("Integrator", Tokens::INTEGRATOR),
                           token_parser("Texture", Tokens::TEXTURE),
                           token_parser("TransformBegin", Tokens::TRANSFORMBEGIN),
                           token_parser("TransformEnd", Tokens::TRANSFORMEND),
                           token_parser("TransformTimes", Tokens::TRANSFORMTIMES),
                           token_parser("Transform", Tokens::TRANSFORM),
                           token_parser("Translate", Tokens::TRANSLATE),
                           token_parser("WorldBegin", Tokens::WORLDBEGIN),
                           token_parser("WorldEnd", Tokens::WORLDEND),
                           token_parser("[", Tokens::LBRACK),
                           token_parser("]", Tokens::RBRACK)]
            .into_iter()
            .map(|parser| try(parser))
            .collect::<Vec<_>>();

    // Add parsers from num, strings, etc...
    parsers.push(try(float_parser()));
    parsers.push(try(string_parser()));
    parsers.push(try(comment_parser()));

    (spaces().with(many::<Vec<_>, _>(choice(parsers))), eof())
        .map(|(res, _)| res)
        .parse(input)
}

fn token_parser<'a, I: Stream<Item = char> + 'a>
    (s: &'static str,
     t: Tokens)
     -> Box<Parser<Input = I, Output = Tokens> + 'a> {
    string(s).skip(spaces()).map(move |_| t.clone()).boxed()
}

fn float_parser<'a, I: Stream<Item = char> + 'a>
    ()
    -> Box<Parser<Input = I, Output = Tokens> + 'a>
{

    (optional(char('-').or(char('+'))),
     many1::<Vec<_>, _>(digit()),
     optional(char('.').with(many::<Vec<_>, _>(digit()))),
     optional(char('e').or(char('E')).with(many1::<Vec<_>, _>(digit()))))
            .skip(spaces())
            .and_then(|(sign, int_part, frac_part, mantissa)| {
                let mut buf = String::new();
                if let Some(s) = sign {
                    buf.push(s);
                }
                for c in int_part {
                    buf.push(c);
                }
                if let Some(frac) = frac_part {
                    buf.push('.');
                    for c in frac {
                        buf.push(c);
                    }
                }
                if let Some(mant) = mantissa {
                    buf.push('e');
                    for c in mant {
                        buf.push(c);
                    }
                }

                buf.parse::<f32>().map(Tokens::NUMBER)
            })
            .boxed()
}

fn string_parser<'a, I: Stream<Item = char> + 'a>
    ()
    -> Box<Parser<Input = I, Output = Tokens> + 'a>
{
    between(token('"'),
            token('"'),
            many::<Vec<_>, _>(none_of("\"".chars())))
            .skip(spaces())
            .map(|chars| {
                     let mut buf = String::new();
                     for c in chars {
                         buf.push(c);
                     }
                     Tokens::STR(buf)
                 })
            .boxed()
}

fn comment_parser<'a, I: Stream<Item = char> + 'a>
    ()
    -> Box<Parser<Input = I, Output = Tokens> + 'a>
{
    token('#')
        .and(skip_many(satisfy(|c| c != '\n')))
        .skip(spaces())
        .map(|_| Tokens::COMMENT)
        .boxed()
}

#[test]
fn test_tokenize() {
    let scene = r##"
LookAt 0 0 5 0 0 0 0 1 0
Camera "perspective" "float fov" [50]

Film "image" "integer xresolution" [800] "integer yresolution" [600]
    "string filename" "test-whitted.tga"

Integrator "whitted"
#Integrator "directlighting"

WorldBegin
  LightSource "distant" "point from" [0 1 5] "point to" [0 0 0]

  #Material "matte" "rgb Kd" [1.0 0.0 0.0] "float sigma" [20]
  AttributeBegin
    #Material "matte" "rgb Kd" [1.0 0.0 0.0]
    Material "plastic" "rgb Kd" [1.0 0.0 0.0] "rgb Ks" [1.0 1.0 1.0]

    Shape "sphere"
  AttributeEnd

  AttributeBegin
    Rotate -90 1 0 0
    Material "matte" "rgb Kd" [1.0 1.0 1.0]
    Shape "disk" "float radius" [20] "float height" [-1]
  AttributeEnd

  AttributeBegin
    AreaLightSource "diffuse" "rgb L" [2.0 2.0 2.0]
    Rotate 90 1 0 0
    Shape "disk" "float height" [-2] "float radius" [0.5]
  AttributeEnd
WorldEnd
        "##;
    let result = tokenize(scene);
    assert!(result.is_ok());
    let (tokens, rest) = result.unwrap();
    assert_eq!(rest, "");
}

#[test]
fn test_string_parser() {
    let s = "\"this is a string\"";
    let result = string_parser().parse(s);
    assert_eq!(result,
               Ok((Tokens::STR("this is a string".to_string()), "")))
}
<commit_msg>Support sign in mantissa in float parser<commit_after>use combine::{eof, satisfy, skip_many, none_of, token, between, optional, many, many1, choice,
              try, Parser, Stream, ParseError};
use combine::char::{string, spaces, digit, char};

#[derive(Clone, Debug, PartialEq)]
pub enum Tokens {
    ACCELERATOR,
    ACTIVETRANSFORM,
    ALL,
    AREALIGHTSOURCE,
    ATTRIBUTEBEGIN,
    ATTRIBUTEEND,
    CAMERA,
    CONCATTRANSFORM,
    COORDINATESYSTEM,
    COORDSYSTRANSFORM,
    ENDTIME,
    FILM,
    IDENTITY,
    INCLUDE,
    LIGHTSOURCE,
    LOOKAT,
    MAKENAMEDMEDIUM,
    MAKENAMEDMATERIAL,
    MATERIAL,
    MEDIUMINTERFACE,
    NAMEDMATERIAL,
    OBJECTBEGIN,
    OBJECTEND,
    OBJECTINSTANCE,
    PIXELFILTER,
    REVERSEORIENTATION,
    ROTATE,
    SAMPLER,
    SCALE,
    SHAPE,
    STARTTIME,
    INTEGRATOR,
    TEXTURE,
    TRANSFORMBEGIN,
    TRANSFORMEND,
    TRANSFORMTIMES,
    TRANSFORM,
    TRANSLATE,
    WORLDBEGIN,
    WORLDEND,
    STR(String),
    NUMBER(f32),
    LBRACK,
    RBRACK,
    COMMENT,
}

pub fn tokenize<'a>(input: &'a str) -> Result<(Vec<Tokens>, &'a str), ParseError<&'a str>> {

    // parsers for keywords
    let mut parsers = vec![token_parser("Accelerator", Tokens::ACCELERATOR),
                           token_parser("ActiveTransform", Tokens::ACTIVETRANSFORM),
                           token_parser("All", Tokens::ALL),
                           token_parser("AreaLightSource", Tokens::AREALIGHTSOURCE),
                           token_parser("AttributeBegin", Tokens::ATTRIBUTEBEGIN),
                           token_parser("AttributeEnd", Tokens::ATTRIBUTEEND),
                           token_parser("Camera", Tokens::CAMERA),
                           token_parser("ConcatTransform", Tokens::CONCATTRANSFORM),
                           token_parser("CoordinateSystem", Tokens::COORDINATESYSTEM),
                           token_parser("CoordSysTransform", Tokens::COORDSYSTRANSFORM),
                           token_parser("EndTime", Tokens::ENDTIME),
                           token_parser("Film", Tokens::FILM),
                           token_parser("Identity", Tokens::IDENTITY),
                           token_parser("Include", Tokens::INCLUDE),
                           token_parser("LightSource", Tokens::LIGHTSOURCE),
                           token_parser("LookAt", Tokens::LOOKAT),
                           token_parser("MakeNamedMedium", Tokens::MAKENAMEDMEDIUM),
                           token_parser("MakeNamedMaterial", Tokens::MAKENAMEDMATERIAL),
                           token_parser("Material", Tokens::MATERIAL),
                           token_parser("MediumInterface", Tokens::MEDIUMINTERFACE),
                           token_parser("NamedMaterial", Tokens::NAMEDMATERIAL),
                           token_parser("ObjectBegin", Tokens::OBJECTBEGIN),
                           token_parser("ObjectEnd", Tokens::OBJECTEND),
                           token_parser("ObjectInstance", Tokens::OBJECTINSTANCE),
                           token_parser("PixelFilter", Tokens::PIXELFILTER),
                           token_parser("ReverseOrientation", Tokens::REVERSEORIENTATION),
                           token_parser("Rotate", Tokens::ROTATE),
                           token_parser("Sampler", Tokens::SAMPLER),
                           token_parser("Scale", Tokens::SCALE),
                           token_parser("Shape", Tokens::SHAPE),
                           token_parser("StartTime", Tokens::STARTTIME),
                           token_parser("Integrator", Tokens::INTEGRATOR),
                           token_parser("Texture", Tokens::TEXTURE),
                           token_parser("TransformBegin", Tokens::TRANSFORMBEGIN),
                           token_parser("TransformEnd", Tokens::TRANSFORMEND),
                           token_parser("TransformTimes", Tokens::TRANSFORMTIMES),
                           token_parser("Transform", Tokens::TRANSFORM),
                           token_parser("Translate", Tokens::TRANSLATE),
                           token_parser("WorldBegin", Tokens::WORLDBEGIN),
                           token_parser("WorldEnd", Tokens::WORLDEND),
                           token_parser("[", Tokens::LBRACK),
                           token_parser("]", Tokens::RBRACK)]
            .into_iter()
            .map(|parser| try(parser))
            .collect::<Vec<_>>();

    // Add parsers from num, strings, etc...
    parsers.push(try(float_parser()));
    parsers.push(try(string_parser()));
    parsers.push(try(comment_parser()));

    (spaces().with(many::<Vec<_>, _>(choice(parsers))), eof())
        .map(|(res, _)| res)
        .parse(input)
}

fn token_parser<'a, I: Stream<Item = char> + 'a>
    (s: &'static str,
     t: Tokens)
     -> Box<Parser<Input = I, Output = Tokens> + 'a> {
    string(s).skip(spaces()).map(move |_| t.clone()).boxed()
}

fn float_parser<'a, I: Stream<Item = char> + 'a>
    ()
    -> Box<Parser<Input = I, Output = Tokens> + 'a>
{

    (optional(char('-').or(char('+'))),
     many1::<Vec<_>, _>(digit()),
     optional(char('.').with(many::<Vec<_>, _>(digit()))),
     optional(char('e').or(char('E')).with((optional(char('-').or(char('+'))), many1::<Vec<_>, _>(digit())))))
            .skip(spaces())
            .and_then(|(sign, int_part, frac_part, mantissa)| {
                let mut buf = String::new();
                if let Some(s) = sign {
                    buf.push(s);
                }
                for c in int_part {
                    buf.push(c);
                }
                if let Some(frac) = frac_part {
                    buf.push('.');
                    for c in frac {
                        buf.push(c);
                    }
                }
                if let Some((mant_sign, mant)) = mantissa {
                    buf.push('e');
                    buf.push(mant_sign.unwrap_or('+'));
                    for c in mant {
                        buf.push(c);
                    }
                }

                buf.parse::<f32>().map(Tokens::NUMBER)
            })
            .boxed()
}

fn string_parser<'a, I: Stream<Item = char> + 'a>
    ()
    -> Box<Parser<Input = I, Output = Tokens> + 'a>
{
    between(token('"'),
            token('"'),
            many::<Vec<_>, _>(none_of("\"".chars())))
            .skip(spaces())
            .map(|chars| {
                     let mut buf = String::new();
                     for c in chars {
                         buf.push(c);
                     }
                     Tokens::STR(buf)
                 })
            .boxed()
}

fn comment_parser<'a, I: Stream<Item = char> + 'a>
    ()
    -> Box<Parser<Input = I, Output = Tokens> + 'a>
{
    token('#')
        .and(skip_many(satisfy(|c| c != '\n')))
        .skip(spaces())
        .map(|_| Tokens::COMMENT)
        .boxed()
}

#[test]
fn test_tokenize() {
    let scene = r##"
LookAt 0 0 5 0 0 0 0 1 0
Camera "perspective" "float fov" [50]

Film "image" "integer xresolution" [800] "integer yresolution" [600]
    "string filename" "test-whitted.tga"

Integrator "whitted"
#Integrator "directlighting"

WorldBegin
  LightSource "distant" "point from" [0 1 5] "point to" [0 0 0]

  #Material "matte" "rgb Kd" [1.0 0.0 0.0] "float sigma" [20]
  AttributeBegin
    #Material "matte" "rgb Kd" [1.0 0.0 0.0]
    Material "plastic" "rgb Kd" [1.0 0.0 0.0] "rgb Ks" [1.0 1.0 1.0]

    Shape "sphere"
  AttributeEnd

  AttributeBegin
    Rotate -90 1 0 0
    Material "matte" "rgb Kd" [1.0 1.0 1.0]
    Shape "disk" "float radius" [20] "float height" [-1]
  AttributeEnd

  AttributeBegin
    AreaLightSource "diffuse" "rgb L" [2.0 2.0 2.0]
    Rotate 90 1 0 0
    Shape "disk" "float height" [-2] "float radius" [0.5]
  AttributeEnd
WorldEnd
        "##;
    let result = tokenize(scene);
    assert!(result.is_ok());
    let (tokens, rest) = result.unwrap();
    assert_eq!(rest, "");
}

#[test]
fn test_string_parser() {
    let s = "\"this is a string\"";
    let result = string_parser().parse(s);
    assert_eq!(result,
               Ok((Tokens::STR("this is a string".to_string()), "")))
}
<|endoftext|>


<commit_before>use hyper::{
    client::{Client, HttpConnector},
    Body, Request as HttpRequest,
};
use futures::stream::StreamExt;
use crate::error::{RetryAfter, WebPushError};
use http::header::{RETRY_AFTER, CONTENT_LENGTH};
use hyper_tls::HttpsConnector;
use crate::message::{WebPushMessage, WebPushService};
use crate::services::{autopush, firebase};

/// An async client for sending the notification payload.
pub struct WebPushClient {
    client: Client<HttpsConnector<HttpConnector>>,
}

impl WebPushClient {
    pub fn new() -> WebPushClient {
        let mut builder = Client::builder();
        builder.keep_alive(true);

        WebPushClient {
            client: builder.build(HttpsConnector::new()),
        }
    }

    /// Sends a notification. Never times out.
    pub async fn send(&self, message: WebPushMessage) -> Result<(), WebPushError> {
        let service = message.service.clone();

        let request: HttpRequest<Body> = match service {
            WebPushService::Firebase => firebase::build_request(message),
            _ => autopush::build_request(message),
        };

        trace!("Request: {:?}", request);

        let response = self.client.request(request).await?;

        let retry_after = response
            .headers()
            .get(RETRY_AFTER)
            .and_then(|ra| ra.to_str().ok())
            .and_then(|ra| RetryAfter::from_str(ra));

        let response_status = response.status();
        trace!("Response status: {}", response_status);

        let content_length: usize = response
            .headers()
            .get(CONTENT_LENGTH)
            .and_then(|s| s.to_str().ok())
            .and_then(|s| s.parse().ok())
            .unwrap_or(0);

        let mut body: Vec<u8> = Vec::with_capacity(content_length);
        let mut chunks = response.into_body();

        while let Some(chunk) = chunks.next().await {
            body.extend_from_slice(&chunk?);
        }
        trace!("Body: {:?}", body);

        let response = match service {
            WebPushService::Firebase => {
                firebase::parse_response(response_status, body.to_vec())
            }
            _ => autopush::parse_response(response_status, body.to_vec()),
        };

        debug!("Response: {:?}", response);

        if let Err(WebPushError::ServerError(None)) = response {
            Err(WebPushError::ServerError(retry_after))
        } else {
            Ok(response?)
        }
    }
}
<commit_msg>Enforce static lifetime for client's future<commit_after>use hyper::{
    client::{Client, HttpConnector},
    Body, Request as HttpRequest,
};
use futures::stream::StreamExt;
use crate::error::{RetryAfter, WebPushError};
use http::header::{RETRY_AFTER, CONTENT_LENGTH};
use hyper_tls::HttpsConnector;
use crate::message::{WebPushMessage, WebPushService};
use crate::services::{autopush, firebase};
use std::future::Future;

/// An async client for sending the notification payload.
pub struct WebPushClient {
    client: Client<HttpsConnector<HttpConnector>>,
}

impl WebPushClient {
    pub fn new() -> WebPushClient {
        let mut builder = Client::builder();
        builder.keep_alive(true);

        WebPushClient {
            client: builder.build(HttpsConnector::new()),
        }
    }

    /// Sends a notification. Never times out.
    pub fn send(&self, message: WebPushMessage) -> impl Future<Output = Result<(), WebPushError>> + 'static {
        let service = message.service.clone();

        let request: HttpRequest<Body> = match service {
            WebPushService::Firebase => firebase::build_request(message),
            _ => autopush::build_request(message),
        };

        trace!("Request: {:?}", request);

        let requesting = self.client.request(request);

        async move {
            let response = requesting.await?;

            let retry_after = response
                .headers()
                .get(RETRY_AFTER)
                .and_then(|ra| ra.to_str().ok())
                .and_then(|ra| RetryAfter::from_str(ra));

            let response_status = response.status();
            trace!("Response status: {}", response_status);

            let content_length: usize = response
                .headers()
                .get(CONTENT_LENGTH)
                .and_then(|s| s.to_str().ok())
                .and_then(|s| s.parse().ok())
                .unwrap_or(0);

            let mut body: Vec<u8> = Vec::with_capacity(content_length);
            let mut chunks = response.into_body();

            while let Some(chunk) = chunks.next().await {
                body.extend_from_slice(&chunk?);
            }
            trace!("Body: {:?}", body);

            let response = match service {
                WebPushService::Firebase => {
                    firebase::parse_response(response_status, body.to_vec())
                }
                _ => autopush::parse_response(response_status, body.to_vec()),
            };

            debug!("Response: {:?}", response);

            if let Err(WebPushError::ServerError(None)) = response {
                Err(WebPushError::ServerError(retry_after))
            } else {
                Ok(response?)
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Support for ANSI terminal colors via the colored crate.
//!
//! To enable support for colors, add the `"colored"` feature in your
//! `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! fern = { version = "0.5", features = ["colored"] }
//! ```
//!
//! ---
//!
//! Colors are mainly supported via coloring the log level itself, but it's
//! also possible to color each entire log line based off of the log level.
//!
//! First, here's an example which colors the log levels themselves ("INFO" /
//! "WARN" text will have color, but won't color the rest of the line).
//! [`ColoredLevelConfig`] lets us configure the colors per-level, but also has
//! sane defaults.
//!
//! ```
//! use fern::colors::{Color, ColoredLevelConfig};
//!
//! let mut colors = ColoredLevelConfig::new()
//!     // use builder methods
//!     .info(Color::Green);
//! // or access raw fields
//! colors.warn = Color::Magenta;
//! ```
//!
//! It can then be used within any regular fern formatting closure:
//!
//! ```
//! # let colors = fern::colors::ColoredLevelConfig::new();
//! fern::Dispatch::new()
//!     // ...
//!     .format(move |out, message, record| {
//!         out.finish(format_args!(
//!             "[{}] {}",
//!             // just use 'colors.color(..)' instead of the level
//!             // itself to insert ANSI colors.
//!             colors.color(record.level()),
//!             message,
//!         ))
//!     })
//!     # .into_log();
//! ```
//!
//! ---
//!
//! Coloring levels is nice, but the alternative is good to. For an example
//! application coloring each entire log line with the right color, see
//! [examples/pretty-colored.rs][ex].
//!
//! [`ColoredLevelConfig`]: struct.ColoredLevelConfig.html
//! [ex]: https://github.com/daboross/fern/blob/master/examples/pretty-colored.rs
use std::fmt;

pub use colored::Color;
use log::Level;

/// Extension crate allowing the use of `.colored` on Levels.
trait ColoredLogLevel {
    /// Colors this log level with the given color.
    fn colored(&self, color: Color) -> WithFgColor<Level>;
}

/// Opaque structure which represents some text data and a color to display it
/// with.
///
/// This implements [`fmt::Display`] to displaying the inner text (usually a
/// log level) with ANSI color markers before to set the color and after to
/// reset the color.
///
/// `WithFgColor` instances can be created and displayed without any allocation.
// this is necessary in order to avoid using colored::ColorString, which has a
// Display implementation involving many allocations, and would involve two
// more string allocations even to create it.
//
// [`fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
pub struct WithFgColor<T>
where
    T: fmt::Display,
{
    text: T,
    color: Color,
}

impl<T> fmt::Display for WithFgColor<T>
where
    T: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "\x1B[{}m", self.color.to_fg_str())?;
        fmt::Display::fmt(&self.text, f)?;
        write!(f, "\x1B[0m")?;
        Ok(())
    }
}

/// Configuration specifying colors a log level can be colored as.
///
/// Example usage setting custom 'info' and 'debug' colors:
///
/// ```
/// use fern::colors::{Color, ColoredLevelConfig};
///
/// let colors = ColoredLevelConfig::new()
///     .info(Color::Green)
///     .debug(Color::Magenta);
///
/// fern::Dispatch::new()
///     .format(move |out, message, record| {
///         out.finish(format_args!(
///             "[{}] {}",
///             colors.color(record.level()),
///             message
///         ))
///     })
///     .chain(std::io::stdout())
/// # /*
///     .apply()?;
/// # */
/// #   .into_log();
/// ```
#[derive(Copy, Clone)]
#[must_use = "builder methods take config by value and thus must be reassigned to variable"]
pub struct ColoredLevelConfig {
    /// The color to color logs with the [`Error`] level.
    ///
    /// [`Error`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Error
    pub error: Color,
    /// The color to color logs with the [`Warn`] level.
    ///
    /// [`Warn`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Warn
    pub warn: Color,
    /// The color to color logs with the [`Info`] level.
    ///
    /// [`Info`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Info
    pub info: Color,
    /// The color to color logs with the [`Debug`] level.
    ///
    /// [`Debug`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Debug
    pub debug: Color,
    /// The color to color logs with the [`Trace`] level.
    ///
    /// [`Trace`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Trace
    pub trace: Color,
}

impl ColoredLevelConfig {
    /// Creates a new ColoredLevelConfig with the default colors.
    ///
    /// This matches the behavior of [`ColoredLevelConfig::default`].
    ///
    /// [`ColoredLevelConfig::default`]: #method.default
    #[inline]
    pub fn new() -> Self {
        #[cfg(windows)]
        {
            let _ = colored::control::set_virtual_terminal(true);
        }
        Self::default()
    }

    /// Overrides the [`Error`] level color with the given color.
    ///
    /// The default color is [`Color::Red`].
    ///
    /// [`Error`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Error
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    pub fn error(mut self, error: Color) -> Self {
        self.error = error;
        self
    }

    /// Overrides the [`Warn`] level color with the given color.
    ///
    /// The default color is [`Color::Yellow`].
    ///
    /// [`Warn`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Warn
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    pub fn warn(mut self, warn: Color) -> Self {
        self.warn = warn;
        self
    }

    /// Overrides the [`Info`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Info`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Info
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn info(mut self, info: Color) -> Self {
        self.info = info;
        self
    }

    /// Overrides the [`Debug`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Debug`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Debug
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn debug(mut self, debug: Color) -> Self {
        self.debug = debug;
        self
    }

    /// Overrides the [`Trace`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Trace`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn trace(mut self, trace: Color) -> Self {
        self.trace = trace;
        self
    }

    /// Colors the given log level with the color in this configuration
    /// corresponding to it's level.
    ///
    /// The structure returned is opaque, but will print the Level surrounded
    /// by ANSI color codes when displayed. This will work correctly for
    /// UNIX terminals, but due to a lack of support from the [`colored`]
    /// crate, this will not function in Windows.
    ///
    /// [`colored`]: https://github.com/mackwic/colored
    pub fn color(&self, level: Level) -> WithFgColor<Level> {
        level.colored(self.get_color(&level))
    }

    /// Retrieves the color that a log level should be colored as.
    pub fn get_color(&self, level: &Level) -> Color {
        match *level {
            Level::Error => self.error,
            Level::Warn => self.warn,
            Level::Info => self.info,
            Level::Debug => self.debug,
            Level::Trace => self.trace,
        }
    }
}

impl Default for ColoredLevelConfig {
    /// Retrieves the default configuration. This has:
    ///
    /// - [`Error`] as [`Color::Red`]
    /// - [`Warn`] as [`Color::Yellow`]
    /// - [`Info`] as [`Color::White`]
    /// - [`Debug`] as [`Color::White`]
    /// - [`Trace`] as [`Color::White`]
    ///
    /// [`Error`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Error
    /// [`Warn`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Warn
    /// [`Info`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Info
    /// [`Debug`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Debug
    /// [`Trace`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    fn default() -> Self {
        ColoredLevelConfig {
            error: Color::Red,
            warn: Color::Yellow,
            debug: Color::White,
            info: Color::White,
            trace: Color::White,
        }
    }
}

impl ColoredLogLevel for Level {
    fn colored(&self, color: Color) -> WithFgColor<Level> {
        WithFgColor {
            text: *self,
            color: color,
        }
    }
}

#[cfg(test)]
mod test {
    use colored::{Color::*, Colorize};

    use super::WithFgColor;

    #[test]
    fn fg_color_matches_colored_behavior() {
        for &color in &[
            Black,
            Red,
            Green,
            Yellow,
            Blue,
            Magenta,
            Cyan,
            White,
            BrightBlack,
            BrightRed,
            BrightGreen,
            BrightYellow,
            BrightBlue,
            BrightMagenta,
            BrightCyan,
            BrightWhite,
        ] {
            assert_eq!(
                format!("{}", "test".color(color)),
                format!(
                    "{}",
                    WithFgColor {
                        text: "test",
                        color: color,
                    }
                )
            );
        }
    }

    #[test]
    fn fg_color_respects_formatting_flags() {
        let s = format!(
            "{:^8}",
            WithFgColor {
                text: "test",
                color: Yellow,
            }
        );
        assert!(s.contains("  test  "));
        assert!(!s.contains("   test  "));
        assert!(!s.contains("  test   "));
    }
}
<commit_msg>Reformat.<commit_after>//! Support for ANSI terminal colors via the colored crate.
//!
//! To enable support for colors, add the `"colored"` feature in your
//! `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! fern = { version = "0.5", features = ["colored"] }
//! ```
//!
//! ---
//!
//! Colors are mainly supported via coloring the log level itself, but it's
//! also possible to color each entire log line based off of the log level.
//!
//! First, here's an example which colors the log levels themselves ("INFO" /
//! "WARN" text will have color, but won't color the rest of the line).
//! [`ColoredLevelConfig`] lets us configure the colors per-level, but also has
//! sane defaults.
//!
//! ```
//! use fern::colors::{Color, ColoredLevelConfig};
//!
//! let mut colors = ColoredLevelConfig::new()
//!     // use builder methods
//!     .info(Color::Green);
//! // or access raw fields
//! colors.warn = Color::Magenta;
//! ```
//!
//! It can then be used within any regular fern formatting closure:
//!
//! ```
//! # let colors = fern::colors::ColoredLevelConfig::new();
//! fern::Dispatch::new()
//!     // ...
//!     .format(move |out, message, record| {
//!         out.finish(format_args!(
//!             "[{}] {}",
//!             // just use 'colors.color(..)' instead of the level
//!             // itself to insert ANSI colors.
//!             colors.color(record.level()),
//!             message,
//!         ))
//!     })
//!     # .into_log();
//! ```
//!
//! ---
//!
//! Coloring levels is nice, but the alternative is good to. For an example
//! application coloring each entire log line with the right color, see
//! [examples/pretty-colored.rs][ex].
//!
//! [`ColoredLevelConfig`]: struct.ColoredLevelConfig.html
//! [ex]: https://github.com/daboross/fern/blob/master/examples/pretty-colored.rs
use std::fmt;

pub use colored::Color;
use log::Level;

/// Extension crate allowing the use of `.colored` on Levels.
trait ColoredLogLevel {
    /// Colors this log level with the given color.
    fn colored(&self, color: Color) -> WithFgColor<Level>;
}

/// Opaque structure which represents some text data and a color to display it
/// with.
///
/// This implements [`fmt::Display`] to displaying the inner text (usually a
/// log level) with ANSI color markers before to set the color and after to
/// reset the color.
///
/// `WithFgColor` instances can be created and displayed without any allocation.
// this is necessary in order to avoid using colored::ColorString, which has a
// Display implementation involving many allocations, and would involve two
// more string allocations even to create it.
//
// [`fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
pub struct WithFgColor<T>
where
    T: fmt::Display,
{
    text: T,
    color: Color,
}

impl<T> fmt::Display for WithFgColor<T>
where
    T: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "\x1B[{}m", self.color.to_fg_str())?;
        fmt::Display::fmt(&self.text, f)?;
        write!(f, "\x1B[0m")?;
        Ok(())
    }
}

/// Configuration specifying colors a log level can be colored as.
///
/// Example usage setting custom 'info' and 'debug' colors:
///
/// ```
/// use fern::colors::{Color, ColoredLevelConfig};
///
/// let colors = ColoredLevelConfig::new()
///     .info(Color::Green)
///     .debug(Color::Magenta);
///
/// fern::Dispatch::new()
///     .format(move |out, message, record| {
///         out.finish(format_args!(
///             "[{}] {}",
///             colors.color(record.level()),
///             message
///         ))
///     })
///     .chain(std::io::stdout())
/// # /*
///     .apply()?;
/// # */
/// #   .into_log();
/// ```
#[derive(Copy, Clone)]
#[must_use = "builder methods take config by value and thus must be reassigned to variable"]
pub struct ColoredLevelConfig {
    /// The color to color logs with the [`Error`] level.
    ///
    /// [`Error`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Error
    pub error: Color,
    /// The color to color logs with the [`Warn`] level.
    ///
    /// [`Warn`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Warn
    pub warn: Color,
    /// The color to color logs with the [`Info`] level.
    ///
    /// [`Info`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Info
    pub info: Color,
    /// The color to color logs with the [`Debug`] level.
    ///
    /// [`Debug`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Debug
    pub debug: Color,
    /// The color to color logs with the [`Trace`] level.
    ///
    /// [`Trace`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Trace
    pub trace: Color,
}

impl ColoredLevelConfig {
    /// Creates a new ColoredLevelConfig with the default colors.
    ///
    /// This matches the behavior of [`ColoredLevelConfig::default`].
    ///
    /// [`ColoredLevelConfig::default`]: #method.default
    #[inline]
    pub fn new() -> Self {
        #[cfg(windows)]
        {
            let _ = colored::control::set_virtual_terminal(true);
        }
        Self::default()
    }

    /// Overrides the [`Error`] level color with the given color.
    ///
    /// The default color is [`Color::Red`].
    ///
    /// [`Error`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Error
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    pub fn error(mut self, error: Color) -> Self {
        self.error = error;
        self
    }

    /// Overrides the [`Warn`] level color with the given color.
    ///
    /// The default color is [`Color::Yellow`].
    ///
    /// [`Warn`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Warn
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    pub fn warn(mut self, warn: Color) -> Self {
        self.warn = warn;
        self
    }

    /// Overrides the [`Info`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Info`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Info
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn info(mut self, info: Color) -> Self {
        self.info = info;
        self
    }

    /// Overrides the [`Debug`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Debug`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Debug
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn debug(mut self, debug: Color) -> Self {
        self.debug = debug;
        self
    }

    /// Overrides the [`Trace`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Trace`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn trace(mut self, trace: Color) -> Self {
        self.trace = trace;
        self
    }

    /// Colors the given log level with the color in this configuration
    /// corresponding to it's level.
    ///
    /// The structure returned is opaque, but will print the Level surrounded
    /// by ANSI color codes when displayed. This will work correctly for
    /// UNIX terminals, but due to a lack of support from the [`colored`]
    /// crate, this will not function in Windows.
    ///
    /// [`colored`]: https://github.com/mackwic/colored
    pub fn color(&self, level: Level) -> WithFgColor<Level> {
        level.colored(self.get_color(&level))
    }

    /// Retrieves the color that a log level should be colored as.
    pub fn get_color(&self, level: &Level) -> Color {
        match *level {
            Level::Error => self.error,
            Level::Warn => self.warn,
            Level::Info => self.info,
            Level::Debug => self.debug,
            Level::Trace => self.trace,
        }
    }
}

impl Default for ColoredLevelConfig {
    /// Retrieves the default configuration. This has:
    ///
    /// - [`Error`] as [`Color::Red`]
    /// - [`Warn`] as [`Color::Yellow`]
    /// - [`Info`] as [`Color::White`]
    /// - [`Debug`] as [`Color::White`]
    /// - [`Trace`] as [`Color::White`]
    ///
    /// [`Error`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Error
    /// [`Warn`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Warn
    /// [`Info`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Info
    /// [`Debug`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Debug
    /// [`Trace`]: https://docs.rs/log/0.4/log/enum.Level.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    fn default() -> Self {
        ColoredLevelConfig {
            error: Color::Red,
            warn: Color::Yellow,
            debug: Color::White,
            info: Color::White,
            trace: Color::White,
        }
    }
}

impl ColoredLogLevel for Level {
    fn colored(&self, color: Color) -> WithFgColor<Level> {
        WithFgColor {
            text: *self,
            color: color,
        }
    }
}

#[cfg(test)]
mod test {
    use colored::{Color::*, Colorize};

    use super::WithFgColor;

    #[test]
    fn fg_color_matches_colored_behavior() {
        for &color in &[
            Black,
            Red,
            Green,
            Yellow,
            Blue,
            Magenta,
            Cyan,
            White,
            BrightBlack,
            BrightRed,
            BrightGreen,
            BrightYellow,
            BrightBlue,
            BrightMagenta,
            BrightCyan,
            BrightWhite,
        ] {
            assert_eq!(
                format!("{}", "test".color(color)),
                format!(
                    "{}",
                    WithFgColor {
                        text: "test",
                        color: color,
                    }
                )
            );
        }
    }

    #[test]
    fn fg_color_respects_formatting_flags() {
        let s = format!(
            "{:^8}",
            WithFgColor {
                text: "test",
                color: Yellow,
            }
        );
        assert!(s.contains("  test  "));
        assert!(!s.contains("   test  "));
        assert!(!s.contains("  test   "));
    }
}
<|endoftext|>


<commit_before>use cards::Card;

// All these functions need reverse sorted vectors of Cards
pub fn has_pair(card_vec: &Vec<&Card>) -> bool {
    has_set(2, card_vec)
}

fn has_set(set_size: u8, card_vec: &Vec<&Card>) -> bool {
    let mut prev: &Card = card_vec[0];
    let mut count: u8 = 1;
    for card in card_vec.iter().skip(1) {
        if *card == prev {
            count += 1;
            if count == set_size {
                return true
            }
            continue;
        }
        prev = *card;
        count = 1;
    }
    false
}
<commit_msg>Change has_set to return an option with the found set<commit_after>use cards::Card;

// All these functions need sorted vectors of Cards
pub fn has_pair<'r>(card_vec: &'r Vec<&Card>) -> Option<&'r Card> {
    has_set(2, card_vec)
}

fn has_set<'r>(set_size: u8, card_vec: &'r Vec<&Card>) -> Option<&'r Card> {
    let mut prev: &&Card = match card_vec.last() {
        Some(x) => x,
        None => return None
    };

    let mut count: u8 = 1;
    for card in card_vec.iter().rev().skip(1) {
        if card == prev {
            count += 1;
            if count == set_size {
                return Some(*prev)
            }
            continue;
        }
        prev = card;
        count = 1;
    }
    None
}

<|endoftext|>


<commit_before>//! Endpoints for the public room directory.

/// [GET /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-publicrooms)
pub mod get_public_rooms {
    use ruma_identifiers::{RoomId, RoomAliasId};
    use ruma_api_macros::ruma_api;

    ruma_api! {
        metadata {
            description: "Get the list of rooms in this homeserver's public directory.",
            method: Method::Get,
            name: "get_public_rooms",
            path: "/_matrix/client/r0/publicRooms",
            rate_limited: false,
            requires_authentication: false,
        }

        request {}

        response {
            /// A pagination token for the response.
            pub start: String,
            /// A paginated chunk of public rooms.
            pub chunk: Vec<PublicRoomsChunk>,
            /// A pagination token for the response.
            pub end: String
        }
    }

    /// A chunk of the response, describing one room
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PublicRoomsChunk {
        /// Aliases of the room.
        pub aliases: Vec<RoomAliasId>,
        /// The URL for the room's avatar, if one is set.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub avatar_url: Option<String>,
        /// Whether guest users may join the room and participate in it.
        ///
        /// If they can, they will be subject to ordinary power level rules like any other user.
        pub guest_can_join: bool,
        /// The name of the room, if any.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub name: Option<String>,
        /// The number of members joined to the room.
        pub num_joined_members: u64,
        /// The ID of the room.
        pub room_id: RoomId,
        /// The topic of the room, if any.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub topic: Option<String>,
        /// Whether the room may be viewed by guest users without joining.
        pub world_readable: bool,
    }
}
<commit_msg>Make aliases optional for global rooms query.<commit_after>//! Endpoints for the public room directory.

/// [GET /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-publicrooms)
pub mod get_public_rooms {
    use ruma_identifiers::{RoomId, RoomAliasId};
    use ruma_api_macros::ruma_api;

    ruma_api! {
        metadata {
            description: "Get the list of rooms in this homeserver's public directory.",
            method: Method::Get,
            name: "get_public_rooms",
            path: "/_matrix/client/r0/publicRooms",
            rate_limited: false,
            requires_authentication: false,
        }

        request {}

        response {
            /// A pagination token for the response.
            pub start: String,
            /// A paginated chunk of public rooms.
            pub chunk: Vec<PublicRoomsChunk>,
            /// A pagination token for the response.
            pub end: String
        }
    }

    /// A chunk of the response, describing one room
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PublicRoomsChunk {
        /// Aliases of the room.
        //#[serde(skip_serializing_if = "Option::is_none")]
        pub aliases: Option<Vec<RoomAliasId>>,
        /// The URL for the room's avatar, if one is set.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub avatar_url: Option<String>,
        /// Whether guest users may join the room and participate in it.
        ///
        /// If they can, they will be subject to ordinary power level rules like any other user.
        pub guest_can_join: bool,
        /// The name of the room, if any.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub name: Option<String>,
        /// The number of members joined to the room.
        pub num_joined_members: u64,
        /// The ID of the room.
        pub room_id: RoomId,
        /// The topic of the room, if any.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub topic: Option<String>,
        /// Whether the room may be viewed by guest users without joining.
        pub world_readable: bool,
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use cursor::xcursor;

/// An image that can be attached to a `Cursor` or `OutputCursor`.
#[derive(Debug, Default, PartialEq)]
pub struct Image<'buffer> {
    pub pixels: &'buffer [u8],
    pub stride: i32,
    pub width: u32,
    pub height: u32,
    pub hotspot_x: i32,
    pub hotspot_y: i32,
    pub delay: u32,
    pub scale: f32
}

impl<'buffer> Image<'buffer> {
    pub fn new(pixels: &'buffer [u8],
               stride: i32,
               width: u32,
               height: u32,
               hotspot_x: i32,
               hotspot_y: i32,
               scale: f32,
               delay: u32)
               -> Image<'buffer> {
        Image { pixels,
                stride,
                width,
                height,
                hotspot_x,
                hotspot_y,
                scale,
                delay }
    }
}

impl<'buffer> From<xcursor::Image<'buffer>> for Image<'buffer> {
    fn from(image: xcursor::Image<'buffer>) -> Self {
        let xcursor::Image { buffer,
                             width,
                             height,
                             hotspot_x,
                             hotspot_y,
                             delay,
                             .. } = image;
        Image { pixels: buffer,
                width,
                height,
                stride: width as i32 * 4,
                scale: 1.0,
                hotspot_x: hotspot_x as _,
                hotspot_y: hotspot_y as _,
                delay }
    }
}
<commit_msg>Remove the phantom data type in image<commit_after>use cursor::xcursor;

/// An image that can be attached to a `Cursor` or `OutputCursor`.
#[derive(Debug, Default, PartialEq)]
pub struct Image<'buffer> {
    pub pixels: &'buffer [u8],
    pub stride: i32,
    pub width: u32,
    pub height: u32,
    pub hotspot_x: i32,
    pub hotspot_y: i32,
    pub delay: u32,
    pub scale: f32
}

impl<'buffer> Image<'buffer> {
    pub fn new(pixels: &'buffer [u8],
               stride: i32,
               width: u32,
               height: u32,
               hotspot_x: i32,
               hotspot_y: i32,
               scale: f32,
               delay: u32)
               -> Image<'buffer> {
        Image { pixels,
                stride,
                width,
                height,
                hotspot_x,
                hotspot_y,
                scale,
                delay }
    }
}

impl<'buffer> From<xcursor::Image<'buffer>> for Image<'buffer> {
    fn from(image: xcursor::Image<'buffer>) -> Self {
        let xcursor::Image { buffer,
                             width,
                             height,
                             hotspot_x,
                             hotspot_y,
                             delay,
                             .. } = image;
        Image { pixels: buffer,
                width,
                height,
                stride: width as i32 * 4,
                scale: 1.0,
                hotspot_x: hotspot_x as _,
                hotspot_y: hotspot_y as _,
                delay }
    }
}
<|endoftext|>


<commit_before>use std::io::fs;
use std::io::fs::PathExtensions;
use std::str::StrExt;

struct Index {
    path: Path,
    entries: Vec<Path>,
}

impl Index {
    fn new(path: &str) -> Index {
        return Index { path: Path::new(path.to_string()), entries: vec![] }
    }

    fn populate(&mut self) {
        let mut directories: fs::Directories;
        let prefix_length = self.path.as_str().unwrap().len()+1;

        // Start by getting any files in the root path.
        match fs::readdir(&self.path) {
            Ok(entries) => {
                // Put all of the file-based Path entries into the index.
                for file in entries.iter().filter(|entry| entry.is_file()) {
                    // Make the file path relative to the index path by stripping it from its string.
                    let file_path = Path::new(file.as_str().unwrap().slice_from(prefix_length));
                    self.entries.push(file_path);
                }
            },
            Err(e) => (),
        }

        // Get an iterator that'll let us walk all of the subdirectories of the index path.
        match fs::walk_dir(&self.path) {
            Ok(iterator) => directories = iterator,
            Err(e) => return,
        }

        for directory in directories {
            // Read the subdirectory entries.
            match fs::readdir(&directory) {
                Ok(entries) => {
                    // Put all of the file-based Path entries into the index.
                    for file in entries.iter().filter(|entry| entry.is_file()) {
                        // Make the file path relative to the index path by stripping it from its string.
                        let file_path = Path::new(file.as_str().unwrap().slice_from(prefix_length));
                        self.entries.push(file_path);
                    }
                },
                Err(e) => continue,
            }
        }
    }
}

#[test]
fn new_creates_index_with_passed_path() {
    let path = "my path";
    let index = Index::new(path);

    // Get the index path as a string.
    let index_path = match index.path.as_str() {
        Some(value) => value,
        None => ""
    };

    assert_eq!(index_path, path);
}

#[test]
fn new_creates_index_with_empty_array() {
    let path = "my path";
    let index = Index::new(path);
    let empty_array: Vec<Path> = vec![];

    assert!(index.entries == empty_array);
}

#[test]
fn populate_adds_all_files_to_entries() {
    let path = "tests/sample";
    let index = &mut Index::new(path);
    let expected_array = vec![Path::new("root_file"), Path::new("directory/nested_file")];
    index.populate();

    assert!(index.entries == expected_array);
}
<commit_msg>Dry up populate method and add comments.<commit_after>use std::io::fs;
use std::io::fs::PathExtensions;
use std::str::StrExt;

struct Index {
    path: Path,
    entries: Vec<Path>,
}

impl Index {
    fn new(path: &str) -> Index {
        return Index { path: Path::new(path.to_string()), entries: vec![] }
    }

    // Finds all files inside and beneath the index path
    // and adds them to the index entries vector.
    fn populate(&mut self) {
        // The entries listed by readdir include the root index path; we want
        // relative paths, so we get this length so that we can strip it.
        let prefix_length = self.path.as_str().unwrap().len()+1;

        // Start by getting any files in the root path. Since
        // read_directory_entries is already borrowing a mutable
        // reference to the index, so we can't also lend out a
        // reference to its path field, hence the clone.
        let path = self.path.clone();
        self.index_directory_files(path, prefix_length);

        // Get an iterator that'll let us walk all of the subdirectories
        // of the index path, bailing out if there's an error of any kind.
        let mut subdirectories = match fs::walk_dir(&self.path) {
            Ok(iterator) => iterator,
            Err(e) => return,
        };

        // Index any other files beneath the root directory.
        for directory in subdirectories {
            self.index_directory_files(directory, prefix_length);
        }
    }

    // Helper method for populate.
    // Finds files for a particular directory, strips prefix_length leading
    // characters from their path, and adds them to the index entries vector.
    fn index_directory_files(&mut self, directory: Path, prefix_length: uint) {
        match fs::readdir(&directory) {
            Ok(entries) => {
                // Put all of the file-based Path entries into the index.
                for file in entries.iter().filter(|entry| entry.is_file()) {
                    // Make the file path relative to the index path by stripping it from its string.
                    let file_path = Path::new(file.as_str().unwrap().slice_from(prefix_length));

                    self.entries.push(file_path);
                }
            },
            Err(e) => (),
        }
    }
}

#[test]
fn new_creates_index_with_passed_path() {
    let path = "my path";
    let index = Index::new(path);

    // Get the index path as a string.
    let index_path = match index.path.as_str() {
        Some(value) => value,
        None => ""
    };

    assert_eq!(index_path, path);
}

#[test]
fn new_creates_index_with_empty_array() {
    let path = "my path";
    let index = Index::new(path);
    let empty_array: Vec<Path> = vec![];

    assert!(index.entries == empty_array);
}

#[test]
fn populate_adds_all_files_to_entries() {
    let path = "tests/sample";
    let index = &mut Index::new(path);
    let expected_array = vec![Path::new("root_file"), Path::new("directory/nested_file")];
    index.populate();

    assert!(index.entries == expected_array);
}
<|endoftext|>


<commit_before>//! combinators applying parsers in sequence

#[macro_use]
mod macros;

use internal::IResult;
use error::ParseError;

/// Gets an object from the first parser,
/// then gets another object from the second parser.
/// # Arguments
/// * `first` The first parser to apply.
/// * `second` The second parser to apply.
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
/// use nom::sequence::pair;
/// use nom::bytes::complete::tag;
/// # fn main() {
/// let first_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("abc")(s)
/// };
/// let second_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("efg")(s)
/// };
/// let parser = |s: &'static str| {
///   pair::<_, _, _, (_, ErrorKind), _, _>(first_parser, second_parser)(s)
/// };
///
/// assert_eq!(parser("abcefg"), Ok(("", ("abc", "efg"))));
/// assert_eq!(parser("abcefghij"), Ok(("hij", ("abc", "efg"))));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// # }
/// ```
pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, (O1, O2), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    second(input).map(|(i, o2)| (i, (o1, o2)))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn pairc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, (O1, O2), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  pair(first, second)(input)
}

/// Matches an object from the first parser and discard it,
/// then gets an object from the second parser.
/// # Arguments
/// * `first` The opening parser.
/// * `second` The second parser to get object.
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
/// use nom::sequence::preceded;
/// use nom::bytes::complete::tag;
/// # fn main() {
/// let first_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("abc")(s)
/// };
/// let second_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("efg")(s)
/// };
/// let parser = |s: &'static str| {
///   preceded::<_, _, _, (_, ErrorKind), _, _>(first_parser, second_parser)(s)
/// };
///
/// assert_eq!(parser("abcefg"), Ok(("", "efg")));
/// assert_eq!(parser("abcefghij"), Ok(("hij", "efg")));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// # }
/// ```
pub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  move |input: I| {
    let (input, _) = first(input)?;
    second(input)
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn precededc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  preceded(first, second)(input)
}

pub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O1, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    second(input).map(|(i, _)| (i, o1))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn terminatedc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O1, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  terminated(first, second)(input)
}

pub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult<I, (O1, O3), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    let (input, _) = sep(input)?;
    second(input).map(|(i, o2)| (i, (o1, o2)))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn separated_pairc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, (O1, O3), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  separated_pair(first, sep, second)(input)
}

pub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  move |input: I| {
    let (input, _) = first(input)?;
    let (input, o2) = sep(input)?;
    second(input).map(|(i, _)| (i, o2))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn delimitedc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  delimited(first, sep, second)(input)
}

/// helper trait for the tuple combinator
///
/// this trait is implemented for tuples of parsers of up to 21 elements
pub trait Tuple<I,O,E> {
  /// parses the input and returns a tuple of results of each parser
  fn parse(&self, input: I) -> IResult<I,O,E>;
}

macro_rules! tuple_trait(
  ($name1:ident $ty1:ident, $name2: ident $ty2:ident, $($name:ident $ty:ident),*) => (
    tuple_trait!(__impl $name1 $ty1, $name2 $ty2; $($name $ty),*);
  );
  (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident, $($name2:ident $ty2:ident),*) => (
    tuple_trait_impl!($($name $ty),+);
    tuple_trait!(__impl $($name $ty),+ , $name1 $ty1; $($name2 $ty2),*);
  );
  (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident) => (
    tuple_trait_impl!($($name $ty),+);
    tuple_trait_impl!($($name $ty),+, $name1 $ty1);
  );
);

macro_rules! tuple_trait_impl(
  ($($name:ident $ty: ident),+) => (
    impl<
      Input: Clone, $($ty),+ , Error: ParseError<Input>,
      $($name: Fn(Input) -> IResult<Input, $ty, Error>),+
    > Tuple<Input, ( $($ty),+ ), Error> for ( $($name),+ ) {

      fn parse(&self, input: Input) -> IResult<Input, ( $($ty),+ ), Error> {
        tuple_trait_inner!(0, self, input, (), $($name)+)

      }
    }
  );
);

macro_rules! tuple_trait_inner(
  ($it:tt, $self:expr, $input:expr, (), $head:ident $($id:ident)+) => ({
    let (i, o) = $self.$it($input.clone())?;

    succ!($it, tuple_trait_inner!($self, i, ( o ), $($id)+))
  });
  ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident $($id:ident)+) => ({
    let (i, o) = $self.$it($input.clone())?;

    succ!($it, tuple_trait_inner!($self, i, ($($parsed)* , o), $($id)+))
  });
  ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident) => ({
    let (i, o) = $self.$it($input.clone())?;

    Ok((i, ($($parsed)* , o)))
  });
);

tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ J, FnK K, FnL L,
  FnM M, FnN N, FnO O, FnP P, FnQ Q, FnR R, FnS S, FnT T, FnU U);

/// applies a tuple of parsers one by one and returns their results as a tuple
pub fn tuple<I: Clone, O, E: ParseError<I>, List: Tuple<I,O,E>>(l: List)  -> impl Fn(I) -> IResult<I, O, E> {
  move |i: I| {
    l.parse(i)
  }
}
<commit_msg>add example of terminated<commit_after>//! combinators applying parsers in sequence

#[macro_use]
mod macros;

use internal::IResult;
use error::ParseError;

/// Gets an object from the first parser,
/// then gets another object from the second parser.
/// # Arguments
/// * `first` The first parser to apply.
/// * `second` The second parser to apply.
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
/// use nom::sequence::pair;
/// use nom::bytes::complete::tag;
/// # fn main() {
/// let first_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("abc")(s)
/// };
/// let second_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("efg")(s)
/// };
/// let parser = |s: &'static str| {
///   pair::<_, _, _, (_, ErrorKind), _, _>(first_parser, second_parser)(s)
/// };
///
/// assert_eq!(parser("abcefg"), Ok(("", ("abc", "efg"))));
/// assert_eq!(parser("abcefghij"), Ok(("hij", ("abc", "efg"))));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// # }
/// ```
pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, (O1, O2), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    second(input).map(|(i, o2)| (i, (o1, o2)))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn pairc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, (O1, O2), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  pair(first, second)(input)
}

/// Matches an object from the first parser and discards it,
/// then gets an object from the second parser.
/// # Arguments
/// * `first` The opening parser.
/// * `second` The second parser to get object.
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
/// use nom::sequence::preceded;
/// use nom::bytes::complete::tag;
/// # fn main() {
/// let first_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("abc")(s)
/// };
/// let second_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("efg")(s)
/// };
/// let parser = |s: &'static str| {
///   preceded::<_, _, _, (_, ErrorKind), _, _>(first_parser, second_parser)(s)
/// };
///
/// assert_eq!(parser("abcefg"), Ok(("", "efg")));
/// assert_eq!(parser("abcefghij"), Ok(("hij", "efg")));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// # }
/// ```
pub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  move |input: I| {
    let (input, _) = first(input)?;
    second(input)
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn precededc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  preceded(first, second)(input)
}

/// Gets an object from the first parser,
/// then matches an object from the second parser and discards it.
/// # Arguments
/// * `first` The first parser to apply.
/// * `second` The second parser to match an object.
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
/// use nom::sequence::terminated;
/// use nom::bytes::complete::tag;
/// # fn main() {
/// let first_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("abc")(s)
/// };
/// let second_parser = |s: &'static str| {
///   tag::<_, _, (_, ErrorKind)>("efg")(s)
/// };
/// let parser = |s: &'static str| {
///   terminated::<_, _, _, (_, ErrorKind), _, _>(first_parser, second_parser)(s)
/// };
///
/// assert_eq!(parser("abcefg"), Ok(("", "abc")));
/// assert_eq!(parser("abcefghij"), Ok(("hij", "abc")));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// # }
/// ```
pub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O1, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    second(input).map(|(i, _)| (i, o1))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn terminatedc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O1, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
{
  terminated(first, second)(input)
}

pub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult<I, (O1, O3), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  move |input: I| {
    let (input, o1) = first(input)?;
    let (input, _) = sep(input)?;
    second(input).map(|(i, o2)| (i, (o1, o2)))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn separated_pairc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, (O1, O3), E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  separated_pair(first, sep, second)(input)
}

pub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  move |input: I| {
    let (input, _) = first(input)?;
    let (input, o2) = sep(input)?;
    second(input).map(|(i, _)| (i, o2))
  }
}

// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn delimitedc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, O2, E>
where
  F: Fn(I) -> IResult<I, O1, E>,
  G: Fn(I) -> IResult<I, O2, E>,
  H: Fn(I) -> IResult<I, O3, E>,
{
  delimited(first, sep, second)(input)
}

/// helper trait for the tuple combinator
///
/// this trait is implemented for tuples of parsers of up to 21 elements
pub trait Tuple<I,O,E> {
  /// parses the input and returns a tuple of results of each parser
  fn parse(&self, input: I) -> IResult<I,O,E>;
}

macro_rules! tuple_trait(
  ($name1:ident $ty1:ident, $name2: ident $ty2:ident, $($name:ident $ty:ident),*) => (
    tuple_trait!(__impl $name1 $ty1, $name2 $ty2; $($name $ty),*);
  );
  (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident, $($name2:ident $ty2:ident),*) => (
    tuple_trait_impl!($($name $ty),+);
    tuple_trait!(__impl $($name $ty),+ , $name1 $ty1; $($name2 $ty2),*);
  );
  (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident) => (
    tuple_trait_impl!($($name $ty),+);
    tuple_trait_impl!($($name $ty),+, $name1 $ty1);
  );
);

macro_rules! tuple_trait_impl(
  ($($name:ident $ty: ident),+) => (
    impl<
      Input: Clone, $($ty),+ , Error: ParseError<Input>,
      $($name: Fn(Input) -> IResult<Input, $ty, Error>),+
    > Tuple<Input, ( $($ty),+ ), Error> for ( $($name),+ ) {

      fn parse(&self, input: Input) -> IResult<Input, ( $($ty),+ ), Error> {
        tuple_trait_inner!(0, self, input, (), $($name)+)

      }
    }
  );
);

macro_rules! tuple_trait_inner(
  ($it:tt, $self:expr, $input:expr, (), $head:ident $($id:ident)+) => ({
    let (i, o) = $self.$it($input.clone())?;

    succ!($it, tuple_trait_inner!($self, i, ( o ), $($id)+))
  });
  ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident $($id:ident)+) => ({
    let (i, o) = $self.$it($input.clone())?;

    succ!($it, tuple_trait_inner!($self, i, ($($parsed)* , o), $($id)+))
  });
  ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident) => ({
    let (i, o) = $self.$it($input.clone())?;

    Ok((i, ($($parsed)* , o)))
  });
);

tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ J, FnK K, FnL L,
  FnM M, FnN N, FnO O, FnP P, FnQ Q, FnR R, FnS S, FnT T, FnU U);

/// applies a tuple of parsers one by one and returns their results as a tuple
pub fn tuple<I: Clone, O, E: ParseError<I>, List: Tuple<I,O,E>>(l: List)  -> impl Fn(I) -> IResult<I, O, E> {
  move |i: I| {
    l.parse(i)
  }
}
<|endoftext|>


<commit_before>use tokenize::tokenize;

struct NGram<'a> {
  text: &'a str,
  n: uint,
  pad: &'a str
}

impl<'a> NGram<'a> {
  fn calculate(&self) -> Vec<Vec<&'a str>> {

    let mut tokenized_sequence = tokenize(self.text);
    tokenized_sequence.shrink_to_fit();

    let count = tokenized_sequence.len() - self.n + 1;

    let mut ngram_result = Vec::new();

    //left-padding
    if self.pad != "" {
      for i in range(1, self.n) {
        let num_blanks = self.n - i;
        let mut this_sequence = Vec::new();
        for _j in range(0, num_blanks) {
          this_sequence.push(self.pad);
        }
        let sl = tokenized_sequence.slice(0, self.n-num_blanks);
        this_sequence.push_all(sl);
        ngram_result.push(this_sequence);
      }
    }

    //Fill the rest of the ngram
    for i in range(0, count) {
      let a = tokenized_sequence.slice(i,i+self.n);
      let sl = a.to_vec();
      ngram_result.push(sl);
    }

    //right-padding
    if self.pad != "" {
      for i in range(1, self.n) {
        let num_blanks = i;
        let last_entry = tokenized_sequence.len();
        let mut tc = Vec::new();
        tc.push_all(tokenized_sequence.slice(last_entry - num_blanks, last_entry));
        for _j in range(0, num_blanks) {
          tc.push(self.pad);
        }
        ngram_result.push(tc);
      }
    }
    ngram_result
  }
}

pub fn get_ngram<'a>(this_text: &'a str, this_n: uint) -> Vec<Vec<&'a str>> {
  let ng = NGram { text: this_text, n: this_n, pad: "" };
  ng.calculate()
}

pub fn get_ngram_with_padding<'a>(this_text: &'a str, this_n: uint, this_padding: &'a str) -> Vec<Vec<&'a str>> {
  let ng = NGram { text: this_text, n: this_n, pad: this_padding };
  ng.calculate()
}<commit_msg>Fixed issues.<commit_after>use tokenize::tokenize;

struct NGram<'a> {
  text: &'a str,
  n: usize,
  pad: &'a str
}

impl<'a> NGram<'a> {
  fn calculate(&self) -> Vec<Vec<&'a str>> {
    let mut tokenized_sequence = tokenize(self.text);
    tokenized_sequence.shrink_to_fit();

    let count = tokenized_sequence.len() - self.n + 1;

    let mut ngram_result = Vec::new();

    //left-padding
    if !self.pad.is_empty() {
      for i in 1..self.n {
        let num_blanks = self.n - i;
        let mut this_sequence = Vec::new();
        for _ in 0..num_blanks {
          this_sequence.push(self.pad);
        }
        let sl = &tokenized_sequence[0 .. (self.n - num_blanks)];
        this_sequence.push_all(sl);
        ngram_result.push(this_sequence);
      }
    }

    //Fill the rest of the ngram
    for i in 0..count {
      let a = tokenized_sequence.slice(i, i + self.n);
      let sl = a.to_vec();
      ngram_result.push(sl);
    }

    //right-padding
    if !self.pad.is_empty() {
      for i in 1..self.n {
        let num_blanks = i;
        let last_entry = tokenized_sequence.len();
        let mut tc = Vec::new();
        tc.push_all(tokenized_sequence[(last_entry - num_blanks) .. last_entry)];
        for _ in 0..num_blanks {
          tc.push(self.pad);
        }
        ngram_result.push(tc);
      }
    }
    ngram_result
  }
}

pub fn get_ngram<'a>(this_text: &'a str, this_n: usize) -> Vec<Vec<&'a str>> {
  let ng = NGram { text: this_text, n: this_n, pad: "" };
  ng.calculate()
}

pub fn get_ngram_with_padding<'a>(this_text: &'a str, this_n: usize, this_padding: &'a str) -> Vec<Vec<&'a str>> {
  let ng = NGram { text: this_text, n: this_n, pad: this_padding };
  ng.calculate()
}
<|endoftext|>


<commit_before>extern crate varlink;

use std::io;
use std::io::prelude::*;
use varlink::parser::Varlink;
use std::process::exit;
use std::path::Path;
use std::fs::File;
use std::env;
use std::io::{Error as IOError, ErrorKind};
use std::error::Error;
use std::result::Result;
use varlink::parser::VType;

trait MainReturn {
    fn into_error_code(self) -> i32;
}

impl<E: Error> MainReturn for Result<(), E> {
    fn into_error_code(self) -> i32 {
        if let Err(e) = self {
            write!(io::stderr(), "{}\n", e).unwrap();
            1
        } else {
            0
        }
    }
}

fn do_main() -> io::Result<()> {
    let mut buffer = String::new();

    let args: Vec<_> = env::args().collect();
    match args.len() {
        0 => io::stdin().read_to_string(&mut buffer)?,
        _ => {
            File::open(Path::new(&args[1]))?
                .read_to_string(&mut buffer)?
        }
    };

    let vr = Varlink::from_string(&buffer);

    if let Err(e) = vr {
        println!("{}", e);
        exit(1);
    }

    let v = vr.unwrap();

    for t in v.interface.typedefs.values() {
        println!("#[derive(Serialize, Deserialize, Debug)]");
        println!("pub struct {} {{", t.name);
        for e in t.vstruct.elts.iter() {
            let v = &e.vtypes[0];
            println!("    pub {} : {};", e.name, match v.vtype {
                VType::Bool(_) => "bool",
                VType::Int(_) => "i64",
                VType::Float(_) => "f64",
                VType::VString(_) => "String",
                VType::VData(_) => "String",
                VType::VTypename(ref v) => v,
                VType::VStruct(_) => return Err(IOError::new(ErrorKind::Other, "oh no!")),

            });
        }
        println!("}}\n");
    }

    Ok(())
}

fn main() {
    exit(do_main().into_error_code());
}
<commit_msg>more code generation<commit_after>extern crate varlink;

use std::io;
use std::io::prelude::*;
use varlink::parser::Varlink;
use std::process::exit;
use std::path::Path;
use std::fs::File;
use std::env;

use std::io::Error as IOError;
use std::error::Error;

use std::result::Result;
use varlink::parser::*;
use std::fmt;

trait MainReturn {
    fn into_error_code(self) -> i32;
}

impl<E: Error> MainReturn for Result<(), E> {
    fn into_error_code(self) -> i32 {
        if let Err(e) = self {
            write!(io::stderr(), "{}\n", e).unwrap();
            1
        } else {
            0
        }
    }
}

trait ToRust {
    fn to_rust(&self) -> Result<String, ToRustError>;
}

#[derive(Debug)]
enum ToRustError {
    BadStruct,
    IoError(IOError),
}

impl Error for ToRustError {
    fn description(&self) -> &str {
        match *self {
            ToRustError::BadStruct => "Anonymous struct",
            ToRustError::IoError(_) => "an I/O error occurred",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match self {
            &ToRustError::IoError(ref err) => Some(&*err as &Error),
            _ => None,
        }
    }
}

impl From<IOError> for ToRustError {
    fn from(err: IOError) -> ToRustError {
        ToRustError::IoError(err)
    }
}

impl fmt::Display for ToRustError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())?;
        Ok(())
    }
}

impl<'a> ToRust for VType<'a> {
    fn to_rust(&self) -> Result<String, ToRustError> {
        match *self {
            VType::Bool(_) => Ok("bool".into()),
            VType::Int(_) => Ok("i64".into()),
            VType::Float(_) => Ok("f64".into()),
            VType::VString(_) => Ok("String".into()),
            VType::VData(_) => Ok("String".into()),
            VType::VTypename(v) => Ok(v.into()),
            VType::VStruct(_) => Err(ToRustError::BadStruct),
        }
    }
}

impl<'a> ToRust for VTypeExt<'a> {
    fn to_rust(&self) -> Result<String, ToRustError> {
        let v = self.vtype.to_rust()?;

        match self.isarray {
            Some(n) => {
                match n {
                    0 => Ok(format!("Vec<{}>", v).into()),
                    _ => Ok(format!("[{}; {}]", v, n).into()),
                }
            }
            None => Ok(v.into()),
        }
    }
}

impl<'a> ToRust for Interface<'a> {
    fn to_rust(&self) -> Result<String, ToRustError> {
        let mut out: String = "".to_owned();

        for t in self.typedefs.values() {
            out += "#[derive(Serialize, Deserialize, Debug)]\n";
            out += format!("pub struct {} {{\n", t.name).as_ref();
            for e in &t.vstruct.elts {
                let v = &e.vtypes[0];
                out += format!("    pub {} : {},\n", e.name, v.to_rust()?).as_ref();
            }
            out += "}\n\n";
        }

        for t in self.methods.values() {
            out += "#[derive(Serialize, Deserialize, Debug)]\n";
            out += format!("pub struct {}Reply {{\n", t.name).as_ref();
            for e in &t.output.elts {
                let v = &e.vtypes[0];
                out += format!("    pub {} : {},\n", e.name, v.to_rust()?).as_ref();
            }
            out += "}\n\n";

            if t.input.elts.len() > 0 {
                out += "#[derive(Serialize, Deserialize, Debug)]\n";
                out += format!("pub struct {}Args {{\n", t.name).as_ref();
                for e in &t.input.elts {
                    let v = &e.vtypes[0];
                    out += format!("    pub {} : {},\n", e.name, v.to_rust()?).as_ref();
                }
                out += "}\n\n";
            }
        }
        Ok(out)
    }
}

fn do_main() -> Result<(), ToRustError> {
    let mut buffer = String::new();

    let args: Vec<_> = env::args().collect();
    match args.len() {
        0 => io::stdin().read_to_string(&mut buffer)?,
        _ => {
            File::open(Path::new(&args[1]))?
                .read_to_string(&mut buffer)?
        }
    };

    let vr = Varlink::from_string(&buffer);

    if let Err(e) = vr {
        println!("{}", e);
        exit(1);
    }

    println!("{}", vr.unwrap().interface.to_rust()?);

    Ok(())
}

fn main() {
    exit(do_main().into_error_code());
}
<|endoftext|>