<commit_before>use unicode_width::UnicodeWidthStr;
use std::io::{self, Write};
use std::iter::FromIterator;
use std::fmt::{self, Write as FmtWrite};

#[derive(Debug,Clone)]
pub enum Action {
    Insert { start: usize, text: Vec<char> },
    Remove { start: usize, text: Vec<char> },
}

impl Action {
    pub fn do_on(&self, buf: &mut Buffer) {
        match *self {
            Action::Insert { start, ref text } => buf.insert_raw(start, &text[..]),
            Action::Remove { start, ref text } => {
                buf.remove_raw(start, start + text.len());
            }
        }
    }

    pub fn undo(&self, buf: &mut Buffer) {
        match *self {
            Action::Insert { start, ref text } => {
                buf.remove_raw(start, start + text.len());
            }
            Action::Remove { start, ref text } => buf.insert_raw(start, &text[..]),
        }
    }
}

#[derive(Debug, Clone)]
pub struct Buffer {
    data: Vec<char>,
    actions: Vec<Action>,
    undone_actions: Vec<Action>,
}

impl From<Buffer> for String {
    fn from(buf: Buffer) -> Self {
        String::from_iter(buf.data)
    }
}

impl From<String> for Buffer {
    fn from(s: String) -> Self {
        Buffer::from_iter(s.chars())
    }
}

impl<'a> From<&'a str> for Buffer {
    fn from(s: &'a str) -> Self {
        Buffer::from_iter(s.chars())
    }
}

impl fmt::Display for Buffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for &c in &self.data {
            try!(f.write_char(c));
        }
        Ok(())
    }
}

impl FromIterator<char> for Buffer {
    fn from_iter<T: IntoIterator<Item = char>>(t: T) -> Self {
        Buffer {
            data: t.into_iter().collect(),
            actions: Vec::new(),
            undone_actions: Vec::new(),
        }
    }
}

impl Buffer {
    pub fn new() -> Self {
        Buffer {
            data: Vec::new(),
            actions: Vec::new(),
            undone_actions: Vec::new(),
        }
    }

    pub fn clear_actions(&mut self) {
        self.actions.clear();
        self.undone_actions.clear();
    }

    pub fn undo(&mut self) -> bool {
        match self.actions.pop() {
            None => false,
            Some(act) => {
                act.undo(self);
                self.undone_actions.push(act);
                true
            }
        }
    }

    pub fn redo(&mut self) -> bool {
        match self.undone_actions.pop() {
            None => false,
            Some(act) => {
                act.do_on(self);
                self.actions.push(act);
                true
            }
        }
    }

    pub fn revert(&mut self) -> bool {
        if self.actions.len() == 0 {
            return false;
        }

        while self.undo() {}
        true
    }

    fn push_action(&mut self, act: Action) {
        self.actions.push(act);
        self.undone_actions.clear();
    }

    pub fn num_chars(&self) -> usize {
        self.data.len()
    }

    pub fn num_bytes(&self) -> usize {
        let s: String = self.clone().into();
        s.len()
    }

    pub fn width(&self) -> usize {
        self.range_width(0, self.num_chars())
    }

    pub fn char_before(&self, cursor: usize) -> Option<char> {
        if cursor == 0 {
            None
        } else {
            self.data.get(cursor - 1).cloned()
        }
    }

    pub fn char_after(&self, cursor: usize) -> Option<char> {
        self.data.get(cursor).cloned()
    }

    /// Returns the number of characters removed.
    pub fn remove(&mut self, start: usize, end: usize) -> usize {
        let s = self.remove_raw(start, end);
        let num_removed = s.len();
        let act = Action::Remove {
            start: start,
            text: s,
        };
        self.push_action(act);
        num_removed
    }

    pub fn insert(&mut self, start: usize, text: &[char]) {
        let act = Action::Insert {
            start: start,
            text: text.into(),
        };
        act.do_on(self);
        self.push_action(act);
    }

    pub fn range(&self, start: usize, end: usize) -> String {
        self.data[start..end].iter().cloned().collect()
    }

    pub fn range_chars(&self, start: usize, end: usize) -> Vec<char> {
        self.data[start..end].iter().cloned().collect()
    }

    pub fn range_width(&self, start: usize, end: usize) -> usize {
        self.range(start, end)[..].width()
    }

    pub fn chars(&self) -> ::std::slice::Iter<char> {
        self.data.iter()
    }

    pub fn truncate(&mut self, num: usize) {
        let end = self.data.len();
        self.remove(num, end);
    }

    pub fn print<W>(&self, out: &mut W) -> io::Result<()>
        where W: Write
    {
        let string: String = self.data.iter().cloned().collect();
        try!(out.write(string.as_bytes()));

        Ok(())
    }

    fn remove_raw(&mut self, start: usize, end: usize) -> Vec<char> {
        self.data.drain(start..end).collect()
    }

    fn insert_raw(&mut self, start: usize, text: &[char]) {
        for (i, &c) in text.iter().enumerate() {
            self.data.insert(start + i, c)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_insert() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_empty() {
        let mut buf = Buffer::new();
        buf.truncate(0);
        assert_eq!(String::from(buf), "");
    }

    #[test]
    fn test_truncate_all() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(0);
        assert_eq!(String::from(buf), "");
    }

    #[test]
    fn test_truncate_end() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        let end = buf.num_chars();
        buf.truncate(end);
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_part() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(3);
        assert_eq!(String::from(buf), "abc");
    }

    #[test]
    fn test_truncate_empty_undo() {
        let mut buf = Buffer::new();
        buf.truncate(0);
        buf.undo();
        assert_eq!(String::from(buf), "");
    }

    #[test]
    fn test_truncate_all_then_undo() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(0);
        buf.undo();
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_end_then_undo() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        let end = buf.num_chars();
        buf.truncate(end);
        buf.undo();
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_part_then_undo() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(3);
        buf.undo();
        assert_eq!(String::from(buf), "abcdefg");
    }
}
<commit_msg>support undoing commands in groups<commit_after>use unicode_width::UnicodeWidthStr;
use std::io::{self, Write};
use std::iter::FromIterator;
use std::fmt::{self, Write as FmtWrite};

#[derive(Debug,Clone)]
pub enum Action {
    Insert { start: usize, text: Vec<char> },
    Remove { start: usize, text: Vec<char> },
    StartGroup,
    EndGroup,
}

impl Action {
    pub fn do_on(&self, buf: &mut Buffer) {
        match *self {
            Action::Insert { start, ref text } => buf.insert_raw(start, &text[..]),
            Action::Remove { start, ref text } => {
                buf.remove_raw(start, start + text.len());
            }
            Action::StartGroup | Action::EndGroup => {}
        }
    }

    pub fn undo(&self, buf: &mut Buffer) {
        match *self {
            Action::Insert { start, ref text } => {
                buf.remove_raw(start, start + text.len());
            }
            Action::Remove { start, ref text } => buf.insert_raw(start, &text[..]),
            Action::StartGroup | Action::EndGroup => {}
        }
    }
}

#[derive(Debug, Clone)]
pub struct Buffer {
    data: Vec<char>,
    actions: Vec<Action>,
    undone_actions: Vec<Action>,
}

impl From<Buffer> for String {
    fn from(buf: Buffer) -> Self {
        String::from_iter(buf.data)
    }
}

impl From<String> for Buffer {
    fn from(s: String) -> Self {
        Buffer::from_iter(s.chars())
    }
}

impl<'a> From<&'a str> for Buffer {
    fn from(s: &'a str) -> Self {
        Buffer::from_iter(s.chars())
    }
}

impl fmt::Display for Buffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for &c in &self.data {
            try!(f.write_char(c));
        }
        Ok(())
    }
}

impl FromIterator<char> for Buffer {
    fn from_iter<T: IntoIterator<Item = char>>(t: T) -> Self {
        Buffer {
            data: t.into_iter().collect(),
            actions: Vec::new(),
            undone_actions: Vec::new(),
        }
    }
}

impl Buffer {
    pub fn new() -> Self {
        Buffer {
            data: Vec::new(),
            actions: Vec::new(),
            undone_actions: Vec::new(),
        }
    }

    pub fn clear_actions(&mut self) {
        self.actions.clear();
        self.undone_actions.clear();
    }

    pub fn start_undo_group(&mut self) {
        self.actions.push(Action::StartGroup);
    }

    pub fn end_undo_group(&mut self) {
        self.actions.push(Action::EndGroup);
    }

    pub fn undo(&mut self) -> bool {
        use Action::*;

        let did = !self.actions.is_empty();
        let mut group_nest = 0;
        let mut group_count = 0;
        while let Some(act) = self.actions.pop() {
            act.undo(self);
            self.undone_actions.push(act.clone());
            match act {
                EndGroup => {
                    group_nest += 1;
                    group_count = 0;
                }
                StartGroup => group_nest -= 1,
                // count the actions in this group so we can ignore empty groups below
                _ => group_count += 1,
            }

            // if we aren't in a group, and the last group wasn't empty
            if group_nest == 0 && group_count > 0 {
                break;
            }
        }
        did
    }

    pub fn redo(&mut self) -> bool {
        use Action::*;

        let did = !self.undone_actions.is_empty();
        let mut group_nest = 0;
        let mut group_count = 0;
        while let Some(act) = self.undone_actions.pop() {
            act.do_on(self);
            self.actions.push(act.clone());
            match act {
                StartGroup => {
                    group_nest += 1;
                    group_count = 0;
                }
                EndGroup => group_nest -= 1,
                // count the actions in this group so we can ignore empty groups below
                _ => group_count += 1,
            }

            // if we aren't in a group, and the last group wasn't empty
            if group_nest == 0 && group_count > 0 {
                break;
            }
        }
        did
    }

    pub fn revert(&mut self) -> bool {
        if self.actions.len() == 0 {
            return false;
        }

        while self.undo() {}
        true
    }

    fn push_action(&mut self, act: Action) {
        self.actions.push(act);
        self.undone_actions.clear();
    }

    pub fn num_chars(&self) -> usize {
        self.data.len()
    }

    pub fn num_bytes(&self) -> usize {
        let s: String = self.clone().into();
        s.len()
    }

    pub fn width(&self) -> usize {
        self.range_width(0, self.num_chars())
    }

    pub fn char_before(&self, cursor: usize) -> Option<char> {
        if cursor == 0 {
            None
        } else {
            self.data.get(cursor - 1).cloned()
        }
    }

    pub fn char_after(&self, cursor: usize) -> Option<char> {
        self.data.get(cursor).cloned()
    }

    /// Returns the number of characters removed.
    pub fn remove(&mut self, start: usize, end: usize) -> usize {
        let s = self.remove_raw(start, end);
        let num_removed = s.len();
        let act = Action::Remove {
            start: start,
            text: s,
        };
        self.push_action(act);
        num_removed
    }

    pub fn insert(&mut self, start: usize, text: &[char]) {
        let act = Action::Insert {
            start: start,
            text: text.into(),
        };
        act.do_on(self);
        self.push_action(act);
    }

    pub fn range(&self, start: usize, end: usize) -> String {
        self.data[start..end].iter().cloned().collect()
    }

    pub fn range_chars(&self, start: usize, end: usize) -> Vec<char> {
        self.data[start..end].iter().cloned().collect()
    }

    pub fn range_width(&self, start: usize, end: usize) -> usize {
        self.range(start, end)[..].width()
    }

    pub fn chars(&self) -> ::std::slice::Iter<char> {
        self.data.iter()
    }

    pub fn truncate(&mut self, num: usize) {
        let end = self.data.len();
        self.remove(num, end);
    }

    pub fn print<W>(&self, out: &mut W) -> io::Result<()>
        where W: Write
    {
        let string: String = self.data.iter().cloned().collect();
        try!(out.write(string.as_bytes()));

        Ok(())
    }

    fn remove_raw(&mut self, start: usize, end: usize) -> Vec<char> {
        self.data.drain(start..end).collect()
    }

    fn insert_raw(&mut self, start: usize, text: &[char]) {
        for (i, &c) in text.iter().enumerate() {
            self.data.insert(start + i, c)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_insert() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_empty() {
        let mut buf = Buffer::new();
        buf.truncate(0);
        assert_eq!(String::from(buf), "");
    }

    #[test]
    fn test_truncate_all() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(0);
        assert_eq!(String::from(buf), "");
    }

    #[test]
    fn test_truncate_end() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        let end = buf.num_chars();
        buf.truncate(end);
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_part() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(3);
        assert_eq!(String::from(buf), "abc");
    }

    #[test]
    fn test_truncate_empty_undo() {
        let mut buf = Buffer::new();
        buf.truncate(0);
        buf.undo();
        assert_eq!(String::from(buf), "");
    }

    #[test]
    fn test_truncate_all_then_undo() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(0);
        buf.undo();
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_end_then_undo() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        let end = buf.num_chars();
        buf.truncate(end);
        buf.undo();
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_truncate_part_then_undo() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.truncate(3);
        buf.undo();
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_undo_group() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.start_undo_group();
        buf.remove(0, 1);
        buf.remove(0, 1);
        buf.remove(0, 1);
        buf.end_undo_group();
        assert_eq!(buf.undo(), true);
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_redo_group() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.start_undo_group();
        buf.remove(0, 1);
        buf.remove(0, 1);
        buf.remove(0, 1);
        buf.end_undo_group();
        assert_eq!(buf.undo(), true);
        assert_eq!(buf.redo(), true);
        assert_eq!(String::from(buf), "defg");
    }

    #[test]
    fn test_nested_undo_group() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.start_undo_group();
        buf.remove(0, 1);
        buf.start_undo_group();
        buf.remove(0, 1);
        buf.end_undo_group();
        buf.remove(0, 1);
        buf.end_undo_group();
        assert_eq!(buf.undo(), true);
        assert_eq!(String::from(buf), "abcdefg");
    }

    #[test]
    fn test_nested_redo_group() {
        let mut buf = Buffer::new();
        buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
        buf.start_undo_group();
        buf.remove(0, 1);
        buf.start_undo_group();
        buf.remove(0, 1);
        buf.end_undo_group();
        buf.remove(0, 1);
        buf.end_undo_group();
        assert_eq!(buf.undo(), true);
        assert_eq!(buf.redo(), true);
        assert_eq!(String::from(buf), "defg");
    }
}
<|endoftext|>


<commit_before>//! Handles parsing GPX format.

// Just a shared macro for testing 'consume'.
#[cfg(test)]
#[macro_export]
macro_rules! consume {
    ($xml: expr, $version: expr) => {{
        let reader = BufReader::new($xml.as_bytes());
        let events = EventReader::new(reader).into_iter().peekable();
        let mut context = Context::new(events, $version);
        consume(&mut context)
    }};
}

pub mod bounds;
pub mod email;
pub mod extensions;
pub mod fix;
pub mod gpx;
pub mod link;
pub mod metadata;
pub mod person;
pub mod string;
pub mod time;
pub mod track;
pub mod tracksegment;
pub mod waypoint;

use errors::*;
use std::io::Read;
use std::iter::Peekable;
use xml::reader::Events;
use xml::reader::XmlEvent;
use xml::attribute::OwnedAttribute;
use types::GpxVersion;

pub struct Context<R: Read> {
    reader: Peekable<Events<R>>,
    version: GpxVersion,
}

impl<R: Read> Context<R> {
    pub fn new(reader: Peekable<Events<R>>, version: GpxVersion) -> Context<R> {
        Context { reader, version }
    }

    pub fn reader(&mut self) -> &mut Peekable<Events<R>> {
        &mut self.reader
    }
}

pub fn verify_starting_tag<R: Read>(
    context: &mut Context<R>,
    local_name: &'static str,
) -> Result<(Vec<OwnedAttribute>)> {
    //makes sure the specified starting tag is the next tag on the stream
    //we ignore and skip all xmlevents except StartElement, Characters and EndElement
    loop {
        let next = context.reader.next();
        println!("{:?}", next);
        match next {
            Some(Ok(XmlEvent::StartElement {
                name, attributes, ..
            })) => {
                ensure!(
                    name.local_name == local_name,
                    ErrorKind::InvalidChildElement(name.local_name, local_name)
                );
                return Ok(attributes);
            }
            Some(Ok(XmlEvent::EndElement { name, .. })) => {
                bail!(ErrorKind::InvalidChildElement(name.local_name, local_name));
            }
            Some(Ok(XmlEvent::Characters(chars))) => {
                bail!(ErrorKind::InvalidChildElement(chars, local_name));
            }
            Some(_) => {} //ignore other elements
            None => bail!("did not find expected opening tag for {}", local_name),
        }
    }
}
<commit_msg>Add helper function verify_starting_tag (unused for now)<commit_after>//! Handles parsing GPX format.

// Just a shared macro for testing 'consume'.
#[cfg(test)]
#[macro_export]
macro_rules! consume {
    ($xml: expr, $version: expr) => {{
        let reader = BufReader::new($xml.as_bytes());
        let events = EventReader::new(reader).into_iter().peekable();
        let mut context = Context::new(events, $version);
        consume(&mut context)
    }};
}

pub mod bounds;
pub mod email;
pub mod extensions;
pub mod fix;
pub mod gpx;
pub mod link;
pub mod metadata;
pub mod person;
pub mod string;
pub mod time;
pub mod track;
pub mod tracksegment;
pub mod waypoint;

use errors::*;
use std::io::Read;
use std::iter::Peekable;
use xml::reader::Events;
use xml::reader::XmlEvent;
use xml::attribute::OwnedAttribute;
use types::GpxVersion;

pub struct Context<R: Read> {
    reader: Peekable<Events<R>>,
    version: GpxVersion,
}

impl<R: Read> Context<R> {
    pub fn new(reader: Peekable<Events<R>>, version: GpxVersion) -> Context<R> {
        Context { reader, version }
    }

    pub fn reader(&mut self) -> &mut Peekable<Events<R>> {
        &mut self.reader
    }
}

pub fn verify_starting_tag<R: Read>(
    context: &mut Context<R>,
    local_name: &'static str,
) -> Result<(Vec<OwnedAttribute>)> {
    //makes sure the specified starting tag is the next tag on the stream
    //we ignore and skip all xmlevents except StartElement, Characters and EndElement
    loop {
        let next = context.reader.next();
        match next {
            Some(Ok(XmlEvent::StartElement {
                name, attributes, ..
            })) => {
                ensure!(
                    name.local_name == local_name,
                    ErrorKind::InvalidChildElement(name.local_name, local_name)
                );
                return Ok(attributes);
            }
            Some(Ok(XmlEvent::EndElement { name, .. })) => {
                bail!(ErrorKind::InvalidChildElement(name.local_name, local_name));
            }
            Some(Ok(XmlEvent::Characters(chars))) => {
                bail!(ErrorKind::InvalidChildElement(chars, local_name));
            }
            Some(_) => {} //ignore other elements
            None => bail!("did not find expected opening tag for {}", local_name),
        }
    }
}
<|endoftext|>


<commit_before>extern {
    #[link_name = "__GPIOA__"] static GPIOA: ::gpio::Gpio;
    #[link_name = "__GPIOB__"] static GPIOB: ::gpio::Gpio;
    #[link_name = "__GPIOC__"] static GPIOC: ::gpio::Gpio;
    #[link_name = "__RCC__"] static RCC: ::rcc::Rcc;
    #[link_name = "__TIM7__"] static TIM7: ::tim::Tim;
}

pub fn gpioa() -> &'static ::gpio::Gpio {
    &GPIOA
}

pub fn gpiob() -> &'static ::gpio::Gpio {
    &GPIOB
}

pub fn gpioc() -> &'static ::gpio::Gpio {
    &GPIOC
}

pub fn rcc() -> &'static ::rcc::Rcc {
    &RCC
}

pub fn tim7() -> &'static ::tim::Tim {
    &TIM7
}
<commit_msg>refactor(peripheral): avoid `link_name` by renaming the static variables<commit_after>extern {
    static __GPIOA__: ::gpio::Gpio;
    static __GPIOB__: ::gpio::Gpio;
    static __GPIOC__: ::gpio::Gpio;
    static __RCC__: ::rcc::Rcc;
    static __TIM7__: ::tim::Tim;
}

pub fn gpioa() -> &'static ::gpio::Gpio {
    &__GPIOA__
}

pub fn gpiob() -> &'static ::gpio::Gpio {
    &__GPIOB__
}

pub fn gpioc() -> &'static ::gpio::Gpio {
    &__GPIOC__
}

pub fn rcc() -> &'static ::rcc::Rcc {
    &__RCC__
}

pub fn tim7() -> &'static ::tim::Tim {
    &__TIM7__
}
<|endoftext|>


<commit_before>use std::io;
use std::net::SocketAddr;

use futures::Future;

use tokio_core::reactor::Handle;
use tokio_core::io::{Framed, Io};
use tokio_core::net::TcpStream;
use tokio_core::io::{Codec, EasyBuf};
use tokio_proto::TcpClient;
use tokio_proto::multiplex::{ClientProto, ClientService};
use tokio_proto::streaming::multiplex::RequestIdSource;
use tokio_service::Service;

use package::Package;
use codec::PackageCodec;

use uuid::Uuid;

pub struct EventStoreClient {
    inner: ClientService<TcpStream, PackageProto>,
}

impl EventStoreClient {
    pub fn connect(addr: &SocketAddr, handle: &Handle) -> Box<Future<Item = Self, Error = io::Error>> {
        let ret = TcpClient::new(PackageProto)
            .connect(addr, handle)
            .map(|client_service| {
                EventStoreClient { inner: client_service }
            });

        Box::new(ret)
    }
}

impl Service for EventStoreClient {
    type Request = Package;
    type Response = Package;
    type Error = io::Error;
    type Future = Box<Future<Item = Package, Error = io::Error>>;

    fn call(&self, req: Package) -> Self::Future {
        Box::new(self.inner.call(req))
    }
}

/*
/// Simple middleware
struct Heartbeats<T> {
    inner: T,
}

impl<T> Stream for Heartbeats<T>
    where T: Service<Request = Package, Response = Package, Error = io::Error>,
          T::Future: 'static
{
    type Request = Package;
    type Response = Package;
    type Error = io::Error;
    type Future = Box<Future<Item = Package, Error = io::Error>>;

    fn call(&self, req: Package) -> Self::Future {
        if self.credentials.as_ref().is_some() && req.authentication.is_none() {
            req.authentication = self.credentials.clone();
        }

        self.inner.call(req)
    }
}
*/

struct Separator;

impl Codec for Separator {
    type In = (Uuid, Package);
    type Out = (Uuid, Package);

    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        PackageCodec.decode(buf).map(|x| x.map(|x| (x.correlation_id, x)))
    }

    fn encode(&mut self, msg: (Uuid, Package), buf: &mut Vec<u8>) -> io::Result<()> {
        let (id, pkg) = msg;
        assert_eq!(id, pkg.correlation_id);
        PackageCodec.encode(pkg, buf)
    }
}

impl RequestIdSource<Uuid, Package> for Separator {
    fn next(&mut self, pkg: &Package) -> Uuid {
        pkg.correlation_id
    }
}

struct PackageProto;

impl<T: Io + 'static> ClientProto<T> for PackageProto {
    type Request = Package;
    type Response = Package;
    type RequestId = Uuid;

    type Transport = Framed<T, Separator>;
    type BindTransport = Result<Self::Transport, io::Error>;
    type RequestIds = Separator;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(Separator))
    }

    fn requestid_source(&self) -> Self::RequestIds {
        Separator
    }
}
<commit_msg>track tokio-proto pr<commit_after>use std::io;
use std::net::SocketAddr;

use futures::Future;

use tokio_core::reactor::Handle;
use tokio_core::io::{Framed, Io};
use tokio_core::net::TcpStream;
use tokio_core::io::{Codec, EasyBuf};
use tokio_proto::TcpClient;
use tokio_proto::multiplex::{ClientProto, ClientService, RequestIdSource};
use tokio_service::Service;

use package::Package;
use codec::PackageCodec;

use uuid::Uuid;

pub struct EventStoreClient {
    inner: ClientService<TcpStream, PackageProto>,
}

impl EventStoreClient {
    pub fn connect(addr: &SocketAddr, handle: &Handle) -> Box<Future<Item = Self, Error = io::Error>> {
        let ret = TcpClient::new(PackageProto)
            .connect(addr, handle)
            .map(|client_service| {
                EventStoreClient { inner: client_service }
            });

        Box::new(ret)
    }
}

impl Service for EventStoreClient {
    type Request = Package;
    type Response = Package;
    type Error = io::Error;
    type Future = Box<Future<Item = Package, Error = io::Error>>;

    fn call(&self, req: Package) -> Self::Future {
        Box::new(self.inner.call(req))
    }
}

/*
/// Simple middleware
struct Heartbeats<T> {
    inner: T,
}

impl<T> Stream for Heartbeats<T>
    where T: Service<Request = Package, Response = Package, Error = io::Error>,
          T::Future: 'static
{
    type Request = Package;
    type Response = Package;
    type Error = io::Error;
    type Future = Box<Future<Item = Package, Error = io::Error>>;

    fn call(&self, req: Package) -> Self::Future {
        if self.credentials.as_ref().is_some() && req.authentication.is_none() {
            req.authentication = self.credentials.clone();
        }

        self.inner.call(req)
    }
}
*/

struct Separator;

impl Codec for Separator {
    type In = (Uuid, Package);
    type Out = (Uuid, Package);

    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        PackageCodec.decode(buf).map(|x| x.map(|x| (x.correlation_id, x)))
    }

    fn encode(&mut self, msg: (Uuid, Package), buf: &mut Vec<u8>) -> io::Result<()> {
        let (id, pkg) = msg;
        assert_eq!(id, pkg.correlation_id);
        PackageCodec.encode(pkg, buf)
    }
}

impl RequestIdSource<Uuid, Package> for Separator {
    fn next(&mut self, pkg: &Package) -> Uuid {
        pkg.correlation_id
    }
}

struct PackageProto;

impl<T: Io + 'static> ClientProto<T> for PackageProto {
    type Request = Package;
    type Response = Package;
    type RequestId = Uuid;

    type Transport = Framed<T, Separator>;
    type BindTransport = Result<Self::Transport, io::Error>;
    type RequestIdSource = Separator;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(Separator))
    }

    fn requestid_source(&self) -> Self::RequestIdSource {
        Separator
    }
}
<|endoftext|>


<commit_before>/// Run as an application, this is the starting point for our app

extern crate rustc_serialize;

use rustc_serialize::json::Json;
use std::slice::SliceConcatExt;

use std::process::Command;
use std::path::Path;
use std::vec::Vec;

pub enum ClippyState {
    Success,
    WithWarnings,
    WithErrors,
}

pub struct ClippyResult {
    pub ended: ClippyState,
    pub warnings: u8,
    pub errors: u8,
}

pub fn run<F>(path: &Path, logger: F) -> Result<ClippyResult, String>
    where F: Fn(&str)
{
    match Command::new("cargo")
              .args(&["rustc",
                      "--",
                      "-Zunstable-options",
                      "-Zextra-plugins=clippy",
                      "-Zno-trans",
                      "-lclippy",
                      "--error-format=json"])
              .current_dir(path)
              .output() {
        Ok(output) => {
            let mut warnings = 0;
            let mut errors = 0;
            let messages: Vec<String> = String::from_utf8(output.stderr)
                                            .unwrap()
                                            .split('\n')
                                            .filter_map(|line| Json::from_str(&line).ok())
                                            .filter_map(|json| {
                                                let obj = json.as_object().unwrap();
                                                match obj.get("level") {
                                                    Some(&Json::String(ref level)) => {
                                                        if level == "warning" {
                                                            warnings += 1;
                                                        } else if level == "error" {
                                                            errors += 1;
                                                        }
                                                        Some(format!("{level}: {msg}",
                                                                     level = level,
                                                                     msg = obj.get("message")
                                                                              .unwrap()))
                                                    }
                                                    _ => None,
                                                }
                                            })
                                            .collect();

            logger(&format!("Messages:\n {}", messages.join("\n")));

            if output.status.success() {
                match (errors, warnings) {
                    (0, 0) => {
                        Ok(ClippyResult {
                            ended: ClippyState::Success,
                            warnings: 0,
                            errors: 0,
                        })
                    }
                    (0, x) => {
                        Ok(ClippyResult {
                            ended: ClippyState::WithWarnings,
                            warnings: x,
                            errors: 0,
                        })
                    }
                    _ => {
                        Ok(ClippyResult {
                            ended: ClippyState::WithErrors,
                            warnings: warnings,
                            errors: errors,
                        })
                    }
                }
            } else {
                Err(format!("Clippy failed with Error code: {}",
                            output.status.code().unwrap_or(-999)))
            }
        }
        Err(error) => Err(format!("Running Clippy failed: {}", error)),
    }
}
<commit_msg>Include our clippy lib in execution context, fixes #5<commit_after>/// Run as an application, this is the starting point for our app

extern crate rustc_serialize;

use rustc_serialize::json::Json;
use std::slice::SliceConcatExt;

use std::process::Command;
use std::path::Path;
use std::vec::Vec;
use std::{env, fs};

pub enum ClippyState {
    Success,
    WithWarnings,
    WithErrors,
}

pub struct ClippyResult {
    pub ended: ClippyState,
    pub warnings: u8,
    pub errors: u8,
}

pub fn run<F>(path: &Path, logger: F) -> Result<ClippyResult, String>
    where F: Fn(&str)
{

    let libs_path = env::current_exe().unwrap();
    let libs_path = fs::canonicalize(libs_path).unwrap();
    let libs_path = libs_path.parent().unwrap();
    let libs_path = libs_path.join("deps");

    match Command::new("cargo")
              .args(&["rustc",
                      "--",
                      "-L",
                      &libs_path.to_string_lossy().into_owned(),
                      "-Zunstable-options",
                      "-Zextra-plugins=clippy",
                      "-Zno-trans",
                      "-lclippy",
                      "--error-format=json"])
              .current_dir(path)
              .output() {
        Ok(output) => {
            let mut warnings = 0;
            let mut errors = 0;
            let messages: Vec<String> = String::from_utf8(output.stderr)
                                            .unwrap()
                                            .split('\n')
                                            .filter_map(|line| Json::from_str(&line).ok())
                                            .filter_map(|json| {
                                                let obj = json.as_object().unwrap();
                                                match obj.get("level") {
                                                    Some(&Json::String(ref level)) => {
                                                        if level == "warning" {
                                                            warnings += 1;
                                                        } else if level == "error" {
                                                            errors += 1;
                                                        }
                                                        Some(format!("{level}: {msg}",
                                                                     level = level,
                                                                     msg = obj.get("message")
                                                                              .unwrap()))
                                                    }
                                                    _ => None,
                                                }
                                            })
                                            .collect();

            logger(&format!("Messages:\n {}", messages.join("\n")));

            if output.status.success() {
                match (errors, warnings) {
                    (0, 0) => {
                        Ok(ClippyResult {
                            ended: ClippyState::Success,
                            warnings: 0,
                            errors: 0,
                        })
                    }
                    (0, x) => {
                        Ok(ClippyResult {
                            ended: ClippyState::WithWarnings,
                            warnings: x,
                            errors: 0,
                        })
                    }
                    _ => {
                        Ok(ClippyResult {
                            ended: ClippyState::WithErrors,
                            warnings: warnings,
                            errors: errors,
                        })
                    }
                }
            } else {
                Err(format!("Clippy failed with Error code: {}",
                            output.status.code().unwrap_or(-999)))
            }
        }
        Err(error) => Err(format!("Running Clippy failed: {}", error)),
    }
}
<|endoftext|>


<commit_before>use super::mode;
use super::string_utils;

#[deriving(Clone)]
#[deriving(Show)]
enum DOC {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Nest(uint, Box<Doc>),
    Text(String),
    Break(uint, uint),
    Newline,
    Group(Box<Doc>)
}

pub type Doc = DOC;

fn fitting(xs:Vec<(uint,mode::Mode,Doc)>, left:uint) -> bool {
    if left as int >= 0 {
        match xs.as_slice() {
            [] => true,
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => fitting(rest.to_vec(), left),
                Append(ref x, ref y) => {
                    let mut ys = [(*i, *mode, *x.clone()), (*i, *mode, *y.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(ys, left)
                },
                Nest(j, ref x) => {
                    let mut ys = [(*i + j, *mode, *x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(ys, left)
                },
                Text(ref str) => fitting(rest.to_vec(), left - str.len()),
                Break(sp, _) => match *mode {
                    mode::Flat => fitting(rest.to_vec(), left - sp),
                    mode::Break => true
                },
                Newline => true,
                Group(ref x) => {
                    let mut ys = [(*i, *mode, *x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(ys, left)
                }
            }
        }
    }
    else {
        false
    }
}

fn prepend<A:Clone>(v: Vec<A>, x:A) -> Vec<A> {
    let mut res = v;
    res.insert(0, x);
    res
}

fn best(w:uint, s:Vec<String>, x:Doc) -> Vec<String> {
    fn go(w:uint, s:Vec<String>, k:uint, xs:Vec<(uint,mode::Mode,Doc)>) -> Vec<String> {
        match xs.as_slice() {
            [] => s.clone(),
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => go(w, s, k, rest.to_vec()),
                Append(ref x, ref y) => {
                    let mut zs = [(*i, *mode, *x.clone()), (*i, *mode, *y.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Nest(j, ref x) => {
                    let mut zs = [(*i + j, *mode, *x.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Text(ref str) => go(w, prepend(s, str.clone()), k + str.len(), rest.to_vec()),
                Newline => go(w, prepend(s, string_utils::nl_space(*i)), *i, rest.to_vec()),
                Break(sp, off) => {
                    match *mode {
                        mode::Flat => go(w, prepend(s.clone(), string_utils::spaces(sp)), k + sp, rest.to_vec()),
                        mode::Break => go(w, prepend(s.clone(), string_utils::nl_space(i + off)), i + off, rest.to_vec())
                    }
                },
                Group(ref x) => {
                    match *mode {
                        mode::Flat => {
                            let mut zs = [(*i, mode::Flat, *x.clone())].to_vec();
                            zs.push_all(*rest);
                            go(w, s, k, zs)
                        },
                        mode::Break => {
                            let mut ys = [(*i, mode::Flat, *x.clone())].to_vec();
                            ys.push_all(*rest);
                            if fitting(ys.clone(), w - k) {
                                go(w, s, k, ys)
                            } else {
                                let mut zs = [(*i, mode::Break, *x.clone())].to_vec();
                                zs.push_all(*rest);
                                go(w, s, k, zs)
                            }
                        }
                    }
                }
            }
        }
    }
    go(w, s, 0, [(0, mode::Break, x)].to_vec())
}

impl Doc {

    pub fn nil() -> Doc {
        Nil
    }

    pub fn append(self, e:Doc) -> Doc {
        match self {
            Nil => e,
            x => match e {
                Nil => x,
                y => Append(box x, box y)
            }
        }
    }

    pub fn nest(self, i:uint) -> Doc {
        Nest(i, box self)
    }

    pub fn text<S:Str>(s:S) -> Doc {
        Text(String::from_str(s.as_slice()))
    }

    pub fn brk(space:uint, offset:uint) -> Doc {
        Break(space, offset)
    }

    pub fn newline() -> Doc {
        Newline
    }

    pub fn group(self) -> Doc {
        Group(box self)
    }

    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    pub fn int(i:int) -> Doc {
        Text(format!("{}", i))
    }

    pub fn char(c:char) -> Doc {
        Text(format!("{}", c))
    }

    pub fn bool(b:bool) -> Doc {
        let res = if b { "true" } else { "false" };
        Text(String::from_str(res))
    }

    pub fn to_string(self, w:uint) -> String {
        let mut strs = best(w, Vec::new(), self);
        strs.reverse();
        strs.push(String::from_str("\n"));
        strs.concat()
    }
}
<commit_msg>Use ToString trait to avoid separate funs<commit_after>use super::mode;
use super::string_utils;

#[deriving(Clone)]
#[deriving(Show)]
enum DOC {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Nest(uint, Box<Doc>),
    Text(String),
    Break(uint, uint),
    Newline,
    Group(Box<Doc>)
}

pub type Doc = DOC;

fn fitting(xs:Vec<(uint,mode::Mode,Doc)>, left:uint) -> bool {
    if left as int >= 0 {
        match xs.as_slice() {
            [] => true,
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => fitting(rest.to_vec(), left),
                Append(ref x, ref y) => {
                    let mut ys = [(*i, *mode, *x.clone()), (*i, *mode, *y.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(ys, left)
                },
                Nest(j, ref x) => {
                    let mut ys = [(*i + j, *mode, *x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(ys, left)
                },
                Text(ref str) => fitting(rest.to_vec(), left - str.len()),
                Break(sp, _) => match *mode {
                    mode::Flat => fitting(rest.to_vec(), left - sp),
                    mode::Break => true
                },
                Newline => true,
                Group(ref x) => {
                    let mut ys = [(*i, *mode, *x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(ys, left)
                }
            }
        }
    }
    else {
        false
    }
}

fn prepend<A:Clone>(v: Vec<A>, x:A) -> Vec<A> {
    let mut res = v;
    res.insert(0, x);
    res
}

fn best(w:uint, s:Vec<String>, x:Doc) -> Vec<String> {
    fn go(w:uint, s:Vec<String>, k:uint, xs:Vec<(uint,mode::Mode,Doc)>) -> Vec<String> {
        match xs.as_slice() {
            [] => s.clone(),
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => go(w, s, k, rest.to_vec()),
                Append(ref x, ref y) => {
                    let mut zs = [(*i, *mode, *x.clone()), (*i, *mode, *y.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Nest(j, ref x) => {
                    let mut zs = [(*i + j, *mode, *x.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Text(ref str) => go(w, prepend(s, str.clone()), k + str.len(), rest.to_vec()),
                Newline => go(w, prepend(s, string_utils::nl_space(*i)), *i, rest.to_vec()),
                Break(sp, off) => {
                    match *mode {
                        mode::Flat => go(w, prepend(s.clone(), string_utils::spaces(sp)), k + sp, rest.to_vec()),
                        mode::Break => go(w, prepend(s.clone(), string_utils::nl_space(i + off)), i + off, rest.to_vec())
                    }
                },
                Group(ref x) => {
                    match *mode {
                        mode::Flat => {
                            let mut zs = [(*i, mode::Flat, *x.clone())].to_vec();
                            zs.push_all(*rest);
                            go(w, s, k, zs)
                        },
                        mode::Break => {
                            let mut ys = [(*i, mode::Flat, *x.clone())].to_vec();
                            ys.push_all(*rest);
                            if fitting(ys.clone(), w - k) {
                                go(w, s, k, ys)
                            } else {
                                let mut zs = [(*i, mode::Break, *x.clone())].to_vec();
                                zs.push_all(*rest);
                                go(w, s, k, zs)
                            }
                        }
                    }
                }
            }
        }
    }
    go(w, s, 0, [(0, mode::Break, x)].to_vec())
}

impl Doc {

    pub fn nil() -> Doc {
        Nil
    }

    pub fn append(self, e:Doc) -> Doc {
        match self {
            Nil => e,
            x => match e {
                Nil => x,
                y => Append(box x, box y)
            }
        }
    }

    pub fn nest(self, i:uint) -> Doc {
        Nest(i, box self)
    }

    pub fn text<S:Str>(s:S) -> Doc {
        Text(String::from_str(s.as_slice()))
    }

    pub fn brk(space:uint, offset:uint) -> Doc {
        Break(space, offset)
    }

    pub fn newline() -> Doc {
        Newline
    }

    pub fn group(self) -> Doc {
        Group(box self)
    }

    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    pub fn as_str<T:ToString>(t:T) -> Doc {
        Doc::text(t.to_string())
    }

    pub fn to_string(self, w:uint) -> String {
        let mut strs = best(w, Vec::new(), self);
        strs.reverse();
        strs.push(String::from_str("\n"));
        strs.concat()
    }
}
<|endoftext|>


<commit_before>//! Module containing color-related functions using the `colored` crate.
//!
//! This module is only available when the `colored` feature is enabled for `fern`.
//! This can be done with the following in `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! # ...
//! fern = { version = "0.4", features = ["colored"] }
//! ```
use std::fmt;
use colored::Color;
use log::LogLevel;

/// Extension crate allowing the use of `.colored` on LogLevels.
trait ColoredLogLevel {
    /// Colors this log level with the given color.
    fn colored(&self, color: Color) -> LogLevelWithColor;
}

/// Opaque structure representing a log level with an associated color. This implements [`fmt::Display`] so that it is
/// displayed as the underlying log level surrounded with ASCII markers for the given color.
// this is necessary in order to avoid using colored::ColorString, which has a Display
// implementation involving many allocations, and would involve two more string allocations
// even to create it.
pub struct LogLevelWithColor {
    level: LogLevel,
    color: Color,
}

impl fmt::Display for LogLevelWithColor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "\x1B[{}m{}\x1B[0m", self.color.to_fg_str(), self.level)
    }
}

/// Configuration specifying colors a log level can be colored as.
#[derive(Copy, Clone)]
pub struct ColoredLogLevelConfig {
    /// The color to color logs with the [`Error`] level.
    ///
    /// [`Error`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Error
    pub error: Color,
    /// The color to color logs with the [`Warn`] level.
    ///
    /// [`Warn`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Warn
    pub warn: Color,
    /// The color to color logs with the [`Info`] level.
    ///
    /// [`Info`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Info
    pub info: Color,
    /// The color to color logs with the [`Debug`] level.
    ///
    /// [`Debug`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Debug
    pub debug: Color,
    /// The color to color logs with the [`Trace`] level.
    ///
    /// [`Trace`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Trace
    pub trace: Color,
}

impl ColoredLogLevelConfig {
    /// Creates a new ColoredLogLevelConfig with the default colors.
    ///
    /// This matches the behavior of [`ColoredLogLevelConfig::default`].
    ///
    /// [`ColoredLogLevelConfig::default`]: #method.default
    #[inline]
    pub fn new() -> Self {
        Self::default()
    }

    /// Overrides the [`Error`] level color with the given color.
    ///
    /// The default color is [`Color::Red`].
    ///
    /// [`Error`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Error
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    pub fn error(&mut self, error: Color) -> &mut Self {
        self.error = error;
        self
    }

    /// Overrides the [`Warn`] level color with the given color.
    ///
    /// The default color is [`Color::Yellow`].
    ///
    /// [`Warn`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Warn
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    pub fn warn(&mut self, warn: Color) -> &mut Self {
        self.warn = warn;
        self
    }

    /// Overrides the [`Info`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Info`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Info
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn info(&mut self, info: Color) -> &mut Self {
        self.info = info;
        self
    }

    /// Overrides the [`Debug`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Debug`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Debug
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn debug(&mut self, debug: Color) -> &mut Self {
        self.debug = debug;
        self
    }

    /// Overrides the [`Trace`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Trace`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn trace(&mut self, trace: Color) -> &mut Self {
        self.trace = trace;
        self
    }

    /// Retrieves the default configuration. This has:
    ///
    /// - [`Error`] as [`Color::Red`]
    /// - [`Warn`] as [`Color::Yellow`]
    /// - [`Info`] as [`Color::White`]
    /// - [`Debug`] as [`Color::White`]
    /// - [`Trace`] as [`Color::White`]
    ///
    /// [`Error`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Error
    /// [`Warn`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Warn
    /// [`Info`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Info
    /// [`Debug`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Debug
    /// [`Trace`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    pub fn default() -> Self {
        ColoredLogLevelConfig {
            error: Color::Red,
            warn: Color::Yellow,
            debug: Color::White,
            info: Color::White,
            trace: Color::White,
        }
    }

    /// Colors the given log level with the correct color.
    ///
    /// This will output ANSI escapes correctly coloring the log level when printed
    /// to a Unix terminal. Due to behavior of the [`colored`] crate, this does not
    /// function on Windows terminals.
    ///
    /// [`colored`]: https://github.com/mackwic/colored
    pub fn color(&self, level: LogLevel) -> LogLevelWithColor {
        level.colored(self.get_color(&level))
    }

    /// Retrieves the color that a log level should be colored as.
    pub fn get_color(&self, level: &LogLevel) -> Color {
        match *level {
            LogLevel::Error => self.error,
            LogLevel::Warn => self.warn,
            LogLevel::Info => self.info,
            LogLevel::Debug => self.debug,
            LogLevel::Trace => self.trace,
        }
    }
}

impl ColoredLogLevel for LogLevel {
    fn colored(&self, color: Color) -> LogLevelWithColor {
        LogLevelWithColor {
            level: *self,
            color: color,
        }
    }
}
<commit_msg>Fix builder methods so they now take configuration by value.<commit_after>//! Module containing color-related functions using the `colored` crate.
//!
//! This module is only available when the `colored` feature is enabled for `fern`.
//! This can be done with the following in `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! # ...
//! fern = { version = "0.4", features = ["colored"] }
//! ```
use std::fmt;
use colored::Color;
use log::LogLevel;

/// Extension crate allowing the use of `.colored` on LogLevels.
trait ColoredLogLevel {
    /// Colors this log level with the given color.
    fn colored(&self, color: Color) -> LogLevelWithColor;
}

/// Opaque structure representing a log level with an associated color. This implements [`fmt::Display`] so that it is
/// displayed as the underlying log level surrounded with ASCII markers for the given color.
// this is necessary in order to avoid using colored::ColorString, which has a Display
// implementation involving many allocations, and would involve two more string allocations
// even to create it.
pub struct LogLevelWithColor {
    level: LogLevel,
    color: Color,
}

impl fmt::Display for LogLevelWithColor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "\x1B[{}m{}\x1B[0m", self.color.to_fg_str(), self.level)
    }
}

/// Configuration specifying colors a log level can be colored as.
#[derive(Copy, Clone)]
#[must_use = "builder methods take config by value and thus must be reassigned to variable"]
pub struct ColoredLogLevelConfig {
    /// The color to color logs with the [`Error`] level.
    ///
    /// [`Error`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Error
    pub error: Color,
    /// The color to color logs with the [`Warn`] level.
    ///
    /// [`Warn`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Warn
    pub warn: Color,
    /// The color to color logs with the [`Info`] level.
    ///
    /// [`Info`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Info
    pub info: Color,
    /// The color to color logs with the [`Debug`] level.
    ///
    /// [`Debug`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Debug
    pub debug: Color,
    /// The color to color logs with the [`Trace`] level.
    ///
    /// [`Trace`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Trace
    pub trace: Color,
}

impl ColoredLogLevelConfig {
    /// Creates a new ColoredLogLevelConfig with the default colors.
    ///
    /// This matches the behavior of [`ColoredLogLevelConfig::default`].
    ///
    /// [`ColoredLogLevelConfig::default`]: #method.default
    #[inline]
    pub fn new() -> Self {
        Self::default()
    }

    /// Overrides the [`Error`] level color with the given color.
    ///
    /// The default color is [`Color::Red`].
    ///
    /// [`Error`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Error
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    pub fn error(mut self, error: Color) -> Self {
        self.error = error;
        self
    }

    /// Overrides the [`Warn`] level color with the given color.
    ///
    /// The default color is [`Color::Yellow`].
    ///
    /// [`Warn`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Warn
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    pub fn warn(mut self, warn: Color) -> Self {
        self.warn = warn;
        self
    }

    /// Overrides the [`Info`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Info`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Info
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn info(mut self, info: Color) -> Self {
        self.info = info;
        self
    }

    /// Overrides the [`Debug`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Debug`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Debug
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn debug(mut self, debug: Color) -> Self {
        self.debug = debug;
        self
    }

    /// Overrides the [`Trace`] level color with the given color.
    ///
    /// The default color is [`Color::White`].
    ///
    /// [`Trace`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    pub fn trace(mut self, trace: Color) -> Self {
        self.trace = trace;
        self
    }

    /// Retrieves the default configuration. This has:
    ///
    /// - [`Error`] as [`Color::Red`]
    /// - [`Warn`] as [`Color::Yellow`]
    /// - [`Info`] as [`Color::White`]
    /// - [`Debug`] as [`Color::White`]
    /// - [`Trace`] as [`Color::White`]
    ///
    /// [`Error`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Error
    /// [`Warn`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Warn
    /// [`Info`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Info
    /// [`Debug`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Debug
    /// [`Trace`]: https://docs.rs/log/0.3/log/enum.LogLevel.html#variant.Trace
    /// [`Color::White`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.White
    /// [`Color::Yellow`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Yellow
    /// [`Color::Red`]: https://docs.rs/colored/1/colored/enum.Color.html#variant.Red
    pub fn default() -> Self {
        ColoredLogLevelConfig {
            error: Color::Red,
            warn: Color::Yellow,
            debug: Color::White,
            info: Color::White,
            trace: Color::White,
        }
    }

    /// Colors the given log level with the correct color.
    ///
    /// This will output ANSI escapes correctly coloring the log level when printed
    /// to a Unix terminal. Due to behavior of the [`colored`] crate, this does not
    /// function on Windows terminals.
    ///
    /// [`colored`]: https://github.com/mackwic/colored
    pub fn color(&self, level: LogLevel) -> LogLevelWithColor {
        level.colored(self.get_color(&level))
    }

    /// Retrieves the color that a log level should be colored as.
    pub fn get_color(&self, level: &LogLevel) -> Color {
        match *level {
            LogLevel::Error => self.error,
            LogLevel::Warn => self.warn,
            LogLevel::Info => self.info,
            LogLevel::Debug => self.debug,
            LogLevel::Trace => self.trace,
        }
    }
}

impl ColoredLogLevel for LogLevel {
    fn colored(&self, color: Color) -> LogLevelWithColor {
        LogLevelWithColor {
            level: *self,
            color: color,
        }
    }
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::str;

use common::{Literal, SqlType};

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum FunctionExpression {
    Avg(Column, bool),
    Count(Column, bool),
    CountStar,
    Sum(Column, bool),
    Max(Column),
    Min(Column),
    GroupConcat(Column, String),
}

impl Display for FunctionExpression {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FunctionExpression::Avg(ref col, d) if d => {
                write!(f, "avg(distinct {})", col.name.as_str())
            }
            FunctionExpression::Count(ref col, d) if d => {
                write!(f, "count(distinct {})", col.name.as_str())
            }
            FunctionExpression::Sum(ref col, d) if d => {
                write!(f, "sum(distinct {})", col.name.as_str())
            }

            FunctionExpression::Avg(ref col, _) => write!(f, "avg({})", col.name.as_str()),
            FunctionExpression::Count(ref col, _) => write!(f, "count({})", col.name.as_str()),
            FunctionExpression::CountStar => write!(f, "count(all)"),
            FunctionExpression::Sum(ref col, _) => write!(f, "sum({})", col.name.as_str()),
            FunctionExpression::Max(ref col) => write!(f, "max({})", col.name.as_str()),
            FunctionExpression::Min(ref col) => write!(f, "min({})", col.name.as_str()),
            FunctionExpression::GroupConcat(ref col, ref s) => {
                write!(f, "group_concat({}, {})", col.name.as_str(), s)
            }
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Column {
    pub name: String,
    pub alias: Option<String>,
    pub table: Option<String>,
    pub function: Option<Box<FunctionExpression>>,
}

impl fmt::Display for Column {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ref table) = self.table {
            write!(f, "{}.{}", table, self.name)?;
        } else {
            write!(f, "{}", self.name)?;
        }
        if let Some(ref alias) = self.alias {
            write!(f, " AS {}", alias)?;
        }
        Ok(())
    }
}

impl<'a> From<&'a str> for Column {
    fn from(c: &str) -> Column {
        match c.find(".") {
            None => Column {
                name: String::from(c),
                alias: None,
                table: None,
                function: None,
            },
            Some(i) => Column {
                name: String::from(&c[i + 1..]),
                alias: None,
                table: Some(String::from(&c[0..i])),
                function: None,
            },
        }
    }
}

impl Ord for Column {
    fn cmp(&self, other: &Column) -> Ordering {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => self.name.cmp(&other.name),
                x => x,
            }
        } else {
            self.name.cmp(&other.name)
        }
    }
}

impl PartialOrd for Column {
    fn partial_cmp(&self, other: &Column) -> Option<Ordering> {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => Some(self.name.cmp(&other.name)),
                x => Some(x),
            }
        } else if self.table.is_none() && other.table.is_none() {
            Some(self.name.cmp(&other.name))
        } else {
            None
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum ColumnConstraint {
    NotNull,
    DefaultValue(Literal),
    AutoIncrement,
    PrimaryKey,
    Unique,
}

impl fmt::Display for ColumnConstraint {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ColumnConstraint::NotNull => write!(f, "NOT NULL"),
            ColumnConstraint::DefaultValue(ref literal) => {
                write!(f, "DEFAULT {}", literal.to_string())
            }
            ColumnConstraint::AutoIncrement => write!(f, "AUTOINCREMENT"),
            ColumnConstraint::PrimaryKey => write!(f, "PRIMARY KEY"),
            ColumnConstraint::Unique => write!(f, "UNIQUE"),
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ColumnSpecification {
    pub column: Column,
    pub sql_type: SqlType,
    pub constraints: Vec<ColumnConstraint>,
}

impl fmt::Display for ColumnSpecification {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {}", self.column, self.sql_type)?;
        for constraint in self.constraints.iter() {
            write!(f, " {}", constraint)?;
        }
        Ok(())
    }
}

impl ColumnSpecification {
    pub fn new(c: Column, t: SqlType) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: vec![],
        }
    }

    pub fn with_constraints(
        c: Column,
        t: SqlType,
        ccs: Vec<ColumnConstraint>,
    ) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: ccs,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn column_from_str() {
        let s = "table.col";
        let c = Column::from(s);

        assert_eq!(
            c,
            Column {
                name: String::from("col"),
                alias: None,
                table: Some(String::from("table")),
                function: None,
            }
        );
    }
}
<commit_msg>Correct AUTO_INCREMENT formatting for MySQL<commit_after>use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::str;

use common::{Literal, SqlType};

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum FunctionExpression {
    Avg(Column, bool),
    Count(Column, bool),
    CountStar,
    Sum(Column, bool),
    Max(Column),
    Min(Column),
    GroupConcat(Column, String),
}

impl Display for FunctionExpression {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FunctionExpression::Avg(ref col, d) if d => {
                write!(f, "avg(distinct {})", col.name.as_str())
            }
            FunctionExpression::Count(ref col, d) if d => {
                write!(f, "count(distinct {})", col.name.as_str())
            }
            FunctionExpression::Sum(ref col, d) if d => {
                write!(f, "sum(distinct {})", col.name.as_str())
            }

            FunctionExpression::Avg(ref col, _) => write!(f, "avg({})", col.name.as_str()),
            FunctionExpression::Count(ref col, _) => write!(f, "count({})", col.name.as_str()),
            FunctionExpression::CountStar => write!(f, "count(all)"),
            FunctionExpression::Sum(ref col, _) => write!(f, "sum({})", col.name.as_str()),
            FunctionExpression::Max(ref col) => write!(f, "max({})", col.name.as_str()),
            FunctionExpression::Min(ref col) => write!(f, "min({})", col.name.as_str()),
            FunctionExpression::GroupConcat(ref col, ref s) => {
                write!(f, "group_concat({}, {})", col.name.as_str(), s)
            }
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Column {
    pub name: String,
    pub alias: Option<String>,
    pub table: Option<String>,
    pub function: Option<Box<FunctionExpression>>,
}

impl fmt::Display for Column {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ref table) = self.table {
            write!(f, "{}.{}", table, self.name)?;
        } else {
            write!(f, "{}", self.name)?;
        }
        if let Some(ref alias) = self.alias {
            write!(f, " AS {}", alias)?;
        }
        Ok(())
    }
}

impl<'a> From<&'a str> for Column {
    fn from(c: &str) -> Column {
        match c.find(".") {
            None => Column {
                name: String::from(c),
                alias: None,
                table: None,
                function: None,
            },
            Some(i) => Column {
                name: String::from(&c[i + 1..]),
                alias: None,
                table: Some(String::from(&c[0..i])),
                function: None,
            },
        }
    }
}

impl Ord for Column {
    fn cmp(&self, other: &Column) -> Ordering {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => self.name.cmp(&other.name),
                x => x,
            }
        } else {
            self.name.cmp(&other.name)
        }
    }
}

impl PartialOrd for Column {
    fn partial_cmp(&self, other: &Column) -> Option<Ordering> {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => Some(self.name.cmp(&other.name)),
                x => Some(x),
            }
        } else if self.table.is_none() && other.table.is_none() {
            Some(self.name.cmp(&other.name))
        } else {
            None
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum ColumnConstraint {
    NotNull,
    DefaultValue(Literal),
    AutoIncrement,
    PrimaryKey,
    Unique,
}

impl fmt::Display for ColumnConstraint {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ColumnConstraint::NotNull => write!(f, "NOT NULL"),
            ColumnConstraint::DefaultValue(ref literal) => {
                write!(f, "DEFAULT {}", literal.to_string())
            }
            ColumnConstraint::AutoIncrement => write!(f, "AUTO_INCREMENT"),
            ColumnConstraint::PrimaryKey => write!(f, "PRIMARY KEY"),
            ColumnConstraint::Unique => write!(f, "UNIQUE"),
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ColumnSpecification {
    pub column: Column,
    pub sql_type: SqlType,
    pub constraints: Vec<ColumnConstraint>,
}

impl fmt::Display for ColumnSpecification {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {}", self.column, self.sql_type)?;
        for constraint in self.constraints.iter() {
            write!(f, " {}", constraint)?;
        }
        Ok(())
    }
}

impl ColumnSpecification {
    pub fn new(c: Column, t: SqlType) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: vec![],
        }
    }

    pub fn with_constraints(
        c: Column,
        t: SqlType,
        ccs: Vec<ColumnConstraint>,
    ) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: ccs,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn column_from_str() {
        let s = "table.col";
        let c = Column::from(s);

        assert_eq!(
            c,
            Column {
                name: String::from("col"),
                alias: None,
                table: Some(String::from("table")),
                function: None,
            }
        );
    }
}
<|endoftext|>


<commit_before>extern crate lazy_static;

use std::env;
use std::io;
use std::path::{Path, PathBuf};
use std::fs::{self, DirEntry};
use std::string::String;

pub struct Config {
    pub steps_file: String,
    pub step_implementations_path: PathBuf,
    pub skel_path: PathBuf,
    pub internal_port: String,
}

lazy_static! {
    pub static ref PROJECT_ROOT: PathBuf = PathBuf::from(env_var("GAUGE_PROJECT_ROOT"));
    pub static ref PLUGIN_SOURCE: PathBuf = match env::current_dir() {
        Ok(d) => d,
        Err(_) => PathBuf::from("")
    };

    pub static ref CONFIG: Config = Config {
        steps_file: String::from("steps.rs"),
        step_implementations_path: path_to("tests", &PROJECT_ROOT),
        skel_path: path_to("skel", &PLUGIN_SOURCE),
        internal_port: env_var("GAUGE_INTERNAL_PORT"),
    };
}

pub fn env_var(ev: &'static str) -> String {
    match env::var(ev) {
        Ok(val) => val,
        Err(_) => String::new(),
    }
}

pub fn path_to<'a>(pathslice: &'a str, root: &PathBuf) -> PathBuf { root.join(pathslice) }

pub fn create_dir(dirpath: &PathBuf) -> io::Result<&PathBuf> {
    try!(fs::create_dir_all(dirpath));
    Ok(dirpath)
}

pub fn copy_file<'a>(from: &'a PathBuf, to: &'a PathBuf) -> io::Result<(&'a PathBuf, &'a PathBuf)> {
    try!(fs::copy(from, to));
    Ok((from, to))
}

pub fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
    if try!(fs::metadata(dir)).is_dir() {
        for entry in try!(fs::read_dir(dir)) {
            let entry = try!(entry);
            if try!(fs::metadata(entry.path())).is_dir() {
                try!(visit_dirs(&entry.path(), cb));
            } else {
                cb(&entry);
            }
        }
    }
    Ok(())
}
<commit_msg>Add source attribution for common::visit_dirs()<commit_after>extern crate lazy_static;

use std::env;
use std::io;
use std::path::{Path, PathBuf};
use std::fs::{self, DirEntry};
use std::string::String;

pub struct Config {
    pub steps_file: String,
    pub step_implementations_path: PathBuf,
    pub skel_path: PathBuf,
    pub internal_port: String,
}

lazy_static! {
    pub static ref PROJECT_ROOT: PathBuf = PathBuf::from(env_var("GAUGE_PROJECT_ROOT"));
    pub static ref PLUGIN_SOURCE: PathBuf = match env::current_dir() {
        Ok(d) => d,
        Err(_) => PathBuf::from("")
    };

    pub static ref CONFIG: Config = Config {
        steps_file: String::from("steps.rs"),
        step_implementations_path: path_to("tests", &PROJECT_ROOT),
        skel_path: path_to("skel", &PLUGIN_SOURCE),
        internal_port: env_var("GAUGE_INTERNAL_PORT"),
    };
}

pub fn env_var(ev: &'static str) -> String {
    match env::var(ev) {
        Ok(val) => val,
        Err(_) => String::new(),
    }
}

pub fn path_to<'a>(pathslice: &'a str, root: &PathBuf) -> PathBuf { root.join(pathslice) }

pub fn create_dir(dirpath: &PathBuf) -> io::Result<&PathBuf> {
    try!(fs::create_dir_all(dirpath));
    Ok(dirpath)
}

pub fn copy_file<'a>(from: &'a PathBuf, to: &'a PathBuf) -> io::Result<(&'a PathBuf, &'a PathBuf)> {
    try!(fs::copy(from, to));
    Ok((from, to))
}

// Source: https://doc.rust-lang.org/std/fs/fn.read_dir.html
pub fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
    if try!(fs::metadata(dir)).is_dir() {
        for entry in try!(fs::read_dir(dir)) {
            let entry = try!(entry);
            if try!(fs::metadata(entry.path())).is_dir() {
                try!(visit_dirs(&entry.path(), cb));
            } else {
                cb(&entry);
            }
        }
    }
    Ok(())
}
<|endoftext|>


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

use xdg;
use rustc_version;

fn xdg_dir() -> xdg::BaseDirectories {
    let prefix = Path::new("afl.rs").join(rustc_version()).join(
        pkg_version(),
    );
    xdg::BaseDirectories::with_prefix(prefix).unwrap()
}

pub fn rustc_version() -> String {
    let mut ret = String::from("rustc-");
    ret.push_str(&rustc_version::version().unwrap().to_string());
    ret
}

fn pkg_version() -> String {
    let mut ret = String::from("afl.rs-");

    let version = env!("CARGO_PKG_VERSION");
    assert!(!version.is_empty());

    ret.push_str(version);
    ret
}

pub fn afl_dir() -> PathBuf {
    xdg_dir().create_data_directory("afl").unwrap()
}

pub fn afl_llvm_rt_dir() -> PathBuf {
    xdg_dir().create_data_directory("afl-llvm-rt").unwrap()
}

#[allow(dead_code)]
pub fn object_file_path() -> PathBuf {
    afl_llvm_rt_dir().join("libafl-llvm-rt.o")
}

pub fn archive_file_path() -> PathBuf {
    afl_llvm_rt_dir().join("libafl-llvm-rt.a")
}
<commit_msg>Incorporate commit hash into directory structure. (#125)<commit_after>use std::path::{Path, PathBuf};

use xdg;
use rustc_version;

fn xdg_dir() -> xdg::BaseDirectories {
    let prefix = Path::new("afl.rs").join(rustc_version()).join(
        pkg_version(),
    );
    xdg::BaseDirectories::with_prefix(prefix).unwrap()
}

pub fn rustc_version() -> String {
    let version_meta = rustc_version::version_meta().unwrap();
    let mut ret = String::from("rustc-");
    ret.push_str(&version_meta.semver.to_string());
    if let Some(commit_hash) = version_meta.commit_hash {
        ret.push('-');
        ret.push_str(&commit_hash[..7]);
    }
    ret
}

fn pkg_version() -> String {
    let mut ret = String::from("afl.rs-");

    let version = env!("CARGO_PKG_VERSION");
    assert!(!version.is_empty());

    ret.push_str(version);
    ret
}

pub fn afl_dir() -> PathBuf {
    xdg_dir().create_data_directory("afl").unwrap()
}

pub fn afl_llvm_rt_dir() -> PathBuf {
    xdg_dir().create_data_directory("afl-llvm-rt").unwrap()
}

#[allow(dead_code)]
pub fn object_file_path() -> PathBuf {
    afl_llvm_rt_dir().join("libafl-llvm-rt.o")
}

pub fn archive_file_path() -> PathBuf {
    afl_llvm_rt_dir().join("libafl-llvm-rt.a")
}
<|endoftext|>


<commit_before>use std::fmt;
use json::JsonValue;

// #[derive(Debug, Default)]
// pub struct Error {
//     pub detail: String,
// }
//
// #[derive(Debug)]
// pub struct CrateLinks {
//     pub owners: Option<String>,
//     pub reverse_dependencies: String,
//     pub version_downloads: String,
//     pub versions: Option<String>,
// }
//
// pub struct Crate {
//     pub created_at: String,
//     pub description: Option<String>,
//     pub documentation: Option<String>,
//     pub downloads: i32,
//     pub homepage: Option<String>,
//     pub id: String,
//     pub keywords: Option<Vec<String>>,
//     pub license: Option<String>,
//     pub links: CrateLinks,
//     pub max_version: String,
//     pub name: String,
//     pub repository: Option<String>,
//     pub updated_at: String,
//     pub versions: Option<Vec<u64>>,
// }
//
// #[derive(Debug)]
// pub struct Keyword {
//     pub crates_cnt: u64,
//     pub created_at: String,
//     pub id: String,
//     pub keyword: String,
// }
//
// #[derive(Debug)]
// pub struct VersionLinks {
//     pub authors: String,
//     pub dependencies: String,
//     pub version_downloads: String,
// }
//
// #[derive(Debug)]
// pub struct Version {
//     pub krate: String,
//     pub created_at: String,
//     pub dl_path: String,
//     pub downloads: i32,
//     pub features: HashMap<String, Vec<String>>,
//     pub id: i32,
//     pub links: VersionLinks,
//     pub num: String,
//     pub updated_at: String,
//     pub yanked: bool,
// }
//
// pub struct Reply {
//     pub errors: Error,
//     pub krate: Crate,
//     pub keywords: Vec<Keyword>,
//     pub versions: Vec<Version>,
// }

pub struct Crate {
    json: JsonValue,
}

impl Crate {
    pub fn new(json: JsonValue) -> Self {
        Crate { json: json }
    }

    pub fn print_repository(&self, verbose: bool) {
        if let JsonValue::String(ref repository) = self.json["repository"] {
            let fmt = if verbose {
                format!("{:<16}{}", "Repository:", repository)
            } else {
                repository.clone()
            };
            println!("{}", fmt);
        }
    }

    pub fn print_documentation(&self, verbose: bool) {
        if let JsonValue::String(ref documentation) = self.json["documentation"] {
            let fmt = if verbose {
                format!("{:<16}{}", "Documentation:", documentation)
            } else {
                documentation.clone()
            };
            println!("{}", fmt);
        }
    }

    pub fn print_downloads(&self, verbose: bool) {
        if let JsonValue::Number(downloads) = self.json["downloads"] {
            let downloads = downloads as i32;
            let fmt = if verbose {
                format!("{:<16}{}", "Downloads:", downloads)
            } else {
                format!("{}", downloads)
            };
            println!("{}", fmt);
        }
    }

    pub fn print_homepage(&self, verbose: bool) {
        if let JsonValue::String(ref homepage) = self.json["homepage"] {
            let fmt = if verbose {
                format!("{:<16}{}", "Homepage:", homepage)
            } else {
                homepage.clone()
            };
            println!("{}", fmt);
        }
    }
}

impl fmt::Display for Crate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let empty = &String::new();

        let name = self.json["name"].as_string().unwrap_or(empty);
        let max_version = self.json["max_version"].as_string().unwrap_or(empty);
        let downloads = self.json["downloads"].as_string().unwrap_or(empty);
        let created_at = self.json["created_at"].as_string().unwrap_or(empty);
        let updated_at = self.json["updated_at"].as_string().unwrap_or(empty);

        let description = self.json["description"].as_string().unwrap_or(empty);
        let documentation = self.json["documentation"].as_string().unwrap_or(empty);
        let homepage = self.json["homepage"].as_string().unwrap_or(empty);
        let repository = self.json["repository"].as_string().unwrap_or(empty);
        let license = self.json["license"].as_string().unwrap_or(empty);

        let keywords = self.json["keywords"]
            .members()
            .filter_map(|jv| jv.as_string().ok())
            .collect::<Vec<_>>();

        if f.alternate() {
            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", name),
                   format_args!("{:<16}{}", "Version:", max_version),
                   format_args!("{:<16}{}", "Description:", description),
                   format_args!("{:<16}{}", "Downloads:", downloads),
                   format_args!("{:<16}{}", "Homepage:", homepage),
                   format_args!("{:<16}{}", "Documentation:", documentation),
                   format_args!("{:<16}{}", "Repository:", repository),
                   format_args!("{:<16}{}", "License:", license),
                   format_args!("{:<16}{:?}", "Keywords:", keywords),
                   format_args!("{:<16}{}", "Created at:", created_at),
                   format_args!("{:<16}{}", "Updated at:", updated_at))
        } else {
            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", name),
                   format_args!("{:<16}{}", "Version:", max_version),
                   format_args!("{:<16}{}", "Description:", description),
                   format_args!("{:<16}{}", "Downloads:", downloads),
                   format_args!("{:<16}{}", "Homepage:", homepage),
                   format_args!("{:<16}{}", "Documentation:", documentation),
                   format_args!("{:<16}{}", "Repository:", repository))
        }
    }
}
<commit_msg>Fix reporting download count<commit_after>use std::fmt;
use json::JsonValue;

// #[derive(Debug, Default)]
// pub struct Error {
//     pub detail: String,
// }
//
// #[derive(Debug)]
// pub struct CrateLinks {
//     pub owners: Option<String>,
//     pub reverse_dependencies: String,
//     pub version_downloads: String,
//     pub versions: Option<String>,
// }
//
// pub struct Crate {
//     pub created_at: String,
//     pub description: Option<String>,
//     pub documentation: Option<String>,
//     pub downloads: i32,
//     pub homepage: Option<String>,
//     pub id: String,
//     pub keywords: Option<Vec<String>>,
//     pub license: Option<String>,
//     pub links: CrateLinks,
//     pub max_version: String,
//     pub name: String,
//     pub repository: Option<String>,
//     pub updated_at: String,
//     pub versions: Option<Vec<u64>>,
// }
//
// #[derive(Debug)]
// pub struct Keyword {
//     pub crates_cnt: u64,
//     pub created_at: String,
//     pub id: String,
//     pub keyword: String,
// }
//
// #[derive(Debug)]
// pub struct VersionLinks {
//     pub authors: String,
//     pub dependencies: String,
//     pub version_downloads: String,
// }
//
// #[derive(Debug)]
// pub struct Version {
//     pub krate: String,
//     pub created_at: String,
//     pub dl_path: String,
//     pub downloads: i32,
//     pub features: HashMap<String, Vec<String>>,
//     pub id: i32,
//     pub links: VersionLinks,
//     pub num: String,
//     pub updated_at: String,
//     pub yanked: bool,
// }
//
// pub struct Reply {
//     pub errors: Error,
//     pub krate: Crate,
//     pub keywords: Vec<Keyword>,
//     pub versions: Vec<Version>,
// }

pub struct Crate {
    json: JsonValue,
}

impl Crate {
    pub fn new(json: JsonValue) -> Self {
        Crate { json: json }
    }

    pub fn print_repository(&self, verbose: bool) {
        if let JsonValue::String(ref repository) = self.json["repository"] {
            let fmt = if verbose {
                format!("{:<16}{}", "Repository:", repository)
            } else {
                repository.clone()
            };
            println!("{}", fmt);
        }
    }

    pub fn print_documentation(&self, verbose: bool) {
        if let JsonValue::String(ref documentation) = self.json["documentation"] {
            let fmt = if verbose {
                format!("{:<16}{}", "Documentation:", documentation)
            } else {
                documentation.clone()
            };
            println!("{}", fmt);
        }
    }

    pub fn print_downloads(&self, verbose: bool) {
        if let JsonValue::Number(downloads) = self.json["downloads"] {
            let fmt = if verbose {
                format!("{:<16}{}", "Downloads:", downloads)
            } else {
                format!("{}", downloads)
            };
            println!("{}", fmt);
        }
    }

    pub fn print_homepage(&self, verbose: bool) {
        if let JsonValue::String(ref homepage) = self.json["homepage"] {
            let fmt = if verbose {
                format!("{:<16}{}", "Homepage:", homepage)
            } else {
                homepage.clone()
            };
            println!("{}", fmt);
        }
    }
}

impl fmt::Display for Crate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let empty = &String::new();
        let zero = &0f64;

        let name = self.json["name"].as_string().unwrap_or(empty);
        let max_version = self.json["max_version"].as_string().unwrap_or(empty);
        let downloads = self.json["downloads"].as_number().unwrap_or(zero);
        let created_at = self.json["created_at"].as_string().unwrap_or(empty);
        let updated_at = self.json["updated_at"].as_string().unwrap_or(empty);

        let description = self.json["description"].as_string().unwrap_or(empty);
        let documentation = self.json["documentation"].as_string().unwrap_or(empty);
        let homepage = self.json["homepage"].as_string().unwrap_or(empty);
        let repository = self.json["repository"].as_string().unwrap_or(empty);
        let license = self.json["license"].as_string().unwrap_or(empty);

        let keywords = self.json["keywords"]
            .members()
            .filter_map(|jv| jv.as_string().ok())
            .collect::<Vec<_>>();

        if f.alternate() {
            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", name),
                   format_args!("{:<16}{}", "Version:", max_version),
                   format_args!("{:<16}{}", "Description:", description),
                   format_args!("{:<16}{}", "Downloads:", downloads),
                   format_args!("{:<16}{}", "Homepage:", homepage),
                   format_args!("{:<16}{}", "Documentation:", documentation),
                   format_args!("{:<16}{}", "Repository:", repository),
                   format_args!("{:<16}{}", "License:", license),
                   format_args!("{:<16}{:?}", "Keywords:", keywords),
                   format_args!("{:<16}{}", "Created at:", created_at),
                   format_args!("{:<16}{}", "Updated at:", updated_at))
        } else {
            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", name),
                   format_args!("{:<16}{}", "Version:", max_version),
                   format_args!("{:<16}{}", "Description:", description),
                   format_args!("{:<16}{}", "Downloads:", downloads),
                   format_args!("{:<16}{}", "Homepage:", homepage),
                   format_args!("{:<16}{}", "Documentation:", documentation),
                   format_args!("{:<16}{}", "Repository:", repository))
        }
    }
}
<|endoftext|>