<commit_before>#![feature(alloc_system)]

extern crate alloc_system;

#[macro_use]
extern crate rustfbp;
extern crate capnp;

use self::rustfbp::scheduler::{Scheduler};
use self::rustfbp::ports::{IP, Ports};

use std::thread;
use std::env;
use std::path::Path;

mod contract_capnp {
    include!("path_capnp.rs");
}
use contract_capnp::path;

fn build_path(path: &'static str) -> Option<String> {
    let pstr = env::current_exe().unwrap();
    let parent_dir = Path::new(&pstr).parent();
    parent_dir.and_then(|s| s.to_str()).map(|s| {format!("{}/../bootstrap/{}", s, path)}).expect("not a file name")
}

#[no_mangle]
pub extern "C" fn run(path_fbp: &str) {

    let mut sched = Scheduler::new();
    sched.add_component("open", &build_path("file_open.so"));
    sched.add_component("lex", &build_path("development_fbp_parser_lexical.so"));
    sched.add_component("sem", &build_path("development_fbp_parser_semantic.so"));
    sched.add_component("fvm", &build_path("development_fbp_fvm.so"));
    sched.add_component("errors", &build_path("development_fbp_errors.so"));
    sched.add_component("graph_print", &build_path("development_fbp_parser_print_graph.so"));
    sched.add_component("sched", &build_path("development_fbp_scheduler.so"));
    sched.add_component("component_lookup", &build_path("component_lookup.so"));
    sched.add_component("contract_lookup", &build_path("contract_lookup.so"));

    let (mut p, senders) = Ports::new("exterior".into(), sched.sender.clone(),
                                      vec!["r".into()],
                                      vec![],
                                      vec!["s".into(), "opt".into()],
                                      vec![]).expect("cannot create");
    sched.inputs.insert("exterior".into(), senders);

    p.connect("s".into(), sched.get_sender("open".into(), "input".into()).unwrap()).expect("unable to connect");
    sched.connect("open".into(), "output".into(), "lex".into(), "input".into()).expect("cannot connect");
    sched.connect("lex".into(), "output".into(), "sem".into(), "input".into()).expect("cannot connect");
    sched.connect("sem".into(), "output".into(), "fvm".into(), "input".into()).expect("cannot connect");

    sched.connect("open".into(), "error".into(), "errors".into(), "file_error".into());
    sched.connect("sem".into(), "error".into(), "errors".into(), "semantic_error".into());
    sched.connect("errors".into(), "output".into(), "fvm".into(), "input".into());

    // reccursive part
    sched.connect("fvm".into(), "ask_graph".into(), "open".into(), "input".into());
    sched.connect("fvm".into(), "ask_path".into(), "component_lookup".into(), "input".into());
    sched.connect("component_lookup".into(), "output".into(), "fvm".into(), "new_path".into());

    sched.connect("fvm".into(), "output".into(), "graph_print".into(), "input".into());
    sched.connect("graph_print".into(), "output".into(), "sched".into(), "input".into());

    let args: Vec<String> = env::args().collect();
    let mut msg = capnp::message::Builder::new_default();
    {
        let mut number = msg.init_root::<path::Builder>();
        number.set_path(&path_fbp);
    }

    let mut ip = IP::new();
    ip.write_builder(&mut msg);
    p.send("s".into(), ip).expect("unable to send to comp");

    sched.join();
}
<commit_msg>Problem : little bug in the conflicts resolution<commit_after>#![feature(alloc_system)]

extern crate alloc_system;

#[macro_use]
extern crate rustfbp;
extern crate capnp;

use self::rustfbp::scheduler::{Scheduler};
use self::rustfbp::ports::{IP, Ports};

use std::thread;
use std::env;
use std::path::Path;

mod contract_capnp {
    include!("path_capnp.rs");
}
use contract_capnp::path;

fn build_path(path: &'static str) -> String {
    let pstr = env::current_exe().unwrap();
    let parent_dir = Path::new(&pstr).parent();
    parent_dir.and_then(|s| s.to_str()).map(|s| {format!("{}/../bootstrap/{}", s, path)}).expect("not a file name")
}

#[no_mangle]
pub extern "C" fn run(path_fbp: &str) {

    let mut sched = Scheduler::new();
    sched.add_component("open", &build_path("file_open.so"));
    sched.add_component("lex", &build_path("development_fbp_parser_lexical.so"));
    sched.add_component("sem", &build_path("development_fbp_parser_semantic.so"));
    sched.add_component("fvm", &build_path("development_fbp_fvm.so"));
    sched.add_component("errors", &build_path("development_fbp_errors.so"));
    sched.add_component("graph_print", &build_path("development_fbp_parser_print_graph.so"));
    sched.add_component("sched", &build_path("development_fbp_scheduler.so"));
    sched.add_component("component_lookup", &build_path("component_lookup.so"));
    sched.add_component("contract_lookup", &build_path("contract_lookup.so"));

    let (mut p, senders) = Ports::new("exterior".into(), sched.sender.clone(),
                                      vec!["r".into()],
                                      vec![],
                                      vec!["s".into(), "opt".into()],
                                      vec![]).expect("cannot create");
    sched.inputs.insert("exterior".into(), senders);

    p.connect("s".into(), sched.get_sender("open".into(), "input".into()).unwrap()).expect("unable to connect");
    sched.connect("open".into(), "output".into(), "lex".into(), "input".into()).expect("cannot connect");
    sched.connect("lex".into(), "output".into(), "sem".into(), "input".into()).expect("cannot connect");
    sched.connect("sem".into(), "output".into(), "fvm".into(), "input".into()).expect("cannot connect");

    sched.connect("open".into(), "error".into(), "errors".into(), "file_error".into());
    sched.connect("sem".into(), "error".into(), "errors".into(), "semantic_error".into());
    sched.connect("errors".into(), "output".into(), "fvm".into(), "input".into());

    // reccursive part
    sched.connect("fvm".into(), "ask_graph".into(), "open".into(), "input".into());
    sched.connect("fvm".into(), "ask_path".into(), "component_lookup".into(), "input".into());
    sched.connect("component_lookup".into(), "output".into(), "fvm".into(), "new_path".into());

    sched.connect("fvm".into(), "output".into(), "graph_print".into(), "input".into());
    sched.connect("graph_print".into(), "output".into(), "sched".into(), "input".into());

    let args: Vec<String> = env::args().collect();
    let mut msg = capnp::message::Builder::new_default();
    {
        let mut number = msg.init_root::<path::Builder>();
        number.set_path(&path_fbp);
    }

    let mut ip = IP::new();
    ip.write_builder(&mut msg);
    p.send("s".into(), ip).expect("unable to send to comp");

    sched.join();
}
<|endoftext|>


<commit_before>use serde::Deserialize;

use std::env;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;

#[derive(Deserialize)]
struct Sections {
    #[serde(default)]
    expand: Config,
}

#[derive(Deserialize, Default)]
pub struct Config {
    pub theme: Option<String>,
    pub color: Option<String>,
    #[serde(default)]
    pub pager: bool,
}

pub fn deserialize() -> Config {
    try_deserialize().unwrap_or_default()
}

fn try_deserialize() -> Option<Config> {
    let cargo_home = env::var_os("CARGO_HOME")?;
    let config_path = PathBuf::from(cargo_home).join("config");
    if !config_path.exists() {
        return None;
    }

    let content = fs::read(&config_path).ok()?;

    let full_config: Sections = match toml::from_slice(&content) {
        Ok(config) => config,
        Err(err) => {
            let _ = writeln!(
                &mut io::stderr(),
                "Warning: {}: {}",
                config_path.display(),
                err
            );
            return None;
        }
    };

    Some(full_config.expand)
}
<commit_msg>Add support for config.toml<commit_after>use serde::Deserialize;

use std::env;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;

#[derive(Deserialize)]
struct Sections {
    #[serde(default)]
    expand: Config,
}

#[derive(Deserialize, Default)]
pub struct Config {
    pub theme: Option<String>,
    pub color: Option<String>,
    #[serde(default)]
    pub pager: bool,
}

pub fn deserialize() -> Config {
    try_deserialize().unwrap_or_default()
}

fn try_deserialize() -> Option<Config> {
    let cargo_home = env::var_os("CARGO_HOME")?;
    let config_names = ["config", "config.toml"];
    let config_path = config_names
        .iter()
        .map(|name| PathBuf::from(cargo_home.clone()).join(name))
        .find(|path| path.exists())?;

    let content = fs::read(&config_path).ok()?;

    let full_config: Sections = match toml::from_slice(&content) {
        Ok(config) => config,
        Err(err) => {
            let _ = writeln!(
                &mut io::stderr(),
                "Warning: {}: {}",
                config_path.display(),
                err
            );
            return None;
        }
    };

    Some(full_config.expand)
}
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use std::collections::HashSet;
use std::fmt;
use std::io;
use std::net::SocketAddr;

use serde::export::Formatter;
use serde::{Deserialize, Serialize};

/// Validation failure for a Config
#[derive(Debug, PartialEq)]
pub enum ValidationError {
    NotUnique(String),
}

impl fmt::Display for ValidationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            ValidationError::NotUnique(field) => write!(f, "field {} is not unique", field),
        }
    }
}

/// Config is the configuration for either a Client or Server proxy
#[derive(Debug, Deserialize, Serialize)]
pub struct Config {
    pub local: Local,
    #[serde(default)]
    pub filters: Vec<Filter>,
    #[serde(flatten)]
    pub connections: ConnectionConfig,
}

/// Local is the local host configuration options
#[derive(Debug, Deserialize, Serialize)]
pub struct Local {
    pub port: u16,
}

/// LoadBalancerPolicy represents how a proxy load-balances
/// traffic between endpoints.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
pub enum LoadBalancerPolicy {
    /// Send all traffic to all endpoints.
    #[serde(rename = "BROADCAST")]
    Broadcast,
    /// Send traffic to endpoints in turns.
    #[serde(rename = "ROUND_ROBIN")]
    RoundRobin,
    /// Send traffic to endpoints chosen at random.
    #[serde(rename = "RANDOM")]
    Random,
}

/// Filter is the configuration for a single filter
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Filter {
    pub name: String,
    pub config: serde_yaml::Value,
}

/// ConnectionConfig is the configuration for either a Client or Server proxy
#[derive(Debug, Deserialize, Serialize)]
pub enum ConnectionConfig {
    /// Client is the configuration for a client proxy, for sitting behind a game client.
    #[serde(rename = "client")]
    Client {
        addresses: Vec<SocketAddr>,
        connection_id: String,
        lb_policy: Option<LoadBalancerPolicy>,
    },

    /// Server is the configuration for a Dedicated Game Server proxy
    #[serde(rename = "server")]
    Server { endpoints: Vec<EndPoint> },
}

/// A singular endpoint, to pass on UDP packets to.
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)]
pub struct EndPoint {
    pub name: String,
    pub address: SocketAddr,
    pub connection_ids: Vec<String>,
}

impl Config {
    /// from_reader returns a config from a given Reader
    pub fn from_reader<R: io::Read>(input: R) -> Result<Config, serde_yaml::Error> {
        serde_yaml::from_reader(input)
    }

    /// validates the current Config.
    pub fn validate(&self) -> Result<(), ValidationError> {
        if let ConnectionConfig::Server { endpoints } = &self.connections {
            if endpoints
                .iter()
                .map(|ep| ep.name.clone())
                .collect::<HashSet<_>>()
                .len()
                != endpoints.len()
            {
                return Err(ValidationError::NotUnique("endpoint.name".to_string()));
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use std::net::SocketAddr;

    use serde_yaml::Value;

    use crate::config::{
        Config, ConnectionConfig, EndPoint, LoadBalancerPolicy, Local, ValidationError,
    };

    #[test]
    fn deserialise_client() {
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Client {
                addresses: vec!["127.0.0.1:25999".parse().unwrap()],
                connection_id: String::from("1234"),
                lb_policy: Some(LoadBalancerPolicy::RoundRobin),
            },
        };
        let yaml = serde_yaml::to_string(&config).unwrap();
        println!("{}", yaml);
    }

    #[test]
    fn deserialise_server() {
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Server {
                endpoints: vec![
                    EndPoint {
                        name: String::from("No.1"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234"), String::from("5678")],
                    },
                    EndPoint {
                        name: String::from("No.2"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("1234")],
                    },
                ],
            },
        };
        let yaml = serde_yaml::to_string(&config).unwrap();
        println!("{}", yaml);
    }

    #[test]
    fn parse_filter_config() {
        let yaml = "
local:
  port: 7000 # the port to receive traffic to locally
filters: # new filters section
  - name: quilkin.core.v1.rate-limiter
    config:
      map: of arbitrary key value pairs
      could:
        - also
        - be
        - 27
        - true
client:
  addresses:
    - 127.0.0.1:7001
  connection_id: 1x7ijy6
        ";
        let config = Config::from_reader(yaml.as_bytes()).unwrap();

        let filter = config.filters.get(0).unwrap();
        assert_eq!("quilkin.core.v1.rate-limiter", filter.name);
        let filter_config = filter.config.as_mapping().unwrap();

        let key = Value::from("map");
        assert_eq!(
            "of arbitrary key value pairs",
            filter_config.get(&key).unwrap().as_str().unwrap()
        );

        let key = Value::from("could");
        let could = filter_config.get(&key).unwrap().as_sequence().unwrap();
        assert_eq!("also", could.get(0).unwrap().as_str().unwrap());
        assert_eq!("be", could.get(1).unwrap().as_str().unwrap());
        assert_eq!(27, could.get(2).unwrap().as_i64().unwrap());
        assert_eq!(true, could.get(3).unwrap().as_bool().unwrap());
    }

    #[test]
    fn parse_client() {
        let yaml = "
local:
  port: 7000
client:
  addresses:
    - 127.0.0.1:25999
  connection_id: 1x7ijy6
  lb_policy: ROUND_ROBIN
  ";
        let config = Config::from_reader(yaml.as_bytes()).unwrap();
        assert_eq!(7000, config.local.port);
        match config.connections {
            ConnectionConfig::Client {
                addresses,
                connection_id,
                lb_policy,
            } => {
                assert_eq!("1x7ijy6", connection_id);
                assert_eq!(
                    vec!["127.0.0.1:25999".parse::<SocketAddr>().unwrap()],
                    addresses
                );
                assert_eq!(Some(LoadBalancerPolicy::RoundRobin), lb_policy);
            }
            ConnectionConfig::Server { .. } => panic!("Should not be a receiver"),
        }
    }

    #[test]
    fn parse_server() {
        let yaml = "
---
local:
  port: 7000
server:
  endpoints:
    - name: Game Server No. 1
      address: 127.0.0.1:26000
      connection_ids:
        - 1x7ijy6
        - 8gj3v2i
    - name: Game Server No. 2
      address: 127.0.0.1:26001
      connection_ids:
        - nkuy70x";
        let config = Config::from_reader(yaml.as_bytes()).unwrap();
        assert_eq!(7000, config.local.port);
        assert_eq!(0, config.filters.len());
        match config.connections {
            ConnectionConfig::Client { .. } => panic!("Should not be a Client"),
            ConnectionConfig::Server { endpoints } => {
                let expected = vec![
                    EndPoint {
                        name: String::from("Game Server No. 1"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1x7ijy6"), String::from("8gj3v2i")],
                    },
                    EndPoint {
                        name: String::from("Game Server No. 2"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("nkuy70x")],
                    },
                ];
                assert_eq!(expected, endpoints);
            }
        }
    }

    #[test]
    fn validate() {
        // client
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Client {
                addresses: vec![
                    "127.0.0.1:25999".parse().unwrap(),
                    "127.0.0.1:25998".parse().unwrap(),
                ],
                connection_id: String::from("1234"),
                lb_policy: Some(LoadBalancerPolicy::RoundRobin),
            },
        };

        assert!(config.validate().is_ok());

        // server - valid
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Server {
                endpoints: vec![
                    EndPoint {
                        name: String::from("ONE"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234"), String::from("5678")],
                    },
                    EndPoint {
                        name: String::from("TWO"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("1234")],
                    },
                ],
            },
        };
        assert!(config.validate().is_ok());

        // server - non unique endpoint names
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Server {
                endpoints: vec![
                    EndPoint {
                        name: String::from("SAME"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234"), String::from("5678")],
                    },
                    EndPoint {
                        name: String::from("SAME"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("1234")],
                    },
                ],
            },
        };

        assert_eq!(
            ValidationError::NotUnique("endpoint.name".to_string()).to_string(),
            config.validate().unwrap_err().to_string()
        )
    }
}
<commit_msg>Validate that addresses are unique (#74)<commit_after>/*
 * Copyright 2020 Google LLC All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use std::collections::HashSet;
use std::fmt;
use std::io;
use std::net::SocketAddr;

use serde::export::Formatter;
use serde::{Deserialize, Serialize};

/// Validation failure for a Config
#[derive(Debug, PartialEq)]
pub enum ValidationError {
    NotUnique(String),
}

impl fmt::Display for ValidationError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            ValidationError::NotUnique(field) => write!(f, "field {} is not unique", field),
        }
    }
}

/// Config is the configuration for either a Client or Server proxy
#[derive(Debug, Deserialize, Serialize)]
pub struct Config {
    pub local: Local,
    #[serde(default)]
    pub filters: Vec<Filter>,
    #[serde(flatten)]
    pub connections: ConnectionConfig,
}

/// Local is the local host configuration options
#[derive(Debug, Deserialize, Serialize)]
pub struct Local {
    pub port: u16,
}

/// LoadBalancerPolicy represents how a proxy load-balances
/// traffic between endpoints.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
pub enum LoadBalancerPolicy {
    /// Send all traffic to all endpoints.
    #[serde(rename = "BROADCAST")]
    Broadcast,
    /// Send traffic to endpoints in turns.
    #[serde(rename = "ROUND_ROBIN")]
    RoundRobin,
    /// Send traffic to endpoints chosen at random.
    #[serde(rename = "RANDOM")]
    Random,
}

/// Filter is the configuration for a single filter
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Filter {
    pub name: String,
    pub config: serde_yaml::Value,
}

/// ConnectionConfig is the configuration for either a Client or Server proxy
#[derive(Debug, Deserialize, Serialize)]
pub enum ConnectionConfig {
    /// Client is the configuration for a client proxy, for sitting behind a game client.
    #[serde(rename = "client")]
    Client {
        addresses: Vec<SocketAddr>,
        connection_id: String,
        lb_policy: Option<LoadBalancerPolicy>,
    },

    /// Server is the configuration for a Dedicated Game Server proxy
    #[serde(rename = "server")]
    Server { endpoints: Vec<EndPoint> },
}

/// A singular endpoint, to pass on UDP packets to.
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)]
pub struct EndPoint {
    pub name: String,
    pub address: SocketAddr,
    pub connection_ids: Vec<String>,
}

impl Config {
    /// from_reader returns a config from a given Reader
    pub fn from_reader<R: io::Read>(input: R) -> Result<Config, serde_yaml::Error> {
        serde_yaml::from_reader(input)
    }

    /// validates the current Config.
    pub fn validate(&self) -> Result<(), ValidationError> {
        match &self.connections {
            ConnectionConfig::Server { endpoints } => {
                if endpoints
                    .iter()
                    .map(|ep| ep.name.clone())
                    .collect::<HashSet<_>>()
                    .len()
                    != endpoints.len()
                {
                    return Err(ValidationError::NotUnique("endpoint.name".to_string()));
                }

                if endpoints
                    .iter()
                    .map(|ep| ep.address)
                    .collect::<HashSet<_>>()
                    .len()
                    != endpoints.len()
                {
                    return Err(ValidationError::NotUnique("endpoint.address".to_string()));
                }
            }
            ConnectionConfig::Client {
                addresses,
                connection_id: _,
                lb_policy: _,
            } => {
                if addresses.iter().collect::<HashSet<_>>().len() != addresses.len() {
                    return Err(ValidationError::NotUnique(
                        "connections.addresses".to_string(),
                    ));
                }
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use std::net::SocketAddr;

    use serde_yaml::Value;

    use crate::config::{
        Config, ConnectionConfig, EndPoint, LoadBalancerPolicy, Local, ValidationError,
    };

    #[test]
    fn deserialise_client() {
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Client {
                addresses: vec!["127.0.0.1:25999".parse().unwrap()],
                connection_id: String::from("1234"),
                lb_policy: Some(LoadBalancerPolicy::RoundRobin),
            },
        };
        let yaml = serde_yaml::to_string(&config).unwrap();
        println!("{}", yaml);
    }

    #[test]
    fn deserialise_server() {
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Server {
                endpoints: vec![
                    EndPoint {
                        name: String::from("No.1"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234"), String::from("5678")],
                    },
                    EndPoint {
                        name: String::from("No.2"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("1234")],
                    },
                ],
            },
        };
        let yaml = serde_yaml::to_string(&config).unwrap();
        println!("{}", yaml);
    }

    #[test]
    fn parse_filter_config() {
        let yaml = "
local:
  port: 7000 # the port to receive traffic to locally
filters: # new filters section
  - name: quilkin.core.v1.rate-limiter
    config:
      map: of arbitrary key value pairs
      could:
        - also
        - be
        - 27
        - true
client:
  addresses:
    - 127.0.0.1:7001
  connection_id: 1x7ijy6
        ";
        let config = Config::from_reader(yaml.as_bytes()).unwrap();

        let filter = config.filters.get(0).unwrap();
        assert_eq!("quilkin.core.v1.rate-limiter", filter.name);
        let filter_config = filter.config.as_mapping().unwrap();

        let key = Value::from("map");
        assert_eq!(
            "of arbitrary key value pairs",
            filter_config.get(&key).unwrap().as_str().unwrap()
        );

        let key = Value::from("could");
        let could = filter_config.get(&key).unwrap().as_sequence().unwrap();
        assert_eq!("also", could.get(0).unwrap().as_str().unwrap());
        assert_eq!("be", could.get(1).unwrap().as_str().unwrap());
        assert_eq!(27, could.get(2).unwrap().as_i64().unwrap());
        assert_eq!(true, could.get(3).unwrap().as_bool().unwrap());
    }

    #[test]
    fn parse_client() {
        let yaml = "
local:
  port: 7000
client:
  addresses:
    - 127.0.0.1:25999
  connection_id: 1x7ijy6
  lb_policy: ROUND_ROBIN
  ";
        let config = Config::from_reader(yaml.as_bytes()).unwrap();
        assert_eq!(7000, config.local.port);
        match config.connections {
            ConnectionConfig::Client {
                addresses,
                connection_id,
                lb_policy,
            } => {
                assert_eq!("1x7ijy6", connection_id);
                assert_eq!(
                    vec!["127.0.0.1:25999".parse::<SocketAddr>().unwrap()],
                    addresses
                );
                assert_eq!(Some(LoadBalancerPolicy::RoundRobin), lb_policy);
            }
            ConnectionConfig::Server { .. } => panic!("Should not be a receiver"),
        }
    }

    #[test]
    fn parse_server() {
        let yaml = "
---
local:
  port: 7000
server:
  endpoints:
    - name: Game Server No. 1
      address: 127.0.0.1:26000
      connection_ids:
        - 1x7ijy6
        - 8gj3v2i
    - name: Game Server No. 2
      address: 127.0.0.1:26001
      connection_ids:
        - nkuy70x";
        let config = Config::from_reader(yaml.as_bytes()).unwrap();
        assert_eq!(7000, config.local.port);
        assert_eq!(0, config.filters.len());
        match config.connections {
            ConnectionConfig::Client { .. } => panic!("Should not be a Client"),
            ConnectionConfig::Server { endpoints } => {
                let expected = vec![
                    EndPoint {
                        name: String::from("Game Server No. 1"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1x7ijy6"), String::from("8gj3v2i")],
                    },
                    EndPoint {
                        name: String::from("Game Server No. 2"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("nkuy70x")],
                    },
                ];
                assert_eq!(expected, endpoints);
            }
        }
    }

    #[test]
    fn validate() {
        // client - valid
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Client {
                addresses: vec![
                    "127.0.0.1:25999".parse().unwrap(),
                    "127.0.0.1:25998".parse().unwrap(),
                ],
                connection_id: String::from("1234"),
                lb_policy: Some(LoadBalancerPolicy::RoundRobin),
            },
        };

        assert!(config.validate().is_ok());

        // client - non unique address
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Client {
                addresses: vec![
                    "127.0.0.1:25999".parse().unwrap(),
                    "127.0.0.1:25999".parse().unwrap(),
                ],
                connection_id: String::from("1234"),
                lb_policy: Some(LoadBalancerPolicy::RoundRobin),
            },
        };

        assert_eq!(
            ValidationError::NotUnique("connections.addresses".to_string()).to_string(),
            config.validate().unwrap_err().to_string()
        );

        // server - valid
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Server {
                endpoints: vec![
                    EndPoint {
                        name: String::from("ONE"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234"), String::from("5678")],
                    },
                    EndPoint {
                        name: String::from("TWO"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("1234")],
                    },
                ],
            },
        };
        assert!(config.validate().is_ok());

        // server - non unique endpoint names
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Server {
                endpoints: vec![
                    EndPoint {
                        name: String::from("SAME"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234"), String::from("5678")],
                    },
                    EndPoint {
                        name: String::from("SAME"),
                        address: "127.0.0.1:26001".parse().unwrap(),
                        connection_ids: vec![String::from("1234")],
                    },
                ],
            },
        };

        assert_eq!(
            ValidationError::NotUnique("endpoint.name".to_string()).to_string(),
            config.validate().unwrap_err().to_string()
        );

        // server - non unique addresses
        let config = Config {
            local: Local { port: 7000 },
            filters: vec![],
            connections: ConnectionConfig::Server {
                endpoints: vec![
                    EndPoint {
                        name: String::from("ONE"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234"), String::from("5678")],
                    },
                    EndPoint {
                        name: String::from("TWO"),
                        address: "127.0.0.1:26000".parse().unwrap(),
                        connection_ids: vec![String::from("1234")],
                    },
                ],
            },
        };

        assert_eq!(
            ValidationError::NotUnique("endpoint.address".to_string()).to_string(),
            config.validate().unwrap_err().to_string()
        );
    }
}
<|endoftext|>


<commit_before>pub type c_char = i8;
pub type c_long = i64;
pub type c_ulong = u64;

pub type wchar_t = i16;

pub type off_t = c_long;
pub type mode_t = u16;
pub type time_t = i64;
pub type pid_t = usize;
pub type gid_t = usize;
pub type uid_t = usize;

pub type suseconds_t = i64;

s! {
    pub struct timeval {
        pub tv_sec: time_t,
        pub tv_usec: suseconds_t,
    }

    pub struct timespec {
        pub tv_sec: time_t,
        pub tv_nsec: c_long,
    }
}

pub const STDIN_FILENO: ::c_int = 0;
pub const STDOUT_FILENO: ::c_int = 1;
pub const STDERR_FILENO: ::c_int = 2;

pub const EXIT_FAILURE: ::c_int = 1;
pub const EXIT_SUCCESS: ::c_int = 0;

pub const S_ISUID: ::c_int = 0x800;
pub const S_ISGID: ::c_int = 0x400;
pub const S_ISVTX: ::c_int = 0x200;

pub const S_IFIFO: mode_t = 0x1000;
pub const S_IFCHR: mode_t = 0x2000;
pub const S_IFBLK: mode_t = 0x6000;
pub const S_IFDIR: mode_t = 0x4000;
pub const S_IFREG: mode_t = 0x8000;
pub const S_IFLNK: mode_t = 0xA000;
pub const S_IFSOCK: mode_t = 0xC000;
pub const S_IFMT: mode_t = 0xF000;
pub const S_IEXEC: mode_t = 0x40;
pub const S_IWRITE: mode_t = 0x80;
pub const S_IREAD: mode_t = 0x100;
pub const S_IRWXU: mode_t = 0x1C0;
pub const S_IXUSR: mode_t = 0x40;
pub const S_IWUSR: mode_t = 0x80;
pub const S_IRUSR: mode_t = 0x100;
pub const S_IRWXG: mode_t = 0x38;
pub const S_IXGRP: mode_t = 0x8;
pub const S_IWGRP: mode_t = 0x10;
pub const S_IRGRP: mode_t = 0x20;
pub const S_IRWXO: mode_t = 0x7;
pub const S_IXOTH: mode_t = 0x1;
pub const S_IWOTH: mode_t = 0x2;
pub const S_IROTH: mode_t = 0x4;

pub const F_DUPFD: ::c_int = 0;
pub const F_GETFD: ::c_int = 1;
pub const F_SETFD: ::c_int = 2;
pub const F_GETFL: ::c_int = 3;
pub const F_SETFL: ::c_int = 4;

pub const O_RDONLY: ::c_int =     0x0001_0000;
pub const O_WRONLY: ::c_int =     0x0002_0000;
pub const O_RDWR: ::c_int =       0x0003_0000;
pub const O_NONBLOCK: ::c_int =   0x0004_0000;
pub const O_APPEND: ::c_int =     0x0008_0000;
pub const O_SHLOCK: ::c_int =     0x0010_0000;
pub const O_EXLOCK: ::c_int =     0x0020_0000;
pub const O_ASYNC: ::c_int =      0x0040_0000;
pub const O_FSYNC: ::c_int =      0x0080_0000;
pub const O_CLOEXEC: ::c_int =    0x0100_0000;
pub const O_CREAT: ::c_int =      0x0200_0000;
pub const O_TRUNC: ::c_int =      0x0400_0000;
pub const O_EXCL: ::c_int =       0x0800_0000;
pub const O_DIRECTORY: ::c_int =  0x1000_0000;
pub const O_STAT: ::c_int =       0x2000_0000;
pub const O_SYMLINK: ::c_int =    0x4000_0000;
pub const O_NOFOLLOW: ::c_int =   0x8000_0000;
pub const O_ACCMODE: ::c_int =    O_RDONLY | O_WRONLY | O_RDWR;

pub const SIGHUP:    ::c_int = 1;
pub const SIGINT:    ::c_int = 2;
pub const SIGQUIT:   ::c_int = 3;
pub const SIGILL:    ::c_int = 4;
pub const SIGTRAP:   ::c_int = 5;
pub const SIGABRT:   ::c_int = 6;
pub const SIGBUS:    ::c_int = 7;
pub const SIGFPE:    ::c_int = 8;
pub const SIGKILL:   ::c_int = 9;
pub const SIGUSR1:   ::c_int = 10;
pub const SIGSEGV:   ::c_int = 11;
pub const SIGUSR2:   ::c_int = 12;
pub const SIGPIPE:   ::c_int = 13;
pub const SIGALRM:   ::c_int = 14;
pub const SIGTERM:   ::c_int = 15;
pub const SIGSTKFLT: ::c_int = 16;
pub const SIGCHLD:   ::c_int = 17;
pub const SIGCONT:   ::c_int = 18;
pub const SIGSTOP:   ::c_int = 19;
pub const SIGTSTP:   ::c_int = 20;
pub const SIGTTIN:   ::c_int = 21;
pub const SIGTTOU:   ::c_int = 22;
pub const SIGURG:    ::c_int = 23;
pub const SIGXCPU:   ::c_int = 24;
pub const SIGXFSZ:   ::c_int = 25;
pub const SIGVTALRM: ::c_int = 26;
pub const SIGPROF:   ::c_int = 27;
pub const SIGWINCH:  ::c_int = 28;
pub const SIGIO:     ::c_int = 29;
pub const SIGPWR:    ::c_int = 30;
pub const SIGSYS:    ::c_int = 31;

extern {
    pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int;
    pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void;
    pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t)
                -> ::ssize_t;
    pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t)
                 -> ::ssize_t;
    pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int;
    pub fn close(fd: ::c_int) -> ::c_int;
}

#[link(name = "c")]
#[link(name = "m")]
extern {}

pub use self::net::*;

mod net;
<commit_msg>Auto merge of #1021 - redox-os:master, r=alexcrichton<commit_after>pub type c_char = i8;
pub type c_long = i64;
pub type c_ulong = u64;

pub type wchar_t = i16;

pub type off_t = c_long;
pub type mode_t = u16;
pub type time_t = i64;
pub type pid_t = usize;
pub type gid_t = usize;
pub type uid_t = usize;

pub type suseconds_t = i64;

s! {
    pub struct timeval {
        pub tv_sec: time_t,
        pub tv_usec: suseconds_t,
    }

    pub struct timespec {
        pub tv_sec: time_t,
        pub tv_nsec: c_long,
    }
}

pub const STDIN_FILENO: ::c_int = 0;
pub const STDOUT_FILENO: ::c_int = 1;
pub const STDERR_FILENO: ::c_int = 2;

pub const EXIT_FAILURE: ::c_int = 1;
pub const EXIT_SUCCESS: ::c_int = 0;

pub const S_ISUID: ::c_int = 0x800;
pub const S_ISGID: ::c_int = 0x400;
pub const S_ISVTX: ::c_int = 0x200;

pub const S_IFIFO: mode_t = 0x1000;
pub const S_IFCHR: mode_t = 0x2000;
pub const S_IFBLK: mode_t = 0x6000;
pub const S_IFDIR: mode_t = 0x4000;
pub const S_IFREG: mode_t = 0x8000;
pub const S_IFLNK: mode_t = 0xA000;
pub const S_IFSOCK: mode_t = 0xC000;
pub const S_IFMT: mode_t = 0xF000;
pub const S_IEXEC: mode_t = 0x40;
pub const S_IWRITE: mode_t = 0x80;
pub const S_IREAD: mode_t = 0x100;
pub const S_IRWXU: mode_t = 0x1C0;
pub const S_IXUSR: mode_t = 0x40;
pub const S_IWUSR: mode_t = 0x80;
pub const S_IRUSR: mode_t = 0x100;
pub const S_IRWXG: mode_t = 0x38;
pub const S_IXGRP: mode_t = 0x8;
pub const S_IWGRP: mode_t = 0x10;
pub const S_IRGRP: mode_t = 0x20;
pub const S_IRWXO: mode_t = 0x7;
pub const S_IXOTH: mode_t = 0x1;
pub const S_IWOTH: mode_t = 0x2;
pub const S_IROTH: mode_t = 0x4;

pub const F_DUPFD: ::c_int = 0;
pub const F_GETFD: ::c_int = 1;
pub const F_SETFD: ::c_int = 2;
pub const F_GETFL: ::c_int = 3;
pub const F_SETFL: ::c_int = 4;

pub const O_RDONLY: ::c_int =     0x0001_0000;
pub const O_WRONLY: ::c_int =     0x0002_0000;
pub const O_RDWR: ::c_int =       0x0003_0000;
pub const O_NONBLOCK: ::c_int =   0x0004_0000;
pub const O_APPEND: ::c_int =     0x0008_0000;
pub const O_SHLOCK: ::c_int =     0x0010_0000;
pub const O_EXLOCK: ::c_int =     0x0020_0000;
pub const O_ASYNC: ::c_int =      0x0040_0000;
pub const O_FSYNC: ::c_int =      0x0080_0000;
pub const O_CLOEXEC: ::c_int =    0x0100_0000;
pub const O_CREAT: ::c_int =      0x0200_0000;
pub const O_TRUNC: ::c_int =      0x0400_0000;
pub const O_EXCL: ::c_int =       0x0800_0000;
pub const O_DIRECTORY: ::c_int =  0x1000_0000;
pub const O_STAT: ::c_int =       0x2000_0000;
pub const O_SYMLINK: ::c_int =    0x4000_0000;
pub const O_NOFOLLOW: ::c_int =   0x8000_0000;
pub const O_ACCMODE: ::c_int =    O_RDONLY | O_WRONLY | O_RDWR;

pub const SIGHUP:    ::c_int = 1;
pub const SIGINT:    ::c_int = 2;
pub const SIGQUIT:   ::c_int = 3;
pub const SIGILL:    ::c_int = 4;
pub const SIGTRAP:   ::c_int = 5;
pub const SIGABRT:   ::c_int = 6;
pub const SIGBUS:    ::c_int = 7;
pub const SIGFPE:    ::c_int = 8;
pub const SIGKILL:   ::c_int = 9;
pub const SIGUSR1:   ::c_int = 10;
pub const SIGSEGV:   ::c_int = 11;
pub const SIGUSR2:   ::c_int = 12;
pub const SIGPIPE:   ::c_int = 13;
pub const SIGALRM:   ::c_int = 14;
pub const SIGTERM:   ::c_int = 15;
pub const SIGSTKFLT: ::c_int = 16;
pub const SIGCHLD:   ::c_int = 17;
pub const SIGCONT:   ::c_int = 18;
pub const SIGSTOP:   ::c_int = 19;
pub const SIGTSTP:   ::c_int = 20;
pub const SIGTTIN:   ::c_int = 21;
pub const SIGTTOU:   ::c_int = 22;
pub const SIGURG:    ::c_int = 23;
pub const SIGXCPU:   ::c_int = 24;
pub const SIGXFSZ:   ::c_int = 25;
pub const SIGVTALRM: ::c_int = 26;
pub const SIGPROF:   ::c_int = 27;
pub const SIGWINCH:  ::c_int = 28;
pub const SIGIO:     ::c_int = 29;
pub const SIGPWR:    ::c_int = 30;
pub const SIGSYS:    ::c_int = 31;

extern {
    pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int;
    pub fn getpid() -> pid_t;
    pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void;
    pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t)
                -> ::ssize_t;
    pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t)
                 -> ::ssize_t;
    pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int;
    pub fn close(fd: ::c_int) -> ::c_int;
}

#[link(name = "c")]
#[link(name = "m")]
extern {}

pub use self::net::*;

mod net;
<|endoftext|>


<commit_before>use std::error;
use std::fmt;
use std::string;
use std::num;

use redis::Value;

use serde::{self, de};

/// Error that can be produced during deserialization
#[derive(Debug)]
pub enum Error {
    Syntax(String),
    EndOfStream,
    UnknownField(String),
    MissingField(&'static str),
    DeserializeNotSupported,
    WrongValue(String),
    FromUtf8(string::FromUtf8Error),
    ParseInt(num::ParseIntError),
    ParseFloat(num::ParseFloatError),
}

impl Error {
    pub fn wrong_value<S>(msg: S) -> Error
        where S: Into<String>
    {
        Error::WrongValue(msg.into())
    }
}

pub type Result<T> = ::std::result::Result<T, Error>;

impl error::Error for Error {
    fn description(&self) -> &str {
        unimplemented!();
    }

    fn cause(&self) -> Option<&error::Error> {
        unimplemented!();
    }
}

impl fmt::Display for Error {
    fn fmt(&self, _fmt: &mut fmt::Formatter) -> fmt::Result {
        unimplemented!();
    }
}

impl de::Error for Error {
    fn syntax(desc: &str) -> Error {
        Error::Syntax(desc.into())
    }

    fn end_of_stream() -> Error {
        Error::EndOfStream
    }

    fn unknown_field(field: &str) -> Error {
        Error::UnknownField(field.into())
    }

    fn missing_field(field: &'static str) -> Error {
        Error::MissingField(field)
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(err: string::FromUtf8Error) -> Error {
        Error::FromUtf8(err)
    }
}

impl From<num::ParseIntError> for Error {
    fn from(err: num::ParseIntError) -> Error {
        Error::ParseInt(err)
    }
}

impl From<num::ParseFloatError> for Error {
    fn from(err: num::ParseFloatError) -> Error {
        Error::ParseFloat(err)
    }
}

/// deserializes Redis `Value`s
#[derive(Debug)]
pub struct Deserializer {
    root_values: Vec<Value>,
    nested_values: Vec<Value>,
    processing_nested_values: bool
}

impl Deserializer {
    pub fn new(redis_value: Value) -> Result<Deserializer> {
        let mut values = match redis_value {
            Value::Data(bytes) => vec![Value::Data(bytes)],
            Value::Bulk(bulk) => bulk,
            Value::Int(i) => vec![Value::Int(i)],
            Value::Nil => vec![Value::Nil],
            _ => return Err(Error::wrong_value("must be a redis value type"))
        };

        // TODO: would be better to turn this into an iterator than have to reverse and use the
        // vector.
        values.reverse();

        Ok(Deserializer {
            root_values: values,
            nested_values: Vec::new(),
            processing_nested_values: false
        })
    }

    /// Returns a reference to the next value
    ///
    /// Some qualification is required on "next value". If processing a subsequence (eg a hashmap
    /// returned in a pipeline), and the subsequence has come to an end, None will be returned even
    /// though the pipeline itself has additional data. This signals to the current visitor that
    /// there are no more values for it. The sequence visitor will continue using the pipeline data.
    pub fn peek(&self) -> Option<&Value> {
        if self.processing_nested_values {
            self.nested_values.last()
        } else {
            self.root_values.last()
        }
    }

    /// Return the next value
    ///
    /// See the qualification in the `peek` documentation as to the meaning of "next value".
    ///
    /// Unlike peek, this function will continue iterating on values. A value will be returned as
    /// long as the current subsequence or root sequence still has Values.
    pub fn next(&mut self) -> Result<Value> {
        // Work in the nested set if it's available
        if self.nested_values.len() != 0 {
            return match self.nested_values.pop() {
                Some(v) =>  Ok(v),
                None => Err(serde::de::Error::end_of_stream())
            };
        }

        // Otherwise, pop off the main list. If it's a bulk value, it becomes the new nested list,
        // and a value is returned from there.
        match self.root_values.pop() {
            Some(v) => {
                match v {
                    Value::Bulk(vals) => {
                        // descend into subsequence
                        self.set_subsequence(vals);
                        self.next()
                    },
                    _ => {
                        // Not processing nested values if this branch is reached.
                        self.processing_nested_values = false;
                        Ok(v)
                    }
                }
            },
            None => Err(serde::de::Error::end_of_stream())
        }
    }

    /// Sets a new subsequence
    fn set_subsequence(&mut self, mut values: Vec<Value>) {
        values.reverse();
        self.nested_values = values;
        self.processing_nested_values = true;
    }

    /// Notify that current bulk item has been completed (eg map, sequence)
    ///
    /// Visitors use this to update the deserializer state.
    pub fn completed_set(&mut self) {
        self.processing_nested_values = false;
    }

    pub fn read_string(&mut self) -> Result<String> {
        let redis_value = try!(self.next());
        Ok(match redis_value {
            Value::Data(bytes) => try!(String::from_utf8(bytes)),
            _ => {
                let msg = format!("Expected Data, got {:?}", &redis_value);
                return Err(Error::wrong_value(msg));
            }
        })
    }
}

macro_rules! impl_num {
    ($ty:ty, $deserialize_method:ident, $visitor_method:ident) => {
        #[inline]
        fn $deserialize_method<V>(&mut self, mut visitor: V) -> Result<V::Value>
            where V: serde::de::Visitor,
        {
            let redis_value = try!(self.next());
            let value = match redis_value {
                Value::Data(bytes) => {
                    let s = try!(String::from_utf8(bytes));
                    try!(s.parse::<$ty>())
                },
                Value::Int(i) => i as $ty,
                _ => {
                    let msg = format!("Expected Data or Int, got {:?}", &redis_value);
                    return Err(Error::wrong_value(msg));
                }
            };

            visitor.$visitor_method(value)
        }
    }
}

impl serde::Deserializer for Deserializer {
    type Error = Error;

    #[inline]
    fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        Err(Error::DeserializeNotSupported)
    }

    #[inline]
    fn deserialize_string<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        let s = try!(self.read_string());
        visitor.visit_string(s)
    }

    impl_num!(u8, deserialize_u8, visit_u8);
    impl_num!(u16, deserialize_u16, visit_u16);
    impl_num!(u32, deserialize_u32, visit_u32);
    impl_num!(u64, deserialize_u64, visit_u64);
    impl_num!(usize, deserialize_usize, visit_usize);

    impl_num!(i8, deserialize_i8, visit_i8);
    impl_num!(i16, deserialize_i16, visit_i16);
    impl_num!(i32, deserialize_i32, visit_i32);
    impl_num!(i64, deserialize_i64, visit_i64);
    impl_num!(isize, deserialize_isize, visit_isize);

    impl_num!(f32, deserialize_f32, visit_f32);
    impl_num!(f64, deserialize_f64, visit_f64);

    #[inline]
    fn deserialize_seq<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_seq(SeqVisitor { de: self })
    }

    #[inline]
    fn deserialize_map<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        visitor.visit_map(MapVisitor { de: self })
    }

    #[inline]
    fn deserialize_struct_key<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        let s = try!(self.read_string());
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_ignored_any<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        let s = try!(self.read_string());
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_enum<V>(&mut self,
                     _enum: &'static str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value>
        where V: serde::de::EnumVisitor,
    {
        visitor.visit(VariantVisitor { de: self })
    }

    #[inline]
    fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor
    {
        let maybe = match self.peek() {
            Some(v) => {
                match *v {
                    Value::Data(_) => Some(()),
                    Value::Int(_) => Some(()),
                    Value::Nil => None,
                    _ => {
                        let msg = format!("Expected Data, Int, or Nil");
                        return Err(Error::wrong_value(msg));
                    }
                }
            },
            None => None,
        };

        if maybe.is_some() {
            visitor.visit_some(self)
        } else {
            visitor.visit_none()
        }
    }

}

struct SeqVisitor<'a> {
    de: &'a mut Deserializer,
}

impl<'a> de::SeqVisitor for SeqVisitor<'a> {
    type Error = Error;

    fn visit<T>(&mut self) -> Result<Option<T>>
        where T: de::Deserialize
    {
        if self.de.peek().is_some() {
            let value = try!(serde::Deserialize::deserialize(self.de));
            Ok(Some(value))
        } else {
            Ok(None)
        }
    }

    fn end(&mut self) -> Result<()> {
        self.de.completed_set();
        Ok(())
    }
}

struct MapVisitor<'a> {
    de: &'a mut Deserializer
}

impl<'a> serde::de::MapVisitor for MapVisitor<'a> {
    type Error = Error;

    fn visit_key<K>(&mut self) -> Result<Option<K>>
        where K: de::Deserialize,
    {
        if self.de.peek().is_some() {
            let key = try!(serde::Deserialize::deserialize(self.de));
            Ok(Some(key))
        } else {
            Ok(None)
        }
    }

    #[inline]
    fn visit_value<V>(&mut self) -> Result<V>
        where V: de::Deserialize,
    {
        serde::Deserialize::deserialize(self.de)
    }

    #[inline]
    fn end(&mut self) -> Result<()> {
        // ignore any unused values since keys can randomly be added in Redis
        self.de.completed_set();
        Ok(())
    }

    fn missing_field<V>(&mut self, _field: &'static str) -> Result<V>
        where V: de::Deserialize,
    {

        let mut de = de::value::ValueDeserializer::into_deserializer(());
        de::Deserialize::deserialize(&mut de)
    }
}

struct VariantVisitor<'a> {
    de: &'a mut Deserializer
}

impl<'a> serde::de::VariantVisitor for VariantVisitor<'a> {
    type Error = Error;

    fn visit_variant<V>(&mut self) -> Result<V>
        where V: serde::Deserialize,
    {
        let value = try!(serde::Deserialize::deserialize(self.de));
        Ok(value)
    }

    fn visit_unit(&mut self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype<T>(&mut self) -> Result<T>
        where T: serde::de::Deserialize,
    {
        Err(de::Error::syntax("newtype variants are not supported"))
    }

    fn visit_tuple<V>(&mut self,
                      _len: usize,
                      _visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        Err(de::Error::syntax("tuple variants are not supported"))
    }

    fn visit_struct<V>(&mut self,
                       _fields: &'static [&'static str],
                       _visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        Err(de::Error::syntax("struct variants are not supported"))
    }
}

<commit_msg>Implements Error and Display for decode::Error<commit_after>use std::error;
use std::fmt;
use std::string;
use std::num;

use redis::Value;

use serde::{self, de};

/// Error that can be produced during deserialization
#[derive(Debug)]
pub enum Error {
    Syntax(String),
    EndOfStream,
    UnknownField(String),
    MissingField(&'static str),
    DeserializeNotSupported,
    WrongValue(String),
    FromUtf8(string::FromUtf8Error),
    ParseInt(num::ParseIntError),
    ParseFloat(num::ParseFloatError),
}

impl Error {
    pub fn wrong_value<S>(msg: S) -> Error
        where S: Into<String>
    {
        Error::WrongValue(msg.into())
    }
}

pub type Result<T> = ::std::result::Result<T, Error>;

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Syntax(_) => "syntax error when decoding redis values",
            Error::EndOfStream => "end of redis value stream",
            Error::UnknownField(_) => "unknown field",
            Error::MissingField(_) => "missing field",
            Error::DeserializeNotSupported => "unsupported deserialization operation",
            Error::WrongValue(_) => "expected value of different type",
            Error::FromUtf8(ref err) => err.description(),
            Error::ParseInt(ref err) => err.description(),
            Error::ParseFloat(ref err) => err.description(),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::FromUtf8(ref err) => Some(err),
            Error::ParseInt(ref err) => Some(err),
            Error::ParseFloat(ref err) => Some(err),
            _ => None,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Syntax(ref reason) => write!(f, "SyntaxError({})", reason),
            Error::EndOfStream => write!(f, "Reached end of stream"),
            Error::UnknownField(ref field) => write!(f, "got unexpected field: {}", field),
            Error::MissingField(ref field) => write!(f, "missing field: {}", field),
            Error::DeserializeNotSupported => write!(f, "Deserialization option not supported"),
            Error::WrongValue(ref value_type) => write!(f, "Got unexpected value: {}", value_type),
            Error::FromUtf8(ref e) => write!(f, "{}", e),
            Error::ParseInt(ref e) => write!(f, "{}", e),
            Error::ParseFloat(ref e) => write!(f, "{}", e),
        }
    }
}

impl de::Error for Error {
    fn syntax(desc: &str) -> Error {
        Error::Syntax(desc.into())
    }

    fn end_of_stream() -> Error {
        Error::EndOfStream
    }

    fn unknown_field(field: &str) -> Error {
        Error::UnknownField(field.into())
    }

    fn missing_field(field: &'static str) -> Error {
        Error::MissingField(field)
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(err: string::FromUtf8Error) -> Error {
        Error::FromUtf8(err)
    }
}

impl From<num::ParseIntError> for Error {
    fn from(err: num::ParseIntError) -> Error {
        Error::ParseInt(err)
    }
}

impl From<num::ParseFloatError> for Error {
    fn from(err: num::ParseFloatError) -> Error {
        Error::ParseFloat(err)
    }
}

/// deserializes Redis `Value`s
#[derive(Debug)]
pub struct Deserializer {
    root_values: Vec<Value>,
    nested_values: Vec<Value>,
    processing_nested_values: bool
}

impl Deserializer {
    pub fn new(redis_value: Value) -> Result<Deserializer> {
        let mut values = match redis_value {
            Value::Data(bytes) => vec![Value::Data(bytes)],
            Value::Bulk(bulk) => bulk,
            Value::Int(i) => vec![Value::Int(i)],
            Value::Nil => vec![Value::Nil],
            _ => return Err(Error::wrong_value("must be a redis value type"))
        };

        // TODO: would be better to turn this into an iterator than have to reverse and use the
        // vector.
        values.reverse();

        Ok(Deserializer {
            root_values: values,
            nested_values: Vec::new(),
            processing_nested_values: false
        })
    }

    /// Returns a reference to the next value
    ///
    /// Some qualification is required on "next value". If processing a subsequence (eg a hashmap
    /// returned in a pipeline), and the subsequence has come to an end, None will be returned even
    /// though the pipeline itself has additional data. This signals to the current visitor that
    /// there are no more values for it. The sequence visitor will continue using the pipeline data.
    pub fn peek(&self) -> Option<&Value> {
        if self.processing_nested_values {
            self.nested_values.last()
        } else {
            self.root_values.last()
        }
    }

    /// Return the next value
    ///
    /// See the qualification in the `peek` documentation as to the meaning of "next value".
    ///
    /// Unlike peek, this function will continue iterating on values. A value will be returned as
    /// long as the current subsequence or root sequence still has Values.
    pub fn next(&mut self) -> Result<Value> {
        // Work in the nested set if it's available
        if self.nested_values.len() != 0 {
            return match self.nested_values.pop() {
                Some(v) =>  Ok(v),
                None => Err(serde::de::Error::end_of_stream())
            };
        }

        // Otherwise, pop off the main list. If it's a bulk value, it becomes the new nested list,
        // and a value is returned from there.
        match self.root_values.pop() {
            Some(v) => {
                match v {
                    Value::Bulk(vals) => {
                        // descend into subsequence
                        self.set_subsequence(vals);
                        self.next()
                    },
                    _ => {
                        // Not processing nested values if this branch is reached.
                        self.processing_nested_values = false;
                        Ok(v)
                    }
                }
            },
            None => Err(serde::de::Error::end_of_stream())
        }
    }

    /// Sets a new subsequence
    fn set_subsequence(&mut self, mut values: Vec<Value>) {
        values.reverse();
        self.nested_values = values;
        self.processing_nested_values = true;
    }

    /// Notify that current bulk item has been completed (eg map, sequence)
    ///
    /// Visitors use this to update the deserializer state.
    pub fn completed_set(&mut self) {
        self.processing_nested_values = false;
    }

    pub fn read_string(&mut self) -> Result<String> {
        let redis_value = try!(self.next());
        Ok(match redis_value {
            Value::Data(bytes) => try!(String::from_utf8(bytes)),
            _ => {
                let msg = format!("Expected Data, got {:?}", &redis_value);
                return Err(Error::wrong_value(msg));
            }
        })
    }
}

macro_rules! impl_num {
    ($ty:ty, $deserialize_method:ident, $visitor_method:ident) => {
        #[inline]
        fn $deserialize_method<V>(&mut self, mut visitor: V) -> Result<V::Value>
            where V: serde::de::Visitor,
        {
            let redis_value = try!(self.next());
            let value = match redis_value {
                Value::Data(bytes) => {
                    let s = try!(String::from_utf8(bytes));
                    try!(s.parse::<$ty>())
                },
                Value::Int(i) => i as $ty,
                _ => {
                    let msg = format!("Expected Data or Int, got {:?}", &redis_value);
                    return Err(Error::wrong_value(msg));
                }
            };

            visitor.$visitor_method(value)
        }
    }
}

impl serde::Deserializer for Deserializer {
    type Error = Error;

    #[inline]
    fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        Err(Error::DeserializeNotSupported)
    }

    #[inline]
    fn deserialize_string<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        let s = try!(self.read_string());
        visitor.visit_string(s)
    }

    impl_num!(u8, deserialize_u8, visit_u8);
    impl_num!(u16, deserialize_u16, visit_u16);
    impl_num!(u32, deserialize_u32, visit_u32);
    impl_num!(u64, deserialize_u64, visit_u64);
    impl_num!(usize, deserialize_usize, visit_usize);

    impl_num!(i8, deserialize_i8, visit_i8);
    impl_num!(i16, deserialize_i16, visit_i16);
    impl_num!(i32, deserialize_i32, visit_i32);
    impl_num!(i64, deserialize_i64, visit_i64);
    impl_num!(isize, deserialize_isize, visit_isize);

    impl_num!(f32, deserialize_f32, visit_f32);
    impl_num!(f64, deserialize_f64, visit_f64);

    #[inline]
    fn deserialize_seq<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_seq(SeqVisitor { de: self })
    }

    #[inline]
    fn deserialize_map<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        visitor.visit_map(MapVisitor { de: self })
    }

    #[inline]
    fn deserialize_struct_key<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        let s = try!(self.read_string());
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_ignored_any<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        let s = try!(self.read_string());
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_enum<V>(&mut self,
                     _enum: &'static str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value>
        where V: serde::de::EnumVisitor,
    {
        visitor.visit(VariantVisitor { de: self })
    }

    #[inline]
    fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor
    {
        let maybe = match self.peek() {
            Some(v) => {
                match *v {
                    Value::Data(_) => Some(()),
                    Value::Int(_) => Some(()),
                    Value::Nil => None,
                    _ => {
                        let msg = format!("Expected Data, Int, or Nil");
                        return Err(Error::wrong_value(msg));
                    }
                }
            },
            None => None,
        };

        if maybe.is_some() {
            visitor.visit_some(self)
        } else {
            visitor.visit_none()
        }
    }

}

struct SeqVisitor<'a> {
    de: &'a mut Deserializer,
}

impl<'a> de::SeqVisitor for SeqVisitor<'a> {
    type Error = Error;

    fn visit<T>(&mut self) -> Result<Option<T>>
        where T: de::Deserialize
    {
        if self.de.peek().is_some() {
            let value = try!(serde::Deserialize::deserialize(self.de));
            Ok(Some(value))
        } else {
            Ok(None)
        }
    }

    fn end(&mut self) -> Result<()> {
        self.de.completed_set();
        Ok(())
    }
}

struct MapVisitor<'a> {
    de: &'a mut Deserializer
}

impl<'a> serde::de::MapVisitor for MapVisitor<'a> {
    type Error = Error;

    fn visit_key<K>(&mut self) -> Result<Option<K>>
        where K: de::Deserialize,
    {
        if self.de.peek().is_some() {
            let key = try!(serde::Deserialize::deserialize(self.de));
            Ok(Some(key))
        } else {
            Ok(None)
        }
    }

    #[inline]
    fn visit_value<V>(&mut self) -> Result<V>
        where V: de::Deserialize,
    {
        serde::Deserialize::deserialize(self.de)
    }

    #[inline]
    fn end(&mut self) -> Result<()> {
        // ignore any unused values since keys can randomly be added in Redis
        self.de.completed_set();
        Ok(())
    }

    fn missing_field<V>(&mut self, _field: &'static str) -> Result<V>
        where V: de::Deserialize,
    {

        let mut de = de::value::ValueDeserializer::into_deserializer(());
        de::Deserialize::deserialize(&mut de)
    }
}

struct VariantVisitor<'a> {
    de: &'a mut Deserializer
}

impl<'a> serde::de::VariantVisitor for VariantVisitor<'a> {
    type Error = Error;

    fn visit_variant<V>(&mut self) -> Result<V>
        where V: serde::Deserialize,
    {
        let value = try!(serde::Deserialize::deserialize(self.de));
        Ok(value)
    }

    fn visit_unit(&mut self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype<T>(&mut self) -> Result<T>
        where T: serde::de::Deserialize,
    {
        Err(de::Error::syntax("newtype variants are not supported"))
    }

    fn visit_tuple<V>(&mut self,
                      _len: usize,
                      _visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        Err(de::Error::syntax("tuple variants are not supported"))
    }

    fn visit_struct<V>(&mut self,
                       _fields: &'static [&'static str],
                       _visitor: V) -> Result<V::Value>
        where V: serde::de::Visitor,
    {
        Err(de::Error::syntax("struct variants are not supported"))
    }
}

<|endoftext|>


<commit_before>//! Decodes a Bitterlemon-encoded byte stream into its original bit stream.

use std::iter::Iterator;

pub fn decode<S>(input: S) -> Decoder<S>
where S : Iterator<Item=u8> {
	Decoder::<S> {
		source: input,
		state: DecodeState::Pending,
	}
}

pub struct Decoder<S> {
	state: DecodeState,
	source: S,
}

#[derive(Debug, PartialEq, Eq)]
pub enum Error {
	TruncatedInput {
		pixels_lost: u8,
		bytes_missing: u8,
	},
}

type IterationResult = Result<bool, Error>;

impl<S> Iterator for Decoder<S>
where S : Iterator<Item=u8> {
	type Item = IterationResult;

	fn next(&mut self) -> Option<Self::Item> {

		// pull from source if needs be
		if self.must_pull() {
			let next = self.source.next();
			self.next_with_pulled(next)
		} else {
			self.next_from_existing()
		}
	}
}

impl<S> Decoder<S>
where S : Iterator<Item=u8> {

	fn must_pull(&self) -> bool {
		match self.state {
			DecodeState::Pending => true,
			DecodeState::Done => false,
			DecodeState::Run(remaining, _) => remaining == 0,
			DecodeState::Frame(remaining, _, stage_size) => remaining == 0 || stage_size == 0,
		}
	}

	fn next_with_pulled(&mut self, next: Option<u8>) -> Option<<Self as Iterator>::Item> {

		// handle None from source
		let next = match next {
			Some(x) => x,
			None => match self.state {
				DecodeState::Pending => {
					self.state = DecodeState::Done;
					return None;
				}, // source was empty
				DecodeState::Done    => { return None; }, // always return None here
				DecodeState::Run(_, _) => {
					unreachable!("next_with_pulled called with more run bits to flush: {:?}", self.state);
				},
				DecodeState::Frame(remaining, _, stage_size) => {
					debug_assert!(stage_size == 0);
					debug_assert!(remaining > 0);

					// missing bytes to complete the frame
					let error_specifics = Error::TruncatedInput {
						pixels_lost: remaining,
						bytes_missing: (remaining + 7) >> 3,
					};
					return Some(Err(error_specifics));
				}
			}
		};

		// handle mid-frame
		if match self.state {
			DecodeState::Frame(ref mut remaining, ref mut stage, ref mut stage_size)
			if *remaining > 0 => {
				debug_assert!(*stage_size == 0); // shouldn't have pulled otherwise
				*stage = next;
				*stage_size = 8;
				// now fall through to real iteration logic
				true
			},
			_ => false
		} {
			return self.next_from_existing();
		}

		let got = match next {
			n if n < 0x80 => {
				// frame beginning
				let frame_size = byte_to_frame_size(n);
				self.state = DecodeState::Frame(frame_size, 0, 0);
				None
			},
			n => {
				// new run
				let frame_size = byte_to_run_size(n);
				let mode = n >= 0xc0;
				self.state = if frame_size > 1 {
					// don't bother moving to run state if only one pixel in this run
					// also, leaving this method in state Run(0, _) is a logic error
					DecodeState::Run(frame_size - 1, mode)
				}
				else {
					DecodeState::Pending
				};
				Some(Ok(mode))
			}
		};

		got.or_else(|| {
			let next = self.source.next();
			self.next_with_pulled(next)
		})
	}

	fn next_from_existing(&mut self) -> Option<<Self as Iterator>::Item> {

		let (to_return, next_state) = match self.state {
			DecodeState::Pending => unreachable!(),
			DecodeState::Done    => { return None; },
			DecodeState::Run(ref mut remaining, ref run_mode) => {
				*remaining -= 1;
				(*run_mode, if *remaining == 0 {Some(DecodeState::Pending)} else {None})
			},
			DecodeState::Frame(ref mut remaining, ref mut stage, ref mut stage_size) => {
				let got_bit = (*stage & 0x80) != 0;
				*stage = (*stage & 0x7f) << 1;
				*stage_size -= 1;
				*remaining -= 1;
				(got_bit, if *remaining == 0 {Some(DecodeState::Pending)} else {None})
			}
		};

		if let Some(next_state) = next_state {
			self.state = next_state;
		}

		Some(Ok(to_return))
	}

}

fn byte_to_run_size(byte: u8) -> u8 {
	let byte = byte & 0x3f;
	if byte == 0 { 0x40 } else { byte }
}

fn byte_to_frame_size(byte: u8) -> u8 {
	if byte == 0 { 0x80 } else { byte }
}

#[derive(Debug)]
enum DecodeState {
	Pending, // should pull
	Run(u8, bool), // run count, is_set
	Frame(u8, u8, u8), // frame pixel count, stage contents, stage size
	Done, // iteration complete
}

#[cfg(test)]
mod test_decoder {

	macro_rules! decoder {
		( $($e:expr),* ) => {
			{
				let v = vec![$( $e, )*];
				super::decode(v.into_iter())
			}
		}
	}

	#[test]
	fn empty_input() {
		let mut iter = decoder![];

		assert_eq!(iter.next(), None);
		assert_eq!(iter.next(), None);
	}

	fn single_run_impl(top_bits: u8, mode: bool) {
		for i in 0..0x3fu8 {
			let run_size = super::byte_to_run_size(i);
			let mut iter = decoder![i+top_bits];
			for _ in 0..run_size {
				assert_eq!(iter.next(), Some(Ok(mode)));
			}
			assert_eq!(iter.next(), None);
		}
	}

	#[test]
	fn single_run_clear() {
		single_run_impl(0x80, false)
	}

	#[test]
	fn single_run_set() {
		single_run_impl(0xc0, true)
	}

	#[test]
	fn single_byte_frame() {
		let case = |byte_in: u8, bool_out: bool| {
			let mut iter = decoder![0x01, byte_in];
			assert_eq!(iter.next(), Some(Ok(bool_out)));
		};

		case(0xff, true);
		case(0x00, false);
		case(0x80, true);
		case(0x7f, false);
	}

	#[test]
	fn full_byte_frame() {
		let mut iter = decoder![0x08, 0x55];

		let mut expected = false;
		for _ in 0..8 {
			assert_eq!(iter.next(), Some(Ok(expected)));
			expected = !expected;
		}

		assert_eq!(iter.next(), None);
	}

	#[test]
	fn two_byte_frame() {
		let mut iter = decoder![0x0f, 0x55, 0x55];

		let mut expected = false;
		for _ in 0..15 {
			assert_eq!(iter.next(), Some(Ok(expected)));
			expected = !expected;
		}

		assert_eq!(iter.next(), None);
	}
}
<commit_msg>More complex test cases for frames<commit_after>//! Decodes a Bitterlemon-encoded byte stream into its original bit stream.

use std::iter::Iterator;

pub fn decode<S>(input: S) -> Decoder<S>
where S : Iterator<Item=u8> {
	Decoder::<S> {
		source: input,
		state: DecodeState::Pending,
	}
}

pub struct Decoder<S> {
	state: DecodeState,
	source: S,
}

#[derive(Debug, PartialEq, Eq)]
pub enum Error {
	TruncatedInput(u8, u8),
}

type IterationResult = Result<bool, Error>;

impl<S> Iterator for Decoder<S>
where S : Iterator<Item=u8> {
	type Item = IterationResult;

	fn next(&mut self) -> Option<Self::Item> {

		// pull from source if needs be
		if self.must_pull() {
			let next = self.source.next();
			self.next_with_pulled(next)
		} else {
			self.next_from_existing()
		}
	}
}

impl<S> Decoder<S>
where S : Iterator<Item=u8> {

	fn must_pull(&self) -> bool {
		match self.state {
			DecodeState::Pending => true,
			DecodeState::Done => false,
			DecodeState::Run(remaining, _) => remaining == 0,
			DecodeState::Frame(remaining, _, stage_size) => remaining == 0 || stage_size == 0,
		}
	}

	fn next_with_pulled(&mut self, next: Option<u8>) -> Option<<Self as Iterator>::Item> {

		// handle None from source
		let next = match next {
			Some(x) => x,
			None => match self.state {
				DecodeState::Pending => {
					self.state = DecodeState::Done;
					return None;
				}, // source was empty
				DecodeState::Done    => { return None; }, // always return None here
				DecodeState::Run(_, _) => {
					unreachable!("next_with_pulled called with more run bits to flush: {:?}", self.state);
				},
				DecodeState::Frame(remaining, _, stage_size) => {
					debug_assert!(stage_size == 0);
					debug_assert!(remaining > 0);

					// missing bytes to complete the frame
					let error_specifics = Error::TruncatedInput(remaining, (remaining + 7) >> 3);
					return Some(Err(error_specifics));
				}
			}
		};

		// handle mid-frame
		if match self.state {
			DecodeState::Frame(ref mut remaining, ref mut stage, ref mut stage_size)
			if *remaining > 0 => {
				debug_assert!(*stage_size == 0); // shouldn't have pulled otherwise
				*stage = next;
				*stage_size = 8;
				// now fall through to real iteration logic
				true
			},
			_ => false
		} {
			return self.next_from_existing();
		}

		let got = match next {
			n if n < 0x80 => {
				// frame beginning
				let frame_size = byte_to_frame_size(n);
				self.state = DecodeState::Frame(frame_size, 0, 0);
				None
			},
			n => {
				// new run
				let frame_size = byte_to_run_size(n);
				let mode = n >= 0xc0;
				self.state = if frame_size > 1 {
					// don't bother moving to run state if only one pixel in this run
					// also, leaving this method in state Run(0, _) is a logic error
					DecodeState::Run(frame_size - 1, mode)
				}
				else {
					DecodeState::Pending
				};
				Some(Ok(mode))
			}
		};

		got.or_else(|| {
			let next = self.source.next();
			self.next_with_pulled(next)
		})
	}

	fn next_from_existing(&mut self) -> Option<<Self as Iterator>::Item> {

		let (to_return, next_state) = match self.state {
			DecodeState::Pending => unreachable!(),
			DecodeState::Done    => { return None; },
			DecodeState::Run(ref mut remaining, ref run_mode) => {
				*remaining -= 1;
				(*run_mode, if *remaining == 0 {Some(DecodeState::Pending)} else {None})
			},
			DecodeState::Frame(ref mut remaining, ref mut stage, ref mut stage_size) => {
				let got_bit = (*stage & 0x80) != 0;
				*stage = (*stage & 0x7f) << 1;
				*stage_size -= 1;
				*remaining -= 1;
				(got_bit, if *remaining == 0 {Some(DecodeState::Pending)} else {None})
			}
		};

		if let Some(next_state) = next_state {
			self.state = next_state;
		}

		Some(Ok(to_return))
	}

}

fn byte_to_run_size(byte: u8) -> u8 {
	let byte = byte & 0x3f;
	if byte == 0 { 0x40 } else { byte }
}

fn byte_to_frame_size(byte: u8) -> u8 {
	if byte == 0 { 0x80 } else { byte }
}

#[derive(Debug)]
enum DecodeState {
	Pending, // should pull
	Run(u8, bool), // run count, is_set
	Frame(u8, u8, u8), // frame pixel count, stage contents, stage size
	Done, // iteration complete
}

#[cfg(test)]
mod test_decoder {

	macro_rules! decoder {
		( $($e:expr),* ) => {
			{
				let v = vec![$( $e, )*];
				super::decode(v.into_iter())
			}
		}
	}

	#[test]
	fn empty_input() {
		let mut iter = decoder![];

		assert_eq!(iter.next(), None);
		assert_eq!(iter.next(), None);
	}

	fn single_run_impl(top_bits: u8, mode: bool) {
		for i in 0..0x3fu8 {
			let run_size = super::byte_to_run_size(i);
			let mut iter = decoder![i+top_bits];
			for _ in 0..run_size {
				assert_eq!(iter.next(), Some(Ok(mode)));
			}
			assert_eq!(iter.next(), None);
		}
	}

	#[test]
	fn single_run_clear() {
		single_run_impl(0x80, false)
	}

	#[test]
	fn single_run_set() {
		single_run_impl(0xc0, true)
	}

	#[test]
	fn single_byte_frame() {
		let case = |byte_in: u8, bool_out: bool| {
			let mut iter = decoder![0x01, byte_in];
			assert_eq!(iter.next(), Some(Ok(bool_out)));
		};

		case(0xff, true);
		case(0x00, false);
		case(0x80, true);
		case(0x7f, false);
	}

	#[test]
	fn full_byte_frame() {
		let mut iter = decoder![0x08, 0x55];

		let mut expected = false;
		for _ in 0..8 {
			assert_eq!(iter.next(), Some(Ok(expected)));
			expected = !expected;
		}

		assert_eq!(iter.next(), None);
	}

	#[test]
	fn two_byte_frame() {
		let mut iter = decoder![0x0f, 0x55, 0x55];

		let mut expected = false;
		for _ in 0..15 {
			assert_eq!(iter.next(), Some(Ok(expected)));
			expected = !expected;
		}

		assert_eq!(iter.next(), None);
	}

	#[test]
	fn alternate_runs_frames() {
		let case = |bytes: &[u8], count: usize, first_output: bool| {
			let mut iter = super::decode(bytes.iter().map(|&b| b));

			let mut expected = first_output;
			for _ in 0..count {
				assert_eq!(iter.next(), Some(Ok(expected)));
				expected = !expected;
			}

			assert_eq!(iter.next(), None);
		};

		case(&[0xc1, 0x10, 0x55, 0x55, 0x81], 18, true);
		case(&[0x81, 0x10, 0xaa, 0xaa, 0xc1], 18, false);
		case(&[0x08, 0xaa, 0xc1, 0x08, 0x55], 17, true);
		case(&[0x08, 0x55, 0x81, 0x08, 0xaa], 17, false);
	}

	#[test]
	fn error_on_frame_cutoff() {
		let case = |bytes: &[u8], pixels_lost: u8, bytes_missing: u8| {
			let mut iter = super::decode(bytes.iter().map(|&b| b));

			let ok_count = (bytes.len() - 1) * 8;
			for _ in 0..ok_count {
				assert!(match iter.next() {
					Some(Ok(_)) => true,
					_ => false
				});
			}

			let error = iter.next();
			assert!(error.is_some());
			let error = error.unwrap();

			assert!(error.is_err());
			match error.unwrap_err() {
				super::Error::TruncatedInput(pl, bm) => {
					assert_eq!(pl, pixels_lost);
					assert_eq!(bm, bytes_missing);
				}
			};
		};

		case(&[0x01], 1, 1);
		case(&[0x02], 2, 1);
		case(&[0x00], 0x80, 0x10);
		case(&[0x09, 0xff], 1, 1);
		case(&[0x7f, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14], 7, 1);
	}
}
<|endoftext|>


<commit_before>use std::io;
use std::num;
use std::rc::Rc;
use solver;
use solver::{Expression, Clause, ClauseRef, Term, Lit, Not};

// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------

pub struct Problem {
	varcount: uint,
	expression: Expression
}

impl Problem {
	pub fn new(varcount: uint, clauses: &[&[Term]]) -> Problem {
		Problem {
			varcount: varcount,
			expression: Expression::from(clauses)
		}
	}
}

// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------

#[deriving(Show, PartialEq)]
pub enum DimacsError {
	IoFailure (io::IoError),
	ParseFailure (String)
}

fn read_int(s: &str) -> Result<int, DimacsError> {
	match from_str(s) {
		Some(n) => Ok(n),
		None => {
			let msg = format!("Not an integer: \"{}\"", s);
			Err(ParseFailure(msg))
		}
	}
}

fn read_clause(s: &str) -> Result<Vec<Term>, DimacsError> {
	let mut clause = Vec::new();
	for item in s.trim().split(' ') {
		match try!(read_int(item)) {
        	n if n > 0 => clause.push(Lit(n as uint)),
        	n if n < 0 => clause.push(Not(num::abs(n) as uint)),
        	n => { break; }
		};
	}
	Ok(clause)
}

fn read_problem_header(s: &str) -> Result<(int, int), DimacsError> {
	let parts : Vec<&str> = s.trim().split(' ').collect();
	match parts.len() {
		4 => {
			if *parts.get(1) != "cnf" {
				let msg = format!("expected \"cnf\", got \"{}\"", parts.get(1));
				return Err(ParseFailure(msg))
			}
			let vars = try!(read_int(*parts.get(2)));
			let clauses = try!(read_int(*parts.get(3)));
			Ok((vars, clauses))
		}
		_ => {
			let msg = format!("Malformed header: {}", s);
			Err(ParseFailure(msg))
		}
	}
}

#[test]
fn reading_problem_header_returns_counts() {
	assert!(read_problem_header("p cnf 42 128").unwrap() == (42, 128));
}

#[test]
fn problem_header_with_bad_type_returns_error() {
	match read_problem_header("p wtf 42 128") {
		Err(ParseFailure(_)) => {},
		_ => fail!("Expected parsing to fail")
	}
}

#[test]
fn problem_header_with_bad_varcount_returns_error() {
	match read_problem_header("p cnf narf 128") {
		Err(ParseFailure(_)) => {},
		_ => fail!("Expected parsing to fail")
	}
}

#[test]
fn problem_header_with_bad_clause_count_returns_error() {
	match read_problem_header("p cnf 42 zort") {
		Err (ParseFailure(_)) => {},
		_ => fail!("Expected parsing to fail")
	}
}

pub fn read<B: io::Buffer>(buf: &mut B) -> Result<Problem, DimacsError> {
	let mut clauses : Vec<Vec<Term>> = Vec::new();
	let mut nvars = 0;
	let mut nclauses = 0;
	for line in buf.lines() {
		match line {
			Ok(text) => {
				match text.as_slice().chars().next() {
					None => { /* empty line */ },
					Some(c) if c == 'c' => { /* comment */ },
					Some(c) if c == 'p' => {
						let (v, c)= try!(read_problem_header(text.as_slice()));
						nvars = v;
					}
					Some(_) => {
						clauses.push(try!(read_clause(text.as_slice())));
					}
				}
			},
			Err(err) => return Err(IoFailure(err))
		}
	}

	let slices : Vec<&[Term]> = clauses.iter()
									   .map(|v| v.as_slice())
									   .collect();
	Ok(Problem::new(nvars as uint, slices.as_slice()))
}

#[config(test)]
fn make_buffer(lines: &[&str]) -> io::MemReader {
	let mut text = io::MemWriter::new();
	for s in lines.iter() {
		text.write_str(*s);
	}
	io::MemReader::new( text.unwrap() )
}

#[test]
fn dimacs_reader() {
	let mut reader = make_buffer([
		"c",
		"c comment\n",
		"c\n",
		"p cnf 5 3\n",
		"1 -5 4 0\n",
		"-1 5 3 4 0\n",
		"-3 -4 0"
	]);

	let problem = read(&mut reader).unwrap();
	assert!(problem.varcount == 5, "Expected varcount 5, got {}", problem.varcount);

	assert!(problem.expression.iter().count() == 3);
	let mut iter = problem.expression.iter();
	let c1 = iter.next().unwrap();
	assert!(**c1 == Clause::from([Lit(1), Not(5), Lit(4)]),
		"Expected [1, ~5, 4], got {}", c1);
}<commit_msg>tabs -> spaces<commit_after>use std::io;
use std::num;
use std::rc::Rc;
use solver;
use solver::{Expression, Clause, ClauseRef, Term, Lit, Not};

// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------

pub struct Problem {
    varcount: uint,
    expression: Expression
}

impl Problem {
    pub fn new(varcount: uint, clauses: &[&[Term]]) -> Problem {
        Problem {
            varcount: varcount,
            expression: Expression::from(clauses)
        }
    }
}

// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------

#[deriving(Show, PartialEq)]
pub enum DimacsError {
    IoFailure (io::IoError),
    ParseFailure (String)
}

fn read_int(s: &str) -> Result<int, DimacsError> {
    match from_str(s) {
        Some(n) => Ok(n),
        None => {
            let msg = format!("Not an integer: \"{}\"", s);
            Err(ParseFailure(msg))
        }
    }
}

fn read_clause(s: &str) -> Result<Vec<Term>, DimacsError> {
    let mut clause = Vec::new();
    for item in s.trim().split(' ') {
        match try!(read_int(item)) {
            n if n > 0 => clause.push(Lit(n as uint)),
            n if n < 0 => clause.push(Not(num::abs(n) as uint)),
            n => { break; }
        };
    }
    Ok(clause)
}

fn read_problem_header(s: &str) -> Result<(int, int), DimacsError> {
    let parts : Vec<&str> = s.trim().split(' ').collect();
    match parts.len() {
        4 => {
            if *parts.get(1) != "cnf" {
                let msg = format!("expected \"cnf\", got \"{}\"", parts.get(1));
                return Err(ParseFailure(msg))
            }
            let vars = try!(read_int(*parts.get(2)));
            let clauses = try!(read_int(*parts.get(3)));
            Ok((vars, clauses))
        }
        _ => {
            let msg = format!("Malformed header: {}", s);
            Err(ParseFailure(msg))
        }
    }
}

#[test]
fn reading_problem_header_returns_counts() {
    assert!(read_problem_header("p cnf 42 128").unwrap() == (42, 128));
}

#[test]
fn problem_header_with_bad_type_returns_error() {
    match read_problem_header("p wtf 42 128") {
        Err(ParseFailure(_)) => {},
        _ => fail!("Expected parsing to fail")
    }
}

#[test]
fn problem_header_with_bad_varcount_returns_error() {
    match read_problem_header("p cnf narf 128") {
        Err(ParseFailure(_)) => {},
        _ => fail!("Expected parsing to fail")
    }
}

#[test]
fn problem_header_with_bad_clause_count_returns_error() {
    match read_problem_header("p cnf 42 zort") {
        Err (ParseFailure(_)) => {},
        _ => fail!("Expected parsing to fail")
    }
}

pub fn read<B: io::Buffer>(buf: &mut B) -> Result<Problem, DimacsError> {
    let mut clauses : Vec<Vec<Term>> = Vec::new();
    let mut nvars = 0;
    let mut nclauses = 0;
    for line in buf.lines() {
        match line {
            Ok(text) => {
                match text.as_slice().chars().next() {
                    None => { /* empty line */ },
                    Some(c) if c == 'c' => { /* comment */ },
                    Some(c) if c == 'p' => {
                        let (v, c)= try!(read_problem_header(text.as_slice()));
                        nvars = v;
                    }
                    Some(_) => {
                        clauses.push(try!(read_clause(text.as_slice())));
                    }
                }
            },
            Err(err) => return Err(IoFailure(err))
        }
    }

    let slices : Vec<&[Term]> = clauses.iter()
                                       .map(|v| v.as_slice())
                                       .collect();
    Ok(Problem::new(nvars as uint, slices.as_slice()))
}

#[config(test)]
fn make_buffer(lines: &[&str]) -> io::MemReader {
    let mut text = io::MemWriter::new();
    for s in lines.iter() {
        text.write_str(*s);
    }
    io::MemReader::new( text.unwrap() )
}

#[test]
fn dimacs_reader() {
    let mut reader = make_buffer([
        "c",
        "c comment\n",
        "c\n",
        "p cnf 5 3\n",
        "1 -5 4 0\n",
        "-1 5 3 4 0\n",
        "-3 -4 0"
    ]);

    let problem = read(&mut reader).unwrap();
    assert!(problem.varcount == 5, "Expected varcount 5, got {}", problem.varcount);

    assert!(problem.expression.iter().count() == 3);
    let mut iter = problem.expression.iter();
    let c1 = iter.next().unwrap();
    assert!(**c1 == Clause::from([Lit(1), Not(5), Lit(4)]),
        "Expected [1, ~5, 4], got {}", c1);
}<|endoftext|>