<commit_before>use super::*;
use crate::backend::Backend;
use crate::dsl::Or;
use crate::expression::operators::And;
use crate::expression::*;
use crate::expression_methods::*;
use crate::result::QueryResult;
use crate::sql_types::Bool;

/// Add `Predicate` to the current `WHERE` clause, joining with `AND` if
/// applicable.
pub trait WhereAnd<Predicate> {
    /// What is the type of the resulting `WHERE` clause?
    type Output;

    /// See the trait-level docs.
    fn and(self, predicate: Predicate) -> Self::Output;
}

/// Add `Predicate` to the current `WHERE` clause, joining with `OR` if
/// applicable.
pub trait WhereOr<Predicate> {
    /// What is the type of the resulting `WHERE` clause?
    type Output;

    /// See the trait-level docs.
    fn or(self, predicate: Predicate) -> Self::Output;
}

/// Represents that a query has no `WHERE` clause.
#[derive(Debug, Clone, Copy, QueryId)]
pub struct NoWhereClause;

impl<DB: Backend> QueryFragment<DB> for NoWhereClause {
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Predicate> WhereAnd<Predicate> for NoWhereClause
where
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Predicate>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(predicate)
    }
}

impl<Predicate> WhereOr<Predicate> for NoWhereClause
where
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Predicate>;

    fn or(self, predicate: Predicate) -> Self::Output {
        WhereClause(predicate)
    }
}

impl<DB> Into<BoxedWhereClause<'static, DB>> for NoWhereClause {
    fn into(self) -> BoxedWhereClause<'static, DB> {
        BoxedWhereClause::None
    }
}

/// The `WHERE` clause of a query.
#[derive(Debug, Clone, Copy, QueryId)]
pub struct WhereClause<Expr>(Expr);

impl<DB, Expr> QueryFragment<DB> for WhereClause<Expr>
where
    DB: Backend,
    Expr: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" WHERE ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Expr, Predicate> WhereAnd<Predicate> for WhereClause<Expr>
where
    Expr: Expression<SqlType = Bool>,
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<And<Expr, Predicate>>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(self.0.and(predicate))
    }
}

impl<Expr, Predicate> WhereOr<Predicate> for WhereClause<Expr>
where
    Expr: Expression<SqlType = Bool>,
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Or<Expr, Predicate>>;

    fn or(self, predicate: Predicate) -> Self::Output {
        WhereClause(self.0.or(predicate))
    }
}

impl<'a, DB, Predicate> Into<BoxedWhereClause<'a, DB>> for WhereClause<Predicate>
where
    DB: Backend,
    Predicate: QueryFragment<DB> + 'a,
{
    fn into(self) -> BoxedWhereClause<'a, DB> {
        BoxedWhereClause::Where(Box::new(self.0))
    }
}

/// Marker trait indicating that a `WHERE` clause is valid for a given query
/// source.
pub trait ValidWhereClause<QS> {}

impl<QS> ValidWhereClause<QS> for NoWhereClause {}

impl<QS, Expr> ValidWhereClause<QS> for WhereClause<Expr> where Expr: AppearsOnTable<QS> {}

#[allow(missing_debug_implementations)] // We can't...
pub enum BoxedWhereClause<'a, DB> {
    Where(Box<dyn QueryFragment<DB> + 'a>),
    None,
}

impl<'a, DB> QueryFragment<DB> for BoxedWhereClause<'a, DB>
where
    DB: Backend,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        match *self {
            BoxedWhereClause::Where(ref where_clause) => {
                out.push_sql(" WHERE ");
                where_clause.walk_ast(out)
            }
            BoxedWhereClause::None => Ok(()),
        }
    }
}

impl<'a, DB> QueryId for BoxedWhereClause<'a, DB> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<'a, DB, Predicate> WhereAnd<Predicate> for BoxedWhereClause<'a, DB>
where
    DB: Backend + 'a,
    Predicate: QueryFragment<DB> + 'a,
{
    type Output = Self;

    fn and(self, predicate: Predicate) -> Self::Output {
        use self::BoxedWhereClause::Where;

        match self {
            Where(where_clause) => Where(Box::new(And::new(where_clause, predicate))),
            BoxedWhereClause::None => Where(Box::new(predicate)),
        }
    }
}

impl<'a, DB, Predicate> WhereOr<Predicate> for BoxedWhereClause<'a, DB>
where
    DB: Backend + 'a,
    Predicate: QueryFragment<DB> + 'a,
{
    type Output = Self;

    fn or(self, predicate: Predicate) -> Self::Output {
        use self::BoxedWhereClause::Where;
        use crate::expression::grouped::Grouped;
        use crate::expression::operators::Or;

        match self {
            Where(where_clause) => Where(Box::new(Grouped(Or::new(where_clause, predicate)))),
            BoxedWhereClause::None => Where(Box::new(predicate)),
        }
    }
}
<commit_msg>Generalize creating a `BoxedWhereClause`<commit_after>use super::*;
use crate::backend::Backend;
use crate::dsl::Or;
use crate::expression::operators::And;
use crate::expression::*;
use crate::expression_methods::*;
use crate::result::QueryResult;
use crate::sql_types::Bool;

/// Add `Predicate` to the current `WHERE` clause, joining with `AND` if
/// applicable.
pub trait WhereAnd<Predicate> {
    /// What is the type of the resulting `WHERE` clause?
    type Output;

    /// See the trait-level docs.
    fn and(self, predicate: Predicate) -> Self::Output;
}

/// Add `Predicate` to the current `WHERE` clause, joining with `OR` if
/// applicable.
pub trait WhereOr<Predicate> {
    /// What is the type of the resulting `WHERE` clause?
    type Output;

    /// See the trait-level docs.
    fn or(self, predicate: Predicate) -> Self::Output;
}

/// Represents that a query has no `WHERE` clause.
#[derive(Debug, Clone, Copy, QueryId)]
pub struct NoWhereClause;

impl<DB: Backend> QueryFragment<DB> for NoWhereClause {
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Predicate> WhereAnd<Predicate> for NoWhereClause
where
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Predicate>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(predicate)
    }
}

impl<Predicate> WhereOr<Predicate> for NoWhereClause
where
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Predicate>;

    fn or(self, predicate: Predicate) -> Self::Output {
        WhereClause(predicate)
    }
}

impl<'a, DB> Into<BoxedWhereClause<'a, DB>> for NoWhereClause {
    fn into(self) -> BoxedWhereClause<'a, DB> {
        BoxedWhereClause::None
    }
}

/// The `WHERE` clause of a query.
#[derive(Debug, Clone, Copy, QueryId)]
pub struct WhereClause<Expr>(Expr);

impl<DB, Expr> QueryFragment<DB> for WhereClause<Expr>
where
    DB: Backend,
    Expr: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" WHERE ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Expr, Predicate> WhereAnd<Predicate> for WhereClause<Expr>
where
    Expr: Expression<SqlType = Bool>,
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<And<Expr, Predicate>>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(self.0.and(predicate))
    }
}

impl<Expr, Predicate> WhereOr<Predicate> for WhereClause<Expr>
where
    Expr: Expression<SqlType = Bool>,
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Or<Expr, Predicate>>;

    fn or(self, predicate: Predicate) -> Self::Output {
        WhereClause(self.0.or(predicate))
    }
}

impl<'a, DB, Predicate> Into<BoxedWhereClause<'a, DB>> for WhereClause<Predicate>
where
    DB: Backend,
    Predicate: QueryFragment<DB> + 'a,
{
    fn into(self) -> BoxedWhereClause<'a, DB> {
        BoxedWhereClause::Where(Box::new(self.0))
    }
}

/// Marker trait indicating that a `WHERE` clause is valid for a given query
/// source.
pub trait ValidWhereClause<QS> {}

impl<QS> ValidWhereClause<QS> for NoWhereClause {}

impl<QS, Expr> ValidWhereClause<QS> for WhereClause<Expr> where Expr: AppearsOnTable<QS> {}

#[allow(missing_debug_implementations)] // We can't...
pub enum BoxedWhereClause<'a, DB> {
    Where(Box<dyn QueryFragment<DB> + 'a>),
    None,
}

impl<'a, DB> QueryFragment<DB> for BoxedWhereClause<'a, DB>
where
    DB: Backend,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        match *self {
            BoxedWhereClause::Where(ref where_clause) => {
                out.push_sql(" WHERE ");
                where_clause.walk_ast(out)
            }
            BoxedWhereClause::None => Ok(()),
        }
    }
}

impl<'a, DB> QueryId for BoxedWhereClause<'a, DB> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<'a, DB, Predicate> WhereAnd<Predicate> for BoxedWhereClause<'a, DB>
where
    DB: Backend + 'a,
    Predicate: QueryFragment<DB> + 'a,
{
    type Output = Self;

    fn and(self, predicate: Predicate) -> Self::Output {
        use self::BoxedWhereClause::Where;

        match self {
            Where(where_clause) => Where(Box::new(And::new(where_clause, predicate))),
            BoxedWhereClause::None => Where(Box::new(predicate)),
        }
    }
}

impl<'a, DB, Predicate> WhereOr<Predicate> for BoxedWhereClause<'a, DB>
where
    DB: Backend + 'a,
    Predicate: QueryFragment<DB> + 'a,
{
    type Output = Self;

    fn or(self, predicate: Predicate) -> Self::Output {
        use self::BoxedWhereClause::Where;
        use crate::expression::grouped::Grouped;
        use crate::expression::operators::Or;

        match self {
            Where(where_clause) => Where(Box::new(Grouped(Or::new(where_clause, predicate)))),
            BoxedWhereClause::None => Where(Box::new(predicate)),
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::{RingBuf, Deque};
use std::io::{TcpStream, IoResult, LineBufferedWriter, BufferedReader};

use message::IrcMessage;
use watchers::{
    RegisterError,
    MessageWatcher,
    RegisterMessageWatcher,
    JoinMessageWatcher,
    JoinResult
};

pub trait IrcBundleEventInterface {
    fn accept(&mut self, message: &IrcMessage) -> bool;
    fn pretty_print(&self) -> String;
}

pub struct IrcBundleJoinEvent {
    channel: String,
    nicks: Vec<String>,
    state: u16
}

impl IrcBundleJoinEvent {
    pub fn new(message: &IrcMessage) -> Option<IrcBundleJoinEvent> {
        if message.get_args().len() == 0 {
            return None;
        }
        let is_join: bool = message.get_command().as_slice() == "JOIN";
        match is_join {
            true => {
                let channel = message.get_arg(0).clone();
                Some(IrcBundleJoinEvent {
                    channel: channel,
                    nicks: Vec::new(),
                    state: 0
                })
            },
            false => None
        }
    }
}

impl IrcBundleEventInterface for IrcBundleJoinEvent {
    fn accept(&mut self, message: &IrcMessage) -> bool {
        let incr_state: bool = match self.state {
            0 => {
                // 353 contains nicks
                // 366 is ``End of /NAMES list''
                if message.get_command().as_slice() == "353" &&
                        *message.get_arg(2) == self.channel {
                    for nick in message.get_arg(3).as_slice().split(' ') {
                        self.nicks.push(String::from_str(nick));
                    }
                };
                message.get_args().len() >= 2 &&
                    message.get_command().as_slice() == "366" &&
                    *message.get_arg(1) == self.channel
            },
            _ => false
        };
        if incr_state {
            self.state += 1;
        }
        self.state == 1
    }

    fn pretty_print(&self) -> String {
        format!("IrcBundleJoinEvent({} with {} nicks)",
            self.channel.as_slice(), self.nicks.len())
    }
}

pub enum IrcEvent {
    IrcEventMessage(Box<IrcMessage>),
    IrcEventBundle(Box<IrcBundleEventInterface+Send>),
    IrcEventWatcherResponse(Box<MessageWatcher+Send>)
}

pub struct IrcConnection {
    // conn: TcpStream,
    writer: LineBufferedWriter<TcpStream>,
    event_queue: Receiver<IrcEvent>,
    watchers: SyncSender<Box<MessageWatcher+Send>>,
    has_registered: bool
}

fn watcher_accept(buf: &mut RingBuf<Box<MessageWatcher+Send>>,
                  message: &IrcMessage
                 ) -> Vec<Box<MessageWatcher+Send>> {

    let mut keep_watchers: RingBuf<Box<MessageWatcher+Send>> = RingBuf::new();
    let mut finished_watchers: Vec<Box<MessageWatcher+Send>> = Vec::new();
    loop {
        match buf.pop_front() {
            Some(mut watcher) => {
                let watcher_repr = watcher.pretty_print();
                watcher.accept(message);
                if watcher.finished() {
                    finished_watchers.push(watcher);
                } else {
                    keep_watchers.push(watcher);
                }

            },
            None => break
        }
    }
    loop {
        match keep_watchers.pop_front() {
            Some(watcher) => buf.push(watcher),
            None => break
        }
    }
    finished_watchers
}

fn bundler_accept(buf: &mut RingBuf<Box<IrcBundleEventInterface+Send>>,
                  message: &IrcMessage
                 ) -> Vec<Box<IrcBundleEventInterface+Send>> {

    let mut keep_watchers: RingBuf<Box<IrcBundleEventInterface+Send>> = RingBuf::new();
    let mut finished_watchers: Vec<Box<IrcBundleEventInterface+Send>> = Vec::new();
    loop {
        match buf.pop_front() {
            Some(mut watcher) => {
                if watcher.accept(message) {
                    finished_watchers.push(watcher);
                } else {
                    keep_watchers.push(watcher);
                }
            },
            None => break
        }
    }
    loop {
        match keep_watchers.pop_front() {
            Some(watcher) => buf.push(watcher),
            None => break
        }
    }
    finished_watchers
}

pub struct IrcRegisterRequest<'a> {
    // NICK {nick}\n
    // USER {username} {mode} * :{realname}
    nick: &'a str,
    username: &'a str,
    mode: uint,
    realname: &'a str
}

impl IrcConnection {
    pub fn new(host: &str, port: u16) -> IoResult<IrcConnection> {
        let stream = match TcpStream::connect(host, port) {
            Ok(stream) => stream,
            Err(err) => return Err(err)
        };

        let (watchers_tx, watchers_rx) = sync_channel(10);
        let (event_queue_tx, event_queue_rx) = sync_channel(1024);
        let reader = BufferedReader::new(stream.clone());

        spawn(proc() {
            let mut watchers: RingBuf<Box<MessageWatcher+Send>> = RingBuf::new();
            let mut event_bundlers: RingBuf<Box<IrcBundleEventInterface+Send>> = RingBuf::new();

            let mut reader = reader;

            loop {
                let string = String::from_str(match reader.read_line() {
                    Ok(string) => string,
                    Err(err) => fail!("{}", err)
                }.as_slice().trim_right());

                loop {
                    match watchers_rx.try_recv() {
                        Ok(value) => watchers.push(value),
                        Err(_) => break
                    };
                }

                let message = match IrcMessage::from_str(string.as_slice()) {
                    Ok(message) => message,
                    Err(err) => {
                        println!("Invalid IRC message: {} for {}", err, string);
                        continue;
                    }
                };

                match IrcBundleJoinEvent::new(&message) {
                    Some(bundler) => event_bundlers.push(box bundler),
                    None => ()
                }

                for resp in watcher_accept(&mut watchers, &message).move_iter() {
                    event_queue_tx.send(IrcEventWatcherResponse(resp));
                }

                for resp in bundler_accept(&mut event_bundlers, &message).move_iter() {
                    event_queue_tx.send(IrcEventBundle(resp));
                }

                event_queue_tx.send(IrcEventMessage(box message));
            }
        });

        Ok(IrcConnection {
            // conn: stream.clone(),
            writer: LineBufferedWriter::new(stream.clone()),
            event_queue: event_queue_rx,
            watchers: watchers_tx,
            has_registered: false
        })
    }

    pub fn register(&mut self, nick: &str) -> Result<(), RegisterError> {
        let mut reg_watcher = RegisterMessageWatcher::new();
        let result_rx = reg_watcher.get_monitor();
        let watcher: Box<MessageWatcher+Send> = box reg_watcher;
        self.watchers.send(watcher);

        match self.writer.write_str(format!("NICK {}\n", nick).as_slice()) {
            Ok(_) => (),
            Err(err) => fail!("Error writing to IRC server: {}", err)
        };

        if !self.has_registered {
            match self.writer.write_str("USER rustbot 8 *: Rust Bot\n") {
                Ok(_) => (),
                Err(err) => fail!("Error writing to IRC server: {}", err)
            };
        }

        result_rx.recv()
    }
    // RX: IrcMessage(miyuki.yasashiisyndicate.org, 475, [
    //    aibi`, #dicks, Cannot join channel (Incorrect channel key), ])

    pub fn join(&mut self, channel: &str) -> JoinResult {
        let mut join_watcher = JoinMessageWatcher::new(channel);
        let result_rx = join_watcher.get_monitor();
        let watcher: Box<MessageWatcher+Send> = box join_watcher;
        self.watchers.send(watcher);

        match self.writer.write_str(format!("JOIN {}\n", channel).as_slice()) {
            Ok(_) => (),
            Err(err) => fail!("Error writing to IRC server: {}", err)
        }

        result_rx.recv()
    }

    pub fn recv(&self) -> IrcEvent {
        self.event_queue.recv()
    }

    pub fn write_str(&mut self, content: &str) -> IoResult<()> {
        self.writer.write_str(content)
    }
}
<commit_msg>Connections QUIT when they are Dropped<commit_after>use std::collections::{RingBuf, Deque};
use std::io::{TcpStream, IoResult, LineBufferedWriter, BufferedReader};

use message::IrcMessage;
use watchers::{
    RegisterError,
    MessageWatcher,
    RegisterMessageWatcher,
    JoinMessageWatcher,
    JoinResult
};

pub trait IrcBundleEventInterface {
    fn accept(&mut self, message: &IrcMessage) -> bool;
    fn pretty_print(&self) -> String;
}

pub struct IrcBundleJoinEvent {
    channel: String,
    nicks: Vec<String>,
    state: u16
}

impl IrcBundleJoinEvent {
    pub fn new(message: &IrcMessage) -> Option<IrcBundleJoinEvent> {
        if message.get_args().len() == 0 {
            return None;
        }
        let is_join: bool = message.get_command().as_slice() == "JOIN";
        match is_join {
            true => {
                let channel = message.get_arg(0).clone();
                Some(IrcBundleJoinEvent {
                    channel: channel,
                    nicks: Vec::new(),
                    state: 0
                })
            },
            false => None
        }
    }
}

impl IrcBundleEventInterface for IrcBundleJoinEvent {
    fn accept(&mut self, message: &IrcMessage) -> bool {
        let incr_state: bool = match self.state {
            0 => {
                // 353 contains nicks
                // 366 is ``End of /NAMES list''
                if message.get_command().as_slice() == "353" &&
                        *message.get_arg(2) == self.channel {
                    for nick in message.get_arg(3).as_slice().split(' ') {
                        self.nicks.push(String::from_str(nick));
                    }
                };
                message.get_args().len() >= 2 &&
                    message.get_command().as_slice() == "366" &&
                    *message.get_arg(1) == self.channel
            },
            _ => false
        };
        if incr_state {
            self.state += 1;
        }
        self.state == 1
    }

    fn pretty_print(&self) -> String {
        format!("IrcBundleJoinEvent({} with {} nicks)",
            self.channel.as_slice(), self.nicks.len())
    }
}

pub enum IrcEvent {
    IrcEventMessage(Box<IrcMessage>),
    IrcEventBundle(Box<IrcBundleEventInterface+Send>),
    IrcEventWatcherResponse(Box<MessageWatcher+Send>)
}

pub struct IrcConnection {
    // conn: TcpStream,
    writer: LineBufferedWriter<TcpStream>,
    event_queue: Receiver<IrcEvent>,
    watchers: SyncSender<Box<MessageWatcher+Send>>,
    has_registered: bool
}

fn watcher_accept(buf: &mut RingBuf<Box<MessageWatcher+Send>>,
                  message: &IrcMessage
                 ) -> Vec<Box<MessageWatcher+Send>> {

    let mut keep_watchers: RingBuf<Box<MessageWatcher+Send>> = RingBuf::new();
    let mut finished_watchers: Vec<Box<MessageWatcher+Send>> = Vec::new();
    loop {
        match buf.pop_front() {
            Some(mut watcher) => {
                let watcher_repr = watcher.pretty_print();
                watcher.accept(message);
                if watcher.finished() {
                    finished_watchers.push(watcher);
                } else {
                    keep_watchers.push(watcher);
                }

            },
            None => break
        }
    }
    loop {
        match keep_watchers.pop_front() {
            Some(watcher) => buf.push(watcher),
            None => break
        }
    }
    finished_watchers
}

fn bundler_accept(buf: &mut RingBuf<Box<IrcBundleEventInterface+Send>>,
                  message: &IrcMessage
                 ) -> Vec<Box<IrcBundleEventInterface+Send>> {

    let mut keep_watchers: RingBuf<Box<IrcBundleEventInterface+Send>> = RingBuf::new();
    let mut finished_watchers: Vec<Box<IrcBundleEventInterface+Send>> = Vec::new();
    loop {
        match buf.pop_front() {
            Some(mut watcher) => {
                if watcher.accept(message) {
                    finished_watchers.push(watcher);
                } else {
                    keep_watchers.push(watcher);
                }
            },
            None => break
        }
    }
    loop {
        match keep_watchers.pop_front() {
            Some(watcher) => buf.push(watcher),
            None => break
        }
    }
    finished_watchers
}

pub struct IrcRegisterRequest<'a> {
    // NICK {nick}\n
    // USER {username} {mode} * :{realname}
    nick: &'a str,
    username: &'a str,
    mode: uint,
    realname: &'a str
}

impl IrcConnection {
    pub fn new(host: &str, port: u16) -> IoResult<IrcConnection> {
        let stream = match TcpStream::connect(host, port) {
            Ok(stream) => stream,
            Err(err) => return Err(err)
        };

        let (watchers_tx, watchers_rx) = sync_channel(10);
        let (event_queue_tx, event_queue_rx) = sync_channel(1024);
        let reader = BufferedReader::new(stream.clone());

        spawn(proc() {
            let mut watchers: RingBuf<Box<MessageWatcher+Send>> = RingBuf::new();
            let mut event_bundlers: RingBuf<Box<IrcBundleEventInterface+Send>> = RingBuf::new();

            let mut reader = reader;

            loop {
                let string = String::from_str(match reader.read_line() {
                    Ok(string) => string,
                    Err(err) => fail!("{}", err)
                }.as_slice().trim_right());

                loop {
                    match watchers_rx.try_recv() {
                        Ok(value) => watchers.push(value),
                        Err(_) => break
                    };
                }

                let message = match IrcMessage::from_str(string.as_slice()) {
                    Ok(message) => message,
                    Err(err) => {
                        println!("Invalid IRC message: {} for {}", err, string);
                        continue;
                    }
                };

                match IrcBundleJoinEvent::new(&message) {
                    Some(bundler) => event_bundlers.push(box bundler),
                    None => ()
                }

                for resp in watcher_accept(&mut watchers, &message).move_iter() {
                    event_queue_tx.send(IrcEventWatcherResponse(resp));
                }

                for resp in bundler_accept(&mut event_bundlers, &message).move_iter() {
                    event_queue_tx.send(IrcEventBundle(resp));
                }

                event_queue_tx.send(IrcEventMessage(box message));
            }
        });

        Ok(IrcConnection {
            // conn: stream.clone(),
            writer: LineBufferedWriter::new(stream.clone()),
            event_queue: event_queue_rx,
            watchers: watchers_tx,
            has_registered: false
        })
    }

    pub fn register(&mut self, nick: &str) -> Result<(), RegisterError> {
        let mut reg_watcher = RegisterMessageWatcher::new();
        let result_rx = reg_watcher.get_monitor();
        let watcher: Box<MessageWatcher+Send> = box reg_watcher;
        self.watchers.send(watcher);

        match self.writer.write_str(format!("NICK {}\n", nick).as_slice()) {
            Ok(_) => (),
            Err(err) => fail!("Error writing to IRC server: {}", err)
        };

        if !self.has_registered {
            match self.writer.write_str("USER rustbot 8 *: Rust Bot\n") {
                Ok(_) => (),
                Err(err) => fail!("Error writing to IRC server: {}", err)
            };
        }

        result_rx.recv()
    }
    // RX: IrcMessage(miyuki.yasashiisyndicate.org, 475, [
    //    aibi`, #dicks, Cannot join channel (Incorrect channel key), ])

    pub fn join(&mut self, channel: &str) -> JoinResult {
        let mut join_watcher = JoinMessageWatcher::new(channel);
        let result_rx = join_watcher.get_monitor();
        let watcher: Box<MessageWatcher+Send> = box join_watcher;
        self.watchers.send(watcher);

        match self.writer.write_str(format!("JOIN {}\n", channel).as_slice()) {
            Ok(_) => (),
            Err(err) => fail!("Error writing to IRC server: {}", err)
        }

        result_rx.recv()
    }

    pub fn recv(&self) -> IrcEvent {
        self.event_queue.recv()
    }

    pub fn write_str(&mut self, content: &str) -> IoResult<()> {
        self.writer.write_str(content)
    }
}

impl Drop for IrcConnection {
    fn drop(&mut self) {
        self.writer.write_str("QUIT\n");
    }
} <|endoftext|>


<commit_before>//! Parsing functionality - get cookie data

use std::collections::hashmap::HashMap;
use serialize::json::{Json, Null};
use serialize::hex::ToHex;
use crypto::digest::Digest;
use crypto::sha2::Sha256;

/// The parsed cookie.
///
/// This is the type stored in the alloy.
#[deriving(Show)]
pub struct Cookie {
    secret: Option<String>,
    /// The parsed RFC 6265-styled cookies.
    pub map: HashMap<String, String>,
    /// Any JSON fields, parsed into a single object
    ///
    /// JSON stored under key `myJson` will be available
    /// under `cookie.json.find(&"myJson".to_string())`.
    pub json: Json
}

impl Cookie {
    /// Create a new cookie
    pub fn new(secret: Option<String>) -> Cookie {
        Cookie {
            secret: secret,
            map: HashMap::new(),
            json: Null
        }
    }

    /// Encode your signature
    ///
    /// Signatures will be encoded with SHA-256.
    pub fn sign(&self, value: &String) -> Option<String> {
        match self.secret {
            Some(ref secret) => {
                let mut sha = Sha256::new();
                sha.input(secret.as_bytes());
                sha.input(value.as_bytes());

                let hash: &mut [u8] = [];
                sha.result(hash);
                Some(hash.as_slice().to_hex())
            },
            None             => None
        }
    }
}
<commit_msg>(fix) Fixed hash length.<commit_after>//! Parsing functionality - get cookie data

use std::collections::hashmap::HashMap;
use serialize::json::{Json, Null};
use serialize::hex::ToHex;
use crypto::digest::Digest;
use crypto::sha2::Sha256;

/// The parsed cookie.
///
/// This is the type stored in the alloy.
#[deriving(Show)]
pub struct Cookie {
    secret: Option<String>,
    /// The parsed RFC 6265-styled cookies.
    pub map: HashMap<String, String>,
    /// Any JSON fields, parsed into a single object
    ///
    /// JSON stored under key `myJson` will be available
    /// under `cookie.json.find(&"myJson".to_string())`.
    pub json: Json
}

impl Cookie {
    /// Create a new cookie
    pub fn new(secret: Option<String>) -> Cookie {
        Cookie {
            secret: secret,
            map: HashMap::new(),
            json: Null
        }
    }

    /// Encode your signature
    ///
    /// Signatures will be encoded with SHA-256.
    pub fn sign(&self, value: &String) -> Option<String> {
        match self.secret {
            Some(ref secret) => {
                let mut sha = Sha256::new();
                sha.input(secret.as_bytes());
                sha.input(value.as_bytes());

                let hash: &mut [u8] = [0, ..32];
                sha.result(hash);
                Some(hash.as_slice().to_hex())
            },
            None             => None
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//! A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
//! and margins in CSS.

use std::num::Zero;

/// A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
/// and margins in CSS.
#[deriving(Clone, Eq)]
pub struct SideOffsets2D<T> {
    pub top: T,
    pub right: T,
    pub bottom: T,
    pub left: T,
}

impl<T> SideOffsets2D<T> {
    pub fn new(top: T, right: T, bottom: T, left: T) -> SideOffsets2D<T> {
        SideOffsets2D {
            top: top,
            right: right,
            bottom: bottom,
            left: left,
        }
    }
}

impl<T:Clone> SideOffsets2D<T> {
    pub fn new_all_same(all: T) -> SideOffsets2D<T> {
        SideOffsets2D::new(all.clone(), all.clone(), all.clone(), all.clone())
    }
}

impl<T:Num> SideOffsets2D<T> {
    pub fn horizontal(&self) -> T {
        self.left + self.right
    }

    pub fn vertical(&self) -> T {
        self.top + self.bottom
    }
}

impl<T:Num> Add<SideOffsets2D<T>, SideOffsets2D<T>> for SideOffsets2D<T> {
    fn add(&self, other: &SideOffsets2D<T>) -> SideOffsets2D<T> {
        SideOffsets2D {
            top: self.top + other.top,
            right: self.right + other.right,
            bottom: self.bottom + other.bottom,
            left: self.left + other.left,
        }
    }
}

impl<T:Num> Zero for SideOffsets2D<T> {
    fn zero() -> SideOffsets2D<T> {
        SideOffsets2D {
            top: Zero::zero(),
            right: Zero::zero(),
            bottom: Zero::zero(),
            left: Zero::zero(),
        }
    }

    fn is_zero(&self) -> bool {
        self.top.is_zero() && self.right.is_zero() && self.bottom.is_zero() && self.left.is_zero()
    }
}

/// A SIMD enabled version of SideOffsets2D specialized for i32.
#[deriving(Clone, Eq, Rand)]
#[simd]
pub struct SideOffsets2DSimdI32 {
    pub top: i32,
    pub bottom: i32,
    pub right: i32,
    pub left: i32,
}

impl SideOffsets2DSimdI32 {
    pub fn new(top: i32, right: i32, bottom: i32, left: i32) -> SideOffsets2DSimdI32 {
        SideOffsets2DSimdI32 {
            top: top,
            bottom: bottom,
            right: right,
            left: left,
        }
    }
}

impl SideOffsets2DSimdI32 {
    pub fn new_all_same(all: i32) -> SideOffsets2DSimdI32 {
        SideOffsets2DSimdI32::new(all.clone(), all.clone(), all.clone(), all.clone())
    }
}

impl SideOffsets2DSimdI32 {
    pub fn horizontal(&self) -> i32 {
        self.left + self.right
    }

    pub fn vertical(&self) -> i32 {
        self.top + self.bottom
    }
}

impl Add<SideOffsets2DSimdI32, SideOffsets2DSimdI32> for SideOffsets2DSimdI32 {
    fn add(&self, other: &SideOffsets2DSimdI32) -> SideOffsets2DSimdI32 {
        SideOffsets2DSimdI32 {
            top: self.top + other.top,
            right: self.right + other.right,
            bottom: self.bottom + other.bottom,
            left: self.left + other.left,
        }
    }
}

impl Zero for SideOffsets2DSimdI32 {
    fn zero() -> SideOffsets2DSimdI32 {
        SideOffsets2DSimdI32 {
            top: Zero::zero(),
            bottom: Zero::zero(),
            right: Zero::zero(),
            left: Zero::zero(),
        }
    }

    #[cfg(not(target_arch = "x86"), not(target_arch = "x86_64"))]
    fn is_zero(&self) -> bool {
        self.top.is_zero() && self.right.is_zero() && self.bottom.is_zero() && self.left.is_zero()
    }

    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "x86_64")]
    #[inline]
    fn is_zero(&self) -> bool {
        let is_zero: bool;
        unsafe {
            asm! {
                "ptest $1, $1
                 setz $0"
                : "=r"(is_zero)
                : "x"(*self)
                :
                : "intel"
            };
        }
        is_zero
    }
}

#[cfg(test)]
mod tests {
    use std::num::Zero;
    use super::SideOffsets2DSimdI32;

    #[test]
    fn test_is_zero() {
        assert!(SideOffsets2DSimdI32::new_all_same(0).is_zero());
        assert!(!SideOffsets2DSimdI32::new_all_same(1).is_zero());
        assert!(!SideOffsets2DSimdI32::new(1, 0, 0, 0).is_zero());
        assert!(!SideOffsets2DSimdI32::new(0, 1, 0, 0).is_zero());
        assert!(!SideOffsets2DSimdI32::new(0, 0, 1, 0).is_zero());
        assert!(!SideOffsets2DSimdI32::new(0, 0, 0, 1).is_zero());
    }
}

#[cfg(bench)]
mod bench {
    use test::BenchHarness;
    use std::num::Zero;
    use rand::{XorShiftRng, Rng};
    use super::SideOffsets2DSimdI32;

    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "x86_64")]
    #[bench]
    fn bench_naive_is_zero(bh: &mut BenchHarness) {
        fn is_zero(x: &SideOffsets2DSimdI32) -> bool {
            x.top.is_zero() && x.right.is_zero() && x.bottom.is_zero() && x.left.is_zero()
        }
        let mut rng = XorShiftRng::new().unwrap();
        bh.iter(|| is_zero(&rng.gen::<SideOffsets2DSimdI32>()))
    }

    #[bench]
    fn bench_is_zero(bh: &mut BenchHarness) {
        let mut rng = XorShiftRng::new().unwrap();
        bh.iter(|| rng.gen::<SideOffsets2DSimdI32>().is_zero())
    }
}
<commit_msg>Implement add using SIMD and add benchmarks<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//! A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
//! and margins in CSS.

use std::num::Zero;

/// A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
/// and margins in CSS.
#[deriving(Clone, Eq)]
pub struct SideOffsets2D<T> {
    pub top: T,
    pub right: T,
    pub bottom: T,
    pub left: T,
}

impl<T> SideOffsets2D<T> {
    pub fn new(top: T, right: T, bottom: T, left: T) -> SideOffsets2D<T> {
        SideOffsets2D {
            top: top,
            right: right,
            bottom: bottom,
            left: left,
        }
    }
}

impl<T:Clone> SideOffsets2D<T> {
    pub fn new_all_same(all: T) -> SideOffsets2D<T> {
        SideOffsets2D::new(all.clone(), all.clone(), all.clone(), all.clone())
    }
}

impl<T:Num> SideOffsets2D<T> {
    pub fn horizontal(&self) -> T {
        self.left + self.right
    }

    pub fn vertical(&self) -> T {
        self.top + self.bottom
    }
}

impl<T:Num> Add<SideOffsets2D<T>, SideOffsets2D<T>> for SideOffsets2D<T> {
    fn add(&self, other: &SideOffsets2D<T>) -> SideOffsets2D<T> {
        SideOffsets2D {
            top: self.top + other.top,
            right: self.right + other.right,
            bottom: self.bottom + other.bottom,
            left: self.left + other.left,
        }
    }
}

impl<T:Num> Zero for SideOffsets2D<T> {
    fn zero() -> SideOffsets2D<T> {
        SideOffsets2D {
            top: Zero::zero(),
            right: Zero::zero(),
            bottom: Zero::zero(),
            left: Zero::zero(),
        }
    }

    fn is_zero(&self) -> bool {
        self.top.is_zero() && self.right.is_zero() && self.bottom.is_zero() && self.left.is_zero()
    }
}

/// A SIMD enabled version of SideOffsets2D specialized for i32.
#[deriving(Clone, Eq, Rand)]
#[simd]
pub struct SideOffsets2DSimdI32 {
    pub top: i32,
    pub bottom: i32,
    pub right: i32,
    pub left: i32,
}

impl SideOffsets2DSimdI32 {
    pub fn new(top: i32, right: i32, bottom: i32, left: i32) -> SideOffsets2DSimdI32 {
        SideOffsets2DSimdI32 {
            top: top,
            bottom: bottom,
            right: right,
            left: left,
        }
    }
}

impl SideOffsets2DSimdI32 {
    pub fn new_all_same(all: i32) -> SideOffsets2DSimdI32 {
        SideOffsets2DSimdI32::new(all.clone(), all.clone(), all.clone(), all.clone())
    }
}

impl SideOffsets2DSimdI32 {
    pub fn horizontal(&self) -> i32 {
        self.left + self.right
    }

    pub fn vertical(&self) -> i32 {
        self.top + self.bottom
    }
}

impl Add<SideOffsets2DSimdI32, SideOffsets2DSimdI32> for SideOffsets2DSimdI32 {
    fn add(&self, other: &SideOffsets2DSimdI32) -> SideOffsets2DSimdI32 {
        *self + *other // Use SIMD addition
    }
}

impl Zero for SideOffsets2DSimdI32 {
    fn zero() -> SideOffsets2DSimdI32 {
        SideOffsets2DSimdI32 {
            top: Zero::zero(),
            bottom: Zero::zero(),
            right: Zero::zero(),
            left: Zero::zero(),
        }
    }

    #[cfg(not(target_arch = "x86"), not(target_arch = "x86_64"))]
    fn is_zero(&self) -> bool {
        self.top.is_zero() && self.right.is_zero() && self.bottom.is_zero() && self.left.is_zero()
    }

    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "x86_64")]
    #[inline]
    fn is_zero(&self) -> bool {
        let is_zero: bool;
        unsafe {
            asm! {
                "ptest $1, $1
                 setz $0"
                : "=r"(is_zero)
                : "x"(*self)
                :
                : "intel"
            };
        }
        is_zero
    }
}

#[cfg(test)]
mod tests {
    use std::num::Zero;
    use super::SideOffsets2DSimdI32;

    #[test]
    fn test_is_zero() {
        assert!(SideOffsets2DSimdI32::new_all_same(0).is_zero());
        assert!(!SideOffsets2DSimdI32::new_all_same(1).is_zero());
        assert!(!SideOffsets2DSimdI32::new(1, 0, 0, 0).is_zero());
        assert!(!SideOffsets2DSimdI32::new(0, 1, 0, 0).is_zero());
        assert!(!SideOffsets2DSimdI32::new(0, 0, 1, 0).is_zero());
        assert!(!SideOffsets2DSimdI32::new(0, 0, 0, 1).is_zero());
    }
}

#[cfg(bench)]
mod bench {
    use test::BenchHarness;
    use std::num::Zero;
    use rand::{XorShiftRng, Rng};
    use super::SideOffsets2DSimdI32;

    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "x86_64")]
    #[bench]
    fn bench_naive_is_zero(bh: &mut BenchHarness) {
        fn is_zero(x: &SideOffsets2DSimdI32) -> bool {
            x.top.is_zero() && x.right.is_zero() && x.bottom.is_zero() && x.left.is_zero()
        }
        let mut rng = XorShiftRng::new().unwrap();
        bh.iter(|| is_zero(&rng.gen::<SideOffsets2DSimdI32>()))
    }

    #[bench]
    fn bench_is_zero(bh: &mut BenchHarness) {
        let mut rng = XorShiftRng::new().unwrap();
        bh.iter(|| rng.gen::<SideOffsets2DSimdI32>().is_zero())
    }

    #[bench]
    fn bench_naive_add(bh: &mut BenchHarness) {
        fn add(x: &SideOffsets2DSimdI32, y: &SideOffsets2DSimdI32) -> SideOffsets2DSimdI32 {
            SideOffsets2DSimdI32 {
                top: x.top + y.top,
                right: x.right + y.right,
                bottom: x.bottom + y.bottom,
                left: x.left + y.left,
            }
        }
        let mut rng = XorShiftRng::new().unwrap();
        bh.iter(|| add(&rng.gen::<SideOffsets2DSimdI32>(), &rng.gen::<SideOffsets2DSimdI32>()))
    }

    #[bench]
    fn bench_add(bh: &mut BenchHarness) {
        let mut rng = XorShiftRng::new().unwrap();
        bh.iter(|| rng.gen::<SideOffsets2DSimdI32>() + rng.gen::<SideOffsets2DSimdI32>())
    }
}
<|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 std::fmt;
use super::address::SBAddress;
use super::breakpoint::SBBreakpoint;
use super::stream::SBStream;
use super::{DescriptionLevel, lldb_addr_t};
use sys;

/// One unique instance (by address) of a logical breakpoint.
///
/// A breakpoint location is defined by the breakpoint that
/// produces it, and the address that resulted in this
/// particular instantiation.  Each breakpoint location has
/// its settable options.
///
/// `SBBreakpoint` contains `SBBreakpointLocation`(s).
/// See [`SBBreakpoint`] for retrieval of an `SBBreakpointLocation`
/// from an SBBreakpoint.
///
/// [`SBBreakpoint`]: struct.SBBreakpoint.html
pub struct SBBreakpointLocation {
    /// The underlying raw `SBBreakpointLocationRef`.
    pub raw: sys::SBBreakpointLocationRef,
}

impl SBBreakpointLocation {
    /// Construct a new `SBBreakpointLocation`.
    pub fn wrap(raw: sys::SBBreakpointLocationRef) -> SBBreakpointLocation {
        SBBreakpointLocation { raw: raw }
    }

    /// Construct a new `Some(SBBreakpointLocation)` or `None`.
    pub fn maybe_wrap(raw: sys::SBBreakpointLocationRef) -> Option<SBBreakpointLocation> {
        if unsafe { sys::SBBreakpointLocationIsValid(raw) != 0 } {
            Some(SBBreakpointLocation { raw: raw })
        } else {
            None
        }
    }

    /// Check whether or not this is a valid `SBBreakpointLocation` value.
    pub fn is_valid(&self) -> bool {
        unsafe { sys::SBBreakpointLocationIsValid(self.raw) != 0 }
    }

    #[allow(missing_docs)]
    pub fn id(&self) -> i32 {
        unsafe { sys::SBBreakpointLocationGetID(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn address(&self) -> Option<SBAddress> {
        SBAddress::maybe_wrap(unsafe { sys::SBBreakpointLocationGetAddress(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn load_address(&self) -> lldb_addr_t {
        unsafe { sys::SBBreakpointLocationGetLoadAddress(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_enabled(&self) -> bool {
        unsafe { sys::SBBreakpointLocationIsEnabled(self.raw) != 0 }
    }

    #[allow(missing_docs)]
    pub fn set_enabled(&self, enabled: bool) {
        unsafe { sys::SBBreakpointLocationSetEnabled(self.raw, enabled as u8) }
    }

    #[allow(missing_docs)]
    pub fn ignore_count(&self) -> u32 {
        unsafe { sys::SBBreakpointLocationGetIgnoreCount(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn set_ignore_count(&self, count: u32) {
        unsafe { sys::SBBreakpointLocationSetIgnoreCount(self.raw, count) }
    }

    #[allow(missing_docs)]
    pub fn is_resolved(&self) -> bool {
        unsafe { sys::SBBreakpointLocationIsResolved(self.raw) != 0 }
    }

    #[allow(missing_docs)]
    pub fn breakpoint(&self) -> SBBreakpoint {
        SBBreakpoint::wrap(unsafe { sys::SBBreakpointLocationGetBreakpoint(self.raw) })
    }
}

impl fmt::Debug for SBBreakpointLocation {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let stream = SBStream::new();
        unsafe {
            sys::SBBreakpointLocationGetDescription(self.raw, stream.raw, DescriptionLevel::Brief)
        };
        write!(fmt, "SBBreakpointLocation {{ {} }}", stream.data())
    }
}

impl Drop for SBBreakpointLocation {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBBreakpointLocation(self.raw) };
    }
}
<commit_msg>clippy,doc: Missing backticks around identifier.<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 std::fmt;
use super::address::SBAddress;
use super::breakpoint::SBBreakpoint;
use super::stream::SBStream;
use super::{DescriptionLevel, lldb_addr_t};
use sys;

/// One unique instance (by address) of a logical breakpoint.
///
/// A breakpoint location is defined by the breakpoint that
/// produces it, and the address that resulted in this
/// particular instantiation.  Each breakpoint location has
/// its settable options.
///
/// `SBBreakpoint` contains `SBBreakpointLocation`(s).
/// See [`SBBreakpoint`] for retrieval of an `SBBreakpointLocation`
/// from an `SBBreakpoint`.
///
/// [`SBBreakpoint`]: struct.SBBreakpoint.html
pub struct SBBreakpointLocation {
    /// The underlying raw `SBBreakpointLocationRef`.
    pub raw: sys::SBBreakpointLocationRef,
}

impl SBBreakpointLocation {
    /// Construct a new `SBBreakpointLocation`.
    pub fn wrap(raw: sys::SBBreakpointLocationRef) -> SBBreakpointLocation {
        SBBreakpointLocation { raw: raw }
    }

    /// Construct a new `Some(SBBreakpointLocation)` or `None`.
    pub fn maybe_wrap(raw: sys::SBBreakpointLocationRef) -> Option<SBBreakpointLocation> {
        if unsafe { sys::SBBreakpointLocationIsValid(raw) != 0 } {
            Some(SBBreakpointLocation { raw: raw })
        } else {
            None
        }
    }

    /// Check whether or not this is a valid `SBBreakpointLocation` value.
    pub fn is_valid(&self) -> bool {
        unsafe { sys::SBBreakpointLocationIsValid(self.raw) != 0 }
    }

    #[allow(missing_docs)]
    pub fn id(&self) -> i32 {
        unsafe { sys::SBBreakpointLocationGetID(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn address(&self) -> Option<SBAddress> {
        SBAddress::maybe_wrap(unsafe { sys::SBBreakpointLocationGetAddress(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn load_address(&self) -> lldb_addr_t {
        unsafe { sys::SBBreakpointLocationGetLoadAddress(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_enabled(&self) -> bool {
        unsafe { sys::SBBreakpointLocationIsEnabled(self.raw) != 0 }
    }

    #[allow(missing_docs)]
    pub fn set_enabled(&self, enabled: bool) {
        unsafe { sys::SBBreakpointLocationSetEnabled(self.raw, enabled as u8) }
    }

    #[allow(missing_docs)]
    pub fn ignore_count(&self) -> u32 {
        unsafe { sys::SBBreakpointLocationGetIgnoreCount(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn set_ignore_count(&self, count: u32) {
        unsafe { sys::SBBreakpointLocationSetIgnoreCount(self.raw, count) }
    }

    #[allow(missing_docs)]
    pub fn is_resolved(&self) -> bool {
        unsafe { sys::SBBreakpointLocationIsResolved(self.raw) != 0 }
    }

    #[allow(missing_docs)]
    pub fn breakpoint(&self) -> SBBreakpoint {
        SBBreakpoint::wrap(unsafe { sys::SBBreakpointLocationGetBreakpoint(self.raw) })
    }
}

impl fmt::Debug for SBBreakpointLocation {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let stream = SBStream::new();
        unsafe {
            sys::SBBreakpointLocationGetDescription(self.raw, stream.raw, DescriptionLevel::Brief)
        };
        write!(fmt, "SBBreakpointLocation {{ {} }}", stream.data())
    }
}

impl Drop for SBBreakpointLocation {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBBreakpointLocation(self.raw) };
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
use std::io::prelude::*;
use std::iter::repeat;
use std::path::{Path, PathBuf};

use curl::http;
use git2;
use registry::{Registry, NewCrate, NewCrateDependency};
use term::color::BLACK;

use core::source::Source;
use core::{Package, SourceId};
use core::dependency::Kind;
use core::manifest::ManifestMetadata;
use ops;
use sources::{PathSource, RegistrySource};
use util::config;
use util::{CargoResult, human, ChainError, ToUrl};
use util::config::{Config, ConfigValue, Location};
use util::important_paths::find_root_manifest_for_cwd;

pub struct RegistryConfig {
    pub index: Option<String>,
    pub token: Option<String>,
}

pub fn publish(manifest_path: &Path,
               config: &Config,
               token: Option<String>,
               index: Option<String>,
               verify: bool) -> CargoResult<()> {
    let mut src = try!(PathSource::for_path(manifest_path.parent().unwrap(),
                                            config));
    try!(src.update());
    let pkg = try!(src.root_package());

    let (mut registry, reg_id) = try!(registry(config, token, index));
    try!(verify_dependencies(&pkg, &reg_id));

    // Prepare a tarball, with a non-surpressable warning if metadata
    // is missing since this is being put online.
    let tarball = try!(ops::package(manifest_path, config, verify,
                                    false, true)).unwrap();

    // Upload said tarball to the specified destination
    try!(config.shell().status("Uploading", pkg.package_id().to_string()));
    try!(transmit(&pkg, &tarball, &mut registry));

    Ok(())
}

fn verify_dependencies(pkg: &Package, registry_src: &SourceId)
                       -> CargoResult<()> {
    for dep in pkg.dependencies().iter() {
        if dep.source_id().is_path() {
            if dep.specified_req().is_none() {
                return Err(human(format!("all path dependencies must have \
                                          a version specified when \
                                          publishing.\n\
                                          dependency `{}` does not specify \
                                          a version", dep.name())))
            }
        } else if dep.source_id() != registry_src {
            return Err(human(format!("all dependencies must come from the \
                                      same source.\ndependency `{}` comes \
                                      from {} instead", dep.name(),
                                     dep.source_id())))
        }
    }
    Ok(())
}

fn transmit(pkg: &Package, tarball: &Path, registry: &mut Registry)
            -> CargoResult<()> {
    let deps = pkg.dependencies().iter().map(|dep| {
        NewCrateDependency {
            optional: dep.is_optional(),
            default_features: dep.uses_default_features(),
            name: dep.name().to_string(),
            features: dep.features().to_vec(),
            version_req: dep.version_req().to_string(),
            target: dep.only_for_platform().map(|s| s.to_string()),
            kind: match dep.kind() {
                Kind::Normal => "normal",
                Kind::Build => "build",
                Kind::Development => "dev",
            }.to_string(),
        }
    }).collect::<Vec<NewCrateDependency>>();
    let manifest = pkg.manifest();
    let ManifestMetadata {
        ref authors, ref description, ref homepage, ref documentation,
        ref keywords, ref readme, ref repository, ref license, ref license_file,
    } = *manifest.metadata();
    let readme = match *readme {
        Some(ref readme) => {
            let path = pkg.root().join(readme);
            let mut contents = String::new();
            try!(File::open(&path).and_then(|mut f| {
                f.read_to_string(&mut contents)
            }).chain_error(|| {
                human("failed to read the specified README")
            }));
            Some(contents)
        }
        None => None,
    };
    match *license_file {
        Some(ref file) => {
            if fs::metadata(&pkg.root().join(file)).is_err() {
                return Err(human(format!("the license file `{}` does not exist",
                                         file)))
            }
        }
        None => {}
    }
    registry.publish(&NewCrate {
        name: pkg.name().to_string(),
        vers: pkg.version().to_string(),
        deps: deps,
        features: pkg.summary().features().clone(),
        authors: authors.clone(),
        description: description.clone(),
        homepage: homepage.clone(),
        documentation: documentation.clone(),
        keywords: keywords.clone(),
        readme: readme,
        repository: repository.clone(),
        license: license.clone(),
        license_file: license_file.clone(),
    }, tarball).map_err(|e| {
        human(e.to_string())
    })
}

pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> {
    let index = try!(config.get_string("registry.index")).map(|p| p.0);
    let token = try!(config.get_string("registry.token")).map(|p| p.0);
    Ok(RegistryConfig { index: index, token: token })
}

pub fn registry(config: &Config,
                token: Option<String>,
                index: Option<String>) -> CargoResult<(Registry, SourceId)> {
    // Parse all configuration options
    let RegistryConfig {
        token: token_config,
        index: index_config,
    } = try!(registry_configuration(config));
    let token = token.or(token_config);
    let index = index.or(index_config).unwrap_or(RegistrySource::default_url());
    let index = try!(index.to_url().map_err(human));
    let sid = SourceId::for_registry(&index);
    let api_host = {
        let mut src = RegistrySource::new(&sid, config);
        try!(src.update().chain_error(|| {
            human(format!("Failed to update registry {}", index))
        }));
        (try!(src.config())).api
    };
    let handle = try!(http_handle(config));
    Ok((Registry::new_handle(api_host, token, handle), sid))
}

/// Create a new HTTP handle with appropriate global configuration for cargo.
pub fn http_handle(config: &Config) -> CargoResult<http::Handle> {
    // The timeout option for libcurl by default times out the entire transfer,
    // but we probably don't want this. Instead we only set timeouts for the
    // connect phase as well as a "low speed" timeout so if we don't receive
    // many bytes in a large-ish period of time then we time out.
    let handle = http::handle().timeout(0)
                               .connect_timeout(30_000 /* milliseconds */)
                               .low_speed_limit(10 /* bytes per second */)
                               .low_speed_timeout(30 /* seconds */);
    let handle = match try!(http_proxy(config)) {
        Some(proxy) => handle.proxy(proxy),
        None => handle,
    };
    let handle = match try!(http_timeout(config)) {
        Some(timeout) => handle.connect_timeout(timeout as usize)
                               .low_speed_timeout((timeout as usize) / 1000),
        None => handle,
    };
    Ok(handle)
}

/// Find an explicit HTTP proxy if one is available.
///
/// Favor cargo's `http.proxy`, then git's `http.proxy`. Proxies specified
/// via environment variables are picked up by libcurl.
fn http_proxy(config: &Config) -> CargoResult<Option<String>> {
    match try!(config.get_string("http.proxy")) {
        Some((s, _)) => return Ok(Some(s)),
        None => {}
    }
    match git2::Config::open_default() {
        Ok(cfg) => {
            match cfg.get_str("http.proxy") {
                Ok(s) => return Ok(Some(s.to_string())),
                Err(..) => {}
            }
        }
        Err(..) => {}
    }
    Ok(None)
}

/// Determine if an http proxy exists.
///
/// Checks the following for existence, in order:
///
/// * cargo's `http.proxy`
/// * git's `http.proxy`
/// * http_proxy env var
/// * HTTP_PROXY env var
/// * https_proxy env var
/// * HTTPS_PROXY env var
pub fn http_proxy_exists(config: &Config) -> CargoResult<bool> {
    if try!(http_proxy(config)).is_some() {
        Ok(true)
    } else {
        Ok(["http_proxy", "HTTP_PROXY",
           "https_proxy", "HTTPS_PROXY"].iter().any(|v| env::var(v).is_ok()))
    }
}

pub fn http_timeout(config: &Config) -> CargoResult<Option<i64>> {
    match try!(config.get_i64("http.timeout")) {
        Some((s, _)) => return Ok(Some(s)),
        None => {}
    }
    Ok(env::var("HTTP_TIMEOUT").ok().and_then(|s| s.parse().ok()))
}

pub fn registry_login(config: &Config, token: String) -> CargoResult<()> {
    let RegistryConfig { index, token: _ } = try!(registry_configuration(config));
    let mut map = HashMap::new();
    let p = config.cwd().to_path_buf();
    match index {
        Some(index) => {
            map.insert("index".to_string(), ConfigValue::String(index, p.clone()));
        }
        None => {}
    }
    map.insert("token".to_string(), ConfigValue::String(token, p));

    config::set_config(config, Location::Global, "registry",
                       ConfigValue::Table(map, PathBuf::from(".")))
}

pub struct OwnersOptions {
    pub krate: Option<String>,
    pub token: Option<String>,
    pub index: Option<String>,
    pub to_add: Option<Vec<String>>,
    pub to_remove: Option<Vec<String>>,
    pub list: bool,
}

pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
    let name = match opts.krate {
        Some(ref name) => name.clone(),
        None => {
            let manifest_path = try!(find_root_manifest_for_cwd(None));
            let mut src = try!(PathSource::for_path(manifest_path.parent().unwrap(),
                                                    config));
            try!(src.update());
            let pkg = try!(src.root_package());
            pkg.name().to_string()
        }
    };

    let (mut registry, _) = try!(registry(config, opts.token.clone(),
                                          opts.index.clone()));

    match opts.to_add {
        Some(ref v) => {
            let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
            try!(config.shell().status("Owner", format!("adding `{:?}` to `{}`",
                                                        v, name)));
            try!(registry.add_owners(&name, &v).map_err(|e| {
                human(format!("failed to add owners: {}", e))
            }));
        }
        None => {}
    }

    match opts.to_remove {
        Some(ref v) => {
            let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
            try!(config.shell().status("Owner", format!("removing `{:?}` from `{}`",
                                                        v, name)));
            try!(registry.remove_owners(&name, &v).map_err(|e| {
                human(format!("failed to remove owners: {}", e))
            }));
        }
        None => {}
    }

    if opts.list {
        let owners = try!(registry.list_owners(&name).map_err(|e| {
            human(format!("failed to list owners: {}", e))
        }));
        for owner in owners.iter() {
            print!("{}", owner.login);
            match (owner.name.as_ref(), owner.email.as_ref()) {
                (Some(name), Some(email)) => println!(" ({} <{}>)", name, email),
                (Some(s), None) |
                (None, Some(s)) => println!(" ({})", s),
                (None, None) => println!(""),
            }
        }
    }

    Ok(())
}

pub fn yank(config: &Config,
            krate: Option<String>,
            version: Option<String>,
            token: Option<String>,
            index: Option<String>,
            undo: bool) -> CargoResult<()> {
    let name = match krate {
        Some(name) => name,
        None => {
            let manifest_path = try!(find_root_manifest_for_cwd(None));
            let mut src = try!(PathSource::for_path(manifest_path.parent().unwrap(),
                                                    config));
            try!(src.update());
            let pkg = try!(src.root_package());
            pkg.name().to_string()
        }
    };
    let version = match version {
        Some(v) => v,
        None => return Err(human("a version must be specified to yank"))
    };

    let (mut registry, _) = try!(registry(config, token, index));

    if undo {
        try!(config.shell().status("Unyank", format!("{}:{}", name, version)));
        try!(registry.unyank(&name, &version).map_err(|e| {
            human(format!("failed to undo a yank: {}", e))
        }));
    } else {
        try!(config.shell().status("Yank", format!("{}:{}", name, version)));
        try!(registry.yank(&name, &version).map_err(|e| {
            human(format!("failed to yank: {}", e))
        }));
    }

    Ok(())
}

pub fn search(query: &str, config: &Config, index: Option<String>) -> CargoResult<()> {
    fn truncate_with_ellipsis(s: &str, max_length: usize) -> String {
        if s.len() < max_length {
            s.to_string()
        } else {
            format!("{}…", &s[..max_length - 1])
        }
    }

    let (mut registry, _) = try!(registry(config, None, index));
    let crates = try!(registry.search(query).map_err(|e| {
        human(format!("failed to retrieve search results from the registry: {}", e))
    }));

    let list_items = crates.iter()
        .map(|krate| (
            format!("{} ({})", krate.name, krate.max_version),
            krate.description.as_ref().map(|desc|
                truncate_with_ellipsis(&desc.replace("\n", " "), 128))
        ))
        .collect::<Vec<_>>();
    let description_margin = list_items.iter()
        .map(|&(ref left, _)| left.len() + 4)
        .max()
        .unwrap_or(0);

    for (name, description) in list_items.into_iter() {
        let line = match description {
            Some(desc) => {
                let space = repeat(' ').take(description_margin - name.len())
                                       .collect::<String>();
                name.to_string() + &space + &desc
            }
            None => name
        };
        try!(config.shell().say(line, BLACK));
    }

    Ok(())
}
<commit_msg>Auto merge of #1896 - achanda:tidy, r=alexcrichton<commit_after>use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
use std::io::prelude::*;
use std::iter::repeat;
use std::path::{Path, PathBuf};

use curl::http;
use git2;
use registry::{Registry, NewCrate, NewCrateDependency};
use term::color::BLACK;

use core::source::Source;
use core::{Package, SourceId};
use core::dependency::Kind;
use core::manifest::ManifestMetadata;
use ops;
use sources::{PathSource, RegistrySource};
use util::config;
use util::{CargoResult, human, ChainError, ToUrl};
use util::config::{Config, ConfigValue, Location};
use util::important_paths::find_root_manifest_for_cwd;

pub struct RegistryConfig {
    pub index: Option<String>,
    pub token: Option<String>,
}

pub fn publish(manifest_path: &Path,
               config: &Config,
               token: Option<String>,
               index: Option<String>,
               verify: bool) -> CargoResult<()> {
    let mut src = try!(PathSource::for_path(manifest_path.parent().unwrap(),
                                            config));
    try!(src.update());
    let pkg = try!(src.root_package());

    let (mut registry, reg_id) = try!(registry(config, token, index));
    try!(verify_dependencies(&pkg, &reg_id));

    // Prepare a tarball, with a non-surpressable warning if metadata
    // is missing since this is being put online.
    let tarball = try!(ops::package(manifest_path, config, verify,
                                    false, true)).unwrap();

    // Upload said tarball to the specified destination
    try!(config.shell().status("Uploading", pkg.package_id().to_string()));
    try!(transmit(&pkg, &tarball, &mut registry));

    Ok(())
}

fn verify_dependencies(pkg: &Package, registry_src: &SourceId)
                       -> CargoResult<()> {
    for dep in pkg.dependencies().iter() {
        if dep.source_id().is_path() {
            if dep.specified_req().is_none() {
                return Err(human(format!("all path dependencies must have \
                                          a version specified when \
                                          publishing.\n\
                                          dependency `{}` does not specify \
                                          a version", dep.name())))
            }
        } else if dep.source_id() != registry_src {
            return Err(human(format!("all dependencies must come from the \
                                      same source.\ndependency `{}` comes \
                                      from {} instead", dep.name(),
                                     dep.source_id())))
        }
    }
    Ok(())
}

fn transmit(pkg: &Package, tarball: &Path, registry: &mut Registry)
            -> CargoResult<()> {
    let deps = pkg.dependencies().iter().map(|dep| {
        NewCrateDependency {
            optional: dep.is_optional(),
            default_features: dep.uses_default_features(),
            name: dep.name().to_string(),
            features: dep.features().to_vec(),
            version_req: dep.version_req().to_string(),
            target: dep.only_for_platform().map(|s| s.to_string()),
            kind: match dep.kind() {
                Kind::Normal => "normal",
                Kind::Build => "build",
                Kind::Development => "dev",
            }.to_string(),
        }
    }).collect::<Vec<NewCrateDependency>>();
    let manifest = pkg.manifest();
    let ManifestMetadata {
        ref authors, ref description, ref homepage, ref documentation,
        ref keywords, ref readme, ref repository, ref license, ref license_file,
    } = *manifest.metadata();
    let readme = match *readme {
        Some(ref readme) => {
            let path = pkg.root().join(readme);
            let mut contents = String::new();
            try!(File::open(&path).and_then(|mut f| {
                f.read_to_string(&mut contents)
            }).chain_error(|| {
                human("failed to read the specified README")
            }));
            Some(contents)
        }
        None => None,
    };
    match *license_file {
        Some(ref file) => {
            if fs::metadata(&pkg.root().join(file)).is_err() {
                return Err(human(format!("the license file `{}` does not exist",
                                         file)))
            }
        }
        None => {}
    }
    registry.publish(&NewCrate {
        name: pkg.name().to_string(),
        vers: pkg.version().to_string(),
        deps: deps,
        features: pkg.summary().features().clone(),
        authors: authors.clone(),
        description: description.clone(),
        homepage: homepage.clone(),
        documentation: documentation.clone(),
        keywords: keywords.clone(),
        readme: readme,
        repository: repository.clone(),
        license: license.clone(),
        license_file: license_file.clone(),
    }, tarball).map_err(|e| {
        human(e.to_string())
    })
}

pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> {
    let index = try!(config.get_string("registry.index")).map(|p| p.0);
    let token = try!(config.get_string("registry.token")).map(|p| p.0);
    Ok(RegistryConfig { index: index, token: token })
}

pub fn registry(config: &Config,
                token: Option<String>,
                index: Option<String>) -> CargoResult<(Registry, SourceId)> {
    // Parse all configuration options
    let RegistryConfig {
        token: token_config,
        index: index_config,
    } = try!(registry_configuration(config));
    let token = token.or(token_config);
    let index = index.or(index_config).unwrap_or(RegistrySource::default_url());
    let index = try!(index.to_url().map_err(human));
    let sid = SourceId::for_registry(&index);
    let api_host = {
        let mut src = RegistrySource::new(&sid, config);
        try!(src.update().chain_error(|| {
            human(format!("Failed to update registry {}", index))
        }));
        (try!(src.config())).api
    };
    let handle = try!(http_handle(config));
    Ok((Registry::new_handle(api_host, token, handle), sid))
}

/// Create a new HTTP handle with appropriate global configuration for cargo.
pub fn http_handle(config: &Config) -> CargoResult<http::Handle> {
    // The timeout option for libcurl by default times out the entire transfer,
    // but we probably don't want this. Instead we only set timeouts for the
    // connect phase as well as a "low speed" timeout so if we don't receive
    // many bytes in a large-ish period of time then we time out.
    let handle = http::handle().timeout(0)
                               .connect_timeout(30_000 /* milliseconds */)
                               .low_speed_limit(10 /* bytes per second */)
                               .low_speed_timeout(30 /* seconds */);
    let handle = match try!(http_proxy(config)) {
        Some(proxy) => handle.proxy(proxy),
        None => handle,
    };
    let handle = match try!(http_timeout(config)) {
        Some(timeout) => handle.connect_timeout(timeout as usize)
                               .low_speed_timeout((timeout as usize) / 1000),
        None => handle,
    };
    Ok(handle)
}

/// Find an explicit HTTP proxy if one is available.
///
/// Favor cargo's `http.proxy`, then git's `http.proxy`. Proxies specified
/// via environment variables are picked up by libcurl.
fn http_proxy(config: &Config) -> CargoResult<Option<String>> {
    match try!(config.get_string("http.proxy")) {
        Some((s, _)) => return Ok(Some(s)),
        None => {}
    }
    match git2::Config::open_default() {
        Ok(cfg) => {
            match cfg.get_str("http.proxy") {
                Ok(s) => return Ok(Some(s.to_string())),
                Err(..) => {}
            }
        }
        Err(..) => {}
    }
    Ok(None)
}

/// Determine if an http proxy exists.
///
/// Checks the following for existence, in order:
///
/// * cargo's `http.proxy`
/// * git's `http.proxy`
/// * http_proxy env var
/// * HTTP_PROXY env var
/// * https_proxy env var
/// * HTTPS_PROXY env var
pub fn http_proxy_exists(config: &Config) -> CargoResult<bool> {
    if try!(http_proxy(config)).is_some() {
        Ok(true)
    } else {
        Ok(["http_proxy", "HTTP_PROXY",
           "https_proxy", "HTTPS_PROXY"].iter().any(|v| env::var(v).is_ok()))
    }
}

pub fn http_timeout(config: &Config) -> CargoResult<Option<i64>> {
    match try!(config.get_i64("http.timeout")) {
        Some((s, _)) => return Ok(Some(s)),
        None => {}
    }
    Ok(env::var("HTTP_TIMEOUT").ok().and_then(|s| s.parse().ok()))
}

pub fn registry_login(config: &Config, token: String) -> CargoResult<()> {
    let RegistryConfig { index, token: _ } = try!(registry_configuration(config));
    let mut map = HashMap::new();
    let p = config.cwd().to_path_buf();
    match index {
        Some(index) => {
            map.insert("index".to_string(), ConfigValue::String(index, p.clone()));
        }
        None => {}
    }
    map.insert("token".to_string(), ConfigValue::String(token, p));

    config::set_config(config, Location::Global, "registry",
                       ConfigValue::Table(map, PathBuf::from(".")))
}

pub struct OwnersOptions {
    pub krate: Option<String>,
    pub token: Option<String>,
    pub index: Option<String>,
    pub to_add: Option<Vec<String>>,
    pub to_remove: Option<Vec<String>>,
    pub list: bool,
}

pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
    let name = match opts.krate {
        Some(ref name) => name.clone(),
        None => {
            let manifest_path = try!(find_root_manifest_for_cwd(None));
            let mut src = try!(PathSource::for_path(manifest_path.parent().unwrap(),
                                                    config));
            try!(src.update());
            let pkg = try!(src.root_package());
            pkg.name().to_string()
        }
    };

    let (mut registry, _) = try!(registry(config, opts.token.clone(),
                                          opts.index.clone()));

    match opts.to_add {
        Some(ref v) => {
            let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
            try!(config.shell().status("Owner", format!("adding {:?} to crate {}",
                                                        v, name)));
            try!(registry.add_owners(&name, &v).map_err(|e| {
                human(format!("failed to add owners: {}", e))
            }));
        }
        None => {}
    }

    match opts.to_remove {
        Some(ref v) => {
            let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
            try!(config.shell().status("Owner", format!("removing {:?} from crate {}",
                                                        v, name)));
            try!(registry.remove_owners(&name, &v).map_err(|e| {
                human(format!("failed to remove owners: {}", e))
            }));
        }
        None => {}
    }

    if opts.list {
        let owners = try!(registry.list_owners(&name).map_err(|e| {
            human(format!("failed to list owners: {}", e))
        }));
        for owner in owners.iter() {
            print!("{}", owner.login);
            match (owner.name.as_ref(), owner.email.as_ref()) {
                (Some(name), Some(email)) => println!(" ({} <{}>)", name, email),
                (Some(s), None) |
                (None, Some(s)) => println!(" ({})", s),
                (None, None) => println!(""),
            }
        }
    }

    Ok(())
}

pub fn yank(config: &Config,
            krate: Option<String>,
            version: Option<String>,
            token: Option<String>,
            index: Option<String>,
            undo: bool) -> CargoResult<()> {
    let name = match krate {
        Some(name) => name,
        None => {
            let manifest_path = try!(find_root_manifest_for_cwd(None));
            let mut src = try!(PathSource::for_path(manifest_path.parent().unwrap(),
                                                    config));
            try!(src.update());
            let pkg = try!(src.root_package());
            pkg.name().to_string()
        }
    };
    let version = match version {
        Some(v) => v,
        None => return Err(human("a version must be specified to yank"))
    };

    let (mut registry, _) = try!(registry(config, token, index));

    if undo {
        try!(config.shell().status("Unyank", format!("{}:{}", name, version)));
        try!(registry.unyank(&name, &version).map_err(|e| {
            human(format!("failed to undo a yank: {}", e))
        }));
    } else {
        try!(config.shell().status("Yank", format!("{}:{}", name, version)));
        try!(registry.yank(&name, &version).map_err(|e| {
            human(format!("failed to yank: {}", e))
        }));
    }

    Ok(())
}

pub fn search(query: &str, config: &Config, index: Option<String>) -> CargoResult<()> {
    fn truncate_with_ellipsis(s: &str, max_length: usize) -> String {
        if s.len() < max_length {
            s.to_string()
        } else {
            format!("{}…", &s[..max_length - 1])
        }
    }

    let (mut registry, _) = try!(registry(config, None, index));
    let crates = try!(registry.search(query).map_err(|e| {
        human(format!("failed to retrieve search results from the registry: {}", e))
    }));

    let list_items = crates.iter()
        .map(|krate| (
            format!("{} ({})", krate.name, krate.max_version),
            krate.description.as_ref().map(|desc|
                truncate_with_ellipsis(&desc.replace("\n", " "), 128))
        ))
        .collect::<Vec<_>>();
    let description_margin = list_items.iter()
        .map(|&(ref left, _)| left.len() + 4)
        .max()
        .unwrap_or(0);

    for (name, description) in list_items.into_iter() {
        let line = match description {
            Some(desc) => {
                let space = repeat(' ').take(description_margin - name.len())
                                       .collect::<String>();
                name.to_string() + &space + &desc
            }
            None => name
        };
        try!(config.shell().say(line, BLACK));
    }

    Ok(())
}
<|endoftext|>


<commit_before>use std::process::exit;
use std::path::{Path, PathBuf};

use package::{
    PrebuiltPackage,
    download_package
};
use utils::find_cmd;

fn emscripten_package() -> Option< PrebuiltPackage > {
    let package =
        if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86_64" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.11-1/emscripten-1.38.11-1-x86_64-unknown-linux-gnu.tgz",
                name: "emscripten",
                version: "1.38.11-1",
                arch: "x86_64-unknown-linux-gnu",
                hash: "cc2727143297c37323c051e2d170fb3b31f43a38999954f812cdca1232555fd5",
                size: 211418062
            }
        } else if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.11-1/emscripten-1.38.11-1-i686-unknown-linux-gnu.tgz",
                name: "emscripten",
                version: "1.38.11-1",
                arch: "i686-unknown-linux-gnu",
                hash: "6be9f70fa79c096688aa630b8fe33df7e6f35716088c28c6fb058921c0ba927e",
                size: 223690133
            }
        } else {
            return None;
        };

    Some( package )
}

fn binaryen_package() -> Option< PrebuiltPackage > {
    let package =
        if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86_64" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.11-1/binaryen-1.38.11-1-x86_64-unknown-linux-gnu.tgz",
                name: "binaryen",
                version: "1.38.11-1",
                arch: "x86_64-unknown-linux-gnu",
                hash: "1035effafac158fc1342a80a16cd800b4fd8418b6100b1e7cc4fd385cd13d801",
                size: 15048525
            }
        } else if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.11-1/binaryen-1.38.11-1-i686-unknown-linux-gnu.tgz",
                name: "binaryen",
                version: "1.38.11-1",
                arch: "i686-unknown-linux-gnu",
                hash: "6bca8f2378e86dfa3305bffc3dc231ace15f93904dab138692c8f8fb3814d337",
                size: 15042751
            }
        } else {
            return None;
        };

    Some( package )
}

fn check_emscripten() {
    let possible_commands =
        if cfg!( windows ) {
            &[ "emcc.bat" ]
        } else {
            &[ "emcc" ]
        };

    if find_cmd( possible_commands ).is_some() {
        return;
    }

    eprintln!( "error: you don't have Emscripten installed!" );
    eprintln!( "" );

    if Path::new( "/usr/bin/pacman" ).exists() {
        eprintln!( "You can most likely install it like this:" );
        eprintln!( "  sudo pacman -S emscripten" );
    } else if Path::new( "/usr/bin/apt-get" ).exists() {
        eprintln!( "You can most likely install it like this:" );
        eprintln!( "  sudo apt-get install emscripten" );
    } else if cfg!( target_os = "linux" ) {
        eprintln!( "You can most likely find it in your distro's repositories." );
    } else if cfg!( target_os = "windows" ) {
        eprintln!( "Download and install emscripten from the official site: http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html" );
    }

    if cfg!( unix ) {
        if cfg!( target_os = "linux" ) {
            eprintln!( "If not you can install it manually like this:" );
        } else {
            eprintln!( "You can install it manually like this:" );
        }
        eprintln!( "  curl -O https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz" );
        eprintln!( "  tar -xzf emsdk-portable.tar.gz" );
        eprintln!( "  source emsdk_portable/emsdk_env.sh" );
        eprintln!( "  emsdk update" );
        eprintln!( "  emsdk install sdk-incoming-64bit" );
        eprintln!( "  emsdk activate sdk-incoming-64bit" );
    }

    exit( 101 );
}

pub struct Emscripten {
    pub binaryen_path: Option< PathBuf >,
    pub emscripten_path: PathBuf,
    pub emscripten_llvm_path: PathBuf
}

pub fn initialize_emscripten(
    use_system_emscripten: bool,
    targeting_webasm: bool
) -> Option< Emscripten > {

    if use_system_emscripten {
        check_emscripten();
        return None;
    }

    let emscripten_package = match emscripten_package() {
        Some( pkg ) => pkg,
        None => {
            check_emscripten();
            return None;
        }
    };

    let binaryen_package = if targeting_webasm {
        match binaryen_package() {
            Some( pkg ) => Some( pkg ),
            None => {
                check_emscripten();
                return None;
            }
        }
    } else {
        None
    };

    let emscripten_root = download_package( &emscripten_package );
    let emscripten_path = emscripten_root.join( "emscripten" );
    let emscripten_llvm_path = emscripten_root.join( "emscripten-fastcomp" );
    let binaryen_path = if let Some( binaryen_package ) = binaryen_package {
        let binaryen_root = download_package( &binaryen_package );
        Some( binaryen_root.join( "binaryen" ) )
    } else {
        None
    };

    Some( Emscripten {
        binaryen_path,
        emscripten_path,
        emscripten_llvm_path
    })
}
<commit_msg>Update to Emscripten 1.38.19<commit_after>use std::process::exit;
use std::path::{Path, PathBuf};

use package::{
    PrebuiltPackage,
    download_package
};
use utils::find_cmd;

fn emscripten_package() -> Option< PrebuiltPackage > {
    let package =
        if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86_64" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.19-1/emscripten-1.38.19-1-x86_64-unknown-linux-gnu.tgz",
                name: "emscripten",
                version: "1.38.19-1",
                arch: "x86_64-unknown-linux-gnu",
                hash: "baab5f1162901bfa220cb009dc628300c5e67b91cf58656ab6bf392d513bff9c",
                size: 211505607
            }
        } else if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.19-1/emscripten-1.38.19-1-i686-unknown-linux-gnu.tgz",
                name: "emscripten",
                version: "1.38.19-1",
                arch: "i686-unknown-linux-gnu",
                hash: "6d211eb0e9bbf82a1bf0dcc336486aa5191952f3938b7c0cf76b8d6946d4c117",
                size: 223770839
            }
        } else {
            return None;
        };

    Some( package )
}

fn binaryen_package() -> Option< PrebuiltPackage > {
    let package =
        if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86_64" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.19-1/binaryen-1.38.19-1-x86_64-unknown-linux-gnu.tgz",
                name: "binaryen",
                version: "1.38.19-1",
                arch: "x86_64-unknown-linux-gnu",
                hash: "af079258c6f13234541d932b873762910951779c4682fc917255716637383dc9",
                size: 15818455
            }
        } else if cfg!( target_os = "linux" ) && cfg!( target_arch = "x86" ) {
            PrebuiltPackage {
                url: "https://github.com/koute/emscripten-build/releases/download/emscripten-1.38.19-1/binaryen-1.38.19-1-i686-unknown-linux-gnu.tgz",
                name: "binaryen",
                version: "1.38.19-1",
                arch: "i686-unknown-linux-gnu",
                hash: "9fd0e30d1760d29e3c96fa24592a35629876316fadb7ef882b9c6d8b2eafb0d8",
                size: 15951181
            }
        } else {
            return None;
        };

    Some( package )
}

fn check_emscripten() {
    let possible_commands =
        if cfg!( windows ) {
            &[ "emcc.bat" ]
        } else {
            &[ "emcc" ]
        };

    if find_cmd( possible_commands ).is_some() {
        return;
    }

    eprintln!( "error: you don't have Emscripten installed!" );
    eprintln!( "" );

    if Path::new( "/usr/bin/pacman" ).exists() {
        eprintln!( "You can most likely install it like this:" );
        eprintln!( "  sudo pacman -S emscripten" );
    } else if Path::new( "/usr/bin/apt-get" ).exists() {
        eprintln!( "You can most likely install it like this:" );
        eprintln!( "  sudo apt-get install emscripten" );
    } else if cfg!( target_os = "linux" ) {
        eprintln!( "You can most likely find it in your distro's repositories." );
    } else if cfg!( target_os = "windows" ) {
        eprintln!( "Download and install emscripten from the official site: http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html" );
    }

    if cfg!( unix ) {
        if cfg!( target_os = "linux" ) {
            eprintln!( "If not you can install it manually like this:" );
        } else {
            eprintln!( "You can install it manually like this:" );
        }
        eprintln!( "  curl -O https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz" );
        eprintln!( "  tar -xzf emsdk-portable.tar.gz" );
        eprintln!( "  source emsdk_portable/emsdk_env.sh" );
        eprintln!( "  emsdk update" );
        eprintln!( "  emsdk install sdk-incoming-64bit" );
        eprintln!( "  emsdk activate sdk-incoming-64bit" );
    }

    exit( 101 );
}

pub struct Emscripten {
    pub binaryen_path: Option< PathBuf >,
    pub emscripten_path: PathBuf,
    pub emscripten_llvm_path: PathBuf
}

pub fn initialize_emscripten(
    use_system_emscripten: bool,
    targeting_webasm: bool
) -> Option< Emscripten > {

    if use_system_emscripten {
        check_emscripten();
        return None;
    }

    let emscripten_package = match emscripten_package() {
        Some( pkg ) => pkg,
        None => {
            check_emscripten();
            return None;
        }
    };

    let binaryen_package = if targeting_webasm {
        match binaryen_package() {
            Some( pkg ) => Some( pkg ),
            None => {
                check_emscripten();
                return None;
            }
        }
    } else {
        None
    };

    let emscripten_root = download_package( &emscripten_package );
    let emscripten_path = emscripten_root.join( "emscripten" );
    let emscripten_llvm_path = emscripten_root.join( "emscripten-fastcomp" );
    let binaryen_path = if let Some( binaryen_package ) = binaryen_package {
        let binaryen_root = download_package( &binaryen_package );
        Some( binaryen_root.join( "binaryen" ) )
    } else {
        None
    };

    Some( Emscripten {
        binaryen_path,
        emscripten_path,
        emscripten_llvm_path
    })
}
<|endoftext|>