<commit_before>use std::net;
use uuid::Uuid;

use frame::frame_result::{RowsMetadata, ColType, ColSpec, BodyResResultRows, ColTypeOptionValue};
use types::{CBytes, IntoRustByName};
use types::data_serialization_types::*;
use types::list::List;
use types::map::Map;
use types::udt::UDT;
use error::Result;

#[derive(Debug)]
pub struct Row {
    metadata: RowsMetadata,
    row_content: Vec<CBytes>
}

impl Row {
    pub fn from_frame_body(body: BodyResResultRows) -> Vec<Row> {
        return body.rows_content
            .iter()
            .map(|row| Row {
                metadata: body.metadata.clone(),
                row_content: row.clone()
            })
            .collect();
    }

    fn get_col_by_name(&self, name: &str) -> Option<(&ColType, &CBytes)> {
        let i_opt = self.metadata.col_specs.iter().position(|spec| spec.name.as_str() == name);
        if !i_opt.is_some() {
            return None;
        }
        let i = i_opt.unwrap();
        let ref data: CBytes = self.row_content[i];
        let ref cassandra_type: ColType = self.metadata.col_specs[i].col_type.id;
        return Some((cassandra_type, data));
    }

    fn get_col_spec_by_name(&self, name: &str) -> Option<(&ColSpec, &CBytes)> {
        let i_opt = self.metadata.col_specs.iter().position(|spec| spec.name.as_str() == name);
        if !i_opt.is_some() {
            return None;
        }
        let i = i_opt.unwrap();
        let ref data: CBytes = self.row_content[i];
        let ref cassandra_type: ColSpec = self.metadata.col_specs[i];
        return Some((cassandra_type, data));
    }
}

impl IntoRustByName<Vec<u8>> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<Vec<u8>>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();
            let converted = match cassandra_type {
                &ColType::Blob => decode_blob(bytes),
                _ => unreachable!()
            };
            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<String> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<String>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Custom => decode_custom(bytes),
                &ColType::Ascii => decode_ascii(bytes),
                &ColType::Varchar => decode_varchar(bytes),
                // TODO: clarify when to use decode_text.
                // it's not mentioned in https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v4.spec#L582
                // &ColType::XXX => decode_text(bytes).ok(),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<bool> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<bool>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Boolean => decode_boolean(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<i64> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<i64>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Int => decode_bigint(bytes),
                &ColType::Bigint => decode_bigint(bytes),
                &ColType::Timestamp => decode_timestamp(bytes),
                &ColType::Time => decode_time(bytes),
                &ColType::Varint => decode_varint(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<i32> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<i32>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Int => decode_int(bytes),
                &ColType::Date => decode_date(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<i16> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<i16>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Smallint => decode_smallint(bytes),
                _ => unreachable!()
            };
            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<f64> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<f64>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Double => decode_double(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<f32> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<f32>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Decimal => decode_decimal(bytes),
                &ColType::Float => decode_float(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<net::IpAddr> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<net::IpAddr>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Inet => decode_inet(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<Uuid> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<Uuid>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Uuid => decode_timeuuid(bytes),
                &ColType::Timeuuid => decode_timeuuid(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<List> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<List>> {
        return self.get_col_spec_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            return match cassandra_type.col_type.id {
                // in fact, both decode_list and decode_set return Ok
                ColType::List => Ok(List::new(decode_list(bytes).unwrap(), cassandra_type.col_type.clone())),
                ColType::Set => Ok(List::new(decode_set(bytes).unwrap(), cassandra_type.col_type.clone())),
                _ => unreachable!()
            };
        });
    }
}

impl IntoRustByName<Map> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<Map>> {
        return self.get_col_spec_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            return match cassandra_type.col_type.id {
                // in fact, both decode_map and decode_set return Ok
                ColType::Map => Ok(Map::new(decode_map(bytes).unwrap(), cassandra_type.col_type.clone())),
                _ => unreachable!()
            }
        });
    }
}

impl IntoRustByName<UDT> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<UDT>> {
        return self.get_col_spec_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();
            let cudt = match cassandra_type.col_type.value {
                Some(ColTypeOptionValue::UdtType(ref t)) => t.clone(),
                _ => unreachable!()
            };

            return match cassandra_type.col_type.id {
                ColType::Map => Ok(UDT::new(decode_udt(bytes).unwrap(), cudt)),
                _ => unreachable!()
            }
        });
    }
}

//TODO: add uuid
<commit_msg>instead of unreahable which resulted in panicked it has been replaced with error wherever possible<commit_after>use std::net;
use uuid::Uuid;

use frame::frame_result::{RowsMetadata, ColType, ColSpec, BodyResResultRows, ColTypeOptionValue};
use types::{CBytes, IntoRustByName};
use types::data_serialization_types::*;
use types::list::List;
use types::map::Map;
use types::udt::UDT;
use error::Result;
use std::io;

#[derive(Debug)]
pub struct Row {
    metadata: RowsMetadata,
    row_content: Vec<CBytes>
}

impl Row {
    pub fn from_frame_body(body: BodyResResultRows) -> Vec<Row> {
        return body.rows_content
            .iter()
            .map(|row| Row {
                metadata: body.metadata.clone(),
                row_content: row.clone()
            })
            .collect();
    }

    fn get_col_by_name(&self, name: &str) -> Option<(&ColType, &CBytes)> {
        let i_opt = self.metadata.col_specs.iter().position(|spec| spec.name.as_str() == name);
        if !i_opt.is_some() {
            return None;
        }
        let i = i_opt.unwrap();
        let ref data: CBytes = self.row_content[i];
        let ref cassandra_type: ColType = self.metadata.col_specs[i].col_type.id;
        return Some((cassandra_type, data));
    }

    fn get_col_spec_by_name(&self, name: &str) -> Option<(&ColSpec, &CBytes)> {
        let i_opt = self.metadata.col_specs.iter().position(|spec| spec.name.as_str() == name);
        if !i_opt.is_some() {
            return None;
        }
        let i = i_opt.unwrap();
        let ref data: CBytes = self.row_content[i];
        let ref cassandra_type: ColSpec = self.metadata.col_specs[i];
        return Some((cassandra_type, data));
    }
}

impl IntoRustByName<Vec<u8>> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<Vec<u8>>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();
            let converted = match cassandra_type {
                &ColType::Blob => decode_blob(bytes),
                _ => unreachable!()
            };
            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<String> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<String>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Custom => decode_custom(bytes),
                &ColType::Ascii => decode_ascii(bytes),
                &ColType::Varchar => decode_varchar(bytes),
                // TODO: clarify when to use decode_text.
                // it's not mentioned in https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v4.spec#L582
                // &ColType::XXX => decode_text(bytes).ok(),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<bool> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<bool>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Boolean => decode_boolean(bytes),
                _ => {
                    let io_err = io::Error::new(
                        io::ErrorKind::NotFound,
                        format!("Unsupported type of converter. {:?} got, but
                    (bool ) is only supported.", cassandra_type));
                    Err(io_err)
                }
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<i64> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<i64>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();
            let converted = match cassandra_type {
                &ColType::Int => decode_bigint(bytes),
                &ColType::Bigint => decode_bigint(bytes),
                &ColType::Timestamp => decode_timestamp(bytes),
                &ColType::Time => decode_time(bytes),
                &ColType::Varint => decode_varint(bytes),
                &ColType::Float => decode_varint(bytes),
                _ => {
                    let io_err = io::Error::new(
                        io::ErrorKind::NotFound,
                        format!("Unsupported type of converter. {:?} got, but
                    (Int,Bigint,Timestamp,Time,Varint,Float ) is only supported.", cassandra_type));
                    Err(io_err)
                }
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<i32> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<i32>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Int => decode_int(bytes),
                &ColType::Date => decode_date(bytes),
                _ => {
                    let io_err = io::Error::new(
                        io::ErrorKind::NotFound,
                        format!("Unsupported type of converter. {:?} got, but
                    (Int,date ) is only supported.", cassandra_type));
                    Err(io_err)
                }
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<i16> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<i16>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Smallint => decode_smallint(bytes),
                _ => {
                    let io_err = io::Error::new(
                        io::ErrorKind::NotFound,
                        format!("Unsupported type of converter. {:?} got, but
                    (Smallint) is only supported.", cassandra_type));
                    Err(io_err)
                }
            };
            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<f64> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<f64>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Double => decode_double(bytes),
                _ => {
                    let io_err = io::Error::new(
                        io::ErrorKind::NotFound,
                        format!("Unsupported type of converter. {:?} got, but
                    (Double) is only supported.", cassandra_type));
                    Err(io_err)
                }
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<f32> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<f32>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Decimal => decode_decimal(bytes),
                &ColType::Float => decode_float(bytes),
                _ => {
                    let io_err = io::Error::new(
                        io::ErrorKind::NotFound,
                        format!("Unsupported type of converter. {:?} got, but
                    (Float,Decimal) is only supported.", cassandra_type));
                    Err(io_err)
                }
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<net::IpAddr> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<net::IpAddr>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Inet => decode_inet(bytes),
                _ => {
                    let io_err = io::Error::new(
                        io::ErrorKind::NotFound,
                        format!("Unsupported type of converter. {:?} got, but
                    (Inet) is only supported.", cassandra_type));
                    Err(io_err)
                }
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<Uuid> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<Uuid>> {
        return self.get_col_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            let converted = match cassandra_type {
                &ColType::Uuid => decode_timeuuid(bytes),
                &ColType::Timeuuid => decode_timeuuid(bytes),
                _ => unreachable!()
            };

            return converted.map_err(|err| err.into());
        });
    }
}

impl IntoRustByName<List> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<List>> {
        return self.get_col_spec_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            return match cassandra_type.col_type.id {
                // in fact, both decode_list and decode_set return Ok
                ColType::List => Ok(List::new(decode_list(bytes).unwrap(), cassandra_type.col_type.clone())),
                ColType::Set => Ok(List::new(decode_set(bytes).unwrap(), cassandra_type.col_type.clone())),
                _ => unreachable!()
            };
        });
    }
}

impl IntoRustByName<Map> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<Map>> {
        return self.get_col_spec_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();

            return match cassandra_type.col_type.id {
                // in fact, both decode_map and decode_set return Ok
                ColType::Map => Ok(Map::new(decode_map(bytes).unwrap(), cassandra_type.col_type.clone())),
                _ => unreachable!()
            }
        });
    }
}

impl IntoRustByName<UDT> for Row {
    fn get_by_name(&self, name: &str) -> Option<Result<UDT>> {
        return self.get_col_spec_by_name(name).map(|(cassandra_type, cbytes)| {
            let bytes = cbytes.as_plain().clone();
            let cudt = match cassandra_type.col_type.value {
                Some(ColTypeOptionValue::UdtType(ref t)) => t.clone(),
                _ => unreachable!()
            };

            return match cassandra_type.col_type.id {
                ColType::Map => Ok(UDT::new(decode_udt(bytes).unwrap(), cudt)),
                _ => unreachable!()
            }
        });
    }
}

//TODO: add uuid
<|endoftext|>


<commit_before>#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::admin::{
    delete_crate, delete_version, populate, render_readmes, test_pagerduty, transfer_crates,
    verify_token,
};

use clap::Clap;

#[derive(Clap, Debug)]
#[clap(name = "crates-admin")]
struct Opts {
    #[clap(subcommand)]
    command: SubCommand,
}

#[derive(Clap, Debug)]
enum SubCommand {
    DeleteCrate(delete_crate::Opts),
    DeleteVersion(delete_version::Opts),
    #[clap(
        about = "Checks for any invariants we expect to be true, and pages whoever is on call if they are not."
    )]
    Populate(populate::Opts),
    RenderReadmes(render_readmes::Opts),
    TestPagerduty(test_pagerduty::Opts),
    TransferCrates(transfer_crates::Opts),
    VerifyToken(verify_token::Opts),
}

fn main() {
    let opts: Opts = Opts::parse();

    match opts.command {
        SubCommand::DeleteCrate(opts) => delete_crate::run(opts),
        SubCommand::DeleteVersion(opts) => delete_version::run(opts),
        SubCommand::Populate(opts) => populate::run(opts),
        SubCommand::RenderReadmes(opts) => render_readmes::run(opts),
        SubCommand::TestPagerduty(opts) => test_pagerduty::run(opts).unwrap(),
        SubCommand::TransferCrates(opts) => transfer_crates::run(opts),
        SubCommand::VerifyToken(opts) => verify_token::run(opts).unwrap(),
    }
}
<commit_msg>Drop wrong description for `crates-admin populate`<commit_after>#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::admin::{
    delete_crate, delete_version, populate, render_readmes, test_pagerduty, transfer_crates,
    verify_token,
};

use clap::Clap;

#[derive(Clap, Debug)]
#[clap(name = "crates-admin")]
struct Opts {
    #[clap(subcommand)]
    command: SubCommand,
}

#[derive(Clap, Debug)]
enum SubCommand {
    DeleteCrate(delete_crate::Opts),
    DeleteVersion(delete_version::Opts),
    Populate(populate::Opts),
    RenderReadmes(render_readmes::Opts),
    TestPagerduty(test_pagerduty::Opts),
    TransferCrates(transfer_crates::Opts),
    VerifyToken(verify_token::Opts),
}

fn main() {
    let opts: Opts = Opts::parse();

    match opts.command {
        SubCommand::DeleteCrate(opts) => delete_crate::run(opts),
        SubCommand::DeleteVersion(opts) => delete_version::run(opts),
        SubCommand::Populate(opts) => populate::run(opts),
        SubCommand::RenderReadmes(opts) => render_readmes::run(opts),
        SubCommand::TestPagerduty(opts) => test_pagerduty::run(opts).unwrap(),
        SubCommand::TransferCrates(opts) => transfer_crates::run(opts),
        SubCommand::VerifyToken(opts) => verify_token::run(opts).unwrap(),
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::str;

use ansi_term;
use dtoa;
use itoa;
use serde;
use serde_json;

use error;
use value;

pub struct JsonSource<R>(serde_json::StreamDeserializer<value::Value, io::Bytes<R>>)
    where R: io::Read;

pub struct JsonSink<W, F>(W, F)
    where W: io::Write,
          F: Clone + serde_json::ser::Formatter;

#[derive(Clone, Debug)]
pub struct ReadableFormatter {
    current_indent: usize,
    is_in_object_key: bool,
    has_value: bool,

    null_style: ansi_term::Style,

    true_style: ansi_term::Style,
    false_style: ansi_term::Style,

    number_style: ansi_term::Style,

    string_quote_style: ansi_term::Style,
    string_char_style: ansi_term::Style,
    string_escape_style: ansi_term::Style,

    array_bracket_style: ansi_term::Style,
    array_comma_style: ansi_term::Style,

    object_brace_style: ansi_term::Style,
    object_colon_style: ansi_term::Style,
    object_comma_style: ansi_term::Style,
    object_key_quote_style: ansi_term::Style,
    object_key_char_style: ansi_term::Style,
    object_key_escape_style: ansi_term::Style,
}

#[inline]
pub fn source<R>(r: R) -> JsonSource<R>
    where R: io::Read
{
    JsonSource(serde_json::StreamDeserializer::new(r.bytes()))
}

#[inline]
pub fn sink_compact<W>(w: W) -> JsonSink<W, serde_json::ser::CompactFormatter>
    where W: io::Write
{
    JsonSink(w, serde_json::ser::CompactFormatter)
}

#[inline]
pub fn sink_readable<W>(w: W) -> JsonSink<W, ReadableFormatter>
    where W: io::Write
{
    JsonSink(w, ReadableFormatter::new())
}

impl<R> value::Source for JsonSource<R>
    where R: io::Read
{
    #[inline]
    fn read(&mut self) -> error::Result<Option<value::Value>> {
        match self.0.next() {
            Some(Ok(v)) => Ok(Some(v)),
            Some(Err(e)) => Err(error::Error::from(e)),
            None => Ok(None),
        }
    }
}

impl<W, F> value::Sink for JsonSink<W, F>
    where W: io::Write,
          F: Clone + serde_json::ser::Formatter
{
    #[inline]
    fn write(&mut self, v: value::Value) -> error::Result<()> {
        {
            let mut serializer =
                serde_json::ser::Serializer::with_formatter(&mut self.0, self.1.clone());
            try!(serde::Serialize::serialize(&v, &mut serializer));
        }
        try!(self.0.write_all(b"\n"));
        Ok(())
    }
}

impl ReadableFormatter {
    fn new() -> ReadableFormatter {
        use ansi_term::Colour;

        ReadableFormatter {
            current_indent: 0,
            is_in_object_key: false,
            has_value: false,

            null_style: Colour::Black.dimmed().bold().italic(),

            true_style: Colour::Green.bold().italic(),
            false_style: Colour::Red.bold().italic(),

            number_style: Colour::Blue.normal(),

            string_quote_style: Colour::Green.dimmed(),
            string_char_style: Colour::Green.normal(),
            string_escape_style: Colour::Green.dimmed(),

            array_bracket_style: Colour::White.bold(),
            array_comma_style: Colour::White.bold(),

            object_brace_style: Colour::White.bold(),
            object_colon_style: Colour::White.bold(),
            object_comma_style: Colour::White.bold(),
            object_key_quote_style: Colour::Blue.dimmed(),
            object_key_char_style: Colour::Blue.normal(),
            object_key_escape_style: Colour::Blue.dimmed(),
        }
    }
}

impl serde_json::ser::Formatter for ReadableFormatter {
    /// Writes a `null` value to the specified writer.
    #[inline]
    fn write_null<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        write!(writer, "{}", self.null_style.paint("null")).map_err(From::from)
    }

    /// Writes a `true` or `false` value to the specified writer.
    #[inline]
    fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> serde_json::Result<()>
        where W: io::Write
    {
        let s = if value {
            self.true_style.paint("true")
        } else {
            self.false_style.paint("false")
        };
        write!(writer, "{}", s).map_err(From::from)
    }

    /// Writes an integer value like `-123` to the specified writer.
    #[inline]
    fn write_integer<W, I>(&mut self, writer: &mut W, value: I) -> serde_json::Result<()>
        where W: io::Write,
              I: itoa::Integer
    {
        try!(write!(writer, "{}", self.number_style.prefix()));
        try!(itoa::write(writer, value));
        try!(write!(writer, "{}", self.number_style.suffix()));
        Ok(())
    }

    /// Writes a floating point value like `-31.26e+12` to the
    /// specified writer.
    #[inline]
    fn write_floating<W, F>(&mut self, writer: &mut W, value: F) -> serde_json::Result<()>
        where W: io::Write,
              F: dtoa::Floating
    {
        try!(write!(writer, "{}", self.number_style.prefix()));
        try!(dtoa::write(writer, value));
        try!(write!(writer, "{}", self.number_style.suffix()));
        Ok(())
    }

    /// Called before each series of `write_string_fragment` and
    /// `write_char_escape`.  Writes a `"` to the specified writer.
    #[inline]
    fn begin_string<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        let style = if self.is_in_object_key {
            self.object_key_quote_style
        } else {
            self.string_quote_style
        };

        write!(writer, "{}", style.paint("\"")).map_err(From::from)
    }

    /// Called after each series of `write_string_fragment` and
    /// `write_char_escape`.  Writes a `"` to the specified writer.
    #[inline]
    fn end_string<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        let style = if self.is_in_object_key {
            self.object_key_quote_style
        } else {
            self.string_quote_style
        };

        write!(writer, "{}", style.paint("\"")).map_err(From::from)
    }

    /// Writes a string fragment that doesn't need any escaping to the
    /// specified writer.
    #[inline]
    fn write_string_fragment<W>(&mut self, writer: &mut W, fragment: &[u8]) -> serde_json::Result<()>
        where W: io::Write
    {
        let style = if self.is_in_object_key {
            self.object_key_char_style
        } else {
            self.string_char_style
        };

        let s = unsafe { str::from_utf8_unchecked(fragment) };
        write!(writer, "{}", style.paint(s)).map_err(From::from)
    }

    /// Writes a character escape code to the specified writer.
    #[inline]
    fn write_char_escape<W>(&mut self, writer: &mut W, char_escape: serde_json::ser::CharEscape) -> serde_json::Result<()>
        where W: io::Write
    {
        use serde_json::ser::CharEscape::*;

        let style = if self.is_in_object_key {
            self.object_key_escape_style
        } else {
            self.string_escape_style
        };

        let s = match char_escape {
            Quote => "\\\"",
            ReverseSolidus => "\\\\",
            Solidus => "\\/",
            Backspace => "\\b",
            FormFeed => "\\f",
            LineFeed => "\\n",
            CarriageReturn => "\\r",
            Tab => "\\t",
            AsciiControl(byte) => {
                static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
                let bytes = &[b'\\', b'u', b'0', b'0',
                              HEX_DIGITS[(byte >> 4) as usize],
                              HEX_DIGITS[(byte & 0xF) as usize]];
                let s = unsafe { str::from_utf8_unchecked(bytes) };

                // Need to return early because of allocated String
                return write!(writer, "{}", style.paint(s)).map_err(From::from);
            }
        };

        write!(writer, "{}", style.paint(s)).map_err(From::from)
    }

    /// Called before every array.  Writes a `[` to the specified
    /// writer.
    #[inline]
    fn begin_array<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent += 1;
        self.has_value = false;

        write!(writer, "{}", self.array_bracket_style.paint("[")).map_err(From::from)
    }

    /// Called after every array.  Writes a `]` to the specified
    /// writer.
    #[inline]
    fn end_array<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent -= 1;

        if self.has_value {
            try!(write!(writer, "\n"));
            try!(indent(writer, self.current_indent));
        }

        write!(writer, "{}", self.array_bracket_style.paint("]")).map_err(From::from)
    }

    /// Called before every array value.  Writes a `,` if needed to
    /// the specified writer.
    #[inline]
    fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> serde_json::Result<()>
        where W: io::Write
    {
        if !first {
            try!(write!(writer, "{}", self.array_comma_style.paint(",")));
        }

        try!(write!(writer, "\n"));
        try!(indent(writer, self.current_indent));
        Ok(())
    }

    /// Called after every array value.
    #[inline]
    fn end_array_value<W>(&mut self, _writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.has_value = true;
        Ok(())
    }

    /// Called before every object.  Writes a `{` to the specified
    /// writer.
    #[inline]
    fn begin_object<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent += 1;
        self.has_value = false;

        write!(writer, "{}", self.object_brace_style.paint("{")).map_err(From::from)
    }

    /// Called after every object.  Writes a `}` to the specified
    /// writer.
    #[inline]
    fn end_object<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent -= 1;

        if self.has_value {
            try!(write!(writer, "\n"));
            try!(indent(writer, self.current_indent));
        }

        write!(writer, "{}", self.object_brace_style.paint("}")).map_err(From::from)
    }

    /// Called before every object key.
    #[inline]
    fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> serde_json::Result<()>
        where W: io::Write
    {
        self.is_in_object_key = true;

        if !first {
            try!(write!(writer, "{}", self.object_comma_style.paint(",")));
        }

        try!(write!(writer, "\n"));
        try!(indent(writer, self.current_indent));
        Ok(())
    }

    /// Called after every object key.  A `:` should be written to the
    /// specified writer by either this method or
    /// `begin_object_value`.
    #[inline]
    fn end_object_key<W>(&mut self, _writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.is_in_object_key = false;
        Ok(())
    }

    /// Called before every object value.  A `:` should be written to
    /// the specified writer by either this method or
    /// `end_object_key`.
    #[inline]
    fn begin_object_value<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        write!(writer, "{}", self.object_colon_style.paint(": ")).map_err(From::from)
    }

    /// Called after every object value.
    #[inline]
    fn end_object_value<W>(&mut self, _writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.has_value = true;
        Ok(())
    }
}

fn indent<W>(wr: &mut W, n: usize) -> serde_json::error::Result<()>
    where W: io::Write
{
    for _ in 0..n {
        try!(wr.write_all(b"  "));
    }

    Ok(())
}
<commit_msg>Make the JSON formatter use the default color instead of white (#124)<commit_after>use std::io;
use std::str;

use ansi_term;
use dtoa;
use itoa;
use serde;
use serde_json;

use error;
use value;

pub struct JsonSource<R>(serde_json::StreamDeserializer<value::Value, io::Bytes<R>>)
    where R: io::Read;

pub struct JsonSink<W, F>(W, F)
    where W: io::Write,
          F: Clone + serde_json::ser::Formatter;

#[derive(Clone, Debug)]
pub struct ReadableFormatter {
    current_indent: usize,
    is_in_object_key: bool,
    has_value: bool,

    null_style: ansi_term::Style,

    true_style: ansi_term::Style,
    false_style: ansi_term::Style,

    number_style: ansi_term::Style,

    string_quote_style: ansi_term::Style,
    string_char_style: ansi_term::Style,
    string_escape_style: ansi_term::Style,

    array_bracket_style: ansi_term::Style,
    array_comma_style: ansi_term::Style,

    object_brace_style: ansi_term::Style,
    object_colon_style: ansi_term::Style,
    object_comma_style: ansi_term::Style,
    object_key_quote_style: ansi_term::Style,
    object_key_char_style: ansi_term::Style,
    object_key_escape_style: ansi_term::Style,
}

#[inline]
pub fn source<R>(r: R) -> JsonSource<R>
    where R: io::Read
{
    JsonSource(serde_json::StreamDeserializer::new(r.bytes()))
}

#[inline]
pub fn sink_compact<W>(w: W) -> JsonSink<W, serde_json::ser::CompactFormatter>
    where W: io::Write
{
    JsonSink(w, serde_json::ser::CompactFormatter)
}

#[inline]
pub fn sink_readable<W>(w: W) -> JsonSink<W, ReadableFormatter>
    where W: io::Write
{
    JsonSink(w, ReadableFormatter::new())
}

impl<R> value::Source for JsonSource<R>
    where R: io::Read
{
    #[inline]
    fn read(&mut self) -> error::Result<Option<value::Value>> {
        match self.0.next() {
            Some(Ok(v)) => Ok(Some(v)),
            Some(Err(e)) => Err(error::Error::from(e)),
            None => Ok(None),
        }
    }
}

impl<W, F> value::Sink for JsonSink<W, F>
    where W: io::Write,
          F: Clone + serde_json::ser::Formatter
{
    #[inline]
    fn write(&mut self, v: value::Value) -> error::Result<()> {
        {
            let mut serializer =
                serde_json::ser::Serializer::with_formatter(&mut self.0, self.1.clone());
            try!(serde::Serialize::serialize(&v, &mut serializer));
        }
        try!(self.0.write_all(b"\n"));
        Ok(())
    }
}

impl ReadableFormatter {
    fn new() -> ReadableFormatter {
        use ansi_term::{Colour, Style};

        ReadableFormatter {
            current_indent: 0,
            is_in_object_key: false,
            has_value: false,

            null_style: Colour::Black.dimmed().bold().italic(),

            true_style: Colour::Green.bold().italic(),
            false_style: Colour::Red.bold().italic(),

            number_style: Colour::Blue.normal(),

            string_quote_style: Colour::Green.dimmed(),
            string_char_style: Colour::Green.normal(),
            string_escape_style: Colour::Green.dimmed(),

            array_bracket_style: Style::default().bold(),
            array_comma_style: Style::default().bold(),

            object_brace_style: Style::default().bold(),
            object_colon_style: Style::default().bold(),
            object_comma_style: Style::default().bold(),
            object_key_quote_style: Colour::Blue.dimmed(),
            object_key_char_style: Colour::Blue.normal(),
            object_key_escape_style: Colour::Blue.dimmed(),
        }
    }
}

impl serde_json::ser::Formatter for ReadableFormatter {
    /// Writes a `null` value to the specified writer.
    #[inline]
    fn write_null<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        write!(writer, "{}", self.null_style.paint("null")).map_err(From::from)
    }

    /// Writes a `true` or `false` value to the specified writer.
    #[inline]
    fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> serde_json::Result<()>
        where W: io::Write
    {
        let s = if value {
            self.true_style.paint("true")
        } else {
            self.false_style.paint("false")
        };
        write!(writer, "{}", s).map_err(From::from)
    }

    /// Writes an integer value like `-123` to the specified writer.
    #[inline]
    fn write_integer<W, I>(&mut self, writer: &mut W, value: I) -> serde_json::Result<()>
        where W: io::Write,
              I: itoa::Integer
    {
        try!(write!(writer, "{}", self.number_style.prefix()));
        try!(itoa::write(writer, value));
        try!(write!(writer, "{}", self.number_style.suffix()));
        Ok(())
    }

    /// Writes a floating point value like `-31.26e+12` to the
    /// specified writer.
    #[inline]
    fn write_floating<W, F>(&mut self, writer: &mut W, value: F) -> serde_json::Result<()>
        where W: io::Write,
              F: dtoa::Floating
    {
        try!(write!(writer, "{}", self.number_style.prefix()));
        try!(dtoa::write(writer, value));
        try!(write!(writer, "{}", self.number_style.suffix()));
        Ok(())
    }

    /// Called before each series of `write_string_fragment` and
    /// `write_char_escape`.  Writes a `"` to the specified writer.
    #[inline]
    fn begin_string<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        let style = if self.is_in_object_key {
            self.object_key_quote_style
        } else {
            self.string_quote_style
        };

        write!(writer, "{}", style.paint("\"")).map_err(From::from)
    }

    /// Called after each series of `write_string_fragment` and
    /// `write_char_escape`.  Writes a `"` to the specified writer.
    #[inline]
    fn end_string<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        let style = if self.is_in_object_key {
            self.object_key_quote_style
        } else {
            self.string_quote_style
        };

        write!(writer, "{}", style.paint("\"")).map_err(From::from)
    }

    /// Writes a string fragment that doesn't need any escaping to the
    /// specified writer.
    #[inline]
    fn write_string_fragment<W>(&mut self, writer: &mut W, fragment: &[u8]) -> serde_json::Result<()>
        where W: io::Write
    {
        let style = if self.is_in_object_key {
            self.object_key_char_style
        } else {
            self.string_char_style
        };

        let s = unsafe { str::from_utf8_unchecked(fragment) };
        write!(writer, "{}", style.paint(s)).map_err(From::from)
    }

    /// Writes a character escape code to the specified writer.
    #[inline]
    fn write_char_escape<W>(&mut self, writer: &mut W, char_escape: serde_json::ser::CharEscape) -> serde_json::Result<()>
        where W: io::Write
    {
        use serde_json::ser::CharEscape::*;

        let style = if self.is_in_object_key {
            self.object_key_escape_style
        } else {
            self.string_escape_style
        };

        let s = match char_escape {
            Quote => "\\\"",
            ReverseSolidus => "\\\\",
            Solidus => "\\/",
            Backspace => "\\b",
            FormFeed => "\\f",
            LineFeed => "\\n",
            CarriageReturn => "\\r",
            Tab => "\\t",
            AsciiControl(byte) => {
                static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
                let bytes = &[b'\\', b'u', b'0', b'0',
                              HEX_DIGITS[(byte >> 4) as usize],
                              HEX_DIGITS[(byte & 0xF) as usize]];
                let s = unsafe { str::from_utf8_unchecked(bytes) };

                // Need to return early because of allocated String
                return write!(writer, "{}", style.paint(s)).map_err(From::from);
            }
        };

        write!(writer, "{}", style.paint(s)).map_err(From::from)
    }

    /// Called before every array.  Writes a `[` to the specified
    /// writer.
    #[inline]
    fn begin_array<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent += 1;
        self.has_value = false;

        write!(writer, "{}", self.array_bracket_style.paint("[")).map_err(From::from)
    }

    /// Called after every array.  Writes a `]` to the specified
    /// writer.
    #[inline]
    fn end_array<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent -= 1;

        if self.has_value {
            try!(write!(writer, "\n"));
            try!(indent(writer, self.current_indent));
        }

        write!(writer, "{}", self.array_bracket_style.paint("]")).map_err(From::from)
    }

    /// Called before every array value.  Writes a `,` if needed to
    /// the specified writer.
    #[inline]
    fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> serde_json::Result<()>
        where W: io::Write
    {
        if !first {
            try!(write!(writer, "{}", self.array_comma_style.paint(",")));
        }

        try!(write!(writer, "\n"));
        try!(indent(writer, self.current_indent));
        Ok(())
    }

    /// Called after every array value.
    #[inline]
    fn end_array_value<W>(&mut self, _writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.has_value = true;
        Ok(())
    }

    /// Called before every object.  Writes a `{` to the specified
    /// writer.
    #[inline]
    fn begin_object<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent += 1;
        self.has_value = false;

        write!(writer, "{}", self.object_brace_style.paint("{")).map_err(From::from)
    }

    /// Called after every object.  Writes a `}` to the specified
    /// writer.
    #[inline]
    fn end_object<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.current_indent -= 1;

        if self.has_value {
            try!(write!(writer, "\n"));
            try!(indent(writer, self.current_indent));
        }

        write!(writer, "{}", self.object_brace_style.paint("}")).map_err(From::from)
    }

    /// Called before every object key.
    #[inline]
    fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> serde_json::Result<()>
        where W: io::Write
    {
        self.is_in_object_key = true;

        if !first {
            try!(write!(writer, "{}", self.object_comma_style.paint(",")));
        }

        try!(write!(writer, "\n"));
        try!(indent(writer, self.current_indent));
        Ok(())
    }

    /// Called after every object key.  A `:` should be written to the
    /// specified writer by either this method or
    /// `begin_object_value`.
    #[inline]
    fn end_object_key<W>(&mut self, _writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.is_in_object_key = false;
        Ok(())
    }

    /// Called before every object value.  A `:` should be written to
    /// the specified writer by either this method or
    /// `end_object_key`.
    #[inline]
    fn begin_object_value<W>(&mut self, writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        write!(writer, "{}", self.object_colon_style.paint(": ")).map_err(From::from)
    }

    /// Called after every object value.
    #[inline]
    fn end_object_value<W>(&mut self, _writer: &mut W) -> serde_json::Result<()>
        where W: io::Write
    {
        self.has_value = true;
        Ok(())
    }
}

fn indent<W>(wr: &mut W, n: usize) -> serde_json::error::Result<()>
    where W: io::Write
{
    for _ in 0..n {
        try!(wr.write_all(b"  "));
    }

    Ok(())
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use std::num::NumCast;
use std::raw::Repr;
use core::slice::SliceExt;
use num::complex::{Complex32, Complex64};
use vector::ops::{Copy, Axpy, Scal, Dot, Nrm2, Asum, Iamax};

#[stable]
pub mod ll;
pub mod ops;

pub trait Vector<T> {
    fn inc(&self) -> i32;
    fn len(&self) -> i32;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

#[unstable]
pub trait VectorOperations<T>: Sized + Vector<T>
    where T: Copy + Axpy + Scal + Dot + Nrm2 + Asum + Iamax {

    #[inline]
    fn into_vec(&self) -> Vec<T> {
        let n = self.len() as usize;

        let mut x = Vec::with_capacity(n);
        Copy::copy(self, &mut x);
        unsafe { x.set_len(n); }

        x
    }

    #[inline]
    fn update(&mut self, alpha: &T, x: &Vector<T>) -> &mut Self {
        Axpy::axpy(alpha, x, self);
        self
    }

    #[inline]
    fn scale(&mut self, alpha: &T) -> &mut Self {
        Scal::scal(alpha, self);
        self
    }

    #[inline]
    fn dot(&self, x: &Vector<T>) -> T {
        Dot::dot(self, x)
    }

    #[inline]
    fn abs_sum(&self) -> T {
        Asum::asum(self)
    }

    #[inline]
    fn norm(&self) -> T {
        Nrm2::nrm2(self)
    }

    #[inline]
    fn max_index(&self) -> usize {
        Iamax::iamax(self)
    }
}

impl<T> Vector<T> for Vec<T> {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(Vec::len(self));
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self[..].as_ptr() }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { (&mut self[..]).as_mut_ptr() }
}

impl<'a, T> Vector<T> for &'a [T] {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(SliceExt::len(*self));
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.repr().data }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.repr().data as *mut T }
}

macro_rules! operations_impl(
    ($v: ident, $($t: ty), +) => (
        $( impl VectorOperations<$t> for $v<$t> {} )+
    )
);

operations_impl!(Vec, f32, f64, Complex32, Complex64);
impl<'a> VectorOperations<f32> for &'a [f32] {}
impl<'a> VectorOperations<f64> for &'a [f64] {}
impl<'a> VectorOperations<Complex32> for &'a [Complex32] {}
impl<'a> VectorOperations<Complex64> for &'a [Complex64] {}
<commit_msg>Fix NumCast import<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use std::raw::Repr;
use core::slice::SliceExt;
use num::traits::NumCast;
use num::complex::{Complex32, Complex64};
use vector::ops::{Copy, Axpy, Scal, Dot, Nrm2, Asum, Iamax};

#[stable]
pub mod ll;
pub mod ops;

pub trait Vector<T> {
    fn inc(&self) -> i32;
    fn len(&self) -> i32;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

#[unstable]
pub trait VectorOperations<T>: Sized + Vector<T>
    where T: Copy + Axpy + Scal + Dot + Nrm2 + Asum + Iamax {

    #[inline]
    fn into_vec(&self) -> Vec<T> {
        let n = self.len() as usize;

        let mut x = Vec::with_capacity(n);
        Copy::copy(self, &mut x);
        unsafe { x.set_len(n); }

        x
    }

    #[inline]
    fn update(&mut self, alpha: &T, x: &Vector<T>) -> &mut Self {
        Axpy::axpy(alpha, x, self);
        self
    }

    #[inline]
    fn scale(&mut self, alpha: &T) -> &mut Self {
        Scal::scal(alpha, self);
        self
    }

    #[inline]
    fn dot(&self, x: &Vector<T>) -> T {
        Dot::dot(self, x)
    }

    #[inline]
    fn abs_sum(&self) -> T {
        Asum::asum(self)
    }

    #[inline]
    fn norm(&self) -> T {
        Nrm2::nrm2(self)
    }

    #[inline]
    fn max_index(&self) -> usize {
        Iamax::iamax(self)
    }
}

impl<T> Vector<T> for Vec<T> {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(Vec::len(self));
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self[..].as_ptr() }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { (&mut self[..]).as_mut_ptr() }
}

impl<'a, T> Vector<T> for &'a [T] {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(SliceExt::len(*self));
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.repr().data }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.repr().data as *mut T }
}

macro_rules! operations_impl(
    ($v: ident, $($t: ty), +) => (
        $( impl VectorOperations<$t> for $v<$t> {} )+
    )
);

operations_impl!(Vec, f32, f64, Complex32, Complex64);
impl<'a> VectorOperations<f32> for &'a [f32] {}
impl<'a> VectorOperations<f64> for &'a [f64] {}
impl<'a> VectorOperations<Complex32> for &'a [Complex32] {}
impl<'a> VectorOperations<Complex64> for &'a [Complex64] {}
<|endoftext|>


<commit_before>extern crate openssl;

use errors::common::CommonError;

use self::openssl::hash::{hash2, MessageDigest, Hasher, DigestBytes};
use self::openssl::error::ErrorStack;

use std::error::Error;

pub const HASHBYTES: usize = 32;

pub fn hash(input: &[u8]) -> Result<Vec<u8>, CommonError> {
    let mut hasher = Hash::new_context()?;
    hasher.update(input)?;
    Ok(hasher.finish2().map(|b| b.to_vec())?)
}

pub struct Digest {
    data: DigestBytes
}

impl Digest {
    fn new(data: DigestBytes) -> Digest {
        Digest {
            data: data
        }
    }

    pub fn to_vec(&self) -> Vec<u8> {
        self.data.to_vec()
    }
}

pub struct Hash {}

impl Hash {
    pub fn new_context() -> Result<Hasher, CommonError> {
        Ok(Hasher::new(MessageDigest::sha256())?)
    }

    pub fn hash_empty() -> Result<Digest, CommonError> {
        Ok(Digest::new(hash2(MessageDigest::sha256(), &[])?))

    }

    pub fn hash_leaf<T>(leaf: &T) -> Result<Digest, CommonError> where T: Hashable {
        let mut ctx = Hash::new_context()?;
        ctx.update(&[0x00])?;
        leaf.update_context(&mut ctx)?;
        Ok(Digest::new(ctx.finish2()?))
    }

    pub fn hash_nodes<T>(left: &T, right: &T) -> Result<Digest, CommonError> where T: Hashable {
        let mut ctx = Hash::new_context()?;
        ctx.update(&[0x01])?;
        left.update_context(&mut ctx)?;
        right.update_context(&mut ctx)?;
        Ok(Digest::new(ctx.finish2()?))
    }

}

/// The type of values stored in a `MerkleTree` must implement
/// this trait, in order for them to be able to be fed
/// to a Ring `Context` when computing the hash of a leaf.
///
/// A default instance for types that already implements
/// `AsRef<[u8]>` is provided.
///
/// ## Example
///
/// Here is an example of how to implement `Hashable` for a type
/// that does not (or cannot) implement `AsRef<[u8]>`:
///
/// ```ignore
/// impl Hashable for PublicKey {
///     fn update_context(&self, context: &mut Hasher) -> Result<(), CommonError> {
///         let bytes: Vec<u8> = self.to_bytes();
///         Ok(context.update(&bytes)?)
///     }
/// }
/// ```
pub trait Hashable {

    /// Update the given `context` with `self`.
    ///
    /// See `openssl::hash::Hasher::update` for more information.
    fn update_context(&self, context: &mut Hasher) -> Result<(), CommonError>;

}

impl <T: AsRef<[u8]>> Hashable for T {

    fn update_context(&self, context: &mut Hasher) -> Result<(), CommonError> {
        Ok(context.update(self.as_ref())?)
    }
}

impl From<ErrorStack> for CommonError {
    fn from(err: ErrorStack) -> CommonError {
        // TODO: FIXME: Analyze ErrorStack and split invalid structure errors from other errors
        CommonError::InvalidStructure(err.description().to_string())
    }
}<commit_msg>openssl_hash<commit_after>extern crate openssl;

use errors::common::CommonError;

use self::openssl::hash::{hash as openssl_hash, MessageDigest, Hasher, DigestBytes};
use self::openssl::error::ErrorStack;

use std::error::Error;

pub const HASHBYTES: usize = 32;

pub fn hash(input: &[u8]) -> Result<Vec<u8>, CommonError> {
    let mut hasher = Hash::new_context()?;
    hasher.update(input)?;
    Ok(hasher.finish().map(|b| b.to_vec())?)
}

pub struct Digest {
    data: DigestBytes
}

impl Digest {
    fn new(data: DigestBytes) -> Digest {
        Digest {
            data: data
        }
    }

    pub fn to_vec(&self) -> Vec<u8> {
        self.data.to_vec()
    }
}

pub struct Hash {}

impl Hash {
    pub fn new_context() -> Result<Hasher, CommonError> {
        Ok(Hasher::new(MessageDigest::sha256())?)
    }

    pub fn hash_empty() -> Result<Digest, CommonError> {
        Ok(Digest::new(openssl_hash(MessageDigest::sha256(), &[])?))

    }

    pub fn hash_leaf<T>(leaf: &T) -> Result<Digest, CommonError> where T: Hashable {
        let mut ctx = Hash::new_context()?;
        ctx.update(&[0x00])?;
        leaf.update_context(&mut ctx)?;
        Ok(Digest::new(ctx.finish()?))
    }

    pub fn hash_nodes<T>(left: &T, right: &T) -> Result<Digest, CommonError> where T: Hashable {
        let mut ctx = Hash::new_context()?;
        ctx.update(&[0x01])?;
        left.update_context(&mut ctx)?;
        right.update_context(&mut ctx)?;
        Ok(Digest::new(ctx.finish()?))
    }

}

/// The type of values stored in a `MerkleTree` must implement
/// this trait, in order for them to be able to be fed
/// to a Ring `Context` when computing the hash of a leaf.
///
/// A default instance for types that already implements
/// `AsRef<[u8]>` is provided.
///
/// ## Example
///
/// Here is an example of how to implement `Hashable` for a type
/// that does not (or cannot) implement `AsRef<[u8]>`:
///
/// ```ignore
/// impl Hashable for PublicKey {
///     fn update_context(&self, context: &mut Hasher) -> Result<(), CommonError> {
///         let bytes: Vec<u8> = self.to_bytes();
///         Ok(context.update(&bytes)?)
///     }
/// }
/// ```
pub trait Hashable {

    /// Update the given `context` with `self`.
    ///
    /// See `openssl::hash::Hasher::update` for more information.
    fn update_context(&self, context: &mut Hasher) -> Result<(), CommonError>;

}

impl <T: AsRef<[u8]>> Hashable for T {

    fn update_context(&self, context: &mut Hasher) -> Result<(), CommonError> {
        Ok(context.update(self.as_ref())?)
    }
}

impl From<ErrorStack> for CommonError {
    fn from(err: ErrorStack) -> CommonError {
        // TODO: FIXME: Analyze ErrorStack and split invalid structure errors from other errors
        CommonError::InvalidStructure(err.description().to_string())
    }
}
<|endoftext|>


<commit_before>extern crate chrono;

use self::chrono::{DateTime, Utc};
use std::env;
use std::time::{SystemTime, UNIX_EPOCH};

pub fn read_env_var(var: &str) -> String {
    env::var_os(var)
        .expect(&format!(
            "{} must be specified. \
             Did you forget to add it to your .env file?",
            var
        ))
        .into_string()
        .expect(&format!("{} does not contain a valid UTF8 string", var))
}

pub fn elapsed_ms(from: DateTime<Utc>, to: DateTime<Utc>) -> Result<u64, ()> {
    let ms = to.signed_duration_since(from).num_milliseconds();
    if ms >= 0 { Ok(ms as u64) } else { Err(()) }
}

pub fn timestamp() -> u64 {
    let now = SystemTime::now();
    let elapsed = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
    let in_ms = elapsed.as_secs() * 1000 + elapsed.subsec_nanos() as u64 / 1_000_000;
    in_ms
}

pub fn clamp<T>(val: T, min: T, max: T) -> T
where
    T: Ord,
{
    match (val < min, val > max) {
        (true, _) => min,
        (_, true) => max,
        _ => val,
    }
}

pub type SeqId = u32;
pub struct SeqIdGen {
    curr_id: SeqId,
}
impl SeqIdGen {
    pub fn new() -> Self {
        SeqIdGen { curr_id: 0 }
    }

    pub fn gen(&mut self) -> SeqId {
        self.curr_id += 1;
        self.curr_id
    }
}

#[macro_export]
macro_rules! newtype {
    (  $name:ident($type:ty)  ) => {
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
    (  $name:ident($type:ty) : $($derives:meta), + ) => {
        #[derive(
            $($derives,)+
        )]
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
}

macro_rules! add_impl {
     (  $name:ident, $type:ty ) => {
         impl Deref for $name {
            type Target = $type;

            fn deref(&self) -> &$type {
                &self.0
            }
        }
        impl DerefMut for $name {
            fn deref_mut(&mut self) -> &mut $type {
                &mut self.0
            }
        }
        impl From<$type> for $name {
            fn from(t: $type) -> Self {
                $name(t)
            }
        }
     };
}

#[cfg(test)]
use util::chrono::TimeZone;

#[test]
fn read_string_envvar() {
    env::set_var("TEST", "foo");
    assert_eq!("foo", &read_env_var("TEST"));
}

#[test]
#[should_panic]
fn read_empty_envvar() {
    env::remove_var("EMPTY");
    read_env_var("EMPTY");
}

#[test]
fn one_elapsed_ms() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 1);
    assert_eq!(1, elapsed_ms(a, b).unwrap());
}

#[test]
fn one_elapsed_second() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(1000, elapsed_ms(a, b).unwrap());
}

#[test]
fn no_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(0, elapsed_ms(a, a).unwrap());
}

#[test]
fn negative_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 0);
    assert!(elapsed_ms(a, b).is_err());
}

#[test]
fn timestamp_wait() {
    use std::thread;
    use std::time::Duration;

    let a = timestamp();
    let delta = 420;
    thread::sleep(Duration::from_millis(delta));
    let b = timestamp();
    assert!(b - a >= delta)
}

#[test]
fn clamp_in_range() {
    let res = clamp(1, 0, 2);
    assert_eq!(1, res);
}

#[test]
fn clamp_min() {
    let res = clamp(-2, -2, 2);
    assert_eq!(-2, res);
}

#[test]
fn clamp_max() {
    let res = clamp(0, -2, 0);
    assert_eq!(0, res);
}

#[test]
fn clamp_less_than_min() {
    let res = clamp(-1, 0, 2);
    assert_eq!(0, res);
}

#[test]
fn clamp_more_than_max() {
    let res = clamp(999, 9, 10);
    assert_eq!(10, res);
}

#[test]
fn seq_id_gen_sequential() {
    let mut id_gen = SeqIdGen::new();
    let ids_count = 1000;
    for i in 0..ids_count {
        assert_eq!(i + 1, id_gen.gen());
    }
}
<commit_msg>Core: Give time sensitive unit test some slack<commit_after>extern crate chrono;

use self::chrono::{DateTime, Utc};
use std::env;
use std::time::{SystemTime, UNIX_EPOCH};

pub fn read_env_var(var: &str) -> String {
    env::var_os(var)
        .expect(&format!(
            "{} must be specified. \
             Did you forget to add it to your .env file?",
            var
        ))
        .into_string()
        .expect(&format!("{} does not contain a valid UTF8 string", var))
}

pub fn elapsed_ms(from: DateTime<Utc>, to: DateTime<Utc>) -> Result<u64, ()> {
    let ms = to.signed_duration_since(from).num_milliseconds();
    if ms >= 0 { Ok(ms as u64) } else { Err(()) }
}

pub fn timestamp() -> u64 {
    let now = SystemTime::now();
    let elapsed = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
    let in_ms = elapsed.as_secs() * 1000 + elapsed.subsec_nanos() as u64 / 1_000_000;
    in_ms
}

pub fn clamp<T>(val: T, min: T, max: T) -> T
where
    T: Ord,
{
    match (val < min, val > max) {
        (true, _) => min,
        (_, true) => max,
        _ => val,
    }
}

pub type SeqId = u32;
pub struct SeqIdGen {
    curr_id: SeqId,
}
impl SeqIdGen {
    pub fn new() -> Self {
        SeqIdGen { curr_id: 0 }
    }

    pub fn gen(&mut self) -> SeqId {
        self.curr_id += 1;
        self.curr_id
    }
}

#[macro_export]
macro_rules! newtype {
    (  $name:ident($type:ty)  ) => {
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
    (  $name:ident($type:ty) : $($derives:meta), + ) => {
        #[derive(
            $($derives,)+
        )]
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
}

macro_rules! add_impl {
     (  $name:ident, $type:ty ) => {
         impl Deref for $name {
            type Target = $type;

            fn deref(&self) -> &$type {
                &self.0
            }
        }
        impl DerefMut for $name {
            fn deref_mut(&mut self) -> &mut $type {
                &mut self.0
            }
        }
        impl From<$type> for $name {
            fn from(t: $type) -> Self {
                $name(t)
            }
        }
     };
}

#[cfg(test)]
use util::chrono::TimeZone;

#[test]
fn read_string_envvar() {
    env::set_var("TEST", "foo");
    assert_eq!("foo", &read_env_var("TEST"));
}

#[test]
#[should_panic]
fn read_empty_envvar() {
    env::remove_var("EMPTY");
    read_env_var("EMPTY");
}

#[test]
fn one_elapsed_ms() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 1);
    assert_eq!(1, elapsed_ms(a, b).unwrap());
}

#[test]
fn one_elapsed_second() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(1000, elapsed_ms(a, b).unwrap());
}

#[test]
fn no_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(0, elapsed_ms(a, a).unwrap());
}

#[test]
fn negative_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 0);
    assert!(elapsed_ms(a, b).is_err());
}

#[test]
fn timestamp_wait() {
    use std::thread;
    use std::time::Duration;

    let a = timestamp();
    let delta = 420;
    thread::sleep(Duration::from_millis(delta + 10));
    let b = timestamp();
    assert!(b - a >= delta)
}

#[test]
fn clamp_in_range() {
    let res = clamp(1, 0, 2);
    assert_eq!(1, res);
}

#[test]
fn clamp_min() {
    let res = clamp(-2, -2, 2);
    assert_eq!(-2, res);
}

#[test]
fn clamp_max() {
    let res = clamp(0, -2, 0);
    assert_eq!(0, res);
}

#[test]
fn clamp_less_than_min() {
    let res = clamp(-1, 0, 2);
    assert_eq!(0, res);
}

#[test]
fn clamp_more_than_max() {
    let res = clamp(999, 9, 10);
    assert_eq!(10, res);
}

#[test]
fn seq_id_gen_sequential() {
    let mut id_gen = SeqIdGen::new();
    let ids_count = 1000;
    for i in 0..ids_count {
        assert_eq!(i + 1, id_gen.gen());
    }
}
<|endoftext|>


<commit_before>#[feature(macro_rules)];

use base::{ParseState, ParseResult, Dot, Expression};

// macro_escape makes macros from annotated module visible in the "super"
// module... and thus in the children of the "super" module as well.
#[macro_escape]
mod macros;

#[macro_escape]
mod base;

macro_rules! rule(
  (
    $name:ident <- $body:expr
  ) => (
    fn $name<'a>( parse_state: &ParseState<'a> ) -> Option< ParseResult<'a> > {
      $body.apply( parse_state )
    }
  );
)

rule!( Class <- seq!( lit!( "[" ),
                      star!( seq!( not!( lit!( "]" ) ), ex!( Range ) ) ),
                      lit!( "]" ),
                      ex!( Spacing ) ) )
rule!( Range <- or!( seq!( ex!( Char ), lit!( "-" ), ex!( Char ) ),
                     ex!( Char ) ) )
rule!( Char <- or!( seq!( lit!( r"\" ),
                          class!( r#"nrt'"[]\"# ) ),
                    seq!( lit!( r"\" ),
                          class!( "0-2" ),
                          class!( "0-7" ),
                          class!( "0-7" ) ),
                    seq!( lit!( r"\" ),
                          class!( "0-7" ),
                          opt!( class!( "0-7" ) ) ),
                    seq!( not!( lit!( r"\" ) ),
                          Dot ) ) )
rule!( LEFTARROW <- seq!( lit!( "<-" ), ex!( Spacing ) ) )
rule!( SLASH <- seq!( lit!( "/" ), ex!( Spacing ) ) )
rule!( NOT <- seq!( lit!( "!" ), ex!( Spacing ) ) )
rule!( QUESTION <- seq!( lit!( "?" ), ex!( Spacing ) ) )
rule!( STAR <- seq!( lit!( "*" ), ex!( Spacing ) ) )
rule!( PLUS <- seq!( lit!( "+" ), ex!( Spacing ) ) )
rule!( OPEN <- seq!( lit!( "(" ), ex!( Spacing ) ) )
rule!( CLOSE <- seq!( lit!( ")" ), ex!( Spacing ) ) )
rule!( DOT <- seq!( lit!( "." ), ex!( Spacing ) ) )
rule!( Spacing <- star!( or!( ex!( Space ), ex!( Comment ) ) ) )
rule!( Comment <- seq!( lit!( "#" ),
                        star!( seq!( not!( ex!( EndOfLine ) ), Dot ) ),
                        ex!( EndOfLine ) ) )
rule!( Space <- or!( lit!( " " ), lit!( "\t" ), ex!( EndOfLine ) ) )
rule!( EndOfLine <- or!( lit!( "\r\n" ), lit!( "\n" ), lit!( "\r" ) ) )
rule!( EndOfFile <- not!( Dot ) )

#[cfg(test)]
mod tests {
  use base::test_utils::ToParseState;
  use base::{ParseResult};
  use super::{EndOfFile, EndOfLine, Space, Comment, Spacing, Char, Range, Class};

  macro_rules! consumes(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        match $name( &ToParseState( input ) ) {
          Some( ParseResult{ nodes: _,
                             parse_state: parse_state } ) => {
            parse_state.input.is_empty()
          }
          _ => false
        }
      }
    );
  )

  macro_rules! matches(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        $name( &ToParseState( input ) ).is_some()
      }
    );
  )

  #[test]
  fn Class_Works() {
    assert!( consumes!( Class, "[a-z]" ) );
    assert!( consumes!( Class, "[a-z]  \n" ) );
    assert!( consumes!( Class, "[abc]" ) );
    assert!( consumes!( Class, "[abc0-9g]" ) );
  }

  #[test]
  fn Range_Works() {
    assert!( consumes!( Range, "a-z" ) );
    assert!( consumes!( Range, "a" ) );
  }

  #[test]
  fn Char_Works() {
    assert!( consumes!( Char, r"\n" ) );
    assert!( consumes!( Char, r"\]" ) );
    assert!( consumes!( Char, r"\\" ) );
    assert!( consumes!( Char, r"\'" ) );
    assert!( consumes!( Char, "a" ) );
    assert!( consumes!( Char, "x" ) );
    assert!( consumes!( Char, "Ć" ) );
    assert!( consumes!( Char, "€" ) );
    assert!( consumes!( Char, r"\277" ) );
    assert!( consumes!( Char, r"\77" ) );
    assert!( consumes!( Char, r"\7" ) );

    assert!( !consumes!( Char, "aa" ) );
  }

  #[test]
  fn Spacing_Works() {
    assert!( consumes!( Spacing, "  \t #g\n" ) );
    assert!( consumes!( Spacing, "#a\n  #1\n" ) );

    // Spacing DOES match here because at the top level, it is a star expression
    // which can match consuming nothing.
    assert!( matches!( Spacing, "" ) );
    assert!( !consumes!( Spacing, "#" ) );
    assert!( !consumes!( Spacing, "a" ) );
  }

  #[test]
  fn Comment_Works() {
    assert!( consumes!( Comment, "#\n" ) );
    assert!( consumes!( Comment, "# foo! \n" ) );
    assert!( !matches!( Comment, "\n" ) );
    assert!( !matches!( Comment, "#" ) );
    assert!( !matches!( Comment, "a" ) );
  }

  #[test]
  fn Space_Works() {
    assert!( consumes!( Space, " " ) );
    assert!( consumes!( Space, "\t" ) );
    assert!( consumes!( Space, "\n" ) );
    assert!( !matches!( Space, "a" ) );
  }

  #[test]
  fn EndOfLine_Works() {
    assert!( consumes!( EndOfLine, "\n" ) );
    assert!( consumes!( EndOfLine, "\r" ) );
    assert!( consumes!( EndOfLine, "\r\n" ) );
    assert!( !matches!( EndOfLine, "a" ) );
  }

  #[test]
  fn EndOfFile_Works() {
    assert!( consumes!( EndOfFile, "" ) );
    assert!( !matches!( EndOfFile, "a" ) );
  }
}
<commit_msg>Literal rule implemented<commit_after>#[feature(macro_rules)];

use base::{ParseState, ParseResult, Dot, Expression};

// macro_escape makes macros from annotated module visible in the "super"
// module... and thus in the children of the "super" module as well.
#[macro_escape]
mod macros;

#[macro_escape]
mod base;

macro_rules! rule(
  (
    $name:ident <- $body:expr
  ) => (
    fn $name<'a>( parse_state: &ParseState<'a> ) -> Option< ParseResult<'a> > {
      $body.apply( parse_state )
    }
  );
)

rule!( Literal <- or!( seq!( class!( "'" ),
                             star!( seq!( not!( class!( "'" ) ),
                                          ex!( Char ) ) ),
                             class!( "'" ),
                             ex!( Spacing ) ),
                       seq!( class!( "\"" ),
                             star!( seq!( not!( class!( "\"" ) ),
                                          ex!( Char ) ) ),
                             class!( "\"" ),
                             ex!( Spacing ) ) ) )
rule!( Class <- seq!( lit!( "[" ),
                      star!( seq!( not!( lit!( "]" ) ), ex!( Range ) ) ),
                      lit!( "]" ),
                      ex!( Spacing ) ) )
rule!( Range <- or!( seq!( ex!( Char ), lit!( "-" ), ex!( Char ) ),
                     ex!( Char ) ) )
rule!( Char <- or!( seq!( lit!( r"\" ),
                          class!( r#"nrt'"[]\"# ) ),
                    seq!( lit!( r"\" ),
                          class!( "0-2" ),
                          class!( "0-7" ),
                          class!( "0-7" ) ),
                    seq!( lit!( r"\" ),
                          class!( "0-7" ),
                          opt!( class!( "0-7" ) ) ),
                    seq!( not!( lit!( r"\" ) ),
                          Dot ) ) )
rule!( LEFTARROW <- seq!( lit!( "<-" ), ex!( Spacing ) ) )
rule!( SLASH <- seq!( lit!( "/" ), ex!( Spacing ) ) )
rule!( NOT <- seq!( lit!( "!" ), ex!( Spacing ) ) )
rule!( QUESTION <- seq!( lit!( "?" ), ex!( Spacing ) ) )
rule!( STAR <- seq!( lit!( "*" ), ex!( Spacing ) ) )
rule!( PLUS <- seq!( lit!( "+" ), ex!( Spacing ) ) )
rule!( OPEN <- seq!( lit!( "(" ), ex!( Spacing ) ) )
rule!( CLOSE <- seq!( lit!( ")" ), ex!( Spacing ) ) )
rule!( DOT <- seq!( lit!( "." ), ex!( Spacing ) ) )
rule!( Spacing <- star!( or!( ex!( Space ), ex!( Comment ) ) ) )
rule!( Comment <- seq!( lit!( "#" ),
                        star!( seq!( not!( ex!( EndOfLine ) ), Dot ) ),
                        ex!( EndOfLine ) ) )
rule!( Space <- or!( lit!( " " ), lit!( "\t" ), ex!( EndOfLine ) ) )
rule!( EndOfLine <- or!( lit!( "\r\n" ), lit!( "\n" ), lit!( "\r" ) ) )
rule!( EndOfFile <- not!( Dot ) )

#[cfg(test)]
mod tests {
  use base::test_utils::ToParseState;
  use base::{ParseResult};
  use super::{EndOfFile, EndOfLine, Space, Comment, Spacing, Char, Range, Class,
              Literal};

  macro_rules! consumes(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        match $name( &ToParseState( input ) ) {
          Some( ParseResult{ nodes: _,
                             parse_state: parse_state } ) => {
            parse_state.input.is_empty()
          }
          _ => false
        }
      }
    );
  )

  macro_rules! matches(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        $name( &ToParseState( input ) ).is_some()
      }
    );
  )

  #[test]
  fn Literal_Works() {
    assert!( consumes!( Literal, "'abc'" ) );
    assert!( consumes!( Literal, r#""abc""# ) );
    assert!( consumes!( Literal, "'abc'  \n" ) );
    assert!( !consumes!( Literal, "'abc''bb'" ) );
  }

  #[test]
  fn Class_Works() {
    assert!( consumes!( Class, "[a-z]" ) );
    assert!( consumes!( Class, "[a-z]  \n" ) );
    assert!( consumes!( Class, "[abc]" ) );
    assert!( consumes!( Class, "[abc0-9g]" ) );
  }

  #[test]
  fn Range_Works() {
    assert!( consumes!( Range, "a-z" ) );
    assert!( consumes!( Range, "a" ) );
  }

  #[test]
  fn Char_Works() {
    assert!( consumes!( Char, r"\n" ) );
    assert!( consumes!( Char, r"\]" ) );
    assert!( consumes!( Char, r"\\" ) );
    assert!( consumes!( Char, r"\'" ) );
    assert!( consumes!( Char, "a" ) );
    assert!( consumes!( Char, "x" ) );
    assert!( consumes!( Char, "Ć" ) );
    assert!( consumes!( Char, "€" ) );
    assert!( consumes!( Char, r"\277" ) );
    assert!( consumes!( Char, r"\77" ) );
    assert!( consumes!( Char, r"\7" ) );

    assert!( !consumes!( Char, "aa" ) );
  }

  #[test]
  fn Spacing_Works() {
    assert!( consumes!( Spacing, "  \t #g\n" ) );
    assert!( consumes!( Spacing, "#a\n  #1\n" ) );

    // Spacing DOES match here because at the top level, it is a star expression
    // which can match consuming nothing.
    assert!( matches!( Spacing, "" ) );
    assert!( !consumes!( Spacing, "#" ) );
    assert!( !consumes!( Spacing, "a" ) );
  }

  #[test]
  fn Comment_Works() {
    assert!( consumes!( Comment, "#\n" ) );
    assert!( consumes!( Comment, "# foo! \n" ) );
    assert!( !matches!( Comment, "\n" ) );
    assert!( !matches!( Comment, "#" ) );
    assert!( !matches!( Comment, "a" ) );
  }

  #[test]
  fn Space_Works() {
    assert!( consumes!( Space, " " ) );
    assert!( consumes!( Space, "\t" ) );
    assert!( consumes!( Space, "\n" ) );
    assert!( !matches!( Space, "a" ) );
  }

  #[test]
  fn EndOfLine_Works() {
    assert!( consumes!( EndOfLine, "\n" ) );
    assert!( consumes!( EndOfLine, "\r" ) );
    assert!( consumes!( EndOfLine, "\r\n" ) );
    assert!( !matches!( EndOfLine, "a" ) );
  }

  #[test]
  fn EndOfFile_Works() {
    assert!( consumes!( EndOfFile, "" ) );
    assert!( !matches!( EndOfFile, "a" ) );
  }
}
<|endoftext|>


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

//! Utilities to throw exceptions from Rust bindings.

use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::codegen::PrototypeList::proto_id_to_name;
use dom::bindings::conversions::root_from_object;
use dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible};
use dom::bindings::global::GlobalRef;
use dom::bindings::str::USVString;
use dom::domexception::{DOMErrorName, DOMException};
use js::error::{throw_range_error, throw_type_error};
use js::jsapi::HandleObject;
use js::jsapi::JSAutoCompartment;
use js::jsapi::JSContext;
use js::jsapi::JSObject;
use js::jsapi::JS_ClearPendingException;
use js::jsapi::JS_ErrorFromException;
use js::jsapi::JS_GetPendingException;
use js::jsapi::JS_IsExceptionPending;
use js::jsapi::JS_SetPendingException;
use js::jsval::UndefinedValue;
use libc::c_uint;
use std::slice::from_raw_parts;

/// DOM exceptions that can be thrown by a native DOM method.
#[derive(Debug, Clone, HeapSizeOf)]
pub enum Error {
    /// IndexSizeError DOMException
    IndexSize,
    /// NotFoundError DOMException
    NotFound,
    /// HierarchyRequestError DOMException
    HierarchyRequest,
    /// WrongDocumentError DOMException
    WrongDocument,
    /// InvalidCharacterError DOMException
    InvalidCharacter,
    /// NotSupportedError DOMException
    NotSupported,
    /// InUseAttributeError DOMException
    InUseAttribute,
    /// InvalidStateError DOMException
    InvalidState,
    /// SyntaxError DOMException
    Syntax,
    /// NamespaceError DOMException
    Namespace,
    /// InvalidAccessError DOMException
    InvalidAccess,
    /// SecurityError DOMException
    Security,
    /// NetworkError DOMException
    Network,
    /// AbortError DOMException
    Abort,
    /// TimeoutError DOMException
    Timeout,
    /// InvalidNodeTypeError DOMException
    InvalidNodeType,
    /// DataCloneError DOMException
    DataClone,
    /// NoModificationAllowedError DOMException
    NoModificationAllowed,
    /// QuotaExceededError DOMException
    QuotaExceeded,
    /// TypeMismatchError DOMException
    TypeMismatch,
    /// InvalidModificationError DOMException
    InvalidModification,

    /// TypeError JavaScript Error
    Type(String),
    /// RangeError JavaScript Error
    Range(String),

    /// A JavaScript exception is already pending.
    JSFailed,
}

/// The return type for IDL operations that can throw DOM exceptions.
pub type Fallible<T> = Result<T, Error>;

/// The return type for IDL operations that can throw DOM exceptions and
/// return `()`.
pub type ErrorResult = Fallible<()>;

/// Set a pending exception for the given `result` on `cx`.
pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result: Error) {
    let code = match result {
        Error::IndexSize => DOMErrorName::IndexSizeError,
        Error::NotFound => DOMErrorName::NotFoundError,
        Error::HierarchyRequest => DOMErrorName::HierarchyRequestError,
        Error::WrongDocument => DOMErrorName::WrongDocumentError,
        Error::InvalidCharacter => DOMErrorName::InvalidCharacterError,
        Error::NotSupported => DOMErrorName::NotSupportedError,
        Error::InUseAttribute => DOMErrorName::InUseAttributeError,
        Error::InvalidState => DOMErrorName::InvalidStateError,
        Error::Syntax => DOMErrorName::SyntaxError,
        Error::Namespace => DOMErrorName::NamespaceError,
        Error::InvalidAccess => DOMErrorName::InvalidAccessError,
        Error::Security => DOMErrorName::SecurityError,
        Error::Network => DOMErrorName::NetworkError,
        Error::Abort => DOMErrorName::AbortError,
        Error::Timeout => DOMErrorName::TimeoutError,
        Error::InvalidNodeType => DOMErrorName::InvalidNodeTypeError,
        Error::DataClone => DOMErrorName::DataCloneError,
        Error::NoModificationAllowed => DOMErrorName::NoModificationAllowedError,
        Error::QuotaExceeded => DOMErrorName::QuotaExceededError,
        Error::TypeMismatch => DOMErrorName::TypeMismatchError,
        Error::InvalidModification => DOMErrorName::InvalidModificationError,
        Error::Type(message) => {
            assert!(!JS_IsExceptionPending(cx));
            throw_type_error(cx, &message);
            return;
        },
        Error::Range(message) => {
            assert!(!JS_IsExceptionPending(cx));
            throw_range_error(cx, &message);
            return;
        },
        Error::JSFailed => {
            assert!(JS_IsExceptionPending(cx));
            return;
        }
    };

    assert!(!JS_IsExceptionPending(cx));
    let exception = DOMException::new(global, code);
    rooted!(in(cx) let mut thrown = UndefinedValue());
    exception.to_jsval(cx, thrown.handle_mut());
    JS_SetPendingException(cx, thrown.handle());
}

struct ErrorInfo {
    filename: String,
    message: String,
    lineno: c_uint,
    column: c_uint,
}

impl ErrorInfo {
    unsafe fn from_native_error(cx: *mut JSContext, object: HandleObject)
                                -> Option<ErrorInfo> {
        let report = JS_ErrorFromException(cx, object);
        if report.is_null() {
            return None;
        }

        let filename = {
            let filename = (*report).filename as *const u8;
            if !filename.is_null() {
                let length = (0..).find(|idx| *filename.offset(*idx) == 0).unwrap();
                let filename = from_raw_parts(filename, length as usize);
                String::from_utf8_lossy(filename).into_owned()
            } else {
                "none".to_string()
            }
        };

        let lineno = (*report).lineno;
        let column = (*report).column;

        let message = {
            let message = (*report).ucmessage;
            let length = (0..).find(|idx| *message.offset(*idx) == 0).unwrap();
            let message = from_raw_parts(message, length as usize);
            String::from_utf16_lossy(message)
        };

        Some(ErrorInfo {
            filename: filename,
            message: message,
            lineno: lineno,
            column: column,
        })
    }

    fn from_dom_exception(cx: *mut JSContext, object: HandleObject) -> Option<ErrorInfo> {
        let exception = match root_from_object::<DOMException>(object.get()) {
            Ok(exception) => exception,
            Err(_) => return None,
        };

        Some(ErrorInfo {
            filename: "".to_string(),
            message: exception.Stringifier().into(),
            lineno: 0,
            column: 0,
        })
    }
}

/// Report a pending exception, thereby clearing it.
pub unsafe fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) {
    if JS_IsExceptionPending(cx) {
        let _ac = JSAutoCompartment::new(cx, obj);
        rooted!(in(cx) let mut value = UndefinedValue());
        if !JS_GetPendingException(cx, value.handle_mut()) {
            JS_ClearPendingException(cx);
            error!("Uncaught exception: JS_GetPendingException failed");
            return;
        }

        JS_ClearPendingException(cx);
        if !value.is_object() {
            match USVString::from_jsval(cx, value.handle(), ()) {
                Ok(USVString(string)) => error!("Uncaught exception: {}", string),
                Err(_) => error!("Uncaught exception: failed to stringify primitive"),
            }
            return;
        }

        rooted!(in(cx) let object = value.to_object());
        let error_info = ErrorInfo::from_native_error(cx, object.handle())
            .or_else(|| ErrorInfo::from_dom_exception(cx, object.handle()));
        let error_info = match error_info {
            Some(error_info) => error_info,
            None => {
                error!("Uncaught exception: failed to extract information");
                return;
            }
        };

        error!("Error at {}:{}:{} {}",
               error_info.filename,
               error_info.lineno,
               error_info.column,
               error_info.message);
    }
}

/// Throw an exception to signal that a `JSVal` can not be converted to any of
/// the types in an IDL union type.
pub unsafe fn throw_not_in_union(cx: *mut JSContext, names: &'static str) {
    assert!(!JS_IsExceptionPending(cx));
    let error = format!("argument could not be converted to any of: {}", names);
    throw_type_error(cx, &error);
}

/// Throw an exception to signal that a `JSObject` can not be converted to a
/// given DOM type.
pub unsafe fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) {
    debug_assert!(!JS_IsExceptionPending(cx));
    let error = format!("\"this\" object does not implement interface {}.",
                        proto_id_to_name(proto_id));
    throw_type_error(cx, &error);
}
<commit_msg>Remove an unused argument to ErrorInfo::from_dom_exception.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Utilities to throw exceptions from Rust bindings.

use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::codegen::PrototypeList::proto_id_to_name;
use dom::bindings::conversions::root_from_object;
use dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible};
use dom::bindings::global::GlobalRef;
use dom::bindings::str::USVString;
use dom::domexception::{DOMErrorName, DOMException};
use js::error::{throw_range_error, throw_type_error};
use js::jsapi::HandleObject;
use js::jsapi::JSAutoCompartment;
use js::jsapi::JSContext;
use js::jsapi::JSObject;
use js::jsapi::JS_ClearPendingException;
use js::jsapi::JS_ErrorFromException;
use js::jsapi::JS_GetPendingException;
use js::jsapi::JS_IsExceptionPending;
use js::jsapi::JS_SetPendingException;
use js::jsval::UndefinedValue;
use libc::c_uint;
use std::slice::from_raw_parts;

/// DOM exceptions that can be thrown by a native DOM method.
#[derive(Debug, Clone, HeapSizeOf)]
pub enum Error {
    /// IndexSizeError DOMException
    IndexSize,
    /// NotFoundError DOMException
    NotFound,
    /// HierarchyRequestError DOMException
    HierarchyRequest,
    /// WrongDocumentError DOMException
    WrongDocument,
    /// InvalidCharacterError DOMException
    InvalidCharacter,
    /// NotSupportedError DOMException
    NotSupported,
    /// InUseAttributeError DOMException
    InUseAttribute,
    /// InvalidStateError DOMException
    InvalidState,
    /// SyntaxError DOMException
    Syntax,
    /// NamespaceError DOMException
    Namespace,
    /// InvalidAccessError DOMException
    InvalidAccess,
    /// SecurityError DOMException
    Security,
    /// NetworkError DOMException
    Network,
    /// AbortError DOMException
    Abort,
    /// TimeoutError DOMException
    Timeout,
    /// InvalidNodeTypeError DOMException
    InvalidNodeType,
    /// DataCloneError DOMException
    DataClone,
    /// NoModificationAllowedError DOMException
    NoModificationAllowed,
    /// QuotaExceededError DOMException
    QuotaExceeded,
    /// TypeMismatchError DOMException
    TypeMismatch,
    /// InvalidModificationError DOMException
    InvalidModification,

    /// TypeError JavaScript Error
    Type(String),
    /// RangeError JavaScript Error
    Range(String),

    /// A JavaScript exception is already pending.
    JSFailed,
}

/// The return type for IDL operations that can throw DOM exceptions.
pub type Fallible<T> = Result<T, Error>;

/// The return type for IDL operations that can throw DOM exceptions and
/// return `()`.
pub type ErrorResult = Fallible<()>;

/// Set a pending exception for the given `result` on `cx`.
pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result: Error) {
    let code = match result {
        Error::IndexSize => DOMErrorName::IndexSizeError,
        Error::NotFound => DOMErrorName::NotFoundError,
        Error::HierarchyRequest => DOMErrorName::HierarchyRequestError,
        Error::WrongDocument => DOMErrorName::WrongDocumentError,
        Error::InvalidCharacter => DOMErrorName::InvalidCharacterError,
        Error::NotSupported => DOMErrorName::NotSupportedError,
        Error::InUseAttribute => DOMErrorName::InUseAttributeError,
        Error::InvalidState => DOMErrorName::InvalidStateError,
        Error::Syntax => DOMErrorName::SyntaxError,
        Error::Namespace => DOMErrorName::NamespaceError,
        Error::InvalidAccess => DOMErrorName::InvalidAccessError,
        Error::Security => DOMErrorName::SecurityError,
        Error::Network => DOMErrorName::NetworkError,
        Error::Abort => DOMErrorName::AbortError,
        Error::Timeout => DOMErrorName::TimeoutError,
        Error::InvalidNodeType => DOMErrorName::InvalidNodeTypeError,
        Error::DataClone => DOMErrorName::DataCloneError,
        Error::NoModificationAllowed => DOMErrorName::NoModificationAllowedError,
        Error::QuotaExceeded => DOMErrorName::QuotaExceededError,
        Error::TypeMismatch => DOMErrorName::TypeMismatchError,
        Error::InvalidModification => DOMErrorName::InvalidModificationError,
        Error::Type(message) => {
            assert!(!JS_IsExceptionPending(cx));
            throw_type_error(cx, &message);
            return;
        },
        Error::Range(message) => {
            assert!(!JS_IsExceptionPending(cx));
            throw_range_error(cx, &message);
            return;
        },
        Error::JSFailed => {
            assert!(JS_IsExceptionPending(cx));
            return;
        }
    };

    assert!(!JS_IsExceptionPending(cx));
    let exception = DOMException::new(global, code);
    rooted!(in(cx) let mut thrown = UndefinedValue());
    exception.to_jsval(cx, thrown.handle_mut());
    JS_SetPendingException(cx, thrown.handle());
}

struct ErrorInfo {
    filename: String,
    message: String,
    lineno: c_uint,
    column: c_uint,
}

impl ErrorInfo {
    unsafe fn from_native_error(cx: *mut JSContext, object: HandleObject)
                                -> Option<ErrorInfo> {
        let report = JS_ErrorFromException(cx, object);
        if report.is_null() {
            return None;
        }

        let filename = {
            let filename = (*report).filename as *const u8;
            if !filename.is_null() {
                let length = (0..).find(|idx| *filename.offset(*idx) == 0).unwrap();
                let filename = from_raw_parts(filename, length as usize);
                String::from_utf8_lossy(filename).into_owned()
            } else {
                "none".to_string()
            }
        };

        let lineno = (*report).lineno;
        let column = (*report).column;

        let message = {
            let message = (*report).ucmessage;
            let length = (0..).find(|idx| *message.offset(*idx) == 0).unwrap();
            let message = from_raw_parts(message, length as usize);
            String::from_utf16_lossy(message)
        };

        Some(ErrorInfo {
            filename: filename,
            message: message,
            lineno: lineno,
            column: column,
        })
    }

    fn from_dom_exception(object: HandleObject) -> Option<ErrorInfo> {
        let exception = match root_from_object::<DOMException>(object.get()) {
            Ok(exception) => exception,
            Err(_) => return None,
        };

        Some(ErrorInfo {
            filename: "".to_string(),
            message: exception.Stringifier().into(),
            lineno: 0,
            column: 0,
        })
    }
}

/// Report a pending exception, thereby clearing it.
pub unsafe fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) {
    if JS_IsExceptionPending(cx) {
        let _ac = JSAutoCompartment::new(cx, obj);
        rooted!(in(cx) let mut value = UndefinedValue());
        if !JS_GetPendingException(cx, value.handle_mut()) {
            JS_ClearPendingException(cx);
            error!("Uncaught exception: JS_GetPendingException failed");
            return;
        }

        JS_ClearPendingException(cx);
        if !value.is_object() {
            match USVString::from_jsval(cx, value.handle(), ()) {
                Ok(USVString(string)) => error!("Uncaught exception: {}", string),
                Err(_) => error!("Uncaught exception: failed to stringify primitive"),
            }
            return;
        }

        rooted!(in(cx) let object = value.to_object());
        let error_info = ErrorInfo::from_native_error(cx, object.handle())
            .or_else(|| ErrorInfo::from_dom_exception(object.handle()));
        let error_info = match error_info {
            Some(error_info) => error_info,
            None => {
                error!("Uncaught exception: failed to extract information");
                return;
            }
        };

        error!("Error at {}:{}:{} {}",
               error_info.filename,
               error_info.lineno,
               error_info.column,
               error_info.message);
    }
}

/// Throw an exception to signal that a `JSVal` can not be converted to any of
/// the types in an IDL union type.
pub unsafe fn throw_not_in_union(cx: *mut JSContext, names: &'static str) {
    assert!(!JS_IsExceptionPending(cx));
    let error = format!("argument could not be converted to any of: {}", names);
    throw_type_error(cx, &error);
}

/// Throw an exception to signal that a `JSObject` can not be converted to a
/// given DOM type.
pub unsafe fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) {
    debug_assert!(!JS_IsExceptionPending(cx));
    let error = format!("\"this\" object does not implement interface {}.",
                        proto_id_to_name(proto_id));
    throw_type_error(cx, &error);
}
<|endoftext|>