<commit_before>use sozu_command::config::LoadBalancingAlgorithms;
use std::net::SocketAddr;

#[derive(StructOpt, PartialEq, Debug)]
pub struct App {
  #[structopt(short="c", long = "config", help = "Sets a custom config file")]
  pub config: String,
  #[structopt(short="t", long = "timeout", help = "Sets a custom timeout for commands (in milliseconds). 0 disables the timeout")]
  pub timeout: Option<u64>,
  #[structopt(subcommand)]
  pub cmd: SubCmd,
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum SubCmd {
  #[structopt(name = "shutdown", about = "shuts down the proxy")]
  Shutdown {
    #[structopt(long = "hard", help = "do not wait for connections to finish")]
    hard: bool,
    #[structopt(short = "w", long = "worker", help = "shuts down the worker with this id")]
    worker: Option<u32>,
  },
  #[structopt(name = "upgrade", about = "upgrade the proxy")]
  Upgrade {
    #[structopt(short = "w", long = "worker", help = "Upgrade the worker with this id")]
    worker: Option<u32>,
  },
  #[structopt(name = "status", about = "gets information on the running workers")]
  Status {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool
  },
  #[structopt(name = "metrics", about = "gets statistics on the master and its workers")]
  Metrics {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool
  },
  #[structopt(name = "logging", about = "change logging level")]
  Logging {
    #[structopt(short = "l", long = "level", help = "change logging level")]
    level: String
  },
  #[structopt(name = "state", about = "state management")]
  State {
    #[structopt(subcommand)]
    cmd: StateCmd,
  },
  #[structopt(name = "application", about = "application management")]
  Application {
    #[structopt(subcommand)]
    cmd: ApplicationCmd,
  },
  #[structopt(name = "backend", about = "backend management")]
  Backend {
    #[structopt(subcommand)]
    cmd: BackendCmd,
  },
  #[structopt(name = "frontend", about = "frontend management")]
  Frontend {
    #[structopt(subcommand)]
    cmd: FrontendCmd,
  },
  #[structopt(name = "certificate", about = "certificate management")]
  Certificate {
    #[structopt(subcommand)]
    cmd: CertificateCmd,
  },
  #[structopt(name = "query", about = "configuration state verification")]
  Query {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool,
    #[structopt(subcommand)]
    cmd: QueryCmd,
  },
  #[structopt(name = "config", about = "configuration file management")]
  Config {
    #[structopt(subcommand)]
    cmd: ConfigCmd
  }
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum StateCmd {
  #[structopt(name = "save", about = "Save state to that file")]
  Save {
    #[structopt(short = "f", long = "file")]
    file: String,
  },
  #[structopt(name = "load", about = "Load state from that file")]
  Load {
    #[structopt(short = "f", long = "file")]
    file: String,
  },
  #[structopt(name = "dump")]
  Dump {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum ApplicationCmd {
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "i", long = "id")]
    id: String,
  },
  #[structopt(name = "add")]
  Add{
    #[structopt(short = "i", long = "id")]
    id: String,
    #[structopt(short = "s", long = "sticky-session")]
    sticky_session: bool,
    #[structopt(short = "h", long = "https-redirect")]
    https_redirect: bool,
    #[structopt(long = "send-proxy", help = "Enforces use of the PROXY protocol version 2 over any connection established to this server.")]
    send_proxy: bool,
    #[structopt(long = "expect-proxy", help = "Configures the client-facing connection to receive a PROXY protocol header version 2")]
    expect_proxy: bool,
    #[structopt(long = "load-balancing-policy", help = "Configures the load balancing policy")]
    load_balancing_policy: LoadBalancingAlgorithms,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum BackendCmd {
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "i", long = "id")]
    id: String,
    #[structopt(long = "backend-id")]
    backend_id: String,
    #[structopt(short = "a", long = "address", help = "server address, format: IP:port")]
    address: SocketAddr,
  },
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "i", long = "id")]
    id: String,
    #[structopt(long = "backend-id")]
    backend_id: String,
    #[structopt(short = "a", long = "address", help = "server address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "s", long = "sticky-id", help = "value for the sticky session cookie")]
    sticky_id: Option<String>,
    #[structopt(short = "b", long = "backup", help = "set backend as a backup backend")]
    backup: Option<bool>,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum FrontendCmd {
  #[structopt(name = "http", about = "HTTP frontend management")]
  Http {
    #[structopt(subcommand)]
    cmd: HttpFrontendCmd,
  },
  #[structopt(name = "https", about = "HTTPS frontend management")]
  Https {
    #[structopt(subcommand)]
    cmd: HttpFrontendCmd,
  },
  #[structopt(name = "tcp", about = "TCP frontend management")]
  Tcp {
    #[structopt(subcommand)]
    cmd: TcpFrontendCmd,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum HttpFrontendCmd {
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "host", long = "hostname")]
    hostname: String,
    #[structopt(short = "p", long = "path", help="URL prefix of the frontend")]
    path_begin: Option<String>,
  },
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "host", long = "hostname")]
    hostname: String,
    #[structopt(short = "p", long = "path", help="URL prefix of the frontend")]
    path_begin: Option<String>,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum TcpFrontendCmd {
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
  },
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum CertificateCmd {
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "a", long = "address", help = "listener address, format: IP:port")]
    address: SocketAddr,
    #[structopt(long = "certificate", help = "path to the certificate")]
    certificate: String,
    #[structopt(long = "certificate-chain", help = "path to the certificate chain")]
    chain: String,
    #[structopt(long = "key", help = "path to the key")]
    key: String,
  },
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "a", long = "address", help = "listener address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "cert", long = "certificate", help = "path to the certificate")]
    certificate: String,
  },
  #[structopt(name = "replace")]
  Replace {
    #[structopt(short = "a", long = "address", help = "listener address, format: IP:port")]
    address: SocketAddr,
    #[structopt(long = "new-certificate", help = "path to the new certificate")]
    certificate: String,
    #[structopt(long = "new-certificate-chain", help = "path to the new certificate chain")]
    chain: String,
    #[structopt(long = "new-key", help = "path to the new key")]
    key: String,
    #[structopt(short = "old-cert", long = "old-certificate", help = "path to the old certificate")]
    old_certificate: String,
  }
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum QueryCmd {
  #[structopt(name = "applications")]
  Applications {
    #[structopt(short = "i", long="id", help="application identifier")]
    id: Option<String>,
    #[structopt(short = "d", long="domain", help="application domain name")]
    domain: Option<String>
  }
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum ConfigCmd {
  #[structopt(name = "check", about = "check configuration file syntax and exit")]
  Check {}
}
<commit_msg>add more info to command line options<commit_after>use sozu_command::config::LoadBalancingAlgorithms;
use std::net::SocketAddr;

#[derive(StructOpt, PartialEq, Debug)]
pub struct App {
  #[structopt(short="c", long = "config", help = "Sets a custom config file")]
  pub config: String,
  #[structopt(short="t", long = "timeout", help = "Sets a custom timeout for commands (in milliseconds). 0 disables the timeout")]
  pub timeout: Option<u64>,
  #[structopt(subcommand)]
  pub cmd: SubCmd,
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum SubCmd {
  #[structopt(name = "shutdown", about = "shuts down the proxy")]
  Shutdown {
    #[structopt(long = "hard", help = "do not wait for connections to finish")]
    hard: bool,
    #[structopt(short = "w", long = "worker", help = "shuts down the worker with this id")]
    worker: Option<u32>,
  },
  #[structopt(name = "upgrade", about = "upgrade the proxy")]
  Upgrade {
    #[structopt(short = "w", long = "worker", help = "Upgrade the worker with this id")]
    worker: Option<u32>,
  },
  #[structopt(name = "status", about = "gets information on the running workers")]
  Status {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool
  },
  #[structopt(name = "metrics", about = "gets statistics on the master and its workers")]
  Metrics {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool
  },
  #[structopt(name = "logging", about = "change logging level")]
  Logging {
    #[structopt(short = "l", long = "level", help = "change logging level")]
    level: String
  },
  #[structopt(name = "state", about = "state management")]
  State {
    #[structopt(subcommand)]
    cmd: StateCmd,
  },
  #[structopt(name = "application", about = "application management")]
  Application {
    #[structopt(subcommand)]
    cmd: ApplicationCmd,
  },
  #[structopt(name = "backend", about = "backend management")]
  Backend {
    #[structopt(subcommand)]
    cmd: BackendCmd,
  },
  #[structopt(name = "frontend", about = "frontend management")]
  Frontend {
    #[structopt(subcommand)]
    cmd: FrontendCmd,
  },
  #[structopt(name = "certificate", about = "certificate management")]
  Certificate {
    #[structopt(subcommand)]
    cmd: CertificateCmd,
  },
  #[structopt(name = "query", about = "configuration state verification")]
  Query {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool,
    #[structopt(subcommand)]
    cmd: QueryCmd,
  },
  #[structopt(name = "config", about = "configuration file management")]
  Config {
    #[structopt(subcommand)]
    cmd: ConfigCmd
  }
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum StateCmd {
  #[structopt(name = "save", about = "Save state to that file")]
  Save {
    #[structopt(short = "f", long = "file")]
    file: String,
  },
  #[structopt(name = "load", about = "Load state from that file")]
  Load {
    #[structopt(short = "f", long = "file")]
    file: String,
  },
  #[structopt(name = "dump")]
  Dump {
    #[structopt(short = "j", long = "json", help = "Print the command result in JSON format")]
    json: bool
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum ApplicationCmd {
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "i", long = "id")]
    id: String,
  },
  #[structopt(name = "add")]
  Add{
    #[structopt(short = "i", long = "id")]
    id: String,
    #[structopt(short = "s", long = "sticky-session")]
    sticky_session: bool,
    #[structopt(short = "h", long = "https-redirect")]
    https_redirect: bool,
    #[structopt(long = "send-proxy", help = "Enforces use of the PROXY protocol version 2 over any connection established to this server.")]
    send_proxy: bool,
    #[structopt(long = "expect-proxy", help = "Configures the client-facing connection to receive a PROXY protocol header version 2")]
    expect_proxy: bool,
    #[structopt(long = "load-balancing-policy", help = "Configures the load balancing policy. Possible values are 'roundrobin', 'random' or 'leastconnections'")]
    load_balancing_policy: LoadBalancingAlgorithms,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum BackendCmd {
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "i", long = "id")]
    id: String,
    #[structopt(long = "backend-id")]
    backend_id: String,
    #[structopt(short = "a", long = "address", help = "server address, format: IP:port")]
    address: SocketAddr,
  },
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "i", long = "id")]
    id: String,
    #[structopt(long = "backend-id")]
    backend_id: String,
    #[structopt(short = "a", long = "address", help = "server address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "s", long = "sticky-id", help = "value for the sticky session cookie")]
    sticky_id: Option<String>,
    #[structopt(short = "b", long = "backup", help = "set backend as a backup backend")]
    backup: Option<bool>,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum FrontendCmd {
  #[structopt(name = "http", about = "HTTP frontend management")]
  Http {
    #[structopt(subcommand)]
    cmd: HttpFrontendCmd,
  },
  #[structopt(name = "https", about = "HTTPS frontend management")]
  Https {
    #[structopt(subcommand)]
    cmd: HttpFrontendCmd,
  },
  #[structopt(name = "tcp", about = "TCP frontend management")]
  Tcp {
    #[structopt(subcommand)]
    cmd: TcpFrontendCmd,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum HttpFrontendCmd {
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "host", long = "hostname")]
    hostname: String,
    #[structopt(short = "p", long = "path", help="URL prefix of the frontend")]
    path_begin: Option<String>,
  },
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "host", long = "hostname")]
    hostname: String,
    #[structopt(short = "p", long = "path", help="URL prefix of the frontend")]
    path_begin: Option<String>,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum TcpFrontendCmd {
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
  },
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "i", long = "id", help = "app id of the frontend")]
    id: String,
    #[structopt(short = "a", long = "address", help = "frontend address, format: IP:port")]
    address: SocketAddr,
  },
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum CertificateCmd {
  #[structopt(name = "add")]
  Add {
    #[structopt(short = "a", long = "address", help = "listener address, format: IP:port")]
    address: SocketAddr,
    #[structopt(long = "certificate", help = "path to the certificate")]
    certificate: String,
    #[structopt(long = "certificate-chain", help = "path to the certificate chain")]
    chain: String,
    #[structopt(long = "key", help = "path to the key")]
    key: String,
  },
  #[structopt(name = "remove")]
  Remove {
    #[structopt(short = "a", long = "address", help = "listener address, format: IP:port")]
    address: SocketAddr,
    #[structopt(short = "cert", long = "certificate", help = "path to the certificate")]
    certificate: String,
  },
  #[structopt(name = "replace")]
  Replace {
    #[structopt(short = "a", long = "address", help = "listener address, format: IP:port")]
    address: SocketAddr,
    #[structopt(long = "new-certificate", help = "path to the new certificate")]
    certificate: String,
    #[structopt(long = "new-certificate-chain", help = "path to the new certificate chain")]
    chain: String,
    #[structopt(long = "new-key", help = "path to the new key")]
    key: String,
    #[structopt(short = "old-cert", long = "old-certificate", help = "path to the old certificate")]
    old_certificate: String,
  }
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum QueryCmd {
  #[structopt(name = "applications")]
  Applications {
    #[structopt(short = "i", long="id", help="application identifier")]
    id: Option<String>,
    #[structopt(short = "d", long="domain", help="application domain name")]
    domain: Option<String>
  }
}

#[derive(StructOpt, PartialEq, Debug)]
pub enum ConfigCmd {
  #[structopt(name = "check", about = "check configuration file syntax and exit")]
  Check {}
}
<|endoftext|>


<commit_before>//! Using MIDI, verify that the user is able to play a given exercise correctly.  The question
//! should be enough of a description to uniquely describe what should be played.  The answer
//! should be a parseable description of what needs to be played.
//!
//! The answer should be a JSON description of what to play, of one of the following types:
//!
//! { "type": "scale", "base": "C♯", "intervals": "WWHWWWH",
//!   "hands": 1, "octaves": 2, "style": "updown" }
//!
//! This describes a scale.  The base is the first note of the scale.  Sharps and flags can either
//! be "#" and "b" or Unicode characters "♯", and "♭".  The intervals describe the intervals
//! between each note.  Valid characters are 'H' for a half step, 'W' for a whole step, 'm' for a
//! minor third, 'M' for a major third, and '4' for a fourth.  It will be checked that the
//! intervals cover a full octabe.  Hands describes how many hands should be playing the exercise,
//! and octaves are how many octaves to play.  The currently only supported style is "updown",
//! which requires the scale be played from base to base, for the given number of octaves and then
//! back down.  Scales can be played starting in any octave.
//!
//! { "type": "voicing", "chords": [
//!    { "base": "D", "notes": [ "3", "7", "9", "5" },
//!    { "base": "G", "notes": [ "7", "3", "#9", "#5" },
//!    { "base": "C", "notes": [ "3", "7", "9", "5", "11" } ] }
//!
//! This describes a voicing exercise, which is a series of chords to be played.  Each chord has a
//! base, which may or may not actually be played.  The notes in the chord are described in musical
//! notation (again with text or Unicode sharp/flat indicators).  The chord will be built using the
//! next note of the given function.  The octave will be chosen so that the lowest non-root note
//! will be between F#-F surrounding middle C.

#![deny(missing_docs)]

extern crate editdistancewf;
extern crate portmidi;
extern crate timelearn;
#[macro_use] extern crate lazy_static;
extern crate serde;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate serde_json;

use portmidi::{PortMidi, InputPort};
use serde_json::{Value};
use std::error;
use std::io::{self, Write};
use std::result;
use std::thread;
use std::time::Duration;
pub use timelearn::{Problem, Status, User};

mod note;
use note::Note;

mod scales;
use scales::{Scale, ScaleSeq};

/// Just box the errors for now.  TODO: Use a proper error type.
pub type Result<T> = result::Result<T, Box<error::Error + Send + Sync>>;

/// A learner based on playing the exercises on a MIDI device.
pub struct MidiLearn {
    input: InputPort,
}

impl MidiLearn {
    /// Construct a new MIDI learning, using the default MIDI port.  Invokes `f` with the
    /// MidiLearn.
    pub fn with_new<F, R>(f: F) -> Result<R>
        where F: FnOnce(&mut MidiLearn) -> R
    {
        let pm = PortMidi::new()?;
        let input = pm.default_input_port(4096)?;
        let mut learn = MidiLearn {
            input: input,
        };
        let result = f(&mut learn);
        Ok(result)
    }

}

impl User for MidiLearn {
    /// Practice a single exercise.  Waits for the user to play the exercise, and then returns a
    /// status indicating how well it was played.
    fn single(&mut self, word: &Problem) -> Result<Status> {
        println!("Play: {}", word.question);

        let json: Value = serde_json::from_str(&word.answer)?;
        // println!("Json: {:?}, {:?}", json, json["typr"]);
        if is_type(&json, "scale") {
            let scale: Scale = serde_json::from_value(json)?;

            let mut seq = ScaleSeq::from_scale(&scale)?;
            // println!("scale: {:?}", seq);

            self.drain()?;
            let user = self.record_scale()?;
            // println!("Played: {:?}", user);
            if seq.adjust_octave(&user) {
                // println!("First note good: {:?}", seq);
                let diff_count = seq.differences(&user);
                println!("There are {} differences", diff_count);
                if diff_count <= 3 {
                    Ok(Status::Continue(4 - diff_count as u8))
                } else {
                    Ok(Status::Continue(1))
                }
            } else {
                println!("First note mismatch, stopping");
                Ok(Status::Stopped)
            }

        } else {
            return Err(format!("Invalid type: {:?}", json["type"].as_str()).into());
        }
    }
}

impl MidiLearn {
    /// Drain any queued midi events.
    fn drain(&mut self) -> Result<()> {
        loop {
            match self.input.read()? {
                Some(_) => (),
                None => break,
            }
        }
        Ok(())
    }

    /// Record the user playing a scale.  Consider the scale done after a small pause of no
    /// playing.
    fn record_scale(&mut self) -> Result<Vec<Note>> {
        let mut notes = vec![];
        let mut idle_count = 0;
        loop {
            match self.input.read()? {
                Some(ev) => {
                    // We only care about note down events here.
                    if ev.message.status & 0xf0 == 0x80 {
                        // println!("Got notes: {:?}", ev);
                        notes.push(Note(ev.message.data1));
                        idle_count = 0;
                    }
                },
                None => {
                    idle_count += 1;
                    if notes.is_empty() {
                        idle_count = 0;
                    }
                    if idle_count >= 3 {
                        println!("Timing out");
                        break;
                    }
                    thread::sleep(Duration::new(1, 0));
                }
            }
        }
        Ok(notes)
    }
}

impl Write for MidiLearn {
    fn flush(&mut self) -> io::Result<()> {
        io::stdout().flush()
    }

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        io::stdout().write(buf)
    }
}

// Determine if the json has a the given type.
fn is_type(json: &Value, t: &str) -> bool {
    json["type"] == json!(t)
}
<commit_msg>midilearn: Reduce scale input timeout<commit_after>//! Using MIDI, verify that the user is able to play a given exercise correctly.  The question
//! should be enough of a description to uniquely describe what should be played.  The answer
//! should be a parseable description of what needs to be played.
//!
//! The answer should be a JSON description of what to play, of one of the following types:
//!
//! { "type": "scale", "base": "C♯", "intervals": "WWHWWWH",
//!   "hands": 1, "octaves": 2, "style": "updown" }
//!
//! This describes a scale.  The base is the first note of the scale.  Sharps and flags can either
//! be "#" and "b" or Unicode characters "♯", and "♭".  The intervals describe the intervals
//! between each note.  Valid characters are 'H' for a half step, 'W' for a whole step, 'm' for a
//! minor third, 'M' for a major third, and '4' for a fourth.  It will be checked that the
//! intervals cover a full octabe.  Hands describes how many hands should be playing the exercise,
//! and octaves are how many octaves to play.  The currently only supported style is "updown",
//! which requires the scale be played from base to base, for the given number of octaves and then
//! back down.  Scales can be played starting in any octave.
//!
//! { "type": "voicing", "chords": [
//!    { "base": "D", "notes": [ "3", "7", "9", "5" },
//!    { "base": "G", "notes": [ "7", "3", "#9", "#5" },
//!    { "base": "C", "notes": [ "3", "7", "9", "5", "11" } ] }
//!
//! This describes a voicing exercise, which is a series of chords to be played.  Each chord has a
//! base, which may or may not actually be played.  The notes in the chord are described in musical
//! notation (again with text or Unicode sharp/flat indicators).  The chord will be built using the
//! next note of the given function.  The octave will be chosen so that the lowest non-root note
//! will be between F#-F surrounding middle C.

#![deny(missing_docs)]

extern crate editdistancewf;
extern crate portmidi;
extern crate timelearn;
#[macro_use] extern crate lazy_static;
extern crate serde;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate serde_json;

use portmidi::{PortMidi, InputPort};
use serde_json::{Value};
use std::error;
use std::io::{self, Write};
use std::result;
use std::thread;
use std::time::Duration;
pub use timelearn::{Problem, Status, User};

mod note;
use note::Note;

mod scales;
use scales::{Scale, ScaleSeq};

/// Just box the errors for now.  TODO: Use a proper error type.
pub type Result<T> = result::Result<T, Box<error::Error + Send + Sync>>;

/// A learner based on playing the exercises on a MIDI device.
pub struct MidiLearn {
    input: InputPort,
}

impl MidiLearn {
    /// Construct a new MIDI learning, using the default MIDI port.  Invokes `f` with the
    /// MidiLearn.
    pub fn with_new<F, R>(f: F) -> Result<R>
        where F: FnOnce(&mut MidiLearn) -> R
    {
        let pm = PortMidi::new()?;
        let input = pm.default_input_port(4096)?;
        let mut learn = MidiLearn {
            input: input,
        };
        let result = f(&mut learn);
        Ok(result)
    }

}

impl User for MidiLearn {
    /// Practice a single exercise.  Waits for the user to play the exercise, and then returns a
    /// status indicating how well it was played.
    fn single(&mut self, word: &Problem) -> Result<Status> {
        println!("Play: {}", word.question);

        let json: Value = serde_json::from_str(&word.answer)?;
        // println!("Json: {:?}, {:?}", json, json["typr"]);
        if is_type(&json, "scale") {
            let scale: Scale = serde_json::from_value(json)?;

            let mut seq = ScaleSeq::from_scale(&scale)?;
            // println!("scale: {:?}", seq);

            self.drain()?;
            let user = self.record_scale()?;
            // println!("Played: {:?}", user);
            if seq.adjust_octave(&user) {
                // println!("First note good: {:?}", seq);
                let diff_count = seq.differences(&user);
                println!("There are {} differences", diff_count);
                if diff_count <= 3 {
                    Ok(Status::Continue(4 - diff_count as u8))
                } else {
                    Ok(Status::Continue(1))
                }
            } else {
                println!("First note mismatch, stopping");
                Ok(Status::Stopped)
            }

        } else {
            return Err(format!("Invalid type: {:?}", json["type"].as_str()).into());
        }
    }
}

impl MidiLearn {
    /// Drain any queued midi events.
    fn drain(&mut self) -> Result<()> {
        loop {
            match self.input.read()? {
                Some(_) => (),
                None => break,
            }
        }
        Ok(())
    }

    /// Record the user playing a scale.  Consider the scale done after a small pause of no
    /// playing.
    fn record_scale(&mut self) -> Result<Vec<Note>> {
        let mut notes = vec![];
        let mut idle_count = 0;
        loop {
            match self.input.read()? {
                Some(ev) => {
                    // We only care about note down events here.
                    if ev.message.status & 0xf0 == 0x80 {
                        // println!("Got notes: {:?}", ev);
                        notes.push(Note(ev.message.data1));
                        idle_count = 0;
                    }
                },
                None => {
                    idle_count += 1;
                    if notes.is_empty() {
                        idle_count = 0;
                    }
                    if idle_count >= 6 {
                        println!("Timing out");
                        break;
                    }
                    thread::sleep(Duration::from_millis(250));
                }
            }
        }
        Ok(notes)
    }
}

impl Write for MidiLearn {
    fn flush(&mut self) -> io::Result<()> {
        io::stdout().flush()
    }

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        io::stdout().write(buf)
    }
}

// Determine if the json has a the given type.
fn is_type(json: &Value, t: &str) -> bool {
    json["type"] == json!(t)
}
<|endoftext|>


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

#![feature(plugin)]
#![plugin(plugins)]

fn main() {
    let x = "foo".to_string();
    //~^ ERROR str.to_owned() is more efficient than str.to_string()

    let x = &x[..];
    x.to_string();
    //~^ ERROR str.to_owned() is more efficient than str.to_string()
}
<commit_msg>Auto merge of #10476 - KiChjang:remove-str-to-string, r=Ms2ger<commit_after><|endoftext|>


<commit_before>#[inline]
pub(crate) fn u64_to_arr(u: u64) -> [u8; 8] {
    [
        u as u8,
        (u >> 8) as u8,
        (u >> 16) as u8,
        (u >> 24) as u8,
        (u >> 32) as u8,
        (u >> 40) as u8,
        (u >> 48) as u8,
        (u >> 56) as u8,
    ]
}

#[inline]
pub(crate) fn arr_to_u64(arr: &[u8]) -> u64 {
    debug_assert_eq!(arr.len(), 8);
    u64::from(arr[0])
        + ((u64::from(arr[1])) << 8)
        + ((u64::from(arr[2])) << 16)
        + ((u64::from(arr[3])) << 24)
        + ((u64::from(arr[4])) << 32)
        + ((u64::from(arr[5])) << 40)
        + ((u64::from(arr[6])) << 48)
        + ((u64::from(arr[7])) << 56)
}

#[inline]
pub(crate) fn arr_to_u32(arr: &[u8]) -> u32 {
    debug_assert_eq!(arr.len(), 4);
    u32::from(arr[0])
        + ((u32::from(arr[1])) << 8)
        + ((u32::from(arr[2])) << 16)
        + ((u32::from(arr[3])) << 24)
}

#[inline]
pub(crate) fn u32_to_arr(u: u32) -> [u8; 4] {
    [u as u8, (u >> 8) as u8, (u >> 16) as u8, (u >> 24) as u8]
}
<commit_msg>Replace the hand-crafted u32/u64 to array conversions by the std one<commit_after>#[inline]
pub(crate) fn u64_to_arr(number: u64) -> [u8; 8] {
    number.to_le_bytes()
}

#[inline]
pub(crate) fn arr_to_u64(arr: &[u8]) -> u64 {
    debug_assert_eq!(arr.len(), 8);
    u64::from(arr[0])
        + ((u64::from(arr[1])) << 8)
        + ((u64::from(arr[2])) << 16)
        + ((u64::from(arr[3])) << 24)
        + ((u64::from(arr[4])) << 32)
        + ((u64::from(arr[5])) << 40)
        + ((u64::from(arr[6])) << 48)
        + ((u64::from(arr[7])) << 56)
}

#[inline]
pub(crate) fn arr_to_u32(arr: &[u8]) -> u32 {
    debug_assert_eq!(arr.len(), 4);
    u32::from(arr[0])
        + ((u32::from(arr[1])) << 8)
        + ((u32::from(arr[2])) << 16)
        + ((u32::from(arr[3])) << 24)
}

#[inline]
pub(crate) fn u32_to_arr(number: u32) -> [u8; 4] {
    number.to_le_bytes()
}
<|endoftext|>


<commit_before>#[repr(i32)]
pub enum FontType {
  Toy = 0,
  FT = 1,
  Win32 = 2,
  Quartz = 3,
  User = 4
}

<commit_msg>Copied documentation from Cairo for font type<commit_after>//! Describe font type

///  cairo_font_type_t is used to describe the type of a given font face or scaled font. The font types are also known as "font backends" within cairo.
///
/// The type of a font face is determined by the function used to create it, which will generally be of the form cairo_type_font_face_create(). The font face type can be queried with cairo_font_face_get_type()
///
/// The various cairo_font_face_t functions can be used with a font face of any type.
///
/// The type of a scaled font is determined by the type of the font face passed to cairo_scaled_font_create(). The scaled font type can be queried with cairo_scaled_font_get_type()
///
/// The various cairo_scaled_font_t functions can be used with scaled fonts of any type, but some font backends also provide type-specific functions that must only be called with a scaled font of the appropriate type. These functions have names that begin with cairo_type_scaled_font() such as cairo_ft_scaled_font_lock_face().
///
/// The behavior of calling a type-specific function with a scaled font of the wrong type is undefined.
///
/// New entries may be added in future versions.
///
/// Since 1.2
#[repr(i32)]
pub enum FontType {
  /// The font was created using cairo's toy font api (Since: 1.2)
  Toy = 0,
  /// The font is of type FreeType (Since: 1.2)
  FT = 1,
  /// The font is of type Win32 (Since: 1.2)
  Win32 = 2,
  /// The font is of type Quartz (Since: 1.6, in 1.2 and 1.4 it was named CAIRO_FONT_TYPE_ATSUI)
  Quartz = 3,
  /// The font was create using cairo's user font api (Since: 1.8)
  User = 4
}

<|endoftext|>


<commit_before>/// Available RPC methods types and ids.
use ssz_derive::{Decode, Encode};
use types::{BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot};

#[derive(Debug)]
pub enum RPCMethod {
    Hello,
    Goodbye,
    BeaconBlockRoots,
    BeaconBlockHeaders,
    BeaconBlockBodies,
    Unknown,
}

impl From<u16> for RPCMethod {
    fn from(method_id: u16) -> Self {
        match method_id {
            0 => RPCMethod::Hello,
            1 => RPCMethod::Goodbye,
            10 => RPCMethod::BeaconBlockRoots,
            11 => RPCMethod::BeaconBlockHeaders,
            12 => RPCMethod::BeaconBlockBodies,
            _ => RPCMethod::Unknown,
        }
    }
}

impl Into<u16> for RPCMethod {
    fn into(self) -> u16 {
        match self {
            RPCMethod::Hello => 0,
            RPCMethod::Goodbye => 1,
            RPCMethod::BeaconBlockRoots => 10,
            RPCMethod::BeaconBlockHeaders => 11,
            RPCMethod::BeaconBlockBodies => 12,
            _ => 0,
        }
    }
}

#[derive(Debug, Clone)]
pub enum RPCRequest {
    Hello(HelloMessage),
    Goodbye(u64),
    BeaconBlockRoots(BeaconBlockRootsRequest),
    BeaconBlockHeaders(BeaconBlockHeadersRequest),
    BeaconBlockBodies(BeaconBlockBodiesRequest),
}

#[derive(Debug, Clone)]
pub enum RPCResponse {
    Hello(HelloMessage),
    BeaconBlockRoots(BeaconBlockRootsResponse),
    BeaconBlockHeaders(BeaconBlockHeadersResponse),
    BeaconBlockBodies(BeaconBlockBodiesResponse),
}

/* Request/Response data structures for RPC methods */

/// The HELLO request/response handshake message.
#[derive(Encode, Decode, Clone, Debug)]
pub struct HelloMessage {
    /// The network ID of the peer.
    pub network_id: u8,
    /// The peers last finalized root.
    pub latest_finalized_root: Hash256,
    /// The peers last finalized epoch.
    pub latest_finalized_epoch: Epoch,
    /// The peers last block root.
    pub best_root: Hash256,
    /// The peers last slot.
    pub best_slot: Slot,
}

/// Request a number of beacon block roots from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockRootsRequest {
    /// The starting slot of the requested blocks.
    start_slot: Slot,
    /// The number of blocks from the start slot.
    count: u64, // this must be less than 32768. //TODO: Enforce this in the lower layers
}

/// Response containing a number of beacon block roots from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockRootsResponse {
    /// List of requested blocks and associated slots.
    roots: Vec<BlockRootSlot>,
}

/// Contains a block root and associated slot.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BlockRootSlot {
    /// The block root.
    block_root: Hash256,
    /// The block slot.
    slot: Slot,
}

/// Request a number of beacon block headers from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockHeadersRequest {
    /// The starting header hash of the requested headers.
    start_root: Hash256,
    /// The starting slot of the requested headers.
    start_slot: Slot,
    /// The maximum number of headers than can be returned.
    max_headers: u64,
    /// The maximum number of slots to skip between blocks.
    skip_slots: u64,
}

/// Response containing requested block headers.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockHeadersResponse {
    /// The list of requested beacon block headers.
    headers: Vec<BeaconBlockHeader>,
}

/// Request a number of beacon block bodies from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockBodiesRequest {
    /// The list of beacon block bodies being requested.
    block_roots: Hash256,
}

/// Response containing the list of requested beacon block bodies.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockBodiesResponse {
    /// The list of beacon block bodies being requested.
    block_bodies: Vec<BeaconBlockBody>,
}
<commit_msg>Implement BeaconChainState RPC method<commit_after>/// Available RPC methods types and ids.
use ssz_derive::{Decode, Encode};
use types::{BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot};

#[derive(Debug)]
pub enum RPCMethod {
    Hello,
    Goodbye,
    BeaconBlockRoots,
    BeaconBlockHeaders,
    BeaconBlockBodies,
    BeaconChainState, // Note: experimental, not complete.
    Unknown,
}

impl From<u16> for RPCMethod {
    fn from(method_id: u16) -> Self {
        match method_id {
            0 => RPCMethod::Hello,
            1 => RPCMethod::Goodbye,
            10 => RPCMethod::BeaconBlockRoots,
            11 => RPCMethod::BeaconBlockHeaders,
            12 => RPCMethod::BeaconBlockBodies,
            13 => RPCMethod::BeaconChainState,

            _ => RPCMethod::Unknown,
        }
    }
}

impl Into<u16> for RPCMethod {
    fn into(self) -> u16 {
        match self {
            RPCMethod::Hello => 0,
            RPCMethod::Goodbye => 1,
            RPCMethod::BeaconBlockRoots => 10,
            RPCMethod::BeaconBlockHeaders => 11,
            RPCMethod::BeaconBlockBodies => 12,
            RPCMethod::BeaconChainState => 13,
            _ => 0,
        }
    }
}

#[derive(Debug, Clone)]
pub enum RPCRequest {
    Hello(HelloMessage),
    Goodbye(u64),
    BeaconBlockRoots(BeaconBlockRootsRequest),
    BeaconBlockHeaders(BeaconBlockHeadersRequest),
    BeaconBlockBodies(BeaconBlockBodiesRequest),
    BeaconChainState(BeaconChainStateRequest),
}

#[derive(Debug, Clone)]
pub enum RPCResponse {
    Hello(HelloMessage),
    BeaconBlockRoots(BeaconBlockRootsResponse),
    BeaconBlockHeaders(BeaconBlockHeadersResponse),
    BeaconBlockBodies(BeaconBlockBodiesResponse),
    BeaconChainState(BeaconChainStateResponse),
}

/* Request/Response data structures for RPC methods */

/// The HELLO request/response handshake message.
#[derive(Encode, Decode, Clone, Debug)]
pub struct HelloMessage {
    /// The network ID of the peer.
    pub network_id: u8,
    /// The peers last finalized root.
    pub latest_finalized_root: Hash256,
    /// The peers last finalized epoch.
    pub latest_finalized_epoch: Epoch,
    /// The peers last block root.
    pub best_root: Hash256,
    /// The peers last slot.
    pub best_slot: Slot,
}

/// Request a number of beacon block roots from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockRootsRequest {
    /// The starting slot of the requested blocks.
    start_slot: Slot,
    /// The number of blocks from the start slot.
    count: u64, // this must be less than 32768. //TODO: Enforce this in the lower layers
}

/// Response containing a number of beacon block roots from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockRootsResponse {
    /// List of requested blocks and associated slots.
    roots: Vec<BlockRootSlot>,
}

/// Contains a block root and associated slot.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BlockRootSlot {
    /// The block root.
    block_root: Hash256,
    /// The block slot.
    slot: Slot,
}

/// Request a number of beacon block headers from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockHeadersRequest {
    /// The starting header hash of the requested headers.
    start_root: Hash256,
    /// The starting slot of the requested headers.
    start_slot: Slot,
    /// The maximum number of headers than can be returned.
    max_headers: u64,
    /// The maximum number of slots to skip between blocks.
    skip_slots: u64,
}

/// Response containing requested block headers.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockHeadersResponse {
    /// The list of requested beacon block headers.
    headers: Vec<BeaconBlockHeader>,
}

/// Request a number of beacon block bodies from a peer.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockBodiesRequest {
    /// The list of beacon block bodies being requested.
    block_roots: Hash256,
}

/// Response containing the list of requested beacon block bodies.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconBlockBodiesResponse {
    /// The list of beacon block bodies being requested.
    block_bodies: Vec<BeaconBlockBody>,
}

/// Request values for tree hashes which yield a blocks `state_root`.
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconChainStateRequest {
    /// The tree hashes that a value is requested for.
    hashes: Vec<Hash256>,
}

/// Request values for tree hashes which yield a blocks `state_root`.
// Note: TBD
#[derive(Encode, Decode, Clone, Debug)]
pub struct BeaconChainStateResponse {
    /// The values corresponding the to the requested tree hashes.
    values: bool, //TBD - stubbed with encodeable bool
}
<|endoftext|>


<commit_before>use level::{add_isize_to_usize, GridLevel};

use na::Vec2;

use rand::os::OsRng;
use rand::XorShiftRng;
use rand::Rand;
use rand::Rng;

use tile::Tile;
use util::{Direction};

pub struct MazeGen {
    pub pos: Vec2<usize>,
    rand: XorShiftRng,
}

impl MazeGen {
    pub fn new(x: usize, y: usize) -> MazeGen {
        MazeGen{
            pos: Vec2::new(x,y),
            rand: XorShiftRng::rand(&mut OsRng::new().unwrap()),
        }
    }

    pub fn generate(&mut self, level: &mut GridLevel<Tile>) {
        use util::Error;
        let mut stack: Vec<Vec2<usize>> = Vec::new();
        stack.push(self.pos);
        'mainloop: while let Some(cur) = stack.pop() {
            let neighbours = Self::get_neighbours(level, &cur);
            match level.get_mut_tile_with_vec(&cur) {

                Ok(tile) => {
                    match *tile {
                        Tile::Void(_) | Tile::Floor(_) => {continue 'mainloop},
                        _ => {},
                    }
                    match neighbours {
                        Some(mut neighbours) => {
                            self.rand.shuffle(&mut neighbours);
                            while let Some(p) = neighbours.pop() {
                                stack.push(p);
                            }
                            *tile = Tile::Floor(0);
                        },
                        None => continue 'mainloop
                    }
                },

                Err(Error::IndexOutOfBounds) => continue 'mainloop
            }

        }
    }

    fn get_neighbours(level: &GridLevel<Tile>, pos: &Vec2<usize>) -> Option<Vec<Vec2<usize>>> {
        let mut neighbours: Vec<Vec2<usize>> = Vec::new();
        let mut floors = 0;
        for d in Direction::get_orthogonal_dirs() {
            let pos = pos.clone();
            let dvec = d.get_vec();
            let coord = match (add_isize_to_usize(dvec.x, pos.x), add_isize_to_usize(dvec.y, pos.y)) {
                (Some(x), Some(y)) => (x,y),
                _ => continue,
            };
            match level.get_tile_with_tuple(coord) {
                Ok(&Tile::Floor(_)) => {
                    floors += 1;
                    if floors > 1 {
                        return None;
                    }
                },
                _ => {},
            }
            neighbours.push(pos);
        }
        Some(neighbours)
    }

}
<commit_msg>mazegen bug fixed<commit_after>use level::{add_isize_to_usize, GridLevel};

use na::Vec2;

use rand::os::OsRng;
use rand::XorShiftRng;
use rand::Rand;
use rand::Rng;

use tile::Tile;
use util::{Direction};

pub struct MazeGen {
    pub pos: Vec2<usize>,
    rand: XorShiftRng,
}

impl MazeGen {
    pub fn new(x: usize, y: usize) -> MazeGen {
        MazeGen{
            pos: Vec2::new(x,y),
            rand: XorShiftRng::rand(&mut OsRng::new().unwrap()),
        }
    }

    pub fn generate(&mut self, level: &mut GridLevel<Tile>) {
        use util::Error;
        let mut stack: Vec<Vec2<usize>> = Vec::new();
        stack.push(self.pos);
        'mainloop: while let Some(cur) = stack.pop() {
            let neighbours = Self::get_neighbours(level, &cur);
            match level.get_mut_tile_with_vec(&cur) {

                Ok(tile) => {
                    match *tile {
                        Tile::Void(_) | Tile::Floor(_) => {continue 'mainloop},
                        _ => {},
                    }
                    match neighbours {
                        Some(mut neighbours) => {
                            self.rand.shuffle(&mut neighbours);
                            while let Some(p) = neighbours.pop() {
                                stack.push(p);
                            }
                            *tile = Tile::Floor(0);
                        },
                        None => continue 'mainloop
                    }
                },

                Err(Error::IndexOutOfBounds) => continue 'mainloop
            }

        }
    }

    fn get_neighbours(level: &GridLevel<Tile>, pos: &Vec2<usize>) -> Option<Vec<Vec2<usize>>> {
        let mut neighbours: Vec<Vec2<usize>> = Vec::new();
        let mut floors = 0;
        for d in Direction::get_orthogonal_dirs() {
            let pos = pos.clone();
            let dvec = d.get_vec();
            let coord = match (add_isize_to_usize(dvec.x, pos.x), add_isize_to_usize(dvec.y, pos.y)) {
                (Some(x), Some(y)) => (x,y),
                _ => continue,
            };
            match level.get_tile_with_tuple(coord) {
                Ok(&Tile::Floor(_)) => {
                    floors += 1;
                    if floors > 1 {
                        return None;
                    }
                },
                _ => {},
            }
            neighbours.push(Vec2::new(coord.0, coord.1));
        }
        Some(neighbours)
    }

}
<|endoftext|>


<commit_before>pub use nalgebra as na;
use std::cmp::{ min, max };

/// A 2 dimensional point representing a location
pub type Point2 = na::Point2<f32>;
/// A 2 dimensional vector representing an offeset of a location
pub type Vector2 = na::Vector2<f32>;
/// A 4 dimensional matrix representing an arbitrary 3d transformation
pub type Matrix4 = na::Matrix4<f32>;

/// Turns a point into an array of floats
pub fn pt2arr(pt: Point2) -> [f32; 2] {
    [pt.x, pt.y]
}

/// Turns an array of floats into a point.
pub fn arr2pt(pt: [f32; 2]) -> Point2 {
    Point2::new(pt[0], pt[1])
}

/// A simple 2D rectangle.
///
/// The ggez convention is that `x` and `y` are the **center** of the rectangle,
/// with `width` and `height` being the total width and height, because this
/// is generally also how OpenGL tends to think about the world.
#[derive(Copy, Clone, PartialEq, Debug, Default)]
pub struct Rect {
    /// X coordinate of the center of the rect.
    pub x: f32,
    /// Y coordinate of the center of the rect.
    pub y: f32,
    /// Total width of the rect
    pub w: f32,
    /// Total height of the rect.
    pub h: f32,
}

impl Rect {
    /// Create a new rect.
    pub fn new(x: f32, y: f32, w: f32, h: f32) -> Self {
        Rect {
            x: x,
            y: y,
            w: w,
            h: h,
        }
    }

    /// Ceates a new rect a la Love2D's love.graphics.newQuad,
    /// as a fraction of the reference rect's size.
    pub fn fraction(x: f32, y: f32, w: f32, h: f32, reference: &Rect) -> Rect {
        Rect {
            x: x / reference.w,
            y: y / reference.h,
            w: w / reference.w,
            h: h / reference.h,
        }
    }

    /// Create a new rect from i32 coordinates.
    pub fn new_i32(x: i32, y: i32, w: i32, h: i32) -> Self {
        Rect {
            x: x as f32,
            y: y as f32,
            w: w as f32,
            h: h as f32,
        }
    }

    /// Create a new `Rect` with all values zero.
    pub fn zero() -> Self {
        Self::new(0.0, 0.0, 0.0, 0.0)
    }

    /// Creates a new `Rect` at 0,0 with width and height 1.
    pub fn one() -> Self {
        Self::new(0.0, 0.0, 1.0, 1.0)
    }

    /// Gets the `Rect`'s x and y coordinates as a `Point2`.
    pub fn point(&self) -> Point2 {
        Point2::new(self.x, self.y)
    }

    /// Returns the left edge of the `Rect`
    pub fn left(&self) -> f32 {
        self.x - (self.w / 2.0)
    }

    /// Returns the right edge of the `Rect`
    pub fn right(&self) -> f32 {
        self.x + (self.w / 2.0)
    }

    /// Returns the top edge of the `Rect`
    pub fn top(&self) -> f32 {
        self.y + (self.h / 2.0)
    }

    /// Returns the bottom edge of the `Rect`
    pub fn bottom(&self) -> f32 {
        self.y - (self.h / 2.0)
    }

    /// Checks whether the `Rect` contains a `Point`
    pub fn contains(&self, point: &Point2) -> bool {
        point.x >= self.left() &&
        point.x <= self.right() &&
        point.y >= self.bottom() &&
        point.y <= self.top()
    }

    /// Checks whether the `Rect` overlaps another `Rect`
    pub fn overlaps(&self, other: &Rect) -> bool {
        self.left() < other.right() &&
        self.right() > other.left() &&
        self.top() > other.bottom() &&
        self.bottom() < other.top()
    }

    /// Translates the `Rect` by an offset of (x, y)
    pub fn translate(&mut self, x: f32, y: f32) {
        self.x += x;
        self.y += y;
    }

    /// Moves the `Rect`'s center to (x, y)
    pub fn move_to(&mut self, x: f32, y: f32) {
        self.x = x;
        self.y = y;
    }

    /// Scales the `Rect` about its center by a factor of (sx, sy)
    pub fn scale(&mut self, sx: f32, sy: f32) {
        self.w *= sx;
        self.h *= sy;
    }

    /// Finds the intersection between two `Rect`s, or `None` iff
    /// they don't intersect.
    pub fn intersect(&self, other: &Rect) -> Option<Rect> {
        if !self.overlaps(other) {
            None
        } else {
            let a = (self.left().max(other.left()), self.top().max(other.top()));
            let b = (self.right().min(other.right()), self.bottom().min(other.bottom()));

            let width = (a.0 - b.0).abs();
            let height = (a.1 - b.1).abs();

            Some(Rect::new(
                a.0 + width / 2.0,
                a.1 + height / 2.0,
                width,
                height,
            ))
        }
    }
}

impl From<[f32; 4]> for Rect {
    fn from(val: [f32; 4]) -> Self {
        Rect::new(val[0], val[1], val[2], val[3])
    }
}

impl From<Rect> for [f32; 4] {
    fn from(val: Rect) -> Self {
        [val.x, val.y, val.w, val.h]
    }
}

/// A RGBA color.
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Color {
    /// Red component
    pub r: f32,
    /// Green component
    pub g: f32,
    /// Blue component
    pub b: f32,
    /// Alpha component
    pub a: f32,
}

/// White
pub const WHITE: Color = Color {
    r: 1.0,
    g: 1.0,
    b: 1.0,
    a: 1.0,
};

/// Black
pub const BLACK: Color = Color {
    r: 0.0,
    g: 0.0,
    b: 0.0,
    a: 1.0,
};

impl Color {
    /// Create a new Color from components.
    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color {
            r: r,
            g: g,
            b: b,
            a: a,
        }
    }
}

impl From<(u8, u8, u8, u8)> for Color {
    fn from(val: (u8, u8, u8, u8)) -> Self {
        let (r, g, b, a) = val;
        let rf = (r as f32) / 255.0;
        let gf = (g as f32) / 255.0;
        let bf = (b as f32) / 255.0;
        let af = (a as f32) / 255.0;
        Color::new(rf, gf, bf, af)
    }
}

impl From<(u8, u8, u8)> for Color {
    fn from(val: (u8, u8, u8)) -> Self {
        let (r, g, b) = val;
        Color::from((r, g, b, 255))
    }
}

impl From<[f32; 4]> for Color {
    fn from(val: [f32; 4]) -> Self {
        Color::new(val[0], val[1], val[2], val[3])
    }
}

impl From<Color> for (u8, u8, u8, u8) {
    fn from(color: Color) -> Self {
        let r = (color.r * 255.0) as u8;
        let g = (color.g * 255.0) as u8;
        let b = (color.b * 255.0) as u8;
        let a = (color.a * 255.0) as u8;
        (r, g, b, a)
    }
}

impl From<Color> for [u8; 4] {
    fn from(color: Color) -> Self {
        let (r, g, b, a) = color.into();
        [r, g, b, a]
    }
}

impl From<Color> for [f32; 4] {
    fn from(color: Color) -> Self {
        [color.r, color.g, color.b, color.a]
    }
}

impl From<Color> for (u8, u8, u8) {
    fn from(color: Color) -> Self {
        let (r, g, b, _) = color.into();
        (r, g, b)
    }
}

impl From<Color> for u32 {
    fn from(color: Color) -> Self {
        let (r, g, b, a): (u8, u8, u8, u8) = color.into();
        let rp = (r as u32) << 24;
        let gp = (g as u32) << 16;
        let bp = (b as u32) << 8;
        let ap = a as u32;
        (rp | gp | bp | ap)
    }
}

/// Specifies whether a shape should be drawn
/// filled or as an outline.
#[derive(Debug, Copy, Clone)]
pub enum DrawMode {
    /// A stroked line with the given width
    Line(f32),
    /// A filled shape.
    Fill,
}

/// Specifies what blending method to use when scaling up/down images.
#[derive(Debug, Copy, Clone)]
pub enum FilterMode {
    /// Use linear interpolation
    Linear,
    /// Use nearest-neighbor interpolation
    Nearest,
}

use gfx::texture;
use gfx::texture::FilterMethod;

impl From<FilterMethod> for FilterMode {
    fn from(f: FilterMethod) -> Self {
        match f {
            FilterMethod::Scale => FilterMode::Nearest,
            _other => FilterMode::Linear,
        }
    }
}

impl From<FilterMode> for FilterMethod {
    fn from(f: FilterMode) -> Self {
        match f {
            FilterMode::Nearest => FilterMethod::Scale,
            FilterMode::Linear => FilterMethod::Bilinear,
        }
    }
}

/// Specifies how to wrap textures.
pub type WrapMode = texture::WrapMode;

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_color_conversions() {
        let white = Color::new(1.0, 1.0, 1.0, 1.0);
        let w1 = Color::from((255, 255, 255, 255));
        assert_eq!(white, w1);
        let w2: u32 = white.into();
        assert_eq!(w2, 0xFFFFFFFF);

        let grey = Color::new(0.5019608, 0.5019608, 0.5019608, 1.0);
        let g1 = Color::from((128, 128, 128, 255));
        assert_eq!(grey, g1);
        let g2: u32 = grey.into();
        assert_eq!(g2, 0x808080FF);

        let black = Color::new(0.0, 0.0, 0.0, 1.0);
        let b1 = Color::from((0, 0, 0, 255));
        assert_eq!(black, b1);
        let b2: u32 = black.into();
        assert_eq!(b2, 0x000000FF);
    }

    #[test]
    fn test_rect_scaling() {
        let r1 = Rect::new(0.0, 0.0, 128.0, 128.0);
        let r2 = Rect::fraction(0.0, 0.0, 32.0, 32.0, &r1);
        assert_eq!(r2, Rect::new(0.0, 0.0, 0.25, 0.25));

        let r2 = Rect::fraction(32.0, 32.0, 32.0, 32.0, &r1);
        assert_eq!(r2, Rect::new(0.25, 0.25, 0.25, 0.25));
    }
}
<commit_msg>Add some tests<commit_after>pub use nalgebra as na;

/// A 2 dimensional point representing a location
pub type Point2 = na::Point2<f32>;
/// A 2 dimensional vector representing an offeset of a location
pub type Vector2 = na::Vector2<f32>;
/// A 4 dimensional matrix representing an arbitrary 3d transformation
pub type Matrix4 = na::Matrix4<f32>;

/// Turns a point into an array of floats
pub fn pt2arr(pt: Point2) -> [f32; 2] {
    [pt.x, pt.y]
}

/// Turns an array of floats into a point.
pub fn arr2pt(pt: [f32; 2]) -> Point2 {
    Point2::new(pt[0], pt[1])
}

/// A simple 2D rectangle.
///
/// The ggez convention is that `x` and `y` are the **center** of the rectangle,
/// with `width` and `height` being the total width and height, because this
/// is generally also how OpenGL tends to think about the world.
#[derive(Copy, Clone, PartialEq, Debug, Default)]
pub struct Rect {
    /// X coordinate of the center of the rect.
    pub x: f32,
    /// Y coordinate of the center of the rect.
    pub y: f32,
    /// Total width of the rect
    pub w: f32,
    /// Total height of the rect.
    pub h: f32,
}

impl Rect {
    /// Create a new rect.
    pub fn new(x: f32, y: f32, w: f32, h: f32) -> Self {
        Rect {
            x: x,
            y: y,
            w: w,
            h: h,
        }
    }

    /// Ceates a new rect a la Love2D's love.graphics.newQuad,
    /// as a fraction of the reference rect's size.
    pub fn fraction(x: f32, y: f32, w: f32, h: f32, reference: &Rect) -> Rect {
        Rect {
            x: x / reference.w,
            y: y / reference.h,
            w: w / reference.w,
            h: h / reference.h,
        }
    }

    /// Create a new rect from i32 coordinates.
    pub fn new_i32(x: i32, y: i32, w: i32, h: i32) -> Self {
        Rect {
            x: x as f32,
            y: y as f32,
            w: w as f32,
            h: h as f32,
        }
    }

    /// Create a new `Rect` with all values zero.
    pub fn zero() -> Self {
        Self::new(0.0, 0.0, 0.0, 0.0)
    }

    /// Creates a new `Rect` at 0,0 with width and height 1.
    pub fn one() -> Self {
        Self::new(0.0, 0.0, 1.0, 1.0)
    }

    /// Gets the `Rect`'s x and y coordinates as a `Point2`.
    pub fn point(&self) -> Point2 {
        Point2::new(self.x, self.y)
    }

    /// Returns the left edge of the `Rect`
    pub fn left(&self) -> f32 {
        self.x - (self.w / 2.0)
    }

    /// Returns the right edge of the `Rect`
    pub fn right(&self) -> f32 {
        self.x + (self.w / 2.0)
    }

    /// Returns the top edge of the `Rect`
    pub fn top(&self) -> f32 {
        self.y + (self.h / 2.0)
    }

    /// Returns the bottom edge of the `Rect`
    pub fn bottom(&self) -> f32 {
        self.y - (self.h / 2.0)
    }

    /// Checks whether the `Rect` contains a `Point`
    pub fn contains(&self, point: &Point2) -> bool {
        point.x >= self.left() &&
        point.x <= self.right() &&
        point.y >= self.bottom() &&
        point.y <= self.top()
    }

    /// Checks whether the `Rect` overlaps another `Rect`
    pub fn overlaps(&self, other: &Rect) -> bool {
        self.left() < other.right() &&
        self.right() > other.left() &&
        self.top() > other.bottom() &&
        self.bottom() < other.top()
    }

    /// Translates the `Rect` by an offset of (x, y)
    pub fn translate(&mut self, x: f32, y: f32) {
        self.x += x;
        self.y += y;
    }

    /// Moves the `Rect`'s center to (x, y)
    pub fn move_to(&mut self, x: f32, y: f32) {
        self.x = x;
        self.y = y;
    }

    /// Scales the `Rect` about its center by a factor of (sx, sy)
    pub fn scale(&mut self, sx: f32, sy: f32) {
        self.w *= sx;
        self.h *= sy;
    }
}

impl From<[f32; 4]> for Rect {
    fn from(val: [f32; 4]) -> Self {
        Rect::new(val[0], val[1], val[2], val[3])
    }
}

impl From<Rect> for [f32; 4] {
    fn from(val: Rect) -> Self {
        [val.x, val.y, val.w, val.h]
    }
}

/// A RGBA color.
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Color {
    /// Red component
    pub r: f32,
    /// Green component
    pub g: f32,
    /// Blue component
    pub b: f32,
    /// Alpha component
    pub a: f32,
}

/// White
pub const WHITE: Color = Color {
    r: 1.0,
    g: 1.0,
    b: 1.0,
    a: 1.0,
};

/// Black
pub const BLACK: Color = Color {
    r: 0.0,
    g: 0.0,
    b: 0.0,
    a: 1.0,
};

impl Color {
    /// Create a new Color from components.
    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color {
            r: r,
            g: g,
            b: b,
            a: a,
        }
    }
}

impl From<(u8, u8, u8, u8)> for Color {
    fn from(val: (u8, u8, u8, u8)) -> Self {
        let (r, g, b, a) = val;
        let rf = (r as f32) / 255.0;
        let gf = (g as f32) / 255.0;
        let bf = (b as f32) / 255.0;
        let af = (a as f32) / 255.0;
        Color::new(rf, gf, bf, af)
    }
}

impl From<(u8, u8, u8)> for Color {
    fn from(val: (u8, u8, u8)) -> Self {
        let (r, g, b) = val;
        Color::from((r, g, b, 255))
    }
}

impl From<[f32; 4]> for Color {
    fn from(val: [f32; 4]) -> Self {
        Color::new(val[0], val[1], val[2], val[3])
    }
}

impl From<Color> for (u8, u8, u8, u8) {
    fn from(color: Color) -> Self {
        let r = (color.r * 255.0) as u8;
        let g = (color.g * 255.0) as u8;
        let b = (color.b * 255.0) as u8;
        let a = (color.a * 255.0) as u8;
        (r, g, b, a)
    }
}

impl From<Color> for [u8; 4] {
    fn from(color: Color) -> Self {
        let (r, g, b, a) = color.into();
        [r, g, b, a]
    }
}

impl From<Color> for [f32; 4] {
    fn from(color: Color) -> Self {
        [color.r, color.g, color.b, color.a]
    }
}

impl From<Color> for (u8, u8, u8) {
    fn from(color: Color) -> Self {
        let (r, g, b, _) = color.into();
        (r, g, b)
    }
}

impl From<Color> for u32 {
    fn from(color: Color) -> Self {
        let (r, g, b, a): (u8, u8, u8, u8) = color.into();
        let rp = (r as u32) << 24;
        let gp = (g as u32) << 16;
        let bp = (b as u32) << 8;
        let ap = a as u32;
        (rp | gp | bp | ap)
    }
}

/// Specifies whether a shape should be drawn
/// filled or as an outline.
#[derive(Debug, Copy, Clone)]
pub enum DrawMode {
    /// A stroked line with the given width
    Line(f32),
    /// A filled shape.
    Fill,
}

/// Specifies what blending method to use when scaling up/down images.
#[derive(Debug, Copy, Clone)]
pub enum FilterMode {
    /// Use linear interpolation
    Linear,
    /// Use nearest-neighbor interpolation
    Nearest,
}

use gfx::texture;
use gfx::texture::FilterMethod;

impl From<FilterMethod> for FilterMode {
    fn from(f: FilterMethod) -> Self {
        match f {
            FilterMethod::Scale => FilterMode::Nearest,
            _other => FilterMode::Linear,
        }
    }
}

impl From<FilterMode> for FilterMethod {
    fn from(f: FilterMode) -> Self {
        match f {
            FilterMode::Nearest => FilterMethod::Scale,
            FilterMode::Linear => FilterMethod::Bilinear,
        }
    }
}

/// Specifies how to wrap textures.
pub type WrapMode = texture::WrapMode;

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_color_conversions() {
        let white = Color::new(1.0, 1.0, 1.0, 1.0);
        let w1 = Color::from((255, 255, 255, 255));
        assert_eq!(white, w1);
        let w2: u32 = white.into();
        assert_eq!(w2, 0xFFFFFFFF);

        let grey = Color::new(0.5019608, 0.5019608, 0.5019608, 1.0);
        let g1 = Color::from((128, 128, 128, 255));
        assert_eq!(grey, g1);
        let g2: u32 = grey.into();
        assert_eq!(g2, 0x808080FF);

        let black = Color::new(0.0, 0.0, 0.0, 1.0);
        let b1 = Color::from((0, 0, 0, 255));
        assert_eq!(black, b1);
        let b2: u32 = black.into();
        assert_eq!(b2, 0x000000FF);
    }

    #[test]
    fn test_rect_scaling() {
        let r1 = Rect::new(0.0, 0.0, 128.0, 128.0);
        let r2 = Rect::fraction(0.0, 0.0, 32.0, 32.0, &r1);
        assert_eq!(r2, Rect::new(0.0, 0.0, 0.25, 0.25));

        let r2 = Rect::fraction(32.0, 32.0, 32.0, 32.0, &r1);
        assert_eq!(r2, Rect::new(0.25, 0.25, 0.25, 0.25));
    }

    #[test]
    fn test_rect_contains() {
        let r = Rect::new(0.0, 0.0, 128.0, 128.0);
        let p = Point2::new(0.0, 0.0);
        assert!(r.contains(&p));

        let p = Point2::new(500.0, 0.0);
        assert!(!r.contains(&p));
    }

    #[test]
    fn test_rect_overlaps() {
        let r1 = Rect::new(0.0, 0.0, 128.0, 128.0);
        let r2 = Rect::new(0.0, 0.0, 64.0, 64.0);
        assert!(r1.overlaps(&r2));

        let r2 = Rect::new(100.0, 0.0, 128.0, 128.0);
        assert!(r1.overlaps(&r2));

        let r2 = Rect::new(500.0, 0.0, 64.0, 64.0);
        assert!(!r1.overlaps(&r2));
    }

    #[test]
    fn test_rect_transform() {
        let mut r1 = Rect::new(0.0, 0.0, 64.0, 64.0);
        let r2 = Rect::new(64.0, 64.0, 64.0, 64.0);
        r1.translate(64.0, 64.0);
        assert!(r1 == r2);

        let mut r1 = Rect::new(0.0, 0.0, 64.0, 64.0);
        let r2 = Rect::new(0.0, 0.0, 128.0, 128.0);
        r1.scale(2.0, 2.0);
        assert!(r1 == r2);

        let mut r1 = Rect::new(32.0, 32.0, 64.0, 64.0);
        let r2 = Rect::new(64.0, 64.0, 64.0, 64.0);
        r1.move_to(64.0, 64.0);
        assert!(r1 == r2);
    }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

use std::collections::VecDeque;
use std::io::Read as _;

use byteorder::{BigEndian, ReadBytesExt as _};

/// A gzchunked streaming decoder.
pub struct Decoder {
    queue: VecDeque<Vec<u8>>,
}

impl Decoder {

    /// Creates a new decoder.
    pub fn new() -> Decoder {
        Decoder {
            queue: VecDeque::new()
        }
    }

    /// Decodes next gzchunked block and puts all results into the internal queue.
    pub fn write(&mut self, buf: &[u8]) -> std::io::Result<()> {
        let mut decoder = flate2::read::GzDecoder::new(buf);
        let mut chunked_data_vec: Vec<u8> = Vec::new();
        decoder.read_to_end(&mut chunked_data_vec)?;
        let mut chunked_data = chunked_data_vec.as_slice();
        while !chunked_data.is_empty() {
            let length = chunked_data.read_u64::<BigEndian>()?;
            let mut data = vec![0; length as usize];
            chunked_data.read_exact(data.as_mut_slice())?;
            self.queue.push_back(data);
        }
        Ok(())
    }

    /// Attempts to retrieve next data piece from queue.
    /// Returns `None` if the queue is empty.
    pub fn try_next_data(&mut self) -> Option<Vec<u8>> {
        self.queue.pop_front()
    }
}
<commit_msg>Create an utility for decoding gzchunked streams.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

use std::collections::VecDeque;
use std::io::Read;

use byteorder::{BigEndian, ReadBytesExt as _};

/// A gzchunked streaming decoder.
pub struct Decoder {
    queue: VecDeque<Vec<u8>>,
}

impl Decoder {

    /// Creates a new decoder.
    pub fn new() -> Decoder {
        Decoder {
            queue: VecDeque::new()
        }
    }

    /// Decodes next gzchunked block and puts all results into the internal queue.
    pub fn write(&mut self, buf: &[u8]) -> std::io::Result<()> {
        let mut decoder = flate2::read::GzDecoder::new(buf);
        let mut chunked_data_vec: Vec<u8> = Vec::new();
        decoder.read_to_end(&mut chunked_data_vec)?;
        let mut chunked_data = chunked_data_vec.as_slice();
        while !chunked_data.is_empty() {
            let length = chunked_data.read_u64::<BigEndian>()?;
            let mut data = vec![0; length as usize];
            chunked_data.read_exact(data.as_mut_slice())?;
            self.queue.push_back(data);
        }
        Ok(())
    }

    /// Attempts to retrieve next data piece from queue.
    /// Returns `None` if the queue is empty.
    pub fn try_next_data(&mut self) -> Option<Vec<u8>> {
        self.queue.pop_front()
    }
}

pub fn decode<I, R>(iter: I) -> impl Iterator<Item=std::io::Result<Vec<u8>>>
where
    I: Iterator<Item=R>,
    R: std::io::Read,
{
    let parts = iter.map(flate2::read::GzDecoder::new);
    crate::chunked::decode(crate::io::IterReader::new(parts))
}
<|endoftext|>