<commit_before>// src/cli.rs
// Argument parser and CLI (Command Line Interface)
// for BreakFast

use clap::{App, Arg, SubCommand};

pub fn build_cli() -> App<'static, 'static> {
    App::new("breakfastrs")
        .version("0.1")
        .about("BreakFast is a toolkit for detecting chromosomal rearrangements based on whole genome sequencing data.")
        .usage("\tbreakfast detect <bam_file> <genome> <out_prefix> [-a N] [-f N] [-q N] [-O OR] [--discard-duplicates=METHOD]\n\
        \tbreakfast detect specific [-A] <bam_file> <donors> <acceptors> <genome> <out_prefix>\n\
        \tbreakfast filter <sv_file> [-r P-S-A]... [--blacklist=PATH]\n\
        \tbreakfast annotate <sv_file> <bed_file>\n\
        \tbreakfast blacklist [--freq-above=FREQ] <sv_files>...\n\
        \tbreakfast visualize <sv_file>\n\
        \tbreakfast tabulate rearranged genes <sv_files>...\n\
        \tbreakfast tabulate fusions <sv_files>...\n\
        \tbreakfast statistics <sv_files>...\n\
        \tbreakfast filter by region <sv_file> <region>\n\
        \tbreakfast filter by distance <min_distance> <sv_file>\n\
        \tbreakfast align junction <reads>")

        .arg(Arg::with_name("anchor-len")
            .short("a")
            .long("anchor-len")
            .global(true)
            .takes_value(true)
            .value_name("N")
            .display_order(1)
            .help("Anchor length for split read analysis. When zero, split reads are not used [default: 0]"))

        .arg(Arg::with_name("max-frag-len")
            .short("f")
            .long("max-frag-len")
            .global(true)
            .takes_value(true)
            .value_name("N")
            .display_order(2)
            .help("Maximum fragment length [default: 5000]"))

        .arg(Arg::with_name("min-mapq")
            .short("q")
            .long("min-mapq")
            .global(true)
            .takes_value(true)
            .value_name("N")
            .display_order(3)
            .help("Minimum mapping quality to consider [default: 15]"))

        .arg(Arg::with_name("orientation")
            .short("O")
            .long("orientation")
            .global(true)
            .takes_value(true)
            .value_name("OR")
            .display_order(4)
            .help("Read pair orientation produced by sequencer. Either 'fr' (converging), 'rf' (diverging) or 'ff' [default: fr]"))

        .arg(Arg::with_name("all-reads")
            .short("A")
            .long("all-reads")
            .global(true)
            .display_order(5)
            .help("Use all reads for rearrangement detection, not just unaligned reads."))

        .arg(Arg::with_name("discard-duplicates")
            .long("discard-duplicates")
            .global(true)
            .takes_value(true)
            .value_name("Method")
            .display_order(6)
            .help("Method to use when discarding duplicate reads.'both-ends' considers a read pair (or unaligned read) to be a duplicate of another if the positions"))

        .arg(Arg::with_name("blacklist")
            .long("blacklist")
            .global(true)
            .takes_value(true)
            .value_name("list")
            .display_order(7)
            .help("Path to a file containing blacklisted regions."))

        .arg(Arg::with_name("min-reads")
            .short("r")
            .long("min-reads")
            .global(true)
            .takes_value(true)
            .value_name("P-S-A")
            .display_order(8)
            .help("Minimum number of spanning reads required to accept a breakpoint. Specified in the format P-S-A, where P=paired, S=split, A=either. For example, -r 1-2-0 would require at least one mate pair and two split reads of evidence [default: 0-0-0]."))

        .arg(Arg::with_name("freq-above")
            .long("freq-above")
            .global(true)
            .takes_value(true)
            .value_name("FREQ")
            .display_order(9)
            .help("Minimum frequency at which a variant must be present among the control samples to be considered a false positive [default: 0]."))

        .subcommand(SubCommand::with_name("detect")
            .usage("\tbreakfast detect <bam_file> <genome> <out_prefix> [-a N] [-f N] [-q N] [-O OR] [--discard-duplicates=METHOD]")
            .display_order(1)
            .arg(Arg::with_name("bam_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("genome")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("out_prefix")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("detect-specific")
            .usage("breakfast detect specific [-A] <bam_file> <donors> <acceptors> <genome> <out_prefix>")
            .display_order(2)
            .arg(Arg::with_name("bam_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("donors")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("acceptors")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("genome")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("out_prefix")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("filter")
            .usage("breakfast filter <sv_file> [-r P-S-A]... [--blacklist=PATH]")
            .display_order(3)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("annotate")
            .usage("breakfast annotate <sv_file> <bed_file>")
            .display_order(4)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("bed_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("blacklist")
            .usage("breakfast blacklist [--freq-above=FREQ] <sv_files>...")
            .display_order(5)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("visualize")
            .usage("breakfast visualize <sv_file>")
            .display_order(6)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("tabulate-rearranged-genes")
            .usage("breakfast tabulate rearranged genes <sv_files>...")
            .display_order(7)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("tabulate-fusions")
            .usage("breakfast tabulate fusions <sv_files>...")
            .display_order(8)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("statistics")
            .usage("breakfast statistics <sv_files>..")
            .display_order(9)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("filter-by-region")
            .usage("breakfast filter by region <sv_file> <region>")
            .display_order(10)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("region")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("filter-by-distance")
            .usage("breakfast filter by distance <min_distance> <sv_file>")
            .display_order(11)
            .arg(Arg::with_name("min_distance")
                .takes_value(true)
                .required(true))
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("align-junction")
            .usage("breakfast align junction <reads>")
            .display_order(12)
            .arg(Arg::with_name("reads")
                .takes_value(true)
                .required(true)))

}
<commit_msg>small changes<commit_after>// src/cli.rs
// Argument parser and CLI (Command Line Interface)
// for BreakFast

use clap::{App, Arg, SubCommand};

pub fn build_cli() -> App<'static, 'static> {
    App::new("breakfastrs")
        .version("0.1")
        .about("BreakFast is a toolkit for detecting chromosomal rearrangements based on whole genome sequencing data.")
        .usage("\tbreakfast detect <bam_file> <genome> <out_prefix> [-a N] [-f N] [-q N] [-O OR] [--discard-duplicates=METHOD]\n\
        \tbreakfast detect specific [-A] <bam_file> <donors> <acceptors> <genome> <out_prefix>\n\
        \tbreakfast filter <sv_file> [-r P-S-A]... [--blacklist=PATH]\n\
        \tbreakfast annotate <sv_file> <bed_file>\n\
        \tbreakfast blacklist [--freq-above=FREQ] <sv_files>...\n\
        \tbreakfast visualize <sv_file>\n\
        \tbreakfast tabulate rearranged genes <sv_files>...\n\
        \tbreakfast tabulate fusions <sv_files>...\n\
        \tbreakfast statistics <sv_files>...\n\
        \tbreakfast filter by region <sv_file> <region>\n\
        \tbreakfast filter by distance <min_distance> <sv_file>\n\
        \tbreakfast align junction <reads>")

        .arg(Arg::with_name("anchor-len")
            .short("a")
            .long("anchor-len")
            .global(true)
            .takes_value(true)
            .value_name("N")
            .display_order(1)
            .help("Anchor length for split read analysis. When zero, split reads are not used [default: 0]"))

        .arg(Arg::with_name("max-frag-len")
            .short("f")
            .long("max-frag-len")
            .global(true)
            .takes_value(true)
            .value_name("N")
            .display_order(2)
            .help("Maximum fragment length [default: 5000]"))

        .arg(Arg::with_name("min-mapq")
            .short("q")
            .long("min-mapq")
            .global(true)
            .takes_value(true)
            .value_name("N")
            .display_order(3)
            .help("Minimum mapping quality to consider [default: 15]"))

        .arg(Arg::with_name("orientation")
            .short("O")
            .long("orientation")
            .global(true)
            .takes_value(true)
            .value_name("OR")
            .display_order(4)
            .help("Read pair orientation produced by sequencer. Either 'fr' (converging), 'rf' (diverging) or 'ff' [default: fr]"))

        .arg(Arg::with_name("all-reads")
            .short("A")
            .long("all-reads")
            .global(true)
            .display_order(5)
            .help("Use all reads for rearrangement detection, not just unaligned reads."))

        .arg(Arg::with_name("discard-duplicates")
            .long("discard-duplicates")
            .global(true)
            .takes_value(true)
            .value_name("Method")
            .display_order(6)
            .help("Method to use when discarding duplicate reads.'both-ends' considers a read pair (or unaligned read) to be a duplicate of another if the positions"))

        .arg(Arg::with_name("blacklist")
            .long("blacklist")
            .global(true)
            .takes_value(true)
            .value_name("list")
            .display_order(7)
            .help("Path to a file containing blacklisted regions."))

        .arg(Arg::with_name("min-reads")
            .short("r")
            .long("min-reads")
            .global(true)
            .takes_value(true)
            .value_name("P-S-A")
            .display_order(8)
            .help("Minimum number of spanning reads required to accept a breakpoint. Specified in the format P-S-A, where P=paired, S=split, A=either. For example, -r 1-2-0 would require at least one mate pair and two split reads of evidence [default: 0-0-0]."))

        .arg(Arg::with_name("freq-above")
            .long("freq-above")
            .global(true)
            .takes_value(true)
            .value_name("FREQ")
            .display_order(9)
            .help("Minimum frequency at which a variant must be present among the control samples to be considered a false positive [default: 0]."))

        .subcommand(SubCommand::with_name("detect")
            .usage("\tbreakfast detect <bam_file> <genome> <out_prefix> [-a N] [-f N] [-q N] [-O OR] [--discard-duplicates=METHOD]")
            .display_order(1)
            .arg(Arg::with_name("bam_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("genome")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("out_prefix")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("detect-specific")
            .usage("breakfast detect specific [-A] <bam_file> <donors> <acceptors> <genome> <out_prefix>")
            .display_order(2)
            .arg(Arg::with_name("bam_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("donors")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("acceptors")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("genome")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("out_prefix")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("filter")
            .usage("breakfast filter <sv_file> [-r P-S-A]... [--blacklist=PATH]")
            .display_order(3)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("annotate")
            .usage("breakfast annotate <sv_file> <bed_file>")
            .display_order(4)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("bed_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("blacklist")
            .usage("breakfast blacklist [--freq-above=FREQ] <sv_files>...")
            .display_order(5)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("visualize")
            .usage("breakfast visualize <sv_file>")
            .display_order(6)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("tabulate-rearranged-genes")
            .usage("breakfast tabulate rearranged genes <sv_files>...")
            .display_order(7)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("tabulate-fusions")
            .usage("breakfast tabulate fusions <sv_files>...")
            .display_order(8)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("statistics")
            .usage("breakfast statistics <sv_files>..")
            .display_order(9)
            .arg(Arg::with_name("sv_files")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("filter-by-region")
            .usage("breakfast filter by region <sv_file> <region>")
            .display_order(10)
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true))
            .arg(Arg::with_name("region")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("filter-by-distance")
            .usage("breakfast filter by distance <min_distance> <sv_file>")
            .display_order(11)
            .arg(Arg::with_name("min_distance")
                .takes_value(true)
                .required(true))
            .arg(Arg::with_name("sv_file")
                .required(true)
                .takes_value(true)))

        .subcommand(SubCommand::with_name("align-junction")
            .usage("breakfast align junction <reads>")
            .display_order(12)
            .arg(Arg::with_name("reads")
                .takes_value(true)
                .required(true)))
}
<|endoftext|>


<commit_before>extern crate std;
extern crate num;
extern crate uuid;

use std::str::SendStr;
use std::io::net::ip::IpAddr;
use self::uuid::Uuid;

pub enum OpcodeRequest {
    //requests
    OpcodeStartup = 0x01,
    OpcodeCredentials = 0x04,
    OpcodeOptions = 0x05,
    OpcodeQuery = 0x07,
    OpcodePrepare = 0x09,
    OpcodeExecute = 0x0A,
    OpcodeRegister = 0x0B,
}

#[deriving(Show)]
pub enum OpcodeResponse {
    //responces
    OpcodeError = 0x00,
    OpcodeReady = 0x02,
    OpcodeAuthenticate = 0x03,
    OpcodeSupported = 0x06,
    OpcodeResult = 0x08,
    OpcodeEvent = 0x0C,

    OpcodeUnknown
}

#[deriving(Show, FromPrimitive)]
pub enum KindResult {
    KindVoid = 0x0001,
    KindRows = 0x0002,
    KindSetKeyspace = 0x0003,
    KindPrepared = 0x0004,
    KindSchemaChange = 0x0005
}

pub fn opcode_response(val: u8) -> OpcodeResponse {
    match val {
        /* requests
        0x01 => OpcodeStartup,
        0x04 => OpcodeCredentials,
        0x05 => OpcodeOptions,
        0x07 => OpcodeQuery,
        0x09 => OpcodePrepare,
        0x0B => OpcodeRegister,
        */

        0x00 => OpcodeError,
        0x02 => OpcodeReady,
        0x03 => OpcodeAuthenticate,
        0x06 => OpcodeSupported,
        0x08 => OpcodeResult,
        // 0x0A => OpcodeExecute,
        0x0C => OpcodeEvent,

        _ => OpcodeUnknown
    }
}

pub mod Consistency {
    pub enum Consistency {
        Any = 0x0000,
        One = 0x0001,
        Two = 0x0002,
        Three = 0x0003,
        Quorum = 0x0004,
        All = 0x0005,
        LocalQuorum = 0x0006,
        EachQuorum = 0x0007,
        Unknown,
    }
}

#[deriving(Show)]
pub enum CqlValueType {
    ColumnCustom = 0x0000,
    ColumnASCII = 0x0001,
    ColumnBigInt = 0x0002,
    ColumnBlob = 0x0003,
    ColumnBoolean = 0x0004,
    ColumnCounter = 0x0005,
    ColumnDecimal = 0x0006,
    ColumnDouble = 0x0007,
    ColumnFloat = 0x0008,
    ColumnInt = 0x0009,
    ColumnText = 0x000A,
    ColumnTimestamp = 0x000B,
    ColumnUuid = 0x000C,
    ColumnVarChar = 0x000D,
    ColumnVarint = 0x000E,
    ColumnTimeUuid = 0x000F,
    ColumnInet = 0x0010,
    ColumnList = 0x0020,
    ColumnMap = 0x0021,
    ColumnSet = 0x0022,
    ColumnUnknown,
}

pub fn cql_column_type(val: u16) -> CqlValueType {
    match val {
        0x0000 => ColumnCustom,
        0x0001 => ColumnASCII,
        0x0002 => ColumnBigInt,
        0x0003 => ColumnBlob,
        0x0004 => ColumnBoolean,
        0x0005 => ColumnCounter,
        0x0006 => ColumnDecimal,
        0x0007 => ColumnDouble,
        0x0008 => ColumnFloat,
        0x0009 => ColumnInt,
        0x000A => ColumnText,
        0x000B => ColumnTimestamp,
        0x000C => ColumnUuid,
        0x000D => ColumnVarChar,
        0x000E => ColumnVarint,
        0x000F => ColumnTimeUuid,
        0x0010 => ColumnInet,
        0x0020 => ColumnList,
        0x0021 => ColumnMap,
        0x0022 => ColumnSet,
        _ => ColumnUnknown
    }
}

#[deriving(Show)]
pub enum RCErrorType {
    ReadError,
    WriteError,
    SerializeError,
    ConnectionError,
    NoDataError,
    GenericError
}

#[deriving(Show)]
pub struct RCError {
    pub kind: RCErrorType,
    pub desc: SendStr,
}

impl RCError {
    pub fn new<T: IntoMaybeOwned<'static>>(msg: T, kind: RCErrorType) -> RCError {
        RCError {
            kind: kind,
            desc: msg.into_maybe_owned()
        }
    }
}

pub type RCResult<T> = Result<T, RCError>;

pub struct CqlStringMap {
    pub pairs: Vec<CqlPair>,
}

pub struct CqlPair {
    pub key: &'static str,
    pub value: &'static str,
}

pub enum CqlBytesSize {
   Cqli32,
   Cqli16
}

#[deriving(Show)]
pub struct CqlColMetadata {
    pub keyspace: SendStr,
    pub table: SendStr,
    pub col_name: SendStr,
    pub col_type: CqlValueType,
    pub col_type_aux1: CqlValueType,
    pub col_type_aux2: CqlValueType
}

#[deriving(Show)]
pub struct CqlMetadata {
    pub flags: u32,
    pub column_count: u32,
    pub keyspace: SendStr,
    pub table: SendStr,
    pub row_metadata: Vec<CqlColMetadata>,
}

#[deriving(Show)]
pub struct Pair<T, V> {
    pub key: T,
    pub value: V
}

pub type CQLList = Vec<CqlValue>;
pub type CQLMap = Vec<Pair<CqlValue, CqlValue>>;
pub type CQLSet = Vec<CqlValue>;

#[deriving(Show)]
pub enum CqlValue {
    CqlASCII(Option<SendStr>),
    CqlBigInt(Option<i64>),
    CqlBlob(Option<Vec<u8>>),
    CqlBoolean(Option<bool>),
    CqlCounter(Option<i64>),
    CqlDecimal(Option<num::BigInt>),
    CqlDouble(Option<f64>),
    CqlFloat(Option<f32>),
    CqlInet(Option<IpAddr>),
    CqlInt(Option<i32>),
    CqlList(Option<CQLList>),
    CqlMap(Option<CQLMap>),
    CqlSet(Option<CQLSet>),
    CqlText(Option<SendStr>),
    CqlTimestamp(Option<u64>),
    CqlUuid(Option<Uuid>),
    CqlTimeUuid(Option<Uuid>),
    CqlVarchar(Option<SendStr>),
    CqlVarint(Option<num::BigInt>),
    CqlUnknown,
}

#[deriving(Show)]
pub struct CqlRow {
    pub cols: Vec<CqlValue>,
}

/*
impl CqlRow {
    fn get_column(&self, col_name: &str) -> Option<CqlValue> {
        let mut i = 0;
        let len = self.metadata.row_metadata.len();
        while i < len {
            if self.metadata.row_metadata.get(i).col_name.as_slice() == col_name {
                return Some(*self.cols.get(i));
            }
            i += 1;
        }
        None
    }
}
*/

#[deriving(Show)]
pub struct CqlRows {
    pub metadata: Box<CqlMetadata>,
    pub rows: Vec<CqlRow>,
}

pub struct CqlRequest<'a> {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeRequest,
    pub body: CqlRequestBody<'a>,
}

pub enum CqlRequestBody<'a> {
    RequestStartup(CqlStringMap),
    RequestCred(&'a Vec<SendStr>),
    RequestQuery(SendStr, Consistency::Consistency, u8),
    RequestPrepare(&'a str),
    RequestExec(&'a CqlPreparedStat, &'a [CqlValue], Consistency::Consistency, u8),
    RequestOptions,
}

#[deriving(Show)]
pub struct CqlResponse {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeResponse,
    pub body: CqlResponseBody,
}

#[deriving(Show)]
pub enum CqlResponseBody {
    ResponseError(u32, SendStr),
    ResponseReady,
    ResponseAuth(SendStr),

    ResultVoid,
    ResultRows(Box<CqlRows>),
    ResultKeyspace(SendStr),
    ResultPrepared(Box<CqlPreparedStat>),
    ResultSchemaChange(SendStr, SendStr, SendStr),
    ResultUnknown,

    ResponseEmpty,
}

#[deriving(Show)]
pub struct CqlPreparedStat {
    pub id: Vec<u8>,
    pub meta: Box<CqlMetadata>,
    pub meta_result: Option<Box<CqlMetadata>>
}

<commit_msg>Change SendStr to &str<commit_after>extern crate std;
extern crate num;
extern crate uuid;

use std::str::SendStr;
use std::io::net::ip::IpAddr;
use self::uuid::Uuid;

pub enum OpcodeRequest {
    //requests
    OpcodeStartup = 0x01,
    OpcodeCredentials = 0x04,
    OpcodeOptions = 0x05,
    OpcodeQuery = 0x07,
    OpcodePrepare = 0x09,
    OpcodeExecute = 0x0A,
    OpcodeRegister = 0x0B,
}

#[deriving(Show)]
pub enum OpcodeResponse {
    //responces
    OpcodeError = 0x00,
    OpcodeReady = 0x02,
    OpcodeAuthenticate = 0x03,
    OpcodeSupported = 0x06,
    OpcodeResult = 0x08,
    OpcodeEvent = 0x0C,

    OpcodeUnknown
}

#[deriving(Show, FromPrimitive)]
pub enum KindResult {
    KindVoid = 0x0001,
    KindRows = 0x0002,
    KindSetKeyspace = 0x0003,
    KindPrepared = 0x0004,
    KindSchemaChange = 0x0005
}

pub fn opcode_response(val: u8) -> OpcodeResponse {
    match val {
        /* requests
        0x01 => OpcodeStartup,
        0x04 => OpcodeCredentials,
        0x05 => OpcodeOptions,
        0x07 => OpcodeQuery,
        0x09 => OpcodePrepare,
        0x0B => OpcodeRegister,
        */

        0x00 => OpcodeError,
        0x02 => OpcodeReady,
        0x03 => OpcodeAuthenticate,
        0x06 => OpcodeSupported,
        0x08 => OpcodeResult,
        // 0x0A => OpcodeExecute,
        0x0C => OpcodeEvent,

        _ => OpcodeUnknown
    }
}

pub mod Consistency {
    pub enum Consistency {
        Any = 0x0000,
        One = 0x0001,
        Two = 0x0002,
        Three = 0x0003,
        Quorum = 0x0004,
        All = 0x0005,
        LocalQuorum = 0x0006,
        EachQuorum = 0x0007,
        Unknown,
    }
}

#[deriving(Show)]
pub enum CqlValueType {
    ColumnCustom = 0x0000,
    ColumnASCII = 0x0001,
    ColumnBigInt = 0x0002,
    ColumnBlob = 0x0003,
    ColumnBoolean = 0x0004,
    ColumnCounter = 0x0005,
    ColumnDecimal = 0x0006,
    ColumnDouble = 0x0007,
    ColumnFloat = 0x0008,
    ColumnInt = 0x0009,
    ColumnText = 0x000A,
    ColumnTimestamp = 0x000B,
    ColumnUuid = 0x000C,
    ColumnVarChar = 0x000D,
    ColumnVarint = 0x000E,
    ColumnTimeUuid = 0x000F,
    ColumnInet = 0x0010,
    ColumnList = 0x0020,
    ColumnMap = 0x0021,
    ColumnSet = 0x0022,
    ColumnUnknown,
}

pub fn cql_column_type(val: u16) -> CqlValueType {
    match val {
        0x0000 => ColumnCustom,
        0x0001 => ColumnASCII,
        0x0002 => ColumnBigInt,
        0x0003 => ColumnBlob,
        0x0004 => ColumnBoolean,
        0x0005 => ColumnCounter,
        0x0006 => ColumnDecimal,
        0x0007 => ColumnDouble,
        0x0008 => ColumnFloat,
        0x0009 => ColumnInt,
        0x000A => ColumnText,
        0x000B => ColumnTimestamp,
        0x000C => ColumnUuid,
        0x000D => ColumnVarChar,
        0x000E => ColumnVarint,
        0x000F => ColumnTimeUuid,
        0x0010 => ColumnInet,
        0x0020 => ColumnList,
        0x0021 => ColumnMap,
        0x0022 => ColumnSet,
        _ => ColumnUnknown
    }
}

#[deriving(Show)]
pub enum RCErrorType {
    ReadError,
    WriteError,
    SerializeError,
    ConnectionError,
    NoDataError,
    GenericError
}

#[deriving(Show)]
pub struct RCError {
    pub kind: RCErrorType,
    pub desc: SendStr,
}

impl RCError {
    pub fn new<T: IntoMaybeOwned<'static>>(msg: T, kind: RCErrorType) -> RCError {
        RCError {
            kind: kind,
            desc: msg.into_maybe_owned()
        }
    }
}

pub type RCResult<T> = Result<T, RCError>;

pub struct CqlStringMap {
    pub pairs: Vec<CqlPair>,
}

pub struct CqlPair {
    pub key: &'static str,
    pub value: &'static str,
}

pub enum CqlBytesSize {
   Cqli32,
   Cqli16
}

#[deriving(Show)]
pub struct CqlColMetadata {
    pub keyspace: SendStr,
    pub table: SendStr,
    pub col_name: SendStr,
    pub col_type: CqlValueType,
    pub col_type_aux1: CqlValueType,
    pub col_type_aux2: CqlValueType
}

#[deriving(Show)]
pub struct CqlMetadata {
    pub flags: u32,
    pub column_count: u32,
    pub keyspace: SendStr,
    pub table: SendStr,
    pub row_metadata: Vec<CqlColMetadata>,
}

#[deriving(Show)]
pub struct Pair<T, V> {
    pub key: T,
    pub value: V
}

pub type CQLList = Vec<CqlValue>;
pub type CQLMap = Vec<Pair<CqlValue, CqlValue>>;
pub type CQLSet = Vec<CqlValue>;

#[deriving(Show)]
pub enum CqlValue {
    CqlASCII(Option<SendStr>),
    CqlBigInt(Option<i64>),
    CqlBlob(Option<Vec<u8>>),
    CqlBoolean(Option<bool>),
    CqlCounter(Option<i64>),
    CqlDecimal(Option<num::BigInt>),
    CqlDouble(Option<f64>),
    CqlFloat(Option<f32>),
    CqlInet(Option<IpAddr>),
    CqlInt(Option<i32>),
    CqlList(Option<CQLList>),
    CqlMap(Option<CQLMap>),
    CqlSet(Option<CQLSet>),
    CqlText(Option<SendStr>),
    CqlTimestamp(Option<u64>),
    CqlUuid(Option<Uuid>),
    CqlTimeUuid(Option<Uuid>),
    CqlVarchar(Option<SendStr>),
    CqlVarint(Option<num::BigInt>),
    CqlUnknown,
}

#[deriving(Show)]
pub struct CqlRow {
    pub cols: Vec<CqlValue>,
}

/*
impl CqlRow {
    fn get_column(&self, col_name: &str) -> Option<CqlValue> {
        let mut i = 0;
        let len = self.metadata.row_metadata.len();
        while i < len {
            if self.metadata.row_metadata.get(i).col_name.as_slice() == col_name {
                return Some(*self.cols.get(i));
            }
            i += 1;
        }
        None
    }
}
*/

#[deriving(Show)]
pub struct CqlRows {
    pub metadata: Box<CqlMetadata>,
    pub rows: Vec<CqlRow>,
}

pub struct CqlRequest<'a> {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeRequest,
    pub body: CqlRequestBody<'a>,
}

pub enum CqlRequestBody<'a> {
    RequestStartup(CqlStringMap),
    RequestCred(&'a Vec<SendStr>),
    RequestQuery(&'a str, Consistency::Consistency, u8),
    RequestPrepare(&'a str),
    RequestExec(&'a CqlPreparedStat, &'a [CqlValue], Consistency::Consistency, u8),
    RequestOptions,
}

#[deriving(Show)]
pub struct CqlResponse {
    pub version: u8,
    pub flags: u8,
    pub stream: i8,
    pub opcode: OpcodeResponse,
    pub body: CqlResponseBody,
}

#[deriving(Show)]
pub enum CqlResponseBody {
    ResponseError(u32, SendStr),
    ResponseReady,
    ResponseAuth(SendStr),

    ResultVoid,
    ResultRows(Box<CqlRows>),
    ResultKeyspace(SendStr),
    ResultPrepared(Box<CqlPreparedStat>),
    ResultSchemaChange(SendStr, SendStr, SendStr),
    ResultUnknown,

    ResponseEmpty,
}

#[deriving(Show)]
pub struct CqlPreparedStat {
    pub id: Vec<u8>,
    pub meta: Box<CqlMetadata>,
    pub meta_result: Option<Box<CqlMetadata>>
}

<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use address::Address;
use basicblock::{BasicBlock, BasicBlockEdge, EdgeType};
use instruction::Instruction;
use petgraph::graph::{Graph, NodeIndex};
use std::collections::BTreeMap;

/// A [control flow graph].
///
/// [control flow graph]: https://en.wikipedia.org/wiki/Control_flow_graph
pub struct CFG<'f> {
    /// The [`Graph`] that stores the actual CFG
    ///
    /// [`Graph`]: ../petgraph/graph/struct.Graph.html
    pub graph: Graph<BasicBlock<'f>, BasicBlockEdge>,
    /// The [`NodeIndex`] for the entry [`BasicBlock`] for this function.
    ///
    /// [`BasicBlock`]: struct.BasicBlock.html
    /// [`NodeIndex`]: ../petgraph/graph/struct.NodeIndex.html
    pub entry_block: Option<NodeIndex>,
    /// Map an [address] to the corresponding [basic block].
    ///
    /// [address]: struct.Address.html
    /// [basic block]: struct.BasicBlock.html
    pub block_finder: BTreeMap<Address, NodeIndex>,
}

impl<'f> CFG<'f> {
    /// Build the CFG from the [`instructions`].
    ///
    /// This is conducted in a 2 step process:
    ///
    /// * First, each instruction is examined to identify block boundaries.
    /// * Then, we go through each instruction again, looking for the
    ///   previously identified block boundaries and build the edges.
    ///
    /// This two step process prevents us from having to construct and then
    /// subsequently split blocks as we find backward edges.
    ///
    /// [`instructions`]: trait.Instruction.html
    pub fn new(instructions: &'f [Box<Instruction>]) -> Self {
        let mut cfg = CFG {
            graph: Graph::new(),
            entry_block: None,
            block_finder: BTreeMap::new(),
        };
        if !instructions.is_empty() {
            cfg.identify_blocks(instructions);
            cfg.build_edges(instructions);
        }
        cfg
    }

    /// Identify basic blocks by their boundaries.
    ///
    /// Inspect each instruction to see if it is a 'leader' or the start of
    /// a new basic block. An instruction is a leader if:
    ///
    /// * It is the first instruction in the basic block.
    /// * It comes after a branch of any sort. We identify these as things
    ///   for which `Instruction::is_block_terminator` returns `true`.
    /// * It is the target of a jump (conditional or unconditional) within
    ///   the function.
    fn identify_blocks(&mut self, instructions: &[Box<Instruction>]) {
        let start_addr = instructions[0].address();
        let end_addr = instructions.last().map(|i| i.address()).unwrap();
        let mut next_is_leader: bool = true;
        for inst in instructions {
            if next_is_leader {
                let idx = self.graph.add_node(BasicBlock::new(inst.address()));
                self.block_finder.insert(inst.address(), idx);
                next_is_leader = false;
            }
            if inst.is_block_terminator() {
                if let Some(target_addr) = inst.target_address() {
                    if !self.block_finder.contains_key(&target_addr) &&
                       target_addr >= start_addr && target_addr <= end_addr {
                        let idx = self.graph.add_node(BasicBlock::new(target_addr));
                        self.block_finder.insert(target_addr, idx);
                    }
                }
                // The next instruction, if any, will be the start of a new block.
                next_is_leader = true;
            }
        }
        self.entry_block = Some(self.block_finder.get(&instructions[0].address()).unwrap().clone());
    }

    /// Build an edge between 2 basic blocks.
    fn build_edge(&mut self,
                  current_block_idx: NodeIndex,
                  next_block_idx: NodeIndex,
                  current_inst: &Box<Instruction>) {
        if current_inst.is_local_conditional_jump() {
            // We have one edge for the jump target and one for the fallthrough.
            // We jump through some hoops here to keep the borrow checker happy.
            if let Some(target_addr) = current_inst.target_address() {
                if let Some(target_block_idx) = self.block_finder.get(&target_addr) {
                    let edge = BasicBlockEdge { edge_type: EdgeType::ConditionalTaken };
                    self.graph.add_edge(current_block_idx, target_block_idx.clone(), edge);
                }
                let edge = BasicBlockEdge { edge_type: EdgeType::ConditionalFallthrough };
                self.graph.add_edge(current_block_idx, next_block_idx, edge);
            }
        } else if current_inst.is_local_jump() || current_inst.is_call() {
            let edge = BasicBlockEdge { edge_type: EdgeType::Unconditional };
            self.graph.add_edge(current_block_idx, next_block_idx, edge);
        } else if current_inst.is_return() {
            // Do we want to record this exit anywhere?
        }
    }

    /// Build edges after having identified the basic blocks.
    ///
    /// After the basic blocks have been identified, we can go back and
    /// connect the basic blocks with their appropriate edges.
    ///
    /// We do this by iterating through the instructions looking for
    /// boundaries between the basic blocks and then setting up the
    /// new edges.
    fn build_edges(&mut self, instructions: &'f [Box<Instruction>]) {
        // Here, we're going to walk through the instructions again in
        // pairs of (i, Some(i + 1)):
        // [1,2..9] -> [Some(1),Some(2)..Some(9),None]
        let current_inst_iter = instructions.iter();
        let mut next_inst_iter = current_inst_iter.clone().map(Some).chain(Some(None).into_iter());
        // Skip the first one so that we're actually working with the next one.
        next_inst_iter.next();
        let mut current_block_idx = self.entry_block.unwrap();
        for ij in current_inst_iter.zip(next_inst_iter) {
            if let (current_inst, Some(next_inst)) = ij {
                // Add this instruction to the current block
                if let Some(current_block) = self.graph.node_weight_mut(current_block_idx) {
                    current_block.instructions.push(current_inst);
                }
                // Does the next instruction begin a basic block?
                let next_block_idx = self.block_finder
                    .get(&next_inst.address())
                    .unwrap_or(&current_block_idx)
                    .clone();
                // If we're at a block boundary, create an edge between the
                // current and next blocks. The type of the edge is determined
                // by looking at the current instruction.
                if next_block_idx != current_block_idx {
                    self.build_edge(current_block_idx, next_block_idx, current_inst);
                    current_block_idx = next_block_idx;
                }
            } else {
                // No next instruction, so we're at the end.
                // Do we want to record this exit anywhere?
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use instruction::Instruction;
    use petgraph::EdgeDirection;
    use super::CFG;
    use tests::*;

    #[test]
    fn construct() {
        let insts: Vec<Box<Instruction>> = vec![];
        let cfg = CFG::new(&insts);
        assert!(cfg.entry_block.is_none());
        assert_eq!(cfg.graph.node_count(), 0);
    }

    #[test]
    fn build_one_basic_block() {
        let insts: Vec<Box<Instruction>> = vec![
            TestInstruction::new(0, Opcode::Add),
            TestInstruction::new(1, Opcode::Add),
            TestInstruction::new(2, Opcode::Ret),
        ];
        let cfg = CFG::new(&insts);
        assert!(cfg.entry_block.is_some());
        assert_eq!(cfg.graph.node_count(), 1);

        let inbound = cfg.graph.externals(EdgeDirection::Incoming);
        assert_eq!(inbound.count(), 1);

        let outbound = cfg.graph.externals(EdgeDirection::Outgoing);
        assert_eq!(outbound.count(), 1);
    }
}
<commit_msg>Fix clippy warnings.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use address::Address;
use basicblock::{BasicBlock, BasicBlockEdge, EdgeType};
use instruction::Instruction;
use petgraph::graph::{Graph, NodeIndex};
use std::collections::BTreeMap;

/// A [control flow graph].
///
/// [control flow graph]: https://en.wikipedia.org/wiki/Control_flow_graph
pub struct CFG<'f> {
    /// The [`Graph`] that stores the actual CFG
    ///
    /// [`Graph`]: ../petgraph/graph/struct.Graph.html
    pub graph: Graph<BasicBlock<'f>, BasicBlockEdge>,
    /// The [`NodeIndex`] for the entry [`BasicBlock`] for this function.
    ///
    /// [`BasicBlock`]: struct.BasicBlock.html
    /// [`NodeIndex`]: ../petgraph/graph/struct.NodeIndex.html
    pub entry_block: Option<NodeIndex>,
    /// Map an [address] to the corresponding [basic block].
    ///
    /// [address]: struct.Address.html
    /// [basic block]: struct.BasicBlock.html
    pub block_finder: BTreeMap<Address, NodeIndex>,
}

impl<'f> CFG<'f> {
    /// Build the CFG from the [`instructions`].
    ///
    /// This is conducted in a 2 step process:
    ///
    /// * First, each instruction is examined to identify block boundaries.
    /// * Then, we go through each instruction again, looking for the
    ///   previously identified block boundaries and build the edges.
    ///
    /// This two step process prevents us from having to construct and then
    /// subsequently split blocks as we find backward edges.
    ///
    /// [`instructions`]: trait.Instruction.html
    pub fn new(instructions: &'f [Box<Instruction>]) -> Self {
        let mut cfg = CFG {
            graph: Graph::new(),
            entry_block: None,
            block_finder: BTreeMap::new(),
        };
        if !instructions.is_empty() {
            cfg.identify_blocks(instructions);
            cfg.build_edges(instructions);
        }
        cfg
    }

    /// Identify basic blocks by their boundaries.
    ///
    /// Inspect each instruction to see if it is a 'leader' or the start of
    /// a new basic block. An instruction is a leader if:
    ///
    /// * It is the first instruction in the basic block.
    /// * It comes after a branch of any sort. We identify these as things
    ///   for which `Instruction::is_block_terminator` returns `true`.
    /// * It is the target of a jump (conditional or unconditional) within
    ///   the function.
    fn identify_blocks(&mut self, instructions: &[Box<Instruction>]) {
        let start_addr = instructions[0].address();
        let end_addr = instructions.last().map(|i| i.address()).unwrap();
        let mut next_is_leader: bool = true;
        for inst in instructions {
            if next_is_leader {
                let idx = self.graph.add_node(BasicBlock::new(inst.address()));
                self.block_finder.insert(inst.address(), idx);
                next_is_leader = false;
            }
            if inst.is_block_terminator() {
                if let Some(target_addr) = inst.target_address() {
                    if !self.block_finder.contains_key(&target_addr) &&
                       target_addr >= start_addr && target_addr <= end_addr {
                        let idx = self.graph.add_node(BasicBlock::new(target_addr));
                        self.block_finder.insert(target_addr, idx);
                    }
                }
                // The next instruction, if any, will be the start of a new block.
                next_is_leader = true;
            }
        }
        self.entry_block = Some(*self.block_finder.get(&instructions[0].address()).unwrap());
    }

    /// Build an edge between 2 basic blocks.
    fn build_edge(&mut self,
                  current_block_idx: NodeIndex,
                  next_block_idx: NodeIndex,
                  current_inst: &Box<Instruction>) {
        if current_inst.is_local_conditional_jump() {
            // We have one edge for the jump target and one for the fallthrough.
            // We jump through some hoops here to keep the borrow checker happy.
            if let Some(target_addr) = current_inst.target_address() {
                if let Some(target_block_idx) = self.block_finder.get(&target_addr) {
                    let edge = BasicBlockEdge { edge_type: EdgeType::ConditionalTaken };
                    self.graph.add_edge(current_block_idx, *target_block_idx, edge);
                }
                let edge = BasicBlockEdge { edge_type: EdgeType::ConditionalFallthrough };
                self.graph.add_edge(current_block_idx, next_block_idx, edge);
            }
        } else if current_inst.is_local_jump() || current_inst.is_call() {
            let edge = BasicBlockEdge { edge_type: EdgeType::Unconditional };
            self.graph.add_edge(current_block_idx, next_block_idx, edge);
        } else if current_inst.is_return() {
            // Do we want to record this exit anywhere?
        }
    }

    /// Build edges after having identified the basic blocks.
    ///
    /// After the basic blocks have been identified, we can go back and
    /// connect the basic blocks with their appropriate edges.
    ///
    /// We do this by iterating through the instructions looking for
    /// boundaries between the basic blocks and then setting up the
    /// new edges.
    fn build_edges(&mut self, instructions: &'f [Box<Instruction>]) {
        // Here, we're going to walk through the instructions again in
        // pairs of (i, Some(i + 1)):
        // [1,2..9] -> [Some(1),Some(2)..Some(9),None]
        let current_inst_iter = instructions.iter();
        let mut next_inst_iter = current_inst_iter.clone().map(Some).chain(Some(None).into_iter());
        // Skip the first one so that we're actually working with the next one.
        next_inst_iter.next();
        let mut current_block_idx = self.entry_block.unwrap();
        for ij in current_inst_iter.zip(next_inst_iter) {
            if let (current_inst, Some(next_inst)) = ij {
                // Add this instruction to the current block
                if let Some(current_block) = self.graph.node_weight_mut(current_block_idx) {
                    current_block.instructions.push(current_inst);
                }
                // Does the next instruction begin a basic block?
                let next_block_idx = *self.block_finder
                    .get(&next_inst.address())
                    .unwrap_or(&current_block_idx);
                // If we're at a block boundary, create an edge between the
                // current and next blocks. The type of the edge is determined
                // by looking at the current instruction.
                if next_block_idx != current_block_idx {
                    self.build_edge(current_block_idx, next_block_idx, current_inst);
                    current_block_idx = next_block_idx;
                }
            } else {
                // No next instruction, so we're at the end.
                // Do we want to record this exit anywhere?
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use instruction::Instruction;
    use petgraph::EdgeDirection;
    use super::CFG;
    use tests::*;

    #[test]
    fn construct() {
        let insts: Vec<Box<Instruction>> = vec![];
        let cfg = CFG::new(&insts);
        assert!(cfg.entry_block.is_none());
        assert_eq!(cfg.graph.node_count(), 0);
    }

    #[test]
    fn build_one_basic_block() {
        let insts: Vec<Box<Instruction>> = vec![
            TestInstruction::new(0, Opcode::Add),
            TestInstruction::new(1, Opcode::Add),
            TestInstruction::new(2, Opcode::Ret),
        ];
        let cfg = CFG::new(&insts);
        assert!(cfg.entry_block.is_some());
        assert_eq!(cfg.graph.node_count(), 1);

        let inbound = cfg.graph.externals(EdgeDirection::Incoming);
        assert_eq!(inbound.count(), 1);

        let outbound = cfg.graph.externals(EdgeDirection::Outgoing);
        assert_eq!(outbound.count(), 1);
    }
}
<|endoftext|>


<commit_before>use serde;
use serde_json as json;

#[derive(Deserialize, Debug)]
pub struct AuthResponse {
    pub session: SessionResponse
}

#[derive(Deserialize, Debug, Clone)]
pub struct SessionResponse {
    pub key: String,
    pub subscriber: i64,
    pub name: String
}

#[derive(Deserialize)]
pub struct NowPlayingResponseWrapper {
    pub nowplaying: NowPlayingResponse
}

#[derive(Deserialize, Debug)]
pub struct NowPlayingResponse {
    pub artist: CorrectableString,
    pub album: CorrectableString,
    #[serde(rename="albumArtist")]
    pub album_artist: CorrectableString,
    pub track: CorrectableString
}

#[derive(Deserialize)]
pub struct ScrobbleResponseWrapper {
    pub scrobbles: Scrobbles
}

#[derive(Deserialize)]
pub struct Scrobbles {
    pub scrobble: ScrobbleResponse
}

#[derive(Deserialize, Debug)]
pub struct ScrobbleResponse {
    pub artist: CorrectableString,
    pub album: CorrectableString,
    #[serde(rename="albumArtist")]
    pub album_artist: CorrectableString,
    pub track: CorrectableString
}

#[derive(Deserialize, Debug)]
pub struct CorrectableString {
    #[serde(deserialize_with="CorrectableString::deserialize_corrected_field")]
    pub corrected: bool,
    #[serde(rename="#text", default)]
    pub text: String
}

impl CorrectableString {

    fn deserialize_corrected_field<D>(de: D) -> Result<bool, D::Error>
        where D: serde::Deserializer
    {
        let deser_result: json::Value = try!(serde::Deserialize::deserialize(de));
        match deser_result {
            json::Value::String(ref s) if &*s == "1" => Ok(true),
            json::Value::String(ref s) if &*s == "0" => Ok(false),
            _ => Err(serde::de::Error::custom("Unexpected value")),
        }
    }

}
<commit_msg>Implement std::fmt::Display for CorrectableString<commit_after>use std::fmt;

use serde;
use serde_json as json;

#[derive(Deserialize, Debug)]
pub struct AuthResponse {
    pub session: SessionResponse
}

#[derive(Deserialize, Debug, Clone)]
pub struct SessionResponse {
    pub key: String,
    pub subscriber: i64,
    pub name: String
}

#[derive(Deserialize)]
pub struct NowPlayingResponseWrapper {
    pub nowplaying: NowPlayingResponse
}

#[derive(Deserialize, Debug)]
pub struct NowPlayingResponse {
    pub artist: CorrectableString,
    pub album: CorrectableString,
    #[serde(rename="albumArtist")]
    pub album_artist: CorrectableString,
    pub track: CorrectableString
}

#[derive(Deserialize)]
pub struct ScrobbleResponseWrapper {
    pub scrobbles: Scrobbles
}

#[derive(Deserialize)]
pub struct Scrobbles {
    pub scrobble: ScrobbleResponse
}

#[derive(Deserialize, Debug)]
pub struct ScrobbleResponse {
    pub artist: CorrectableString,
    pub album: CorrectableString,
    #[serde(rename="albumArtist")]
    pub album_artist: CorrectableString,
    pub track: CorrectableString
}

#[derive(Deserialize, Debug)]
pub struct CorrectableString {
    #[serde(deserialize_with="CorrectableString::deserialize_corrected_field")]
    pub corrected: bool,
    #[serde(rename="#text", default)]
    pub text: String
}

impl CorrectableString {

    fn deserialize_corrected_field<D>(de: D) -> Result<bool, D::Error>
        where D: serde::Deserializer
    {
        let deser_result: json::Value = try!(serde::Deserialize::deserialize(de));
        match deser_result {
            json::Value::String(ref s) if &*s == "1" => Ok(true),
            json::Value::String(ref s) if &*s == "0" => Ok(false),
            _ => Err(serde::de::Error::custom("Unexpected value")),
        }
    }

}

impl fmt::Display for CorrectableString {

    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.text)
    }

}<|endoftext|>


<commit_before>use atom::*;
use symbol;
use errors::*;
use std::fmt;
use std::rc::Rc;
use std::cell::RefCell;

#[derive (Debug, Clone, PartialEq)]
struct Entry {
    key: symbol::InternedStr,
    value: Atom,
}

impl fmt::Display for Entry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} => {}", self.key, self.value)
    }
}

#[derive(Debug,PartialEq)]
struct EnvGeneration {
    value: Vec<Entry>,
    parent: Option<Env>,
}

impl fmt::Display for EnvGeneration {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "EnvGeneration[{:p}]", self));
        for i in &self.value {
            try!(write!(f, "\t{}", i));
        }
        Ok(())
    }
}

impl EnvGeneration {
    fn new(parent: Option<Env>) -> EnvGeneration {
        EnvGeneration {
            value: Vec::new(),
            parent: parent,
        }
    }

    fn find(&self, key: &str) -> Option<&Entry> {
        self.value.iter().rev().find(|entry| entry.key.as_ref() == key)
    }
}

#[derive (Debug, Clone, PartialEq)]
pub struct Env(Rc<RefCell<EnvGeneration>>);

impl Default for Env {
    fn default() -> Env {
        Env::new(None)
    }
}

impl fmt::Display for Env {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let gen = self.0.borrow();
        try!(write!(f, "Top-level: EnvGeneration: {}\n", *gen));

        if let Some(ref parent) = gen.parent {
            try!(write!(f, "parent: {}\n", parent));
        } else {
            try!(write!(f, "no parent\n"));
        }
        Ok(())
    }
}

impl Env {
    pub fn new(parent: Option<Env>) -> Env {
        Env(Rc::new(RefCell::new(EnvGeneration::new(parent))))
    }

    fn find(&self, key: &str) -> Option<Atom> {
        let gen = self.0.borrow();
        let value = &gen.value;
        match value.iter().rev().find(|entry| entry.key.as_ref() == key) {
            Some(ref entry) => Some(entry.value.clone()),
            None => {
                if let Some(ref parent) = gen.parent {
                    parent.find(key)
                } else {
                    None
                }
            }
        }
    }

    pub fn num_generations(&self) -> usize {
        self.num_gen(1)
    }

    fn num_gen(&self, c: usize) -> usize {
        let gen = self.0.borrow();
        if let Some(ref parent) = gen.parent {
            return parent.num_gen(c + 1)
        }
        else {
            c
        }
    }

    pub fn generation_size(&self) -> usize {
        self.0.borrow().value.len()
    }

    pub fn bind_mut(&mut self, params: &[Atom], args: &[Atom]) {
        let mut params_iter = params.iter();
        let mut args_iter = args.iter();
        while let Some(&Atom::Symbol(ref sym)) = params_iter.next() {
            if sym.as_ref() == "&" {
                if let Some(&Atom::Symbol(ref splat)) = params_iter.next() {
                    let vals = args_iter.cloned().collect();
                    self.0.borrow_mut().value.push(Entry {
                        key: *splat,
                        value: Atom::list(vals),
                    });
                    break;
                }
            } else {
                let arg = args_iter.next().cloned().unwrap_or(Atom::Nil);

                {
                    // tricking the borrow checker here
                    let mut gen = self.0.borrow_mut();

                    if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == *sym) {
                        entry.value = arg;
                        continue;
                    }
                }

                self.0.borrow_mut().value.push(Entry {
                    key: *sym,
                    value: arg,
                });
            }
        }
    }

    pub fn bind(&mut self, params: &[Atom], args: &[Atom]) -> Env {
        let mut arg_map = Vec::with_capacity(params.len());
        let mut params_iter = params.iter();
        let mut args_iter = args.iter();

        while let Some(&Atom::Symbol(ref sym)) = params_iter.next() {
            if sym.as_ref() == "&" {
                if let Some(&Atom::Symbol(ref splat)) = params_iter.next() {
                    let vals = args_iter.cloned().collect();
                    arg_map.push(Entry {
                        key: *splat,
                        value: Atom::list(vals),
                    });
                    break;
                }
            } else {
                let arg = args_iter.next().cloned().unwrap_or(Atom::Nil);

                self.0.borrow_mut().value.push(Entry {
                    key: *sym,
                    value: arg,
                });
            }
        }

        let env_gen = EnvGeneration {
            value: arg_map,
            parent: Some(self.clone()),
        };
        Env(Rc::new(RefCell::new(env_gen)))
    }

    pub fn get(&self, key: &str) -> Option<Atom> {
        self.find(key)
    }

    pub fn define(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        if let Some(_) = self.0.borrow().find(key.as_ref()) {
            // println!("env is: {}", self);
            return Err(invalid_arg(&format!("define has entry already: {}", key.as_ref())));
        }
        self.0.borrow_mut().value.push(Entry {
            key: key,
            value: value,
        });
        Ok(Atom::Symbol(key))
    }

    pub fn set(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        {
            // set in current generation
            let mut gen = self.0.borrow_mut();
            if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == key) {
                entry.value = value;
                return Ok(Atom::Symbol(key));
            }
        }

        if let Some(ref mut parent) = self.0.borrow_mut().parent {
            parent.set(key, value)
        } else {
            Err(invalid_arg("in set"))
        }
    }
}

#[cfg(test)]
mod tests {
    use self::super::*;
    use atom::*;
    use errors::*;
    use symbol::*;

    #[test]
    fn nested_get() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::String("bar".to_owned())).unwrap();

        let env2 = Env::new(Some(env.clone()));

        assert_eq!(Atom::String("bar".to_owned()),
                   env2.get(intern("foo").as_ref()).unwrap());
    }

    #[test]
    fn splat() {
        let mut env = Env::new(None);

        let params = vec![Atom::symbol("&"), Atom::symbol("body")];

        let e = env.bind(&params, &vec![Atom::from(0), Atom::from(1), Atom::from(2)]);

        let body = e.get("body").unwrap();

        assert_eq!(Atom::list(vec![Atom::from(0), Atom::from(1), Atom::from(2)]),
                   body);
    }

    #[test]
    fn define() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::string("bar")).unwrap();

        if let Err(Error::InvalidArguments(_)) = env.set(intern("bar"), Atom::string("foo")) {
            assert!(true);
        } else {
            assert!(false);
        }

        let mut env2 = Env::new(Some(env.clone()));

        env2.set(intern("foo"), Atom::parse("0")).unwrap();

        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env2.get("foo").unwrap());

        env2.define(intern("foo"), Atom::string("baz")).unwrap();

        assert_eq!(Atom::string("baz"), env2.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
    }

    #[test]
    fn bind_mut() {
        let mut env = Env::default();
        let args = vec![Atom::from(0), Atom::from(1)];
        let params = vec![Atom::symbol("a"), Atom::symbol("b")];
        env.bind_mut(&params, &args);

        assert_eq!(env.get("a").unwrap(), Atom::from(0));
        assert_eq!(env.get("b").unwrap(), Atom::from(1));

        env.bind_mut(&params, &vec![Atom::from(2), Atom::from(42)]);

        assert_eq!(env.get("a").unwrap(), Atom::from(2));
        assert_eq!(env.get("b").unwrap(), Atom::from(42));

        assert_eq!(2, env.generation_size());
    }

}
<commit_msg>dont need a function for this<commit_after>use atom::*;
use symbol;
use errors::*;
use std::fmt;
use std::rc::Rc;
use std::cell::RefCell;

#[derive (Debug, Clone, PartialEq)]
struct Entry {
    key: symbol::InternedStr,
    value: Atom,
}

impl fmt::Display for Entry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} => {}", self.key, self.value)
    }
}

#[derive(Debug,PartialEq)]
struct EnvGeneration {
    value: Vec<Entry>,
    parent: Option<Env>,
}

impl fmt::Display for EnvGeneration {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "EnvGeneration[{:p}]", self));
        for i in &self.value {
            try!(write!(f, "\t{}", i));
        }
        Ok(())
    }
}

impl EnvGeneration {
    fn new(parent: Option<Env>) -> EnvGeneration {
        EnvGeneration {
            value: Vec::new(),
            parent: parent,
        }
    }

    fn find(&self, key: &str) -> Option<&Entry> {
        self.value.iter().rev().find(|entry| entry.key.as_ref() == key)
    }
}

#[derive (Debug, Clone, PartialEq)]
pub struct Env(Rc<RefCell<EnvGeneration>>);

impl Default for Env {
    fn default() -> Env {
        Env::new(None)
    }
}

impl fmt::Display for Env {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let gen = self.0.borrow();
        try!(write!(f, "Top-level: EnvGeneration: {}\n", *gen));

        if let Some(ref parent) = gen.parent {
            try!(write!(f, "parent: {}\n", parent));
        } else {
            try!(write!(f, "no parent\n"));
        }
        Ok(())
    }
}

impl Env {
    pub fn new(parent: Option<Env>) -> Env {
        Env(Rc::new(RefCell::new(EnvGeneration::new(parent))))
    }

    fn find(&self, key: &str) -> Option<Atom> {
        let gen = self.0.borrow();
        let value = &gen.value;
        match value.iter().rev().find(|entry| entry.key.as_ref() == key) {
            Some(ref entry) => Some(entry.value.clone()),
            None => {
                if let Some(ref parent) = gen.parent {
                    parent.find(key)
                } else {
                    None
                }
            }
        }
    }

    #[allow(dead_code)]
    pub fn num_generations(&self) -> usize {
        self.num_gen(1)
    }

    fn num_gen(&self, c: usize) -> usize {
        let gen = self.0.borrow();
        if let Some(ref parent) = gen.parent {
            return parent.num_gen(c + 1)
        }
        else {
            c
        }
    }

    pub fn bind_mut(&mut self, params: &[Atom], args: &[Atom]) {
        let mut params_iter = params.iter();
        let mut args_iter = args.iter();
        while let Some(&Atom::Symbol(ref sym)) = params_iter.next() {
            if sym.as_ref() == "&" {
                if let Some(&Atom::Symbol(ref splat)) = params_iter.next() {
                    let vals = args_iter.cloned().collect();
                    self.0.borrow_mut().value.push(Entry {
                        key: *splat,
                        value: Atom::list(vals),
                    });
                    break;
                }
            } else {
                let arg = args_iter.next().cloned().unwrap_or(Atom::Nil);

                {
                    // tricking the borrow checker here
                    let mut gen = self.0.borrow_mut();

                    if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == *sym) {
                        entry.value = arg;
                        continue;
                    }
                }

                self.0.borrow_mut().value.push(Entry {
                    key: *sym,
                    value: arg,
                });
            }
        }
    }

    pub fn bind(&mut self, params: &[Atom], args: &[Atom]) -> Env {
        let mut arg_map = Vec::with_capacity(params.len());
        let mut params_iter = params.iter();
        let mut args_iter = args.iter();

        while let Some(&Atom::Symbol(ref sym)) = params_iter.next() {
            if sym.as_ref() == "&" {
                if let Some(&Atom::Symbol(ref splat)) = params_iter.next() {
                    let vals = args_iter.cloned().collect();
                    arg_map.push(Entry {
                        key: *splat,
                        value: Atom::list(vals),
                    });
                    break;
                }
            } else {
                let arg = args_iter.next().cloned().unwrap_or(Atom::Nil);

                self.0.borrow_mut().value.push(Entry {
                    key: *sym,
                    value: arg,
                });
            }
        }

        let env_gen = EnvGeneration {
            value: arg_map,
            parent: Some(self.clone()),
        };
        Env(Rc::new(RefCell::new(env_gen)))
    }

    pub fn get(&self, key: &str) -> Option<Atom> {
        self.find(key)
    }

    pub fn define(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        if let Some(_) = self.0.borrow().find(key.as_ref()) {
            // println!("env is: {}", self);
            return Err(invalid_arg(&format!("define has entry already: {}", key.as_ref())));
        }
        self.0.borrow_mut().value.push(Entry {
            key: key,
            value: value,
        });
        Ok(Atom::Symbol(key))
    }

    pub fn set(&mut self, key: symbol::InternedStr, value: Atom) -> Result<Atom, Error> {
        {
            // set in current generation
            let mut gen = self.0.borrow_mut();
            if let Some(mut entry) = gen.value.iter_mut().find(|entry| entry.key == key) {
                entry.value = value;
                return Ok(Atom::Symbol(key));
            }
        }

        if let Some(ref mut parent) = self.0.borrow_mut().parent {
            parent.set(key, value)
        } else {
            Err(invalid_arg("in set"))
        }
    }
}

#[cfg(test)]
mod tests {
    use self::super::*;
    use atom::*;
    use errors::*;
    use symbol::*;

    #[test]
    fn nested_get() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::String("bar".to_owned())).unwrap();

        let env2 = Env::new(Some(env.clone()));

        assert_eq!(Atom::String("bar".to_owned()),
                   env2.get(intern("foo").as_ref()).unwrap());
    }

    #[test]
    fn splat() {
        let mut env = Env::new(None);

        let params = vec![Atom::symbol("&"), Atom::symbol("body")];

        let e = env.bind(&params, &vec![Atom::from(0), Atom::from(1), Atom::from(2)]);

        let body = e.get("body").unwrap();

        assert_eq!(Atom::list(vec![Atom::from(0), Atom::from(1), Atom::from(2)]),
                   body);
    }

    #[test]
    fn define() {
        let mut env = Env::new(None);

        env.define(intern("foo"), Atom::string("bar")).unwrap();

        if let Err(Error::InvalidArguments(_)) = env.set(intern("bar"), Atom::string("foo")) {
            assert!(true);
        } else {
            assert!(false);
        }

        let mut env2 = Env::new(Some(env.clone()));

        env2.set(intern("foo"), Atom::parse("0")).unwrap();

        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env2.get("foo").unwrap());

        env2.define(intern("foo"), Atom::string("baz")).unwrap();

        assert_eq!(Atom::string("baz"), env2.get("foo").unwrap());
        assert_eq!(Atom::parse("0"), env.get("foo").unwrap());
    }

    #[test]
    fn bind_mut() {
        let mut env = Env::default();
        let args = vec![Atom::from(0), Atom::from(1)];
        let params = vec![Atom::symbol("a"), Atom::symbol("b")];
        env.bind_mut(&params, &args);

        assert_eq!(env.get("a").unwrap(), Atom::from(0));
        assert_eq!(env.get("b").unwrap(), Atom::from(1));

        env.bind_mut(&params, &vec![Atom::from(2), Atom::from(42)]);

        assert_eq!(env.get("a").unwrap(), Atom::from(2));
        assert_eq!(env.get("b").unwrap(), Atom::from(42));

        assert_eq!(2, env.0.borrow().value.len());
    }

}
<|endoftext|>


<commit_before>use std::{io, vec};
use std::net::IpAddr;
use std::sync::{Arc, Mutex, Once};

use futures::{future, Future};
use hyper::client::connect::dns as hyper_dns;
use tokio;
use trust_dns_resolver::{system_conf, AsyncResolver, BackgroundLookupIp};

// If instead the type were just `AsyncResolver`, it breaks the default recursion limit
// for the compiler to determine if `reqwest::Client` is `Send`. This is because `AsyncResolver`
// has **a lot** of internal generic types that pushes us over the limit.
//
// "Erasing" the internal resolver type saves us from this limit.
type ErasedResolver = Box<dyn Fn(hyper_dns::Name) -> BackgroundLookupIp + Send + Sync>;
type Background = Box<dyn Future<Item=(), Error=()> + Send>;

#[derive(Clone)]
pub(crate) struct TrustDnsResolver {
    inner: Arc<Inner>,
}

struct Inner {
    background: Mutex<Option<Background>>,
    once: Once,
    resolver: ErasedResolver,
}

impl TrustDnsResolver {
    pub(crate) fn new() -> io::Result<Self> {
        let (conf, opts) = system_conf::read_system_conf()?;
        let (resolver, bg) = AsyncResolver::new(conf, opts);

        let resolver: ErasedResolver = Box::new(move |name| {
            resolver.lookup_ip(name.as_str())
        });
        let background = Mutex::new(Some(Box::new(bg) as Background));
        let once = Once::new();

        Ok(TrustDnsResolver {
            inner: Arc::new(Inner {
                background,
                once,
                resolver,
            }),
        })
    }
}

impl hyper_dns::Resolve for TrustDnsResolver {
    type Addrs = vec::IntoIter<IpAddr>;
    type Future = Box<Future<Item=Self::Addrs, Error=io::Error> + Send>;

    fn resolve(&self, name: hyper_dns::Name) -> Self::Future {
        let inner = self.inner.clone();
        Box::new(future::lazy(move || {
            inner.once.call_once(|| {
                // The `bg` (background) future needs to be spawned onto an executor,
                // but a `reqwest::Client` may be constructed before an executor is ready.
                // So, the `bg` future cannot be spawned *until* the executor starts to
                // `poll` this future.
                let bg = inner
                    .background
                    .lock()
                    .expect("resolver background lock")
                    .take()
                    .expect("background only taken once");

                tokio::spawn(bg);
            });

            (inner.resolver)(name)
                .map(|lookup| {
                    lookup
                        .iter()
                        .collect::<Vec<_>>()
                        .into_iter()
                })
                .map_err(|err| {
                    io::Error::new(io::ErrorKind::Other, err.to_string())
                })
        }))
    }
}

<commit_msg>fix bare trait object lint in dns module<commit_after>use std::{io, vec};
use std::net::IpAddr;
use std::sync::{Arc, Mutex, Once};

use futures::{future, Future};
use hyper::client::connect::dns as hyper_dns;
use tokio;
use trust_dns_resolver::{system_conf, AsyncResolver, BackgroundLookupIp};

// If instead the type were just `AsyncResolver`, it breaks the default recursion limit
// for the compiler to determine if `reqwest::Client` is `Send`. This is because `AsyncResolver`
// has **a lot** of internal generic types that pushes us over the limit.
//
// "Erasing" the internal resolver type saves us from this limit.
type ErasedResolver = Box<dyn Fn(hyper_dns::Name) -> BackgroundLookupIp + Send + Sync>;
type Background = Box<dyn Future<Item=(), Error=()> + Send>;

#[derive(Clone)]
pub(crate) struct TrustDnsResolver {
    inner: Arc<Inner>,
}

struct Inner {
    background: Mutex<Option<Background>>,
    once: Once,
    resolver: ErasedResolver,
}

impl TrustDnsResolver {
    pub(crate) fn new() -> io::Result<Self> {
        let (conf, opts) = system_conf::read_system_conf()?;
        let (resolver, bg) = AsyncResolver::new(conf, opts);

        let resolver: ErasedResolver = Box::new(move |name| {
            resolver.lookup_ip(name.as_str())
        });
        let background = Mutex::new(Some(Box::new(bg) as Background));
        let once = Once::new();

        Ok(TrustDnsResolver {
            inner: Arc::new(Inner {
                background,
                once,
                resolver,
            }),
        })
    }
}

impl hyper_dns::Resolve for TrustDnsResolver {
    type Addrs = vec::IntoIter<IpAddr>;
    type Future = Box<dyn Future<Item=Self::Addrs, Error=io::Error> + Send>;

    fn resolve(&self, name: hyper_dns::Name) -> Self::Future {
        let inner = self.inner.clone();
        Box::new(future::lazy(move || {
            inner.once.call_once(|| {
                // The `bg` (background) future needs to be spawned onto an executor,
                // but a `reqwest::Client` may be constructed before an executor is ready.
                // So, the `bg` future cannot be spawned *until* the executor starts to
                // `poll` this future.
                let bg = inner
                    .background
                    .lock()
                    .expect("resolver background lock")
                    .take()
                    .expect("background only taken once");

                tokio::spawn(bg);
            });

            (inner.resolver)(name)
                .map(|lookup| {
                    lookup
                        .iter()
                        .collect::<Vec<_>>()
                        .into_iter()
                })
                .map_err(|err| {
                    io::Error::new(io::ErrorKind::Other, err.to_string())
                })
        }))
    }
}

<|endoftext|>


<commit_before>//! DNS Resolution

use std::io::{stderr, Write};
use std::time::Duration;

use async_std::io;
use async_std::net::{SocketAddr, ToSocketAddrs};
use log::Level::Info;

use super::results::{CabotError, CabotResult};

pub struct Resolver {
    verbose: bool,
}

impl Resolver {
    pub fn new(verbose: bool) -> Self {
        Resolver { verbose }
    }
    pub async fn get_addr(
        &self,
        authority: &str,
        ipv4: bool,
        ipv6: bool,
        dns_timeout: u64,
    ) -> CabotResult<SocketAddr> {
        debug!("Resolving TCP Endpoint for authority {}", authority);

        let addrs = io::timeout(Duration::from_millis(dns_timeout), async {
            authority.to_socket_addrs().await
        })
        .await?;

        let addr = addrs
            .filter(|addr| (ipv4 && addr.is_ipv4()) || (ipv6 && addr.is_ipv6()))
            .next()
            .ok_or(CabotError::DNSLookupError(
                "Host does not exists".to_owned(),
            ))?;
        if log_enabled!(Info) {
            info!("Authority {} has been resolved to {}", authority, addr);
        } else if self.verbose {
            writeln!(
                &mut stderr(),
                "* Authority {} has been resolved to {}",
                authority,
                addr
            )
            .unwrap();
        }
        Ok(addr)
    }
}
<commit_msg>Improve error message on dns timeout<commit_after>//! DNS Resolution

use std::io::{stderr, Write};
use std::time::Duration;

use async_std::io;
use async_std::net::{SocketAddr, ToSocketAddrs};
use log::Level::Info;

use super::results::{CabotError, CabotResult};

pub struct Resolver {
    verbose: bool,
}

impl Resolver {
    pub fn new(verbose: bool) -> Self {
        Resolver { verbose }
    }
    pub async fn get_addr(
        &self,
        authority: &str,
        ipv4: bool,
        ipv6: bool,
        dns_timeout: u64,
    ) -> CabotResult<SocketAddr> {
        debug!("Resolving TCP Endpoint for authority {}", authority);

        let addrs = io::timeout(Duration::from_millis(dns_timeout), async {
            authority.to_socket_addrs().await
        })
        .await
        .map_err(|err| match err.kind() {
            io::ErrorKind::TimedOut => CabotError::DNSLookupError("Timeout".to_owned()),
            io::ErrorKind::Other => CabotError::DNSLookupError("Host does not exists".to_owned()),
            _ => CabotError::DNSLookupError(format!("{}", err)),
        })?;

        let addr = addrs
            .filter(|addr| (ipv4 && addr.is_ipv4()) || (ipv6 && addr.is_ipv6()))
            .next()
            .ok_or(CabotError::DNSLookupError(
                "No IP found for this host".to_owned(),
            ))?;
        if log_enabled!(Info) {
            info!("Authority {} has been resolved to {}", authority, addr);
        } else if self.verbose {
            writeln!(
                &mut stderr(),
                "* Authority {} has been resolved to {}",
                authority,
                addr
            )
            .unwrap();
        }
        Ok(addr)
    }
}
<|endoftext|>


<commit_before>use client;
use interface;

fn help(event: &interface::CommandEvent) {
    let plugins = event.client.plugins.read();
    let commands = plugins.commands.keys().collect::<Vec<&String>>().connect(", ");
    event.client.send_message(event.channel, format!("Available commands: {}", commands).as_slice());
    event.client.send_message(event.channel, format!("Use a command with `{}command_name` or `{}, command_name`", event.client.config.command_prefix, event.client.state.read().nick).as_slice());
}

pub fn register(register: &mut client::PluginRegister) {
    register.register_command("help", help);
}
<commit_msg>Simplify statement a bit, because it's redundant to specify config, as client already dereferences to config.<commit_after>use client;
use interface;

fn help(event: &interface::CommandEvent) {
    let plugins = event.client.plugins.read();
    let commands = plugins.commands.keys().collect::<Vec<&String>>().connect(", ");
    event.client.send_message(event.channel, format!("Available commands: {}", commands).as_slice());
    event.client.send_message(event.channel, format!("Use a command with `{}command_name` or `{}, command_name`", event.client.command_prefix, event.client.state.read().nick).as_slice());
}

pub fn register(register: &mut client::PluginRegister) {
    register.register_command("help", help);
}
<|endoftext|>


<commit_before>use future::{Future, IntoFuture};
use stream::Stream;
use poll::Poll;
use Async;
use stack::{Stack, Drain};
use task::NotifyContext;

use std::prelude::v1::*;

/// An adaptor for a stream of futures to execute the futures concurrently, if
/// possible, delivering results as they become available.
///
/// This adaptor will return their results in the order that they complete.
/// This is created by the `futures` method.
///
#[derive(Debug)]
#[must_use = "streams do nothing unless polled"]
pub struct FuturesUnordered<F>
    where F: Future
{
    futures: Vec<Option<F>>,
    stack: NotifyContext<Stack<usize>>,
    pending: Option<Drain<usize>>,
    active: usize,
}

/// Converts a list of futures into a `Stream` of results from the futures.
///
/// This function will take an list of futures (e.g. a vector, an iterator,
/// etc), and return a stream. The stream will yield items as they become
/// available on the futures internally, in the order that they become
/// available. This function is similar to `buffer_unordered` in that it may
/// return items in a different order than in the list specified.
pub fn futures_unordered<I>(futures: I) -> FuturesUnordered<<I::Item as IntoFuture>::Future>
    where I: IntoIterator,
          I::Item: IntoFuture
{
    let futures = futures.into_iter()
                         .map(IntoFuture::into_future)
                         .map(Some)
                         .collect::<Vec<_>>();
    let stack = NotifyContext::new(Stack::new());
    for i in 0..futures.len() {
        stack.get_ref().push(i);
    }
    FuturesUnordered {
        active: futures.len(),
        futures: futures,
        pending: None,
        stack: stack,
    }
}

impl<F> FuturesUnordered<F>
    where F: Future
{
    fn poll_pending(&mut self, mut drain: Drain<usize>)
                    -> Option<Poll<Option<F::Item>, F::Error>> {
        while let Some(id) = drain.next() {
            // If this future was already done just skip the notification
            if self.futures[id].is_none() {
                continue
            }

            let res = {
                let f = &mut self.futures[id];
                self.stack.with(id as u64, || {
                    f.as_mut()
                        .unwrap()
                        .poll()
                })
            };

            let ret = match res {
                Ok(Async::NotReady) => continue,
                Ok(Async::Ready(val)) => Ok(Async::Ready(Some(val))),
                Err(e) => Err(e),
            };
            self.pending = Some(drain);
            self.active -= 1;
            self.futures[id] = None;
            return Some(ret)
        }
        None
    }
}

impl<F> Stream for FuturesUnordered<F>
    where F: Future
{
    type Item = F::Item;
    type Error = F::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        if self.active == 0 {
            return Ok(Async::Ready(None))
        }
        if let Some(drain) = self.pending.take() {
            if let Some(ret) = self.poll_pending(drain) {
                return ret
            }
        }
        let drain = self.stack.get_ref().drain();
        if let Some(ret) = self.poll_pending(drain) {
            return ret
        }
        assert!(self.active > 0);
        Ok(Async::NotReady)
    }
}
<commit_msg>Switch FuturesUnordered to use ReadyQueue<commit_after>use future::{Future, IntoFuture, ReadyQueue};
use stream::Stream;
use poll::Poll;

use std::prelude::v1::*;

/// An adaptor for a stream of futures to execute the futures concurrently, if
/// possible, delivering results as they become available.
///
/// This adaptor will return their results in the order that they complete.
/// This is created by the `futures` method.
///
#[derive(Debug)]
#[must_use = "streams do nothing unless polled"]
pub struct FuturesUnordered<F>
    where F: Future
{
    queue: ReadyQueue<F>,
}

/// Converts a list of futures into a `Stream` of results from the futures.
///
/// This function will take an list of futures (e.g. a vector, an iterator,
/// etc), and return a stream. The stream will yield items as they become
/// available on the futures internally, in the order that they become
/// available. This function is similar to `buffer_unordered` in that it may
/// return items in a different order than in the list specified.
pub fn futures_unordered<I>(futures: I) -> FuturesUnordered<<I::Item as IntoFuture>::Future>
    where I: IntoIterator,
          I::Item: IntoFuture
{
    let mut queue = ReadyQueue::new();

    for future in futures {
        queue.push(future.into_future());
    }

    FuturesUnordered { queue: queue }
}

impl<F> Stream for FuturesUnordered<F>
    where F: Future
{
    type Item = F::Item;
    type Error = F::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        self.queue.poll()
    }
}
<|endoftext|>