<commit_before>// Copyright 2017 Jeremy Wall <jeremy@marzhillstudios.com>
//
//  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.

//! Contains code for converting a UCG Val into the command line flag output target.
use std::io::Write;
use std::rc::Rc;

use build::Val;
use convert::traits::{Converter, Result};

/// FlagConverter implements the conversion logic for converting a Val into a set
/// of command line flags.
pub struct FlagConverter {}

impl FlagConverter {
    pub fn new() -> Self {
        FlagConverter {}
    }

    fn write_flag_name(&self, pfx: &str, name: &str, w: &mut Write) -> Result {
        if name.chars().count() > 1 || pfx.chars().count() > 0 {
            try!(write!(w, "--{}{} ", pfx, name));
        } else {
            try!(write!(w, "-{} ", name));
        }
        return Ok(());
    }

    fn write_list_flag(&self, pfx: &str, name: &str, def: &Vec<Rc<Val>>, w: &mut Write) -> Result {
        // first of all we need to make sure that each &Val is only a primitive type.
        for v in def.iter() {
            let vref = v.as_ref();
            if vref.is_list() || vref.is_tuple() || vref.is_macro() {
                eprintln!(
                    "Skipping non primitive val in list for flag {}{}",
                    pfx, name
                );
            } else {
                try!(self.write_flag_name(pfx, name, w));
                try!(self.write(pfx, vref, w));
            }
        }
        return Ok(());
    }

    fn write(&self, pfx: &str, v: &Val, w: &mut Write) -> Result {
        match v {
            &Val::Empty => {
                // Empty is a noop.
                return Ok(());
            }
            &Val::Boolean(b) => {
                try!(write!(w, "{}", if b { "true" } else { "false" }));
            }
            &Val::Float(ref f) => {
                try!(write!(w, "{} ", f));
            }
            &Val::Int(ref i) => {
                try!(write!(w, "{} ", i));
            }
            &Val::Str(ref s) => {
                try!(write!(w, "'{}' ", s));
            }
            &Val::List(ref _def) => {
                eprintln!("Skipping List...");
            }
            &Val::Tuple(ref flds) => for &(ref name, ref val) in flds.iter() {
                if let &Val::Empty = val.as_ref() {
                    try!(self.write_flag_name(pfx, &name.val, w));
                    continue;
                }
                match val.as_ref() {
                    &Val::Tuple(_) => {
                        let new_pfx = format!("{}{}.", pfx, name);
                        try!(self.write(&new_pfx, val, w));
                    }
                    &Val::List(ref def) => {
                        try!(self.write_list_flag(pfx, &name.val, def, w));
                    }
                    _ => {
                        try!(self.write_flag_name(pfx, &name.val, w));
                        try!(self.write(pfx, &val, w));
                    }
                }
            },
            &Val::Macro(ref _def) => {
                // This is ignored
                eprintln!("Skipping macro...");
            }
        }
        Ok(())
    }
}

impl Converter for FlagConverter {
    fn convert(&self, v: Rc<Val>, mut w: &mut Write) -> Result {
        self.write("", &v, &mut w)
    }

    fn file_ext(&self) -> String {
        String::from("txt")
    }

    fn description(&self) -> String {
        "Convert ucg Vals into command line flags.".to_string()
    }
}

// We need some unit tests for this now :D
<commit_msg>BUGFIX: A bug in boolean values for flag converters.<commit_after>// Copyright 2017 Jeremy Wall <jeremy@marzhillstudios.com>
//
//  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.

//! Contains code for converting a UCG Val into the command line flag output target.
use std::io::Write;
use std::rc::Rc;

use build::Val;
use convert::traits::{Converter, Result};

/// FlagConverter implements the conversion logic for converting a Val into a set
/// of command line flags.
pub struct FlagConverter {}

impl FlagConverter {
    pub fn new() -> Self {
        FlagConverter {}
    }

    fn write_flag_name(&self, pfx: &str, name: &str, w: &mut Write) -> Result {
        if name.chars().count() > 1 || pfx.chars().count() > 0 {
            try!(write!(w, "--{}{} ", pfx, name));
        } else {
            try!(write!(w, "-{} ", name));
        }
        return Ok(());
    }

    fn write_list_flag(&self, pfx: &str, name: &str, def: &Vec<Rc<Val>>, w: &mut Write) -> Result {
        // first of all we need to make sure that each &Val is only a primitive type.
        for v in def.iter() {
            let vref = v.as_ref();
            if vref.is_list() || vref.is_tuple() || vref.is_macro() {
                eprintln!(
                    "Skipping non primitive val in list for flag {}{}",
                    pfx, name
                );
            } else {
                try!(self.write_flag_name(pfx, name, w));
                try!(self.write(pfx, vref, w));
            }
        }
        return Ok(());
    }

    fn write(&self, pfx: &str, v: &Val, w: &mut Write) -> Result {
        match v {
            &Val::Empty => {
                // Empty is a noop.
                return Ok(());
            }
            &Val::Boolean(b) => {
                try!(write!(w, "{} ", if b { "true" } else { "false" }));
            }
            &Val::Float(ref f) => {
                try!(write!(w, "{} ", f));
            }
            &Val::Int(ref i) => {
                try!(write!(w, "{} ", i));
            }
            &Val::Str(ref s) => {
                try!(write!(w, "'{}' ", s));
            }
            &Val::List(ref _def) => {
                eprintln!("Skipping List...");
            }
            &Val::Tuple(ref flds) => for &(ref name, ref val) in flds.iter() {
                if let &Val::Empty = val.as_ref() {
                    try!(self.write_flag_name(pfx, &name.val, w));
                    continue;
                }
                match val.as_ref() {
                    &Val::Tuple(_) => {
                        let new_pfx = format!("{}{}.", pfx, name);
                        try!(self.write(&new_pfx, val, w));
                    }
                    &Val::List(ref def) => {
                        try!(self.write_list_flag(pfx, &name.val, def, w));
                    }
                    _ => {
                        try!(self.write_flag_name(pfx, &name.val, w));
                        try!(self.write(pfx, &val, w));
                    }
                }
            },
            &Val::Macro(ref _def) => {
                // This is ignored
                eprintln!("Skipping macro...");
            }
        }
        Ok(())
    }
}

impl Converter for FlagConverter {
    fn convert(&self, v: Rc<Val>, mut w: &mut Write) -> Result {
        self.write("", &v, &mut w)
    }

    fn file_ext(&self) -> String {
        String::from("txt")
    }

    fn description(&self) -> String {
        "Convert ucg Vals into command line flags.".to_string()
    }
}

// We need some unit tests for this now :D
<|endoftext|>


<commit_before>#![feature(slicing_syntax, box_syntax)]
#![deny(missing_docs)]
#![allow(unstable)]
#![cfg_attr(test, deny(warnings))]

//! # Hyper
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both an HTTP/S client an HTTP server which can be used to drive
//! complex web applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapper over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations can
//! be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's header representation is likely the most complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/server`.
//!
//! #### Handler + Server
//!
//! A `Handler` in Hyper accepts a `Request` and `Response`. This is where
//! user-code can handle each connection. The server accepts connections in a
//! task pool with a customizable number of threads, and passes the Request /
//! Response to the handler.
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for sever Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate "rustc-serialize" as serialize;
extern crate time;
extern crate url;
extern crate openssl;
#[macro_use] extern crate log;
#[cfg(test)] extern crate test;
extern crate "unsafe-any" as uany;
extern crate cookie;
extern crate mucell;
extern crate unicase;

pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
pub use mimewrapper::mime;
pub use url::Url;
pub use client::Client;
pub use method::Method::{Get, Head, Post, Delete};
pub use status::StatusCode::{Ok, BadRequest, NotFound};
pub use server::Server;

use std::error::{Error, FromError};
use std::fmt;
use std::io::IoError;

use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError,
                      HttpHeaderError, HttpStatusError, HttpIoError};

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        log!(5, "TODO: {:?}", format_args!($($arg)*))
    })
);

macro_rules! inspect(
    ($name:expr, $value:expr) => ({
        let v = $value;
        debug!("inspect: {:?} = {:?}", $name, v);
        v
    })
);

#[cfg(test)]
#[macro_use]
mod mock;

pub mod client;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

mod mimewrapper {
    /// Re-exporting the mime crate, for convenience.
    extern crate mime;
}

/// Result type often returned from methods that can have `HttpError`s.
pub type HttpResult<T> = Result<T, HttpError>;

/// A set of errors that can occur parsing HTTP streams.
#[derive(Debug, PartialEq, Clone)]
pub enum HttpError {
    /// An invalid `Method`, such as `GE,T`.
    HttpMethodError,
    /// An invalid `RequestUri`, such as `exam ple.domain`.
    HttpUriError(url::ParseError),
    /// An invalid `HttpVersion`, such as `HTP/1.1`
    HttpVersionError,
    /// An invalid `Header`.
    HttpHeaderError,
    /// An invalid `Status`, such as `1337 ELITE`.
    HttpStatusError,
    /// An `IoError` that occured while trying to read or write to a network stream.
    HttpIoError(IoError),
}

impl fmt::Display for HttpError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.description())
    }
}

impl Error for HttpError {
    fn description(&self) -> &str {
        match *self {
            HttpMethodError => "Invalid Method specified",
            HttpUriError(_) => "Invalid Request URI specified",
            HttpVersionError => "Invalid HTTP version specified",
            HttpHeaderError => "Invalid Header provided",
            HttpStatusError => "Invalid Status provided",
            HttpIoError(_) => "An IoError occurred while connecting to the specified network",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            HttpIoError(ref error) => Some(error as &Error),
            HttpUriError(ref error) => Some(error as &Error),
            _ => None,
        }
    }
}

impl FromError<IoError> for HttpError {
    fn from_error(err: IoError) -> HttpError {
        HttpIoError(err)
    }
}

impl FromError<url::ParseError> for HttpError {
    fn from_error(err: url::ParseError) -> HttpError {
        HttpUriError(err)
    }
}

fn _assert_send<T: Send>() {
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();
}
<commit_msg>chore(warnings): Allow direct recursion for type enforcement.<commit_after>#![feature(slicing_syntax, box_syntax)]
#![deny(missing_docs)]
#![allow(unstable)]
#![cfg_attr(test, deny(warnings))]

//! # Hyper
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both an HTTP/S client an HTTP server which can be used to drive
//! complex web applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapper over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations can
//! be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's header representation is likely the most complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/server`.
//!
//! #### Handler + Server
//!
//! A `Handler` in Hyper accepts a `Request` and `Response`. This is where
//! user-code can handle each connection. The server accepts connections in a
//! task pool with a customizable number of threads, and passes the Request /
//! Response to the handler.
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for sever Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate "rustc-serialize" as serialize;
extern crate time;
extern crate url;
extern crate openssl;
#[macro_use] extern crate log;
#[cfg(test)] extern crate test;
extern crate "unsafe-any" as uany;
extern crate cookie;
extern crate mucell;
extern crate unicase;

pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
pub use mimewrapper::mime;
pub use url::Url;
pub use client::Client;
pub use method::Method::{Get, Head, Post, Delete};
pub use status::StatusCode::{Ok, BadRequest, NotFound};
pub use server::Server;

use std::error::{Error, FromError};
use std::fmt;
use std::io::IoError;

use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError,
                      HttpHeaderError, HttpStatusError, HttpIoError};

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        log!(5, "TODO: {:?}", format_args!($($arg)*))
    })
);

macro_rules! inspect(
    ($name:expr, $value:expr) => ({
        let v = $value;
        debug!("inspect: {:?} = {:?}", $name, v);
        v
    })
);

#[cfg(test)]
#[macro_use]
mod mock;

pub mod client;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

mod mimewrapper {
    /// Re-exporting the mime crate, for convenience.
    extern crate mime;
}

/// Result type often returned from methods that can have `HttpError`s.
pub type HttpResult<T> = Result<T, HttpError>;

/// A set of errors that can occur parsing HTTP streams.
#[derive(Debug, PartialEq, Clone)]
pub enum HttpError {
    /// An invalid `Method`, such as `GE,T`.
    HttpMethodError,
    /// An invalid `RequestUri`, such as `exam ple.domain`.
    HttpUriError(url::ParseError),
    /// An invalid `HttpVersion`, such as `HTP/1.1`
    HttpVersionError,
    /// An invalid `Header`.
    HttpHeaderError,
    /// An invalid `Status`, such as `1337 ELITE`.
    HttpStatusError,
    /// An `IoError` that occured while trying to read or write to a network stream.
    HttpIoError(IoError),
}

impl fmt::Display for HttpError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.description())
    }
}

impl Error for HttpError {
    fn description(&self) -> &str {
        match *self {
            HttpMethodError => "Invalid Method specified",
            HttpUriError(_) => "Invalid Request URI specified",
            HttpVersionError => "Invalid HTTP version specified",
            HttpHeaderError => "Invalid Header provided",
            HttpStatusError => "Invalid Status provided",
            HttpIoError(_) => "An IoError occurred while connecting to the specified network",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            HttpIoError(ref error) => Some(error as &Error),
            HttpUriError(ref error) => Some(error as &Error),
            _ => None,
        }
    }
}

impl FromError<IoError> for HttpError {
    fn from_error(err: IoError) -> HttpError {
        HttpIoError(err)
    }
}

impl FromError<url::ParseError> for HttpError {
    fn from_error(err: url::ParseError) -> HttpError {
        HttpUriError(err)
    }
}

#[allow(unconditional_recursion)]
fn _assert_send<T: Send>() {
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();
}
<|endoftext|>


<commit_before>#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Entry {
    pub id          : String,
    pub osm_node    : Option<u64>,
    pub created     : u64,
    pub version     : u64,
    pub title       : String,
    pub description : String,
    pub lat         : f64,
    pub lng         : f64,
    pub street      : Option<String>,
    pub zip         : Option<String>,
    pub city        : Option<String>,
    pub country     : Option<String>,
    pub email       : Option<String>,
    pub telephone   : Option<String>,
    pub homepage    : Option<String>,
    pub categories  : Vec<String>,
    pub tags        : Vec<String>,
    pub license     : Option<String>,
    pub image_url     : Option<String>,
    pub image_link_url: Option<String>,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Category {
    pub id      : String,
    pub created : u64,
    pub version : u64,
    pub name    : String
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Tag {
    pub id: String,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ObjectId {
    Entry(String),
    Tag(String),
    User(String),
    Comment(String),
    Rating(String),
    BboxSubscription(String),
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct User {
    pub id              : String, // TODO: remove
    pub username        : String,
    pub password        : String,
    pub email           : String,
    pub email_confirmed : bool,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Comment {
    pub id        : String,
    pub created   : u64,
    pub text      : String,
    pub rating_id : String,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum RatingContext {
    Diversity,
    Renewable,
    Fairness,
    Humanity,
    Transparency,
    Solidarity,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Rating {
    pub id       : String,
    pub entry_id : String,
    pub created  : u64,
    pub title    : String,
    pub value    : i8,
    pub context  : RatingContext,
    pub source   : Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Coordinate {
    pub lat: f64,
    pub lng: f64,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Bbox {
    pub south_west: Coordinate,
    pub north_east: Coordinate,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct BboxSubscription {
    pub id       : String,
    pub bbox     : Bbox,
    pub username : String,
}

#[cfg(test)]
pub use self::entry_builder::*;

#[cfg(test)]
pub mod entry_builder {

    use super::*;
    use uuid::Uuid;

    pub trait EntryBuilder {
        fn build() -> EntryBuild;
    }

    pub struct EntryBuild {
        entry: Entry,
    }

    impl EntryBuild {
        pub fn id(mut self, id: &str) -> Self {
            self.entry.id = id.into();
            self
        }
        pub fn version(mut self, v: u64) -> Self {
            self.entry.version = v;
            self
        }
        pub fn title(mut self, title: &str) -> Self {
            self.entry.title = title.into();
            self
        }
        pub fn description(mut self, desc: &str) -> Self {
            self.entry.description = desc.into();
            self
        }
        pub fn lat(mut self, lat: f64) -> Self {
            self.entry.lat = lat;
            self
        }
        pub fn lng(mut self, lng: f64) -> Self {
            self.entry.lng = lng;
            self
        }
        pub fn categories(mut self, cats: Vec<&str>) -> Self {
            self.entry.categories = cats.into_iter().map(|x| x.into()).collect();
            self
        }
        pub fn tags(mut self, tags: Vec<&str>) -> Self {
            self.entry.tags = tags.into_iter().map(|x| x.into()).collect();
            self
        }
        pub fn license(mut self, license: Option<&str>) -> Self {
            self.entry.license = license.map(|s| s.into());
            self
        }
        pub fn image_url(mut self, image_url: Option<&str>) -> Self {
            self.entry.image_url = image_url.map(Into::into);
            self
        }
        pub fn image_link_url(mut self, image_link_url: Option<&str>) -> Self {
            self.entry.image_link_url = image_link_url.map(Into::into);
            self
        }
        pub fn finish(self) -> Entry {
            self.entry
        }
    }

    impl EntryBuilder for Entry {
        fn build() -> EntryBuild {
            EntryBuild {
                entry: Entry::default(),
            }
        }
    }

    impl Default for Entry {
        fn default() -> Entry {
            #[cfg_attr(rustfmt, rustfmt_skip)]
            Entry{
                id          : Uuid::new_v4().simple().to_string(),
                osm_node    : None,
                created     : 0,
                version     : 0,
                title       : "".into(),
                description : "".into(),
                lat         : 0.0,
                lng         : 0.0,
                street      : None,
                zip         : None,
                city        : None,
                country     : None,
                email       : None,
                telephone   : None,
                homepage    : None,
                categories  : vec![],
                tags        : vec![],
                license     : None,
                image_url     : None,
                image_link_url: None,
            }
        }
    }

}
<commit_msg>Remove implementation of Default for Entry in 'test' configuration<commit_after>#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Entry {
    pub id          : String,
    pub osm_node    : Option<u64>,
    pub created     : u64,
    pub version     : u64,
    pub title       : String,
    pub description : String,
    pub lat         : f64,
    pub lng         : f64,
    pub street      : Option<String>,
    pub zip         : Option<String>,
    pub city        : Option<String>,
    pub country     : Option<String>,
    pub email       : Option<String>,
    pub telephone   : Option<String>,
    pub homepage    : Option<String>,
    pub categories  : Vec<String>,
    pub tags        : Vec<String>,
    pub license     : Option<String>,
    pub image_url     : Option<String>,
    pub image_link_url: Option<String>,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Category {
    pub id      : String,
    pub created : u64,
    pub version : u64,
    pub name    : String
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Tag {
    pub id: String,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ObjectId {
    Entry(String),
    Tag(String),
    User(String),
    Comment(String),
    Rating(String),
    BboxSubscription(String),
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct User {
    pub id              : String, // TODO: remove
    pub username        : String,
    pub password        : String,
    pub email           : String,
    pub email_confirmed : bool,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Comment {
    pub id        : String,
    pub created   : u64,
    pub text      : String,
    pub rating_id : String,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum RatingContext {
    Diversity,
    Renewable,
    Fairness,
    Humanity,
    Transparency,
    Solidarity,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Rating {
    pub id       : String,
    pub entry_id : String,
    pub created  : u64,
    pub title    : String,
    pub value    : i8,
    pub context  : RatingContext,
    pub source   : Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Coordinate {
    pub lat: f64,
    pub lng: f64,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Bbox {
    pub south_west: Coordinate,
    pub north_east: Coordinate,
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct BboxSubscription {
    pub id       : String,
    pub bbox     : Bbox,
    pub username : String,
}

#[cfg(test)]
pub use self::entry_builder::*;

#[cfg(test)]
pub mod entry_builder {

    use super::*;
    use uuid::Uuid;

    pub trait EntryBuilder {
        fn build() -> EntryBuild;
    }

    pub struct EntryBuild {
        entry: Entry,
    }

    impl EntryBuild {
        pub fn id(mut self, id: &str) -> Self {
            self.entry.id = id.into();
            self
        }
        pub fn version(mut self, v: u64) -> Self {
            self.entry.version = v;
            self
        }
        pub fn title(mut self, title: &str) -> Self {
            self.entry.title = title.into();
            self
        }
        pub fn description(mut self, desc: &str) -> Self {
            self.entry.description = desc.into();
            self
        }
        pub fn lat(mut self, lat: f64) -> Self {
            self.entry.lat = lat;
            self
        }
        pub fn lng(mut self, lng: f64) -> Self {
            self.entry.lng = lng;
            self
        }
        pub fn categories(mut self, cats: Vec<&str>) -> Self {
            self.entry.categories = cats.into_iter().map(|x| x.into()).collect();
            self
        }
        pub fn tags(mut self, tags: Vec<&str>) -> Self {
            self.entry.tags = tags.into_iter().map(|x| x.into()).collect();
            self
        }
        pub fn license(mut self, license: Option<&str>) -> Self {
            self.entry.license = license.map(|s| s.into());
            self
        }
        pub fn image_url(mut self, image_url: Option<&str>) -> Self {
            self.entry.image_url = image_url.map(Into::into);
            self
        }
        pub fn image_link_url(mut self, image_link_url: Option<&str>) -> Self {
            self.entry.image_link_url = image_link_url.map(Into::into);
            self
        }
        pub fn finish(self) -> Entry {
            self.entry
        }
    }

    impl EntryBuilder for Entry {
        fn build() -> EntryBuild {
            EntryBuild {
                entry: Entry {
                    id: Uuid::new_v4().simple().to_string(),
                    osm_node: None,
                    created: 0,
                    version: 0,
                    title: "".into(),
                    description: "".into(),
                    lat: 0.0,
                    lng: 0.0,
                    street: None,
                    zip: None,
                    city: None,
                    country: None,
                    email: None,
                    telephone: None,
                    homepage: None,
                    categories: vec![],
                    tags: vec![],
                    license: None,
                    image_url: None,
                    image_link_url: None,
                },
            }
        }
    }

}
<|endoftext|>


<commit_before>pub use std::collections::{HashSet, HashMap};

mod graph;
mod traversal;
mod tree;

fn main() {

}
<commit_msg>Add some basic tests in main<commit_after>pub use std::collections::{HashSet, HashMap};
use graph::{Graph, Ungraph, Digraph};

mod graph;
mod traversal;
mod tree;

fn main() {
    let mut g = Ungraph::new();

    println!("{}", g);
    g.add_node('a');
    g.add_node('b');
    g.add_node('c');
    println!("{}", g);
    g.add_edge(0, 1);
    g.add_edge(0, 2);
    println!("{}", g);

    let mut h = Digraph::new();

    println!("{}", h);
    h.add_node('a');
    h.add_node('b');
    h.add_node('c');
    println!("{}", h);
    h.add_edge(0, 1);
    h.add_edge(0, 2);
    println!("{}", h);
}
<|endoftext|>


<commit_before>//! Serialize a Rust data structure into UBJSON data.

use std::io::Write;

use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use serde::ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
                 SerializeTupleVariant, SerializeMap, SerializeStruct, SerializeStructVariant};

use error::{Error, Result};

/// Serialize the given value as a UBJSON byte vector.
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
    where T: Serialize
{
    let mut serializer = Serializer::new(Vec::new());
    value.serialize(&mut serializer)?;
    Ok(serializer.into_inner())
}

/// Serialize the given value as UBJSON into the IO stream.
pub fn to_writer<T, W>(writer: W, value: &T) -> Result<()>
    where W: Write,
          T: Serialize
{
    let mut serializer = Serializer::new(writer);
    value.serialize(&mut serializer)?;
    Ok(())
}

/// Structure for serializing Rust values into UBJSON.
pub struct Serializer<W> {
    inner: W,
}

impl<W> Serializer<W>
    where W: Write
{
    /// Creates a new UBJSON serializer.
    pub fn new(writer: W) -> Self {
        Serializer { inner: writer }
    }

    /// Consumes the serializer and returns the writer it wrapped.
    fn into_inner(self) -> W {
        self.inner
    }
}

impl<'a, W> ser::Serializer for &'a mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Compound<'a, W>;
    type SerializeTuple = Compound<'a, W>;

    fn serialize_bool(self, v: bool) -> Result<()> {
        self.inner
            .write_u8(match v {
                          true => b'T',
                          false => b'F',
                      })
            .map_err(Error::Io)
    }

    fn serialize_i8(self, v: i8) -> Result<()> {
        self.inner
            .write_u8(b'i')
            .and_then(|_| self.inner.write_i8(v))
            .map_err(Error::Io)
    }

    fn serialize_i16(self, v: i16) -> Result<()> {
        if (i8::min_value() as i16 <= v) && (v <= i8::max_value() as i16) {
            self.serialize_i8(v as i8)
        } else {
            self.inner
                .write_u8(b'I')
                .and_then(|_| self.inner.write_i16::<BigEndian>(v))
                .map_err(Error::Io)
        }
    }

    fn serialize_i32(self, v: i32) -> Result<()> {
        if (i16::min_value() as i32 <= v) && (v <= i16::max_value() as i32) {
            self.serialize_i16(v as i16)
        } else {
            self.inner
                .write_u8(b'l')
                .and_then(|_| self.inner.write_i32::<BigEndian>(v))
                .map_err(Error::Io)
        }
    }

    fn serialize_i64(self, v: i64) -> Result<()> {
        if (i32::min_value() as i64 <= v) && (v <= i32::max_value() as i64) {
            self.serialize_i32(v as i32)
        } else {
            self.inner
                .write_u8(b'L')
                .and_then(|_| self.inner.write_i64::<BigEndian>(v))
                .map_err(|err| Error::io(err))
        }
    }

    fn serialize_u8(self, v: u8) -> Result<()> {
        self.inner
            .write_u8(b'U')
            .and_then(|_| self.inner.write_u8(v))
            .map_err(Error::Io)
    }

    fn serialize_u16(self, v: u16) -> Result<()> {
        if v <= u8::max_value() as u16 {
            self.serialize_u8(v as u8)
        } else if v <= i16::max_value() as u16 {
            self.serialize_i16(v as i16)
        } else {
            self.serialize_i32(v as i32)
        }
    }

    fn serialize_u32(self, v: u32) -> Result<()> {
        if v <= u16::max_value() as u32 {
            self.serialize_u16(v as u16)
        } else if v <= i32::max_value() as u32 {
            self.serialize_i32(v as i32)
        } else {
            self.serialize_i64(v as i64)
        }
    }

    fn serialize_u64(self, v: u64) -> Result<()> {
        if v <= u32::max_value() as u64 {
            self.serialize_u32(v as u32)
        } else if v <= i64::max_value() as u64 {
            self.serialize_i64(v as i64)
        } else {
            let v = v.to_string();
            self.inner
                .write_u8(b'H')
                .map_err(Error::Io)
                .and_then(|_| self.serialize_u64(v.len()))
                .and_then(|_| self.inner.write_all(v.as_bytes()).map_err(Error::Io))
        }
    }

    fn serialize_f32(self, v: f32) -> Result<()> {
        self.inner
            .write_u8(b'd')
            .and_then(|_| self.inner.write_f32::<BigEndian>(v))
            .map_err(Error::Io)
    }

    fn serialize_f64(self, v: f64) -> Result<()> {
        self.inner
            .write_u8(b'D')
            .and_then(|_| self.inner.write_f64::<BigEndian>(v))
            .map_err(Error::Io)
    }

    fn serialize_char(self, v: char) -> Result<()> {
        let v: u32 = v.into();
        if v <= u8::max_value() as u32 {
            self.inner
                .write_u8(b'C')
                .and_then(|_| self.inner.write_u8(v as u8))
                .map_err(Error::Io)
        } else {
            self.serialize_u32(v)
        }
    }

    fn serialize_str(self, v: &str) -> Result<()> {
        self.inner
            .write_u8(b'S')
            .map_err(Error::Io)
            .and_then(|_| self.serialize_u64(v.len() as u64))
            .and_then(|_| self.inner.write_all(v.as_bytes()).map_err(Error::Io))
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
        self.inner
            .write_all(b"[$U#")
            .map_err(Error::Io)
            .and_then(|_| self.serialize_u64(v.len() as u64))
            .and_then(|_| self.inner.write_all(v.as_bytes()).map_err(Error::Io))
    }

    fn serialize_none(self) -> Result<()> {
        self.inner.write_u8(b'Z').map_err(Error::Io)
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
        where T: Serialize
    {
        value.serialize(self)
    }

    fn serialize_unit(self) -> Result<()> {
        self.serialize_none()
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
        self.serialize_none()
    }

    fn serialize_unit_variant(self,
                              name: &'static str,
                              variant_index: u32,
                              variant: &'static str)
                              -> Result<()> {
        unimplemented!()
    }

    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<()>
        where T: Serialize
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(self,
                                            name: &'static str,
                                            variant_index: u32,
                                            variant: &'static str,
                                            value: &T)
                                            -> Result<()>
        where T: Serialize
    {
        unimplemented!()
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Compound<'a, W>> {
        if let Some(len) = len {
            self.serialize_tuple(self, len)
        } else {
            self.inner.write_u8(b'[').map_err(Error::Io)?;
            Ok(Compound {
                ser: self,
                length_known: false,
            })
        }
    }

    fn serialize_tuple(self, len: usize) -> Result<Compound<'a, W>> {
        self.inner.write_all(b"[#").map_err(Error::Io)?;
        self.serialize_u64(len as u64)?;
        Ok(Compound {
            ser: self,
            length_known: true,
        })
    }
}

#[doc(hidden)]
pub struct Compound<'a, W: 'a> {
    ser: &'a mut Serializer<W>,
    length_known: bool,
}

impl<'a, W: 'a> SerializeSeq for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
        where T: Serialize
    {
        value.serialize(self.ser)
    }

    fn end(self) -> Result<()> {
        if self.length_known {
            Ok(())
        } else {
            self.ser.inner.write_u8(b']').map_err(Error::Io)
        }
    }
}

impl <'a, W: 'a> SerializeTuple for Compound<'a, W> {
    type Ok = ();
    type Error = Error;
    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> Result<()> {
        SerializeSeq::end(self)
    }
}
<commit_msg>Add placeholder implementations for Serialize method<commit_after>//! Serialize a Rust data structure into UBJSON data.

use std::io::Write;

use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use serde::ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
                 SerializeTupleVariant, SerializeMap, SerializeStruct, SerializeStructVariant};

use error::{Error, Result};

/// Serialize the given value as a UBJSON byte vector.
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
    where T: Serialize
{
    let mut serializer = Serializer::new(Vec::new());
    value.serialize(&mut serializer)?;
    Ok(serializer.into_inner())
}

/// Serialize the given value as UBJSON into the IO stream.
pub fn to_writer<T, W>(writer: W, value: &T) -> Result<()>
    where W: Write,
          T: Serialize
{
    let mut serializer = Serializer::new(writer);
    value.serialize(&mut serializer)?;
    Ok(())
}

/// Structure for serializing Rust values into UBJSON.
pub struct Serializer<W> {
    inner: W,
}

impl<W> Serializer<W>
    where W: Write
{
    /// Creates a new UBJSON serializer.
    pub fn new(writer: W) -> Self {
        Serializer { inner: writer }
    }

    /// Consumes the serializer and returns the writer it wrapped.
    fn into_inner(self) -> W {
        self.inner
    }
}

impl<'a, W: Write> ser::Serializer for &'a mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Compound<'a, W>;
    type SerializeTuple = Compound<'a, W>;
    type SerializeTupleStruct = Compound<'a, W>;
    type SerializeTupleVariant = Compound<'a, W>;
    type SerializeMap = Compound<'a, W>;
    type SerializeStruct = Compound<'a, W>;
    type SerializeStructVariant = Compound<'a, W>;

    fn serialize_bool(self, v: bool) -> Result<()> {
        self.inner
            .write_u8(match v {
                          true => b'T',
                          false => b'F',
                      })
            .map_err(Error::Io)
    }

    fn serialize_i8(self, v: i8) -> Result<()> {
        self.inner
            .write_u8(b'i')
            .and_then(|_| self.inner.write_i8(v))
            .map_err(Error::Io)
    }

    fn serialize_i16(self, v: i16) -> Result<()> {
        if (i8::min_value() as i16 <= v) && (v <= i8::max_value() as i16) {
            self.serialize_i8(v as i8)
        } else {
            self.inner
                .write_u8(b'I')
                .and_then(|_| self.inner.write_i16::<BigEndian>(v))
                .map_err(Error::Io)
        }
    }

    fn serialize_i32(self, v: i32) -> Result<()> {
        if (i16::min_value() as i32 <= v) && (v <= i16::max_value() as i32) {
            self.serialize_i16(v as i16)
        } else {
            self.inner
                .write_u8(b'l')
                .and_then(|_| self.inner.write_i32::<BigEndian>(v))
                .map_err(Error::Io)
        }
    }

    fn serialize_i64(self, v: i64) -> Result<()> {
        if (i32::min_value() as i64 <= v) && (v <= i32::max_value() as i64) {
            self.serialize_i32(v as i32)
        } else {
            self.inner
                .write_u8(b'L')
                .and_then(|_| self.inner.write_i64::<BigEndian>(v))
                .map_err(|err| Error::io(err))
        }
    }

    fn serialize_u8(self, v: u8) -> Result<()> {
        self.inner
            .write_u8(b'U')
            .and_then(|_| self.inner.write_u8(v))
            .map_err(Error::Io)
    }

    fn serialize_u16(self, v: u16) -> Result<()> {
        if v <= u8::max_value() as u16 {
            self.serialize_u8(v as u8)
        } else if v <= i16::max_value() as u16 {
            self.serialize_i16(v as i16)
        } else {
            self.serialize_i32(v as i32)
        }
    }

    fn serialize_u32(self, v: u32) -> Result<()> {
        if v <= u16::max_value() as u32 {
            self.serialize_u16(v as u16)
        } else if v <= i32::max_value() as u32 {
            self.serialize_i32(v as i32)
        } else {
            self.serialize_i64(v as i64)
        }
    }

    fn serialize_u64(self, v: u64) -> Result<()> {
        if v <= u32::max_value() as u64 {
            self.serialize_u32(v as u32)
        } else if v <= i64::max_value() as u64 {
            self.serialize_i64(v as i64)
        } else {
            let v = v.to_string();
            self.inner
                .write_u8(b'H')
                .map_err(Error::Io)
                .and_then(|_| self.serialize_u64(v.len()))
                .and_then(|_| self.inner.write_all(v.as_bytes()).map_err(Error::Io))
        }
    }

    fn serialize_f32(self, v: f32) -> Result<()> {
        self.inner
            .write_u8(b'd')
            .and_then(|_| self.inner.write_f32::<BigEndian>(v))
            .map_err(Error::Io)
    }

    fn serialize_f64(self, v: f64) -> Result<()> {
        self.inner
            .write_u8(b'D')
            .and_then(|_| self.inner.write_f64::<BigEndian>(v))
            .map_err(Error::Io)
    }

    fn serialize_char(self, v: char) -> Result<()> {
        let v: u32 = v.into();
        if v <= u8::max_value() as u32 {
            self.inner
                .write_u8(b'C')
                .and_then(|_| self.inner.write_u8(v as u8))
                .map_err(Error::Io)
        } else {
            self.serialize_u32(v)
        }
    }

    fn serialize_str(self, v: &str) -> Result<()> {
        self.inner
            .write_u8(b'S')
            .map_err(Error::Io)
            .and_then(|_| self.serialize_u64(v.len() as u64))
            .and_then(|_| self.inner.write_all(v.as_bytes()).map_err(Error::Io))
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
        self.inner
            .write_all(b"[$U#")
            .map_err(Error::Io)
            .and_then(|_| self.serialize_u64(v.len() as u64))
            .and_then(|_| self.inner.write_all(v.as_bytes()).map_err(Error::Io))
    }

    fn serialize_none(self) -> Result<()> {
        self.inner.write_u8(b'Z').map_err(Error::Io)
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
        where T: Serialize
    {
        value.serialize(self)
    }

    fn serialize_unit(self) -> Result<()> {
        self.serialize_none()
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
        self.serialize_none()
    }

    fn serialize_unit_variant(self,
                              name: &'static str,
                              variant_index: u32,
                              variant: &'static str)
                              -> Result<()> {
        unimplemented!()
    }

    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<()>
        where T: Serialize
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(self,
                                            name: &'static str,
                                            variant_index: u32,
                                            variant: &'static str,
                                            value: &T)
                                            -> Result<()>
        where T: Serialize
    {
        unimplemented!()
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Compound<'a, W>> {
        if let Some(len) = len {
            self.serialize_tuple(self, len)
        } else {
            self.inner.write_u8(b'[').map_err(Error::Io)?;
            Ok(Compound {
                ser: self,
                length_known: false,
            })
        }
    }

    fn serialize_tuple(self, len: usize) -> Result<Compound<'a, W>> {
        self.inner.write_all(b"[#").map_err(Error::Io)?;
        self.serialize_u64(len as u64)?;
        Ok(Compound {
            ser: self,
            length_known: true,
        })
    }

    fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Compound<'a, W>> {
        unimplemented!()
    }

    fn serialize_tuple_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<Compound<'a, W>> {
        unimplemented!()
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Compound<'a, W>> {
        unimplemented!()
    }

    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Compound<'a, W>> {
        unimplemented!()
    }

    fn serialize_struct_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<Compound<'a, W>> {
        unimplemented!()
    }
}

#[doc(hidden)]
pub struct Compound<'a, W: 'a> {
    ser: &'a mut Serializer<W>,
    length_known: bool,
}

impl<'a, W: 'a> SerializeSeq for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
        where T: Serialize
    {
        value.serialize(self.ser)
    }

    fn end(self) -> Result<()> {
        if self.length_known {
            Ok(())
        } else {
            self.ser.inner.write_u8(b']').map_err(Error::Io)
        }
    }
}

impl<'a, W: 'a> SerializeTuple for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> Result<()> {
        SerializeSeq::end(self)
    }
}

impl<'a, W: 'a> SerializeTupleStruct for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        unimplemented!()
    }

    fn end(self) -> Result<()> {
        unimplemented!()
    }
}

impl<'a, W: 'a> SerializeTupleVariant for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        unimplemented!()
    }

    fn end(self) -> Result<()> {
        unimplemented!()
    }
}

impl<'a, W: 'a> SerializeMap for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
        unimplemented!()
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        unimplemented!()
    }

    fn end(self) -> Result<()> {
        unimplemented!()
    }
}

impl<'a, W: 'a> SerializeStruct for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()> where T: Serialize {
        unimplemented!()
    }

    fn end(self) -> Result<()> {
        unimplemented!()
    }
}

impl<'a, W: 'a> SerializeStructVariant for Compound<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()> where T: Serialize {
        unimplemented!()
    }

    fn end(self) -> Result<()> {
        unimplemented!()
    }
}
<|endoftext|>


<commit_before>/// The Toml Set extensions

use toml::Value;

use tokenizer::tokenize_with_seperator;
use tokenizer::Token;
use error::*;

pub trait TomlValueSetExt<'doc> {

    /// Extension function for setting a value in the current toml::Value document
    /// using a custom seperator
    ///
    /// # Semantics
    ///
    /// The function _never_ creates intermediate data structures (Tables or Arrays) in the
    /// document.
    ///
    /// # Return value
    ///
    /// * If the set operation worked correctly, `Ok(None)` is returned.
    /// * If the set operation replaced an existing value `Ok(Some(old_value))` is returned
    /// * On failure, `Err(e)` is returned:
    ///     * If the query is `"a.b.c"` but there is no table `"b"`: error
    ///     * If the query is `"a.b.[0]"` but "`b"` is not an array: error
    ///     * If the query is `"a.b.[3]"` but the array at "`b"` has no index `3`: error
    ///     * etc.
    ///
    fn set_with_seperator(&mut self, query: &String, sep: char, value: Value) -> Result<Option<Value>>;

    /// Extension function for setting a value from the current toml::Value document
    ///
    /// See documentation of `TomlValueSetExt::set_with_seperator`
    fn set(&mut self, query: &String, value: Value) -> Result<Option<Value>> {
        self.set_with_seperator(query, '.', value)
    }

}

impl<'doc> TomlValueSetExt<'doc> for Value {

    fn set_with_seperator(&mut self, query: &String, sep: char, value: Value) -> Result<Option<Value>> {
        use resolver::mut_resolver::resolve;

        let mut tokens = try!(tokenize_with_seperator(query, sep));
        let last = tokens.pop_last();

        let mut val = try!(resolve(self, &tokens));
        let last = last.unwrap_or_else(|| Box::new(tokens));

        match *last {
            Token::Identifier { ident, .. } => {
                match val {
                    &mut Value::Table(ref mut t) => {
                        Ok(t.insert(ident, value))
                    }
                    _ => unimplemented!()
                }
            }

            Token::Index { idx, .. } => {
                match val {
                    &mut Value::Array(ref mut a) => {
                        if a.len() > idx {
                            let result = a.swap_remove(idx);
                            a.insert(idx, value);
                            Ok(Some(result))
                        } else {
                            a.push(value);
                            Ok(None)
                        }
                    }
                    _ => unimplemented!()
                }
            }

        }
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use toml::Value;
    use toml::from_str as toml_from_str;

    #[test]
    fn test_set_with_seperator_into_table() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        a = 0
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_some());
        let res = res.unwrap();
        assert!(is_match!(res, Value::Integer(0)));

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("table");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Table(_)));
                match inner {
                    &Value::Table(ref t) => {
                        assert!(!t.is_empty());

                        let a = t.get("a");
                        assert!(a.is_some());

                        let a = a.unwrap();
                        assert!(is_match!(a, &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_table_key_nonexistent() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_ok());
        let res = res.unwrap();

        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("table");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Table(_)));
                match inner {
                    &Value::Table(ref t) => {
                        assert!(!t.is_empty());

                        let a = t.get("a");
                        assert!(a.is_some());

                        let a = a.unwrap();
                        assert!(is_match!(a, &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_array() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = [ 0 ]
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("array.[0]"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_some());
        let res = res.unwrap();
        assert!(is_match!(res, Value::Integer(0)));

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("array");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Array(_)));
                match inner {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_table_index_nonexistent() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = []
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("array.[0]"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("array");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Array(_)));
                match inner {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_nested_table() {
        let mut toml : Value = toml_from_str(r#"
        [a.b.c]
        d = 0
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("a.b.c.d"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_some());
        let res = res.unwrap();
        assert!(is_match!(res, Value::Integer(0)));

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let a = t.get("a");
                assert!(a.is_some());

                let a = a.unwrap();
                assert!(is_match!(a, &Value::Table(_)));
                match a {
                    &Value::Table(ref a) => {
                        assert!(!a.is_empty());

                        let b_tab = a.get("b");
                        assert!(b_tab.is_some());

                        let b_tab = b_tab.unwrap();
                        assert!(is_match!(b_tab, &Value::Table(_)));
                        match b_tab {
                            &Value::Table(ref b) => {
                                assert!(!b.is_empty());

                                let c_tab = b.get("c");
                                assert!(c_tab.is_some());

                                let c_tab = c_tab.unwrap();
                                assert!(is_match!(c_tab, &Value::Table(_)));
                                match c_tab {
                                    &Value::Table(ref c) => {
                                        assert!(!c.is_empty());

                                        let d = c.get("d");
                                        assert!(d.is_some());

                                        let d = d.unwrap();
                                        assert!(is_match!(d, &Value::Integer(1)));
                                    },
                                    _ => panic!("What just happenend?"),
                                }
                            },
                            _ => panic!("What just happenend?"),
                        }
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_nonexistent_table() {
        let mut toml : Value = toml_from_str("").unwrap();

        let res = toml.set_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_err());

        let res = res.unwrap_err();
        assert!(is_match!(res.kind(), &ErrorKind::IdentifierNotFoundInDocument(_)));
    }

    #[test]
    fn test_set_with_seperator_into_nonexistent_array() {
        let mut toml : Value = toml_from_str("").unwrap();

        let res = toml.set_with_seperator(&String::from("[0]"), '.', Value::Integer(1));

        assert!(res.is_err());

        let res = res.unwrap_err();
        assert!(is_match!(res.kind(), &ErrorKind::NoIndexInTable(0)));
    }

}

<commit_msg>Remove unneeded lifetimes<commit_after>/// The Toml Set extensions

use toml::Value;

use tokenizer::tokenize_with_seperator;
use tokenizer::Token;
use error::*;

pub trait TomlValueSetExt {

    /// Extension function for setting a value in the current toml::Value document
    /// using a custom seperator
    ///
    /// # Semantics
    ///
    /// The function _never_ creates intermediate data structures (Tables or Arrays) in the
    /// document.
    ///
    /// # Return value
    ///
    /// * If the set operation worked correctly, `Ok(None)` is returned.
    /// * If the set operation replaced an existing value `Ok(Some(old_value))` is returned
    /// * On failure, `Err(e)` is returned:
    ///     * If the query is `"a.b.c"` but there is no table `"b"`: error
    ///     * If the query is `"a.b.[0]"` but "`b"` is not an array: error
    ///     * If the query is `"a.b.[3]"` but the array at "`b"` has no index `3`: error
    ///     * etc.
    ///
    fn set_with_seperator(&mut self, query: &String, sep: char, value: Value) -> Result<Option<Value>>;

    /// Extension function for setting a value from the current toml::Value document
    ///
    /// See documentation of `TomlValueSetExt::set_with_seperator`
    fn set(&mut self, query: &String, value: Value) -> Result<Option<Value>> {
        self.set_with_seperator(query, '.', value)
    }

}

impl TomlValueSetExt for Value {

    fn set_with_seperator(&mut self, query: &String, sep: char, value: Value) -> Result<Option<Value>> {
        use resolver::mut_resolver::resolve;

        let mut tokens = try!(tokenize_with_seperator(query, sep));
        let last = tokens.pop_last();

        let mut val = try!(resolve(self, &tokens));
        let last = last.unwrap_or_else(|| Box::new(tokens));

        match *last {
            Token::Identifier { ident, .. } => {
                match val {
                    &mut Value::Table(ref mut t) => {
                        Ok(t.insert(ident, value))
                    }
                    _ => unimplemented!()
                }
            }

            Token::Index { idx, .. } => {
                match val {
                    &mut Value::Array(ref mut a) => {
                        if a.len() > idx {
                            let result = a.swap_remove(idx);
                            a.insert(idx, value);
                            Ok(Some(result))
                        } else {
                            a.push(value);
                            Ok(None)
                        }
                    }
                    _ => unimplemented!()
                }
            }

        }
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use toml::Value;
    use toml::from_str as toml_from_str;

    #[test]
    fn test_set_with_seperator_into_table() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        a = 0
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_some());
        let res = res.unwrap();
        assert!(is_match!(res, Value::Integer(0)));

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("table");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Table(_)));
                match inner {
                    &Value::Table(ref t) => {
                        assert!(!t.is_empty());

                        let a = t.get("a");
                        assert!(a.is_some());

                        let a = a.unwrap();
                        assert!(is_match!(a, &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_table_key_nonexistent() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_ok());
        let res = res.unwrap();

        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("table");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Table(_)));
                match inner {
                    &Value::Table(ref t) => {
                        assert!(!t.is_empty());

                        let a = t.get("a");
                        assert!(a.is_some());

                        let a = a.unwrap();
                        assert!(is_match!(a, &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_array() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = [ 0 ]
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("array.[0]"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_some());
        let res = res.unwrap();
        assert!(is_match!(res, Value::Integer(0)));

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("array");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Array(_)));
                match inner {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_table_index_nonexistent() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = []
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("array.[0]"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let inner = t.get("array");
                assert!(inner.is_some());

                let inner = inner.unwrap();
                assert!(is_match!(inner, &Value::Array(_)));
                match inner {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_nested_table() {
        let mut toml : Value = toml_from_str(r#"
        [a.b.c]
        d = 0
        "#).unwrap();

        let res = toml.set_with_seperator(&String::from("a.b.c.d"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_some());
        let res = res.unwrap();
        assert!(is_match!(res, Value::Integer(0)));

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let a = t.get("a");
                assert!(a.is_some());

                let a = a.unwrap();
                assert!(is_match!(a, &Value::Table(_)));
                match a {
                    &Value::Table(ref a) => {
                        assert!(!a.is_empty());

                        let b_tab = a.get("b");
                        assert!(b_tab.is_some());

                        let b_tab = b_tab.unwrap();
                        assert!(is_match!(b_tab, &Value::Table(_)));
                        match b_tab {
                            &Value::Table(ref b) => {
                                assert!(!b.is_empty());

                                let c_tab = b.get("c");
                                assert!(c_tab.is_some());

                                let c_tab = c_tab.unwrap();
                                assert!(is_match!(c_tab, &Value::Table(_)));
                                match c_tab {
                                    &Value::Table(ref c) => {
                                        assert!(!c.is_empty());

                                        let d = c.get("d");
                                        assert!(d.is_some());

                                        let d = d.unwrap();
                                        assert!(is_match!(d, &Value::Integer(1)));
                                    },
                                    _ => panic!("What just happenend?"),
                                }
                            },
                            _ => panic!("What just happenend?"),
                        }
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_set_with_seperator_into_nonexistent_table() {
        let mut toml : Value = toml_from_str("").unwrap();

        let res = toml.set_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_err());

        let res = res.unwrap_err();
        assert!(is_match!(res.kind(), &ErrorKind::IdentifierNotFoundInDocument(_)));
    }

    #[test]
    fn test_set_with_seperator_into_nonexistent_array() {
        let mut toml : Value = toml_from_str("").unwrap();

        let res = toml.set_with_seperator(&String::from("[0]"), '.', Value::Integer(1));

        assert!(res.is_err());

        let res = res.unwrap_err();
        assert!(is_match!(res.kind(), &ErrorKind::NoIndexInTable(0)));
    }

}

<|endoftext|>


<commit_before>use binary_reader::{ReadAll, BinaryRead, BinaryReader};

use std::io::{Result, Error, ErrorKind, Seek, SeekFrom, BufReader};
use std::fs::File;

pub type SpcResult = Result<Spc>;

pub struct Spc {
    pub header: [u8; 33],
    pub version_minor: u8,
    pub pc: u16,
    pub a: u8,
    pub x: u8,
    pub y: u8,
    pub psw: u8,
    pub sp: u8,
    //pub id666_tag: Option<Id666>,
    pub ram: [u8; 0x10000],
    pub regs: [u8; 128],
    pub ipl_rom: [u8; 64]
}

impl Spc {
    pub fn load(file_name: &String) -> SpcResult {
        macro_rules! bad_header {
            ($add_info:expr) => ({
                let message_text = "Unrecognized SPC header".to_string();
                let message =
                    match $add_info {
                        "" => message_text,
                        _ => message_text + " (" + $add_info + ")"
                    };
                return Err(Error::new(ErrorKind::Other, message));
            });
            () => (bad_header!(""))
        }

        macro_rules! assert_header {
            ($cond:expr, $message:expr) => (if !$cond { bad_header!($message); });
            ($cond:expr) => (assert_header!($cond, ""))
        }

        let file = try!(File::open(file_name));
        let mut r = BinaryReader::new(BufReader::new(file));

        macro_rules! u8 {
            () => (try!(r.read_u8()))
        }

        macro_rules! u16 {
            () => (try!(r.read_le_u16()))
        }

        macro_rules! i32 {
            () => (try!(r.read_le_i32()))
        }

        let mut header = [0; 33];
        try!(r.read_all(&mut header));
        assert_header!(
            header.iter()
                .zip(b"SNES-SPC700 Sound File Data v0.30".iter())
                .all(|(x, y)| x == y),
            "Invalid header string");

        assert_header!(u16!() == 0x1a1a);

        let has_id666_tag = match u8!() {
            0x1a => true,
            0x1b => false,
            _ => bad_header!("Unable to determine if file contains ID666 tag")
        };

        let version_minor = u8!();

        let pc = u16!();
        let a = u8!();
        let x = u8!();
        let y = u8!();
        let psw = u8!();
        let sp = u8!();

        // TODO: Read ID666 tag if available

        try!(r.seek(SeekFrom::Start(0x100)));
        let mut ram = [0; 0x10000];
        try!(r.read_all(&mut ram));
        let mut regs = [0; 128];
        try!(r.read_all(&mut regs));
        try!(r.seek(SeekFrom::Start(0x101c0)));
        let mut ipl_rom = [0; 64];
        try!(r.read_all(&mut ipl_rom));

        Ok(Spc {
            header: header,
            version_minor: version_minor,
            pc: pc,
            a: a,
            x: x,
            y: y,
            psw: psw,
            sp: sp,
            ram: ram,
            regs: regs,
            ipl_rom: ipl_rom
        })
    }
}

/*pub struct Id666 {
    pub song_title: String,
    pub game_title: String,
    pub dumper_name: String,
    pub date_dumped: String,
    pub seconds_to_play_before_fading_out: i32,
    pub fade_out_length: i32,
    pub artist_name: String,
    pub default_channel_disables: u8,
    pub dumping_emulator: Emulator
}

pub enum Emulator {
    Unknown,
    ZSnes,
    Snes9x
}*/
<commit_msg>tiny bit more generic<commit_after>use binary_reader::{ReadAll, BinaryRead, BinaryReader};

use std::io::{Result, Error, ErrorKind, Seek, SeekFrom, BufReader};
use std::path::Path;
use std::fs::File;

pub type SpcResult = Result<Spc>;

pub struct Spc {
    pub header: [u8; 33],
    pub version_minor: u8,
    pub pc: u16,
    pub a: u8,
    pub x: u8,
    pub y: u8,
    pub psw: u8,
    pub sp: u8,
    //pub id666_tag: Option<Id666>,
    pub ram: [u8; 0x10000],
    pub regs: [u8; 128],
    pub ipl_rom: [u8; 64]
}

impl Spc {
    pub fn load<P: AsRef<Path>>(path: P) -> SpcResult {
        macro_rules! bad_header {
            ($add_info:expr) => ({
                let message_text = "Unrecognized SPC header".to_string();
                let message =
                    match $add_info {
                        "" => message_text,
                        _ => message_text + " (" + $add_info + ")"
                    };
                return Err(Error::new(ErrorKind::Other, message));
            });
            () => (bad_header!(""))
        }

        macro_rules! assert_header {
            ($cond:expr, $message:expr) => (if !$cond { bad_header!($message); });
            ($cond:expr) => (assert_header!($cond, ""))
        }

        let file = try!(File::open(path));
        let mut r = BinaryReader::new(BufReader::new(file));

        macro_rules! u8 {
            () => (try!(r.read_u8()))
        }

        macro_rules! u16 {
            () => (try!(r.read_le_u16()))
        }

        macro_rules! i32 {
            () => (try!(r.read_le_i32()))
        }

        let mut header = [0; 33];
        try!(r.read_all(&mut header));
        assert_header!(
            header.iter()
                .zip(b"SNES-SPC700 Sound File Data v0.30".iter())
                .all(|(x, y)| x == y),
            "Invalid header string");

        assert_header!(u16!() == 0x1a1a);

        let has_id666_tag = match u8!() {
            0x1a => true,
            0x1b => false,
            _ => bad_header!("Unable to determine if file contains ID666 tag")
        };

        let version_minor = u8!();

        let pc = u16!();
        let a = u8!();
        let x = u8!();
        let y = u8!();
        let psw = u8!();
        let sp = u8!();

        // TODO: Read ID666 tag if available

        try!(r.seek(SeekFrom::Start(0x100)));
        let mut ram = [0; 0x10000];
        try!(r.read_all(&mut ram));
        let mut regs = [0; 128];
        try!(r.read_all(&mut regs));
        try!(r.seek(SeekFrom::Start(0x101c0)));
        let mut ipl_rom = [0; 64];
        try!(r.read_all(&mut ipl_rom));

        Ok(Spc {
            header: header,
            version_minor: version_minor,
            pc: pc,
            a: a,
            x: x,
            y: y,
            psw: psw,
            sp: sp,
            ram: ram,
            regs: regs,
            ipl_rom: ipl_rom
        })
    }
}

/*pub struct Id666 {
    pub song_title: String,
    pub game_title: String,
    pub dumper_name: String,
    pub date_dumped: String,
    pub seconds_to_play_before_fading_out: i32,
    pub fade_out_length: i32,
    pub artist_name: String,
    pub default_channel_disables: u8,
    pub dumping_emulator: Emulator
}

pub enum Emulator {
    Unknown,
    ZSnes,
    Snes9x
}*/
<|endoftext|>


<commit_before>use std::f64;
use std::option::Option;
use rand::Rng;
use consts;
use distribution::{Distribution, Univariate, Continuous};
use error::StatsError;
use result;

#[derive(Debug, Clone, PartialEq)]
pub struct Exponential {
    rate: f64
}

impl Exponential {
    pub fn new(rate: f64) -> result::Result<Exponential> {
        if rate < 0.0 {
            Err(StatsError::BadParams);
        } else {
            Ok(Exponential{rate: rate})
        }
    }

    pub fn rate(&self) -> f64 {
        self.rate
    }
}

impl Distribution for Exponential {
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        0.0
    }
}

impl Univariate for Exponential {
    fn mean(&self) -> f64 {
        1.0 / self.rate
    }

    fn variance(&self) -> f64 {
        1.0 / (self.rate * self.rate)
    }

    fn std_dev(&self) -> f64 {
        1.0 / self.rate
    }

    fn entropy(&self) -> f64 {
        1.0 - self.rate.ln()
    }

    fn skewness(&self) -> f64 {
        2.0
    }

    fn median(&self) -> Option<f64> {
        Some(consts::LN_2 / self.rate)
    }

    fn cdf(&self, x: f64) -> result::Result<f64> {
        if x < 0.0 {
            Ok(0.0)
        } else {
            Ok(1.0 - (-self.rate * x).exp())
        }
    }
}

impl Continuous for Exponential {
    fn mode(&self) -> f64 {
        0.0
    }

    fn min(&self) -> f64 {
        0.0
    }

    fn max(&self) -> f64 {
        f64::INFINITY
    }

    fn pdf(&self, x: f64) -> f64 {
        if x < 0.0 {
            0.0
        } else {
            self.rate * (-self.rate * x).exp()
        }
    }

    fn ln_pdf(&self, x: f64) -> f64 {
        self.rate.ln() - self.rate * x
    }
}<commit_msg>fix parameter guard on exponential distribution<commit_after>use std::f64;
use std::option::Option;
use rand::Rng;
use consts;
use distribution::{Distribution, Univariate, Continuous};
use error::StatsError;
use result;

#[derive(Debug, Clone, PartialEq)]
pub struct Exponential {
    rate: f64
}

impl Exponential {
    pub fn new(rate: f64) -> result::Result<Exponential> {
        if rate <= 0.0 {
            Err(StatsError::BadParams);
        } else {
            Ok(Exponential{rate: rate})
        }
    }

    pub fn rate(&self) -> f64 {
        self.rate
    }
}

impl Distribution for Exponential {
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        0.0
    }
}

impl Univariate for Exponential {
    fn mean(&self) -> f64 {
        1.0 / self.rate
    }

    fn variance(&self) -> f64 {
        1.0 / (self.rate * self.rate)
    }

    fn std_dev(&self) -> f64 {
        1.0 / self.rate
    }

    fn entropy(&self) -> f64 {
        1.0 - self.rate.ln()
    }

    fn skewness(&self) -> f64 {
        2.0
    }

    fn median(&self) -> Option<f64> {
        Some(consts::LN_2 / self.rate)
    }

    fn cdf(&self, x: f64) -> result::Result<f64> {
        if x < 0.0 {
            Ok(0.0)
        } else {
            Ok(1.0 - (-self.rate * x).exp())
        }
    }
}

impl Continuous for Exponential {
    fn mode(&self) -> f64 {
        0.0
    }

    fn min(&self) -> f64 {
        0.0
    }

    fn max(&self) -> f64 {
        f64::INFINITY
    }

    fn pdf(&self, x: f64) -> f64 {
        if x < 0.0 {
            0.0
        } else {
            self.rate * (-self.rate * x).exp()
        }
    }

    fn ln_pdf(&self, x: f64) -> f64 {
        self.rate.ln() - self.rate * x
    }
}<|endoftext|>