<commit_before>iface to_str { fn to_str() -> str; }

impl of to_str for int {
    fn to_str() -> str { int::str(self) }
}
impl of to_str for i8 {
    fn to_str() -> str { i8::str(self) }
}
impl of to_str for i16 {
    fn to_str() -> str { i16::str(self) }
}
impl of to_str for i32 {
    fn to_str() -> str { i32::str(self) }
}
impl of to_str for i64 {
    fn to_str() -> str { i64::str(self) }
}
impl of to_str for uint {
    fn to_str() -> str { uint::str(self) }
}
impl of to_str for u8 {
    fn to_str() -> str { u8::str(self) }
}
impl of to_str for u16 {
    fn to_str() -> str { u16::str(self) }
}
impl of to_str for u32 {
    fn to_str() -> str { u32::str(self) }
}
impl of to_str for u64 {
    fn to_str() -> str { u64::str(self) }
}
impl of to_str for float {
    fn to_str() -> str { float::to_str(self, 4u) }
}
impl of to_str for bool {
    fn to_str() -> str { bool::to_str(self) }
}
impl of to_str for () {
    fn to_str() -> str { "()" }
}
impl of to_str for str {
    fn to_str() -> str { self }
}

impl <A: to_str copy, B: to_str copy> of to_str for (A, B) {
    fn to_str() -> str {
        let (a, b) = self;
        "(" + a.to_str() + ", " + b.to_str() + ")"
    }
}
impl <A: to_str copy, B: to_str copy, C: to_str copy> of to_str for (A, B, C){
    fn to_str() -> str {
        let (a, b, c) = self;
        "(" + a.to_str() + ", " + b.to_str() + ", " + c.to_str() + ")"
    }
}

impl <A: to_str> of to_str for ~[A] {
    fn to_str() -> str {
        let mut acc = "[", first = true;
        for vec::each(self) |elt| {
            if first { first = false; }
            else { str::push_str(acc, ", "); }
            str::push_str(acc, elt.to_str());
        }
        str::push_char(acc, ']');
        acc
    }
}

impl <A: to_str> of to_str for @A {
    fn to_str() -> str { "@" + (*self).to_str() }
}
impl <A: to_str> of to_str for ~A {
    fn to_str() -> str { "~" + (*self).to_str() }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_simple_types() {
        assert 1.to_str() == "1";
        assert (-1).to_str() == "-1";
        assert 200u.to_str() == "200";
        assert 2u8.to_str() == "2";
        assert true.to_str() == "true";
        assert false.to_str() == "false";
        assert ().to_str() == "()";
        assert "hi".to_str() == "hi";
    }

    #[test]
    fn test_tuple_types() {
        assert (1, 2).to_str() == "(1, 2)";
        assert ("a", "b", false).to_str() == "(a, b, false)";
        assert ((), ((), 100)).to_str() == "((), ((), 100))";
    }

    fn test_vectors() {
        let x: ~[int] = ~[];
        assert x.to_str() == "~[]";
        assert (~[1]).to_str() == "~[1]";
        assert (~[1, 2, 3]).to_str() == "~[1, 2, 3]";
        assert (~[~[], ~[1], ~[1, 1]]).to_str() ==
               "~[~[], ~[1], ~[1, 1]]";
    }

    fn test_pointer_types() {
        assert (@1).to_str() == "@1";
        assert (~(true, false)).to_str() == "~(true, false)";
    }
}
<commit_msg>Add test attributes to test functions missing test attributes.<commit_after>iface to_str { fn to_str() -> str; }

impl of to_str for int {
    fn to_str() -> str { int::str(self) }
}
impl of to_str for i8 {
    fn to_str() -> str { i8::str(self) }
}
impl of to_str for i16 {
    fn to_str() -> str { i16::str(self) }
}
impl of to_str for i32 {
    fn to_str() -> str { i32::str(self) }
}
impl of to_str for i64 {
    fn to_str() -> str { i64::str(self) }
}
impl of to_str for uint {
    fn to_str() -> str { uint::str(self) }
}
impl of to_str for u8 {
    fn to_str() -> str { u8::str(self) }
}
impl of to_str for u16 {
    fn to_str() -> str { u16::str(self) }
}
impl of to_str for u32 {
    fn to_str() -> str { u32::str(self) }
}
impl of to_str for u64 {
    fn to_str() -> str { u64::str(self) }
}
impl of to_str for float {
    fn to_str() -> str { float::to_str(self, 4u) }
}
impl of to_str for bool {
    fn to_str() -> str { bool::to_str(self) }
}
impl of to_str for () {
    fn to_str() -> str { "()" }
}
impl of to_str for str {
    fn to_str() -> str { self }
}

impl <A: to_str copy, B: to_str copy> of to_str for (A, B) {
    fn to_str() -> str {
        let (a, b) = self;
        "(" + a.to_str() + ", " + b.to_str() + ")"
    }
}
impl <A: to_str copy, B: to_str copy, C: to_str copy> of to_str for (A, B, C){
    fn to_str() -> str {
        let (a, b, c) = self;
        "(" + a.to_str() + ", " + b.to_str() + ", " + c.to_str() + ")"
    }
}

impl <A: to_str> of to_str for ~[A] {
    fn to_str() -> str {
        let mut acc = "[", first = true;
        for vec::each(self) |elt| {
            if first { first = false; }
            else { str::push_str(acc, ", "); }
            str::push_str(acc, elt.to_str());
        }
        str::push_char(acc, ']');
        acc
    }
}

impl <A: to_str> of to_str for @A {
    fn to_str() -> str { "@" + (*self).to_str() }
}
impl <A: to_str> of to_str for ~A {
    fn to_str() -> str { "~" + (*self).to_str() }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_simple_types() {
        assert 1.to_str() == "1";
        assert (-1).to_str() == "-1";
        assert 200u.to_str() == "200";
        assert 2u8.to_str() == "2";
        assert true.to_str() == "true";
        assert false.to_str() == "false";
        assert ().to_str() == "()";
        assert "hi".to_str() == "hi";
    }

    #[test]
    fn test_tuple_types() {
        assert (1, 2).to_str() == "(1, 2)";
        assert ("a", "b", false).to_str() == "(a, b, false)";
        assert ((), ((), 100)).to_str() == "((), ((), 100))";
    }

    #[test]
    fn test_vectors() {
        let x: ~[int] = ~[];
        assert x.to_str() == "~[]";
        assert (~[1]).to_str() == "~[1]";
        assert (~[1, 2, 3]).to_str() == "~[1, 2, 3]";
        assert (~[~[], ~[1], ~[1, 1]]).to_str() ==
               "~[~[], ~[1], ~[1, 1]]";
    }

    #[test]
    fn test_pointer_types() {
        assert (@1).to_str() == "@1";
        assert (~(true, false)).to_str() == "~(true, false)";
    }
}
<|endoftext|>


<commit_before><commit_msg>God damn it how did I miss this one<commit_after>//! Handler for outputs

use libc;
use output;
use wlroots_sys::wlr_output;

pub trait OutputHandler {
    /// Called every time the output frame is updated.
    fn output_frame(&mut self, &mut output::Output) {
        // TODO
    }

    /// Called every time the output resolution changes.
    fn output_resolution(&mut self, &mut output::Output) {
        // TODO
    }
}

wayland_listener!(Output, Box<OutputHandler>, [
    frame_listener => frame_notify: |this: &mut Output, data: *mut libc::c_void,| unsafe {
        // TODO Ensure safety
        this.data.output_frame(&mut output::Output::from_ptr(data as *mut wlr_output))
    };
    resolution_listener => resolution_notify: |this: &mut Output, data: *mut libc::c_void,| unsafe {
        // TODO Ensure safety
        this.data.output_resolution(&mut output::Output::from_ptr(data as *mut wlr_output))
    };
]);
<|endoftext|>


<commit_before><commit_msg>languages/rust/learn-rust/3-chapter/12-code.rs<commit_after><|endoftext|>


<commit_before>use std::collections::{BTreeMap, BTreeSet};
use std::io;
use std::error::FromError;

use rustc_serialize::json;
use rustc_serialize::json::{Json, ToJson};

#[derive(Clone, Debug, PartialEq)]
pub enum ChatJsonError {
    MalformedJson(json::ParserError),
    IoError(io::Error),
    InvalidObject,
    InvalidField,
    UnknownField,
    UnknownColor,
    InvalidClickEvent,
    InvalidHoverEvent
}

impl FromError<io::Error> for ChatJsonError {
    fn from_error(err: io::Error) -> ChatJsonError {
        ChatJsonError::IoError(err)
    }
}

impl FromError<json::ParserError> for ChatJsonError {
    fn from_error(err: json::ParserError) -> ChatJsonError {
        if let json::ParserError::IoError(e) = err {
            ChatJsonError::IoError(e)
        } else {
            ChatJsonError::MalformedJson(err)
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct ChatJson {
    pub msg: Message,
    pub extra: Option<Vec<Json>>,
    pub color: Option<Color>,
    pub formats: BTreeSet<Format>,
    pub click_event: Option<ClickEvent>,
    pub hover_event: Option<HoverEvent>,
    pub insertion: Option<String>
}

impl ChatJson {
    pub fn msg(msg: String) -> ChatJson {
        ChatJson {
            msg: Message::PlainText(msg), extra: None, color: None, formats: BTreeSet::new(),
            click_event: None, hover_event: None, insertion: None
        }
    }

    pub fn from_json<T: Iterator<Item=char>>(src: T) -> Result<ChatJson, ChatJsonError> {
        let json = try!(json::Builder::new(src).build());
        if let Json::Object(map) = json {
            let mut result = ChatJson::msg("".to_string());
            for (key, value) in map {
                println!("{:?}: {:?}", key, value);
                match key.as_slice() {
                    "text" => {
                        if let Json::String(string) = value {
                            result.msg = Message::PlainText(string);
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    "insertion" => {
                        if let Json::String(string) = value {
                            result.insertion = Some(string);
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    "color" => {
                        if let Json::String(string) = value {
                            result.color = match Color::from_string(&string) {
                                None => return Err(ChatJsonError::UnknownColor),
                                c => c
                            };
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    // Handle all of the different format strings.
                    "bold"|"italic"|"underlined"|"strikethrough"|"obfuscated"|"reset"|"random" => {
                        if let Json::Boolean(b) = value {
                            if b == true {
                                result.formats.insert(Format::from_string(&key).unwrap());
                            }
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    // Handle the JSON format of click events.
                    "clickEvent" => {
                        if let Json::Object(event) = value {
                            // Get the `value` first.
                            let val: String = match event.get("value") {
                                Some(&Json::String(ref string)) => string.clone(),
                                _ => return Err(ChatJsonError::InvalidClickEvent)
                            };
                            // Handle the different click events.
                            if let Some(&Json::String(ref string)) = event.get("action") {
                                result.click_event = match string.as_slice() {
                                    "open_url" => Some(ClickEvent::OpenUrl(val)),
                                    "open_file" => Some(ClickEvent::OpenFile(val)),
                                    "run_command" => Some(ClickEvent::RunCommand(val)),
                                    "suggest_command" => Some(ClickEvent::SuggestCommand(val)),
                                    _ => return Err(ChatJsonError::InvalidClickEvent)
                                };
                            } else {
                                return Err(ChatJsonError::InvalidClickEvent);
                            }
                        }
                    },
                    // Handle the JSON format of hover events.
                    "hoverEvent" => {
                        if let Json::Object(event) = value {
                            // Get the `value` first.
                            let val: String = match event.get("value") {
                                Some(&Json::String(ref string)) => string.clone(),
                                _ => return Err(ChatJsonError::InvalidHoverEvent)
                            };
                            // Handle the different click events.
                            if let Some(&Json::String(ref string)) = event.get("action") {
                                result.hover_event = match string.as_slice() {
                                    "show_text" => Some(HoverEvent::Text(val)),
                                    "show_achievement" => Some(HoverEvent::Achievement(val)),
                                    "show_item" => Some(HoverEvent::Item(val)),
                                    _ => return Err(ChatJsonError::InvalidHoverEvent)
                                };
                            } else {
                                return Err(ChatJsonError::InvalidHoverEvent);
                            }
                        }
                    },
                    "extra" => {
                        if let Json::Array(extra) = value {
                            result.extra = Some(extra);
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    // TODO: Error on unknown key when the implementation is complete.
                    _ => (),
                };
            }
            Ok(result)
        } else {
            Err(ChatJsonError::InvalidObject)
        }
    }
}

impl ToJson for ChatJson {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        match self.msg {
            Message::PlainText(ref text) => {
                d.insert("text".to_string(), text.to_json());
            },
            _ => unimplemented!()
        };

        for format in self.formats.iter() {
            d.insert(format.to_string(), Json::Boolean(true));
        }

        if let Some(ref extra) = self.extra {
            d.insert("extra".to_string(), extra.to_json());
        }
        if let Some(ref color) = self.color {
            d.insert("color".to_string(), color.to_string().to_json());
        }
        if let Some(ref event) = self.click_event {
            d.insert("clickEvent".to_string(), event.to_json());
        }
        if let Some(ref event) = self.hover_event {
            d.insert("hoverEvent".to_string(), event.to_json());
        }
        if let Some(ref ins) = self.insertion {
            d.insert("insertion".to_string(), ins.to_json());
        }

        Json::Object(d)
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Message {
    PlainText(String),
    Score(String, String),
    Translatable,
    Selector
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ClickEvent {
    OpenUrl(String),
    OpenFile(String),
    RunCommand(String),
    SuggestCommand(String)
}

impl ToJson for ClickEvent {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self {
            &ClickEvent::OpenUrl(ref url) => {
                d.insert("action".to_string(), "open_url".to_json());
                d.insert("value".to_string(), url.to_json());
            },
            &ClickEvent::OpenFile(ref file) => {
                d.insert("action".to_string(), "open_file".to_json());
                d.insert("value".to_string(), file.to_json());
            },
            &ClickEvent::RunCommand(ref cmd) => {
                d.insert("action".to_string(), "run_command".to_json());
                d.insert("value".to_string(), cmd.to_json());
            },
            &ClickEvent::SuggestCommand(ref cmd) => {
                d.insert("action".to_string(), "suggest_command".to_json());
                d.insert("value".to_string(), cmd.to_json());
            }
        }
        Json::Object(d)
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum HoverEvent {
    Text(String),
    Achievement(String),
    Item(String)
}

impl ToJson for HoverEvent {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self {
            &HoverEvent::Text(ref text) => {
                d.insert("action".to_string(), "show_text".to_json());
                d.insert("value".to_string(), text.to_json());
            },
            &HoverEvent::Achievement(ref ach) => {
                d.insert("action".to_string(), "show_achievement".to_json());
                d.insert("value".to_string(), ach.to_json());
            },
            &HoverEvent::Item(ref item) => {
                d.insert("action".to_string(), "show_item".to_json());
                // The string is actually a JSON object, just in the form of a
                // string.
                d.insert("value".to_string(), item.to_json());
            }
        }
        Json::Object(d)
    }
}

#[derive(Copy, Debug, Clone, Eq, PartialEq)]
pub enum Color {
    Black       = 0x0,
    DarkBlue    = 0x1,
    DarkGreen   = 0x2,
    DarkCyan    = 0x3,
    DarkRed     = 0x4,
    Purple      = 0x5,
    Gold        = 0x6,
    Gray        = 0x7,
    DarkGray    = 0x8,
    Blue        = 0x9,
    BrightGreen = 0xa,
    Cyan        = 0xb,
    Red         = 0xc,
    Pink        = 0xd,
    Yellow      = 0xe,
    White       = 0xf
}

impl Color {
    pub fn to_string(&self) -> String {
        match self {
            &Color::Black => "black".to_string(),
            &Color::DarkBlue => "dark_blue".to_string(),
            &Color::DarkGreen => "dark_green".to_string(),
            &Color::DarkCyan => "dark_aqua".to_string(),
            &Color::DarkRed => "dark_red".to_string(),
            &Color::Purple => "dark_purple".to_string(),
            &Color::Gold => "gold".to_string(),
            &Color::Gray => "gray".to_string(),
            &Color::DarkGray => "dark_gray".to_string(),
            &Color::Blue => "blue".to_string(),
            &Color::BrightGreen => "green".to_string(),
            &Color::Cyan => "aqua".to_string(),
            &Color::Red => "red".to_string(),
            &Color::Pink => "light_purple".to_string(),
            &Color::Yellow => "yellow".to_string(),
            &Color::White => "white".to_string()
        }
    }

    pub fn from_string(string: &String) -> Option<Color> {
        match string.as_slice() {
            "black"        => Some(Color::Black),
            "dark_blue"    => Some(Color::DarkBlue),
            "dark_green"   => Some(Color::DarkGreen),
            "dark_aqua"    => Some(Color::DarkCyan),
            "dark_red"     => Some(Color::DarkRed),
            "dark_purple"  => Some(Color::Purple),
            "gold"         => Some(Color::Gold),
            "gray"         => Some(Color::Gray),
            "dark_gray"    => Some(Color::DarkGray),
            "blue"         => Some(Color::Blue),
            "green"        => Some(Color::BrightGreen),
            "aqua"         => Some(Color::Cyan),
            "red"          => Some(Color::Red),
            "light_purple" => Some(Color::Pink),
            "yellow"       => Some(Color::Yellow),
            "white"        => Some(Color::White),
            _              => None
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
pub enum Format {
    Bold, Underlined, Strikethrough, Italic, Obfuscated, Random, Reset
}

impl Format {
    pub fn to_string(&self) -> String {
        match self {
            &Format::Bold          => "bold".to_string(),
            &Format::Italic        => "italic".to_string(),
            &Format::Underlined    => "underlined".to_string(),
            &Format::Strikethrough => "strikethrough".to_string(),
            &Format::Obfuscated    => "obfuscated".to_string(),
            &Format::Random        => "random".to_string(),
            &Format::Reset         => "reset".to_string()
        }
    }

    pub fn from_string(string: &String) -> Option<Format> {
        match string.as_slice() {
            "bold"          => Some(Format::Bold),
            "italic"        => Some(Format::Italic),
            "underlined"    => Some(Format::Underlined),
            "strikethrough" => Some(Format::Strikethrough),
            "obfuscated"    => Some(Format::Obfuscated),
            "random"        => Some(Format::Random),
            "reset"         => Some(Format::Reset),
            _               => None
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rustc_serialize::json::{Builder, ToJson};

    #[test]
    fn chat_plain() {
        let msg = ChatJson::msg("Hello, world!".to_string());
        let blob = r#"{
            "text": "Hello, world!"
        }"#;
        let parsed = ChatJson::from_json(blob.chars()).unwrap();
        assert_eq!(&msg, &parsed);
    }

    #[test]
    fn chat_invalid_field() {
        let blob = r#"{
            "text": true
        }"#;
        let parsed = ChatJson::from_json(blob.chars());
        assert_eq!(&parsed, &Err(ChatJsonError::InvalidField));
    }

    #[test]
    fn chat_with_events() {
        let mut msg = ChatJson::msg("Hello, world!".to_string());
        msg.formats.insert(Format::Bold);
        msg.formats.insert(Format::Strikethrough);
        msg.color = Some(Color::Red);
        msg.insertion = Some("Hello, world!".to_string());
        msg.click_event = Some(ClickEvent::RunCommand("/time set day".to_string()));
        msg.hover_event = Some(HoverEvent::Text("Goodbye!".to_string()));

        let blob = r#"{
            "text": "Hello, world!",
            "bold": true,
            "strikethrough": true,
            "color":"red",
            "clickEvent":{
                "action":"run_command",
                "value": "/time set day"
            },
            "hoverEvent": {
                "action":"show_text",
                "value": "Goodbye!"
            },
            "insertion": "Hello, world!"
        }"#;

        let blob_json = Builder::new(blob.chars()).build().unwrap();
        assert_eq!(&blob_json, &msg.to_json());
        assert_eq!(&msg, &ChatJson::from_json(blob.chars()));
    }

    #[test]
    fn chat_extra() {
        let blob = r#"{
            "text": "Hello world",
            "extra": [
                "Testing",
                {"translate":"demo.day.2"}
            ],
            "bold":true,
            "italic":false,
            "underlined": false,
            "strikethrough": true,
            "obfuscated": false,
            "color":"red",
            "clickEvent":{
                "action":"run_command",
                "value": "/time set day"
            },
            "hoverEvent": {
                "action":"show_text",
                "value": "Hello"
            },
            "insertion": "Hello world"
        }"#;

        let parsed = ChatJson::from_json(blob.chars());
        println!("{:?}", parsed);
    }
}
<commit_msg>chat: Now uses `Json::from_reader()` directly.<commit_after>use std::collections::{BTreeMap, BTreeSet};
use std::io;
use std::error::FromError;

use rustc_serialize::json;
use rustc_serialize::json::{Json, ToJson};

#[derive(Clone, Debug, PartialEq)]
pub enum ChatJsonError {
    MalformedJson(json::ParserError),
    IoError(io::Error),
    InvalidObject,
    InvalidField,
    UnknownField,
    UnknownColor,
    InvalidClickEvent,
    InvalidHoverEvent
}

impl FromError<io::Error> for ChatJsonError {
    fn from_error(err: io::Error) -> ChatJsonError {
        ChatJsonError::IoError(err)
    }
}

impl FromError<json::ParserError> for ChatJsonError {
    fn from_error(err: json::ParserError) -> ChatJsonError {
        if let json::ParserError::IoError(e) = err {
            ChatJsonError::IoError(e)
        } else {
            ChatJsonError::MalformedJson(err)
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct ChatJson {
    pub msg: Message,
    pub extra: Option<Vec<Json>>,
    pub color: Option<Color>,
    pub formats: BTreeSet<Format>,
    pub click_event: Option<ClickEvent>,
    pub hover_event: Option<HoverEvent>,
    pub insertion: Option<String>
}

impl ChatJson {
    pub fn msg(msg: String) -> ChatJson {
        ChatJson {
            msg: Message::PlainText(msg), extra: None, color: None, formats: BTreeSet::new(),
            click_event: None, hover_event: None, insertion: None
        }
    }

    pub fn from_json(src: &mut io::Read) -> Result<ChatJson, ChatJsonError> {
        let json = try!(Json::from_reader(src));
        if let Json::Object(map) = json {
            let mut result = ChatJson::msg("".to_string());
            for (key, value) in map {
                println!("{:?}: {:?}", key, value);
                match key.as_slice() {
                    "text" => {
                        if let Json::String(string) = value {
                            result.msg = Message::PlainText(string);
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    "insertion" => {
                        if let Json::String(string) = value {
                            result.insertion = Some(string);
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    "color" => {
                        if let Json::String(string) = value {
                            result.color = match Color::from_string(&string) {
                                None => return Err(ChatJsonError::UnknownColor),
                                c => c
                            };
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    // Handle all of the different format strings.
                    "bold"|"italic"|"underlined"|"strikethrough"|"obfuscated"|"reset"|"random" => {
                        if let Json::Boolean(b) = value {
                            if b == true {
                                result.formats.insert(Format::from_string(&key).unwrap());
                            }
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    // Handle the JSON format of click events.
                    "clickEvent" => {
                        if let Json::Object(event) = value {
                            // Get the `value` first.
                            let val: String = match event.get("value") {
                                Some(&Json::String(ref string)) => string.clone(),
                                _ => return Err(ChatJsonError::InvalidClickEvent)
                            };
                            // Handle the different click events.
                            if let Some(&Json::String(ref string)) = event.get("action") {
                                result.click_event = match string.as_slice() {
                                    "open_url" => Some(ClickEvent::OpenUrl(val)),
                                    "open_file" => Some(ClickEvent::OpenFile(val)),
                                    "run_command" => Some(ClickEvent::RunCommand(val)),
                                    "suggest_command" => Some(ClickEvent::SuggestCommand(val)),
                                    _ => return Err(ChatJsonError::InvalidClickEvent)
                                };
                            } else {
                                return Err(ChatJsonError::InvalidClickEvent);
                            }
                        }
                    },
                    // Handle the JSON format of hover events.
                    "hoverEvent" => {
                        if let Json::Object(event) = value {
                            // Get the `value` first.
                            let val: String = match event.get("value") {
                                Some(&Json::String(ref string)) => string.clone(),
                                _ => return Err(ChatJsonError::InvalidHoverEvent)
                            };
                            // Handle the different click events.
                            if let Some(&Json::String(ref string)) = event.get("action") {
                                result.hover_event = match string.as_slice() {
                                    "show_text" => Some(HoverEvent::Text(val)),
                                    "show_achievement" => Some(HoverEvent::Achievement(val)),
                                    "show_item" => Some(HoverEvent::Item(val)),
                                    _ => return Err(ChatJsonError::InvalidHoverEvent)
                                };
                            } else {
                                return Err(ChatJsonError::InvalidHoverEvent);
                            }
                        }
                    },
                    "extra" => {
                        if let Json::Array(extra) = value {
                            result.extra = Some(extra);
                        } else {
                            return Err(ChatJsonError::InvalidField);
                        }
                    },
                    // TODO: Error on unknown key when the implementation is complete.
                    _ => (),
                };
            }
            Ok(result)
        } else {
            Err(ChatJsonError::InvalidObject)
        }
    }
}

impl ToJson for ChatJson {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        match self.msg {
            Message::PlainText(ref text) => {
                d.insert("text".to_string(), text.to_json());
            },
            _ => unimplemented!()
        };

        for format in self.formats.iter() {
            d.insert(format.to_string(), Json::Boolean(true));
        }

        if let Some(ref extra) = self.extra {
            d.insert("extra".to_string(), extra.to_json());
        }
        if let Some(ref color) = self.color {
            d.insert("color".to_string(), color.to_string().to_json());
        }
        if let Some(ref event) = self.click_event {
            d.insert("clickEvent".to_string(), event.to_json());
        }
        if let Some(ref event) = self.hover_event {
            d.insert("hoverEvent".to_string(), event.to_json());
        }
        if let Some(ref ins) = self.insertion {
            d.insert("insertion".to_string(), ins.to_json());
        }

        Json::Object(d)
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Message {
    PlainText(String),
    Score(String, String),
    Translatable,
    Selector
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ClickEvent {
    OpenUrl(String),
    OpenFile(String),
    RunCommand(String),
    SuggestCommand(String)
}

impl ToJson for ClickEvent {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self {
            &ClickEvent::OpenUrl(ref url) => {
                d.insert("action".to_string(), "open_url".to_json());
                d.insert("value".to_string(), url.to_json());
            },
            &ClickEvent::OpenFile(ref file) => {
                d.insert("action".to_string(), "open_file".to_json());
                d.insert("value".to_string(), file.to_json());
            },
            &ClickEvent::RunCommand(ref cmd) => {
                d.insert("action".to_string(), "run_command".to_json());
                d.insert("value".to_string(), cmd.to_json());
            },
            &ClickEvent::SuggestCommand(ref cmd) => {
                d.insert("action".to_string(), "suggest_command".to_json());
                d.insert("value".to_string(), cmd.to_json());
            }
        }
        Json::Object(d)
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum HoverEvent {
    Text(String),
    Achievement(String),
    Item(String)
}

impl ToJson for HoverEvent {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self {
            &HoverEvent::Text(ref text) => {
                d.insert("action".to_string(), "show_text".to_json());
                d.insert("value".to_string(), text.to_json());
            },
            &HoverEvent::Achievement(ref ach) => {
                d.insert("action".to_string(), "show_achievement".to_json());
                d.insert("value".to_string(), ach.to_json());
            },
            &HoverEvent::Item(ref item) => {
                d.insert("action".to_string(), "show_item".to_json());
                // The string is actually a JSON object, just in the form of a
                // string.
                d.insert("value".to_string(), item.to_json());
            }
        }
        Json::Object(d)
    }
}

#[derive(Copy, Debug, Clone, Eq, PartialEq)]
pub enum Color {
    Black       = 0x0,
    DarkBlue    = 0x1,
    DarkGreen   = 0x2,
    DarkCyan    = 0x3,
    DarkRed     = 0x4,
    Purple      = 0x5,
    Gold        = 0x6,
    Gray        = 0x7,
    DarkGray    = 0x8,
    Blue        = 0x9,
    BrightGreen = 0xa,
    Cyan        = 0xb,
    Red         = 0xc,
    Pink        = 0xd,
    Yellow      = 0xe,
    White       = 0xf
}

impl Color {
    pub fn to_string(&self) -> String {
        match self {
            &Color::Black => "black".to_string(),
            &Color::DarkBlue => "dark_blue".to_string(),
            &Color::DarkGreen => "dark_green".to_string(),
            &Color::DarkCyan => "dark_aqua".to_string(),
            &Color::DarkRed => "dark_red".to_string(),
            &Color::Purple => "dark_purple".to_string(),
            &Color::Gold => "gold".to_string(),
            &Color::Gray => "gray".to_string(),
            &Color::DarkGray => "dark_gray".to_string(),
            &Color::Blue => "blue".to_string(),
            &Color::BrightGreen => "green".to_string(),
            &Color::Cyan => "aqua".to_string(),
            &Color::Red => "red".to_string(),
            &Color::Pink => "light_purple".to_string(),
            &Color::Yellow => "yellow".to_string(),
            &Color::White => "white".to_string()
        }
    }

    pub fn from_string(string: &String) -> Option<Color> {
        match string.as_slice() {
            "black"        => Some(Color::Black),
            "dark_blue"    => Some(Color::DarkBlue),
            "dark_green"   => Some(Color::DarkGreen),
            "dark_aqua"    => Some(Color::DarkCyan),
            "dark_red"     => Some(Color::DarkRed),
            "dark_purple"  => Some(Color::Purple),
            "gold"         => Some(Color::Gold),
            "gray"         => Some(Color::Gray),
            "dark_gray"    => Some(Color::DarkGray),
            "blue"         => Some(Color::Blue),
            "green"        => Some(Color::BrightGreen),
            "aqua"         => Some(Color::Cyan),
            "red"          => Some(Color::Red),
            "light_purple" => Some(Color::Pink),
            "yellow"       => Some(Color::Yellow),
            "white"        => Some(Color::White),
            _              => None
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
pub enum Format {
    Bold, Underlined, Strikethrough, Italic, Obfuscated, Random, Reset
}

impl Format {
    pub fn to_string(&self) -> String {
        match self {
            &Format::Bold          => "bold".to_string(),
            &Format::Italic        => "italic".to_string(),
            &Format::Underlined    => "underlined".to_string(),
            &Format::Strikethrough => "strikethrough".to_string(),
            &Format::Obfuscated    => "obfuscated".to_string(),
            &Format::Random        => "random".to_string(),
            &Format::Reset         => "reset".to_string()
        }
    }

    pub fn from_string(string: &String) -> Option<Format> {
        match string.as_slice() {
            "bold"          => Some(Format::Bold),
            "italic"        => Some(Format::Italic),
            "underlined"    => Some(Format::Underlined),
            "strikethrough" => Some(Format::Strikethrough),
            "obfuscated"    => Some(Format::Obfuscated),
            "random"        => Some(Format::Random),
            "reset"         => Some(Format::Reset),
            _               => None
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io;
    use rustc_serialize::json::{Builder, ToJson};

    #[test]
    fn chat_plain() {
        let msg = ChatJson::msg("Hello, world!".to_string());
        let blob = r#"{
            "text": "Hello, world!"
        }"#;
        let parsed = ChatJson::from_json(&mut io::Cursor::new(blob.as_bytes())).unwrap();
        assert_eq!(&msg, &parsed);
    }

    #[test]
    fn chat_invalid_field() {
        let blob = r#"{
            "text": true
        }"#;
        let parsed = ChatJson::from_json(&mut io::Cursor::new(blob.as_bytes()));
        assert_eq!(&parsed, &Err(ChatJsonError::InvalidField));
    }

    #[test]
    fn chat_with_events() {
        let mut msg = ChatJson::msg("Hello, world!".to_string());
        msg.formats.insert(Format::Bold);
        msg.formats.insert(Format::Strikethrough);
        msg.color = Some(Color::Red);
        msg.insertion = Some("Hello, world!".to_string());
        msg.click_event = Some(ClickEvent::RunCommand("/time set day".to_string()));
        msg.hover_event = Some(HoverEvent::Text("Goodbye!".to_string()));

        let blob = r#"{
            "text": "Hello, world!",
            "bold": true,
            "strikethrough": true,
            "color":"red",
            "clickEvent":{
                "action":"run_command",
                "value": "/time set day"
            },
            "hoverEvent": {
                "action":"show_text",
                "value": "Goodbye!"
            },
            "insertion": "Hello, world!"
        }"#;

        let blob_json = Builder::new(blob.chars()).build().unwrap();
        assert_eq!(&blob_json, &msg.to_json());
        let parsed = ChatJson::from_json(&mut io::Cursor::new(blob.as_bytes())).unwrap();
        assert_eq!(&msg, &parsed);
    }

    #[test]
    fn chat_extra() {
        let blob = r#"{
            "text": "Hello world",
            "extra": [
                "Testing",
                {"translate":"demo.day.2"}
            ],
            "bold":true,
            "italic":false,
            "underlined": false,
            "strikethrough": true,
            "obfuscated": false,
            "color":"red",
            "clickEvent":{
                "action":"run_command",
                "value": "/time set day"
            },
            "hoverEvent": {
                "action":"show_text",
                "value": "Hello"
            },
            "insertion": "Hello world"
        }"#;

        let parsed = ChatJson::from_json(&mut io::Cursor::new(blob.as_bytes()));
        println!("{:?}", parsed);
    }
}
<|endoftext|>


<commit_before><commit_msg>coords<commit_after><|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

//! Check license of third-party deps by inspecting src/vendor

use std::collections::{BTreeSet, HashSet};
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;

use serde_json;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "Apache-2.0 / MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
    "Unlicense OR MIT",
];

/// These are exceptions to Rust's permissive licensing policy, and
/// should be considered bugs. Exceptions are only allowed in Rust
/// tooling. It is _crucial_ that no exception crates be dependencies
/// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook",             // MPL2, mdbook
    "openssl",            // BSD+advertising clause, cargo, mdbook
    "pest",               // MPL2, mdbook via handlebars
    "thread-id",          // Apache-2.0, mdbook
    "toml-query",         // MPL-2.0, mdbook
    "is-match",           // MPL-2.0, mdbook
    "cssparser",          // MPL-2.0, rustdoc
    "smallvec",           // MPL-2.0, rustdoc
    "fuchsia-zircon-sys", // BSD-3-Clause, rustdoc, rustc, cargo
    "fuchsia-zircon",     // BSD-3-Clause, rustdoc, rustc, cargo (jobserver & tempdir)
    "cssparser-macros",   // MPL-2.0, rustdoc
    "selectors",          // MPL-2.0, rustdoc
    "clippy_lints",       // MPL-2.0, rls
    "colored",            // MPL-2.0, rustfmt
    "ordslice",           // Apache-2.0, rls
];

/// Which crates to check against the whitelist?
static WHITELIST_CRATES: &'static [CrateVersion] = &[
    CrateVersion("rustc", "0.0.0"),
    CrateVersion("rustc_codegen_llvm", "0.0.0"),
];

/// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
static WHITELIST: &'static [Crate] = &[
    Crate("aho-corasick"),
    Crate("arrayvec"),
    Crate("atty"),
    Crate("backtrace"),
    Crate("backtrace-sys"),
    Crate("bitflags"),
    Crate("byteorder"),
    Crate("cc"),
    Crate("chalk-engine"),
    Crate("chalk-macros"),
    Crate("cfg-if"),
    Crate("cmake"),
    Crate("crossbeam-deque"),
    Crate("crossbeam-epoch"),
    Crate("crossbeam-utils"),
    Crate("datafrog"),
    Crate("either"),
    Crate("ena"),
    Crate("env_logger"),
    Crate("filetime"),
    Crate("flate2"),
    Crate("fuchsia-zircon"),
    Crate("fuchsia-zircon-sys"),
    Crate("getopts"),
    Crate("humantime"),
    Crate("jobserver"),
    Crate("kernel32-sys"),
    Crate("lazy_static"),
    Crate("libc"),
    Crate("log"),
    Crate("log_settings"),
    Crate("memchr"),
    Crate("memoffset"),
    Crate("miniz-sys"),
    Crate("nodrop"),
    Crate("num_cpus"),
    Crate("owning_ref"),
    Crate("parking_lot"),
    Crate("parking_lot_core"),
    Crate("polonius-engine"),
    Crate("pkg-config"),
    Crate("quick-error"),
    Crate("rand"),
    Crate("redox_syscall"),
    Crate("redox_termios"),
    Crate("regex"),
    Crate("regex-syntax"),
    Crate("remove_dir_all"),
    Crate("rustc-demangle"),
    Crate("rustc-hash"),
    Crate("rustc-rayon"),
    Crate("rustc-rayon-core"),
    Crate("scoped-tls"),
    Crate("scopeguard"),
    Crate("smallvec"),
    Crate("stable_deref_trait"),
    Crate("tempfile"),
    Crate("termcolor"),
    Crate("terminon"),
    Crate("termion"),
    Crate("thread_local"),
    Crate("ucd-util"),
    Crate("unicode-width"),
    Crate("unreachable"),
    Crate("utf8-ranges"),
    Crate("void"),
    Crate("winapi"),
    Crate("winapi-build"),
    Crate("winapi-i686-pc-windows-gnu"),
    Crate("winapi-x86_64-pc-windows-gnu"),
    Crate("wincolor"),
];

// Some types for Serde to deserialize the output of `cargo metadata` to...

#[derive(Deserialize)]
struct Output {
    resolve: Resolve,
}

#[derive(Deserialize)]
struct Resolve {
    nodes: Vec<ResolveNode>,
}

#[derive(Deserialize)]
struct ResolveNode {
    id: String,
    dependencies: Vec<String>,
}

/// A unique identifier for a crate
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct Crate<'a>(&'a str); // (name,)

#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct CrateVersion<'a>(&'a str, &'a str); // (name, version)

impl<'a> Crate<'a> {
    pub fn id_str(&self) -> String {
        format!("{} ", self.0)
    }
}

impl<'a> CrateVersion<'a> {
    /// Returns the struct and whether or not the dep is in-tree
    pub fn from_str(s: &'a str) -> (Self, bool) {
        let mut parts = s.split(' ');
        let name = parts.next().unwrap();
        let version = parts.next().unwrap();
        let path = parts.next().unwrap();

        let is_path_dep = path.starts_with("(path+");

        (CrateVersion(name, version), is_path_dep)
    }

    pub fn id_str(&self) -> String {
        format!("{} {}", self.0, self.1)
    }
}

impl<'a> From<CrateVersion<'a>> for Crate<'a> {
    fn from(cv: CrateVersion<'a>) -> Crate<'a> {
        Crate(cv.0)
    }
}

/// Checks the dependency at the given path. Changes `bad` to `true` if a check failed.
///
/// Specifically, this checks that the license is correct.
pub fn check(path: &Path, bad: &mut bool) {
    // Check licences
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        if EXCEPTIONS.iter().any(|exception| {
            dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception))
        }) {
            continue;
        }

        let toml = dir.path().join("Cargo.toml");
        *bad = *bad || !check_license(&toml);
    }
    assert!(saw_dir, "no vendored source");
}

/// Checks the dependency of WHITELIST_CRATES at the given path. Changes `bad` to `true` if a check
/// failed.
///
/// Specifically, this checks that the dependencies are on the WHITELIST.
pub fn check_whitelist(path: &Path, cargo: &Path, bad: &mut bool) {
    // Get dependencies from cargo metadata
    let resolve = get_deps(path, cargo);

    // Get the whitelist into a convenient form
    let whitelist: HashSet<_> = WHITELIST.iter().cloned().collect();

    // Check dependencies
    let mut visited = BTreeSet::new();
    let mut unapproved = BTreeSet::new();
    for &krate in WHITELIST_CRATES.iter() {
        let mut bad = check_crate_whitelist(&whitelist, &resolve, &mut visited, krate, false);
        unapproved.append(&mut bad);
    }

    if unapproved.len() > 0 {
        println!("Dependencies not on the whitelist:");
        for dep in unapproved {
            println!("* {}", dep.id_str());
        }
        *bad = true;
    }
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1..l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}

/// Get the dependencies of the crate at the given path using `cargo metadata`.
fn get_deps(path: &Path, cargo: &Path) -> Resolve {
    // Run `cargo metadata` to get the set of dependencies
    let output = Command::new(cargo)
        .arg("metadata")
        .arg("--format-version")
        .arg("1")
        .arg("--manifest-path")
        .arg(path.join("Cargo.toml"))
        .output()
        .expect("Unable to run `cargo metadata`")
        .stdout;
    let output = String::from_utf8_lossy(&output);
    let output: Output = serde_json::from_str(&output).unwrap();

    output.resolve
}

/// Checks the dependencies of the given crate from the given cargo metadata to see if they are on
/// the whitelist. Returns a list of illegal dependencies.
fn check_crate_whitelist<'a, 'b>(
    whitelist: &'a HashSet<Crate>,
    resolve: &'a Resolve,
    visited: &'b mut BTreeSet<CrateVersion<'a>>,
    krate: CrateVersion<'a>,
    must_be_on_whitelist: bool,
) -> BTreeSet<Crate<'a>> {
    // Will contain bad deps
    let mut unapproved = BTreeSet::new();

    // Check if we have already visited this crate
    if visited.contains(&krate) {
        return unapproved;
    }

    visited.insert(krate);

    // If this path is in-tree, we don't require it to be on the whitelist
    if must_be_on_whitelist {
        // If this dependency is not on the WHITELIST, add to bad set
        if !whitelist.contains(&krate.into()) {
            unapproved.insert(krate.into());
        }
    }

    // Do a DFS in the crate graph (it's a DAG, so we know we have no cycles!)
    let to_check = resolve
        .nodes
        .iter()
        .find(|n| n.id.starts_with(&krate.id_str()))
        .expect("crate does not exist");

    for dep in to_check.dependencies.iter() {
        let (krate, is_path_dep) = CrateVersion::from_str(dep);

        let mut bad = check_crate_whitelist(whitelist, resolve, visited, krate, !is_path_dep);
        unapproved.append(&mut bad);
    }

    unapproved
}
<commit_msg>Exempt cloudabi from license check.<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

//! Check license of third-party deps by inspecting src/vendor

use std::collections::{BTreeSet, HashSet};
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;

use serde_json;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "Apache-2.0 / MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
    "Unlicense OR MIT",
];

/// These are exceptions to Rust's permissive licensing policy, and
/// should be considered bugs. Exceptions are only allowed in Rust
/// tooling. It is _crucial_ that no exception crates be dependencies
/// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook",             // MPL2, mdbook
    "openssl",            // BSD+advertising clause, cargo, mdbook
    "pest",               // MPL2, mdbook via handlebars
    "thread-id",          // Apache-2.0, mdbook
    "toml-query",         // MPL-2.0, mdbook
    "is-match",           // MPL-2.0, mdbook
    "cssparser",          // MPL-2.0, rustdoc
    "smallvec",           // MPL-2.0, rustdoc
    "fuchsia-zircon-sys", // BSD-3-Clause, rustdoc, rustc, cargo
    "fuchsia-zircon",     // BSD-3-Clause, rustdoc, rustc, cargo (jobserver & tempdir)
    "cssparser-macros",   // MPL-2.0, rustdoc
    "selectors",          // MPL-2.0, rustdoc
    "clippy_lints",       // MPL-2.0, rls
    "colored",            // MPL-2.0, rustfmt
    "ordslice",           // Apache-2.0, rls
    "cloudabi",           // BSD-2-Clause, (rls -> crossbeam-channel 0.2 -> rand 0.5)
];

/// Which crates to check against the whitelist?
static WHITELIST_CRATES: &'static [CrateVersion] = &[
    CrateVersion("rustc", "0.0.0"),
    CrateVersion("rustc_codegen_llvm", "0.0.0"),
];

/// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
static WHITELIST: &'static [Crate] = &[
    Crate("aho-corasick"),
    Crate("arrayvec"),
    Crate("atty"),
    Crate("backtrace"),
    Crate("backtrace-sys"),
    Crate("bitflags"),
    Crate("byteorder"),
    Crate("cc"),
    Crate("chalk-engine"),
    Crate("chalk-macros"),
    Crate("cfg-if"),
    Crate("cmake"),
    Crate("crossbeam-deque"),
    Crate("crossbeam-epoch"),
    Crate("crossbeam-utils"),
    Crate("datafrog"),
    Crate("either"),
    Crate("ena"),
    Crate("env_logger"),
    Crate("filetime"),
    Crate("flate2"),
    Crate("fuchsia-zircon"),
    Crate("fuchsia-zircon-sys"),
    Crate("getopts"),
    Crate("humantime"),
    Crate("jobserver"),
    Crate("kernel32-sys"),
    Crate("lazy_static"),
    Crate("libc"),
    Crate("log"),
    Crate("log_settings"),
    Crate("memchr"),
    Crate("memoffset"),
    Crate("miniz-sys"),
    Crate("nodrop"),
    Crate("num_cpus"),
    Crate("owning_ref"),
    Crate("parking_lot"),
    Crate("parking_lot_core"),
    Crate("polonius-engine"),
    Crate("pkg-config"),
    Crate("quick-error"),
    Crate("rand"),
    Crate("redox_syscall"),
    Crate("redox_termios"),
    Crate("regex"),
    Crate("regex-syntax"),
    Crate("remove_dir_all"),
    Crate("rustc-demangle"),
    Crate("rustc-hash"),
    Crate("rustc-rayon"),
    Crate("rustc-rayon-core"),
    Crate("scoped-tls"),
    Crate("scopeguard"),
    Crate("smallvec"),
    Crate("stable_deref_trait"),
    Crate("tempfile"),
    Crate("termcolor"),
    Crate("terminon"),
    Crate("termion"),
    Crate("thread_local"),
    Crate("ucd-util"),
    Crate("unicode-width"),
    Crate("unreachable"),
    Crate("utf8-ranges"),
    Crate("void"),
    Crate("winapi"),
    Crate("winapi-build"),
    Crate("winapi-i686-pc-windows-gnu"),
    Crate("winapi-x86_64-pc-windows-gnu"),
    Crate("wincolor"),
];

// Some types for Serde to deserialize the output of `cargo metadata` to...

#[derive(Deserialize)]
struct Output {
    resolve: Resolve,
}

#[derive(Deserialize)]
struct Resolve {
    nodes: Vec<ResolveNode>,
}

#[derive(Deserialize)]
struct ResolveNode {
    id: String,
    dependencies: Vec<String>,
}

/// A unique identifier for a crate
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct Crate<'a>(&'a str); // (name,)

#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct CrateVersion<'a>(&'a str, &'a str); // (name, version)

impl<'a> Crate<'a> {
    pub fn id_str(&self) -> String {
        format!("{} ", self.0)
    }
}

impl<'a> CrateVersion<'a> {
    /// Returns the struct and whether or not the dep is in-tree
    pub fn from_str(s: &'a str) -> (Self, bool) {
        let mut parts = s.split(' ');
        let name = parts.next().unwrap();
        let version = parts.next().unwrap();
        let path = parts.next().unwrap();

        let is_path_dep = path.starts_with("(path+");

        (CrateVersion(name, version), is_path_dep)
    }

    pub fn id_str(&self) -> String {
        format!("{} {}", self.0, self.1)
    }
}

impl<'a> From<CrateVersion<'a>> for Crate<'a> {
    fn from(cv: CrateVersion<'a>) -> Crate<'a> {
        Crate(cv.0)
    }
}

/// Checks the dependency at the given path. Changes `bad` to `true` if a check failed.
///
/// Specifically, this checks that the license is correct.
pub fn check(path: &Path, bad: &mut bool) {
    // Check licences
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        if EXCEPTIONS.iter().any(|exception| {
            dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception))
        }) {
            continue;
        }

        let toml = dir.path().join("Cargo.toml");
        *bad = *bad || !check_license(&toml);
    }
    assert!(saw_dir, "no vendored source");
}

/// Checks the dependency of WHITELIST_CRATES at the given path. Changes `bad` to `true` if a check
/// failed.
///
/// Specifically, this checks that the dependencies are on the WHITELIST.
pub fn check_whitelist(path: &Path, cargo: &Path, bad: &mut bool) {
    // Get dependencies from cargo metadata
    let resolve = get_deps(path, cargo);

    // Get the whitelist into a convenient form
    let whitelist: HashSet<_> = WHITELIST.iter().cloned().collect();

    // Check dependencies
    let mut visited = BTreeSet::new();
    let mut unapproved = BTreeSet::new();
    for &krate in WHITELIST_CRATES.iter() {
        let mut bad = check_crate_whitelist(&whitelist, &resolve, &mut visited, krate, false);
        unapproved.append(&mut bad);
    }

    if unapproved.len() > 0 {
        println!("Dependencies not on the whitelist:");
        for dep in unapproved {
            println!("* {}", dep.id_str());
        }
        *bad = true;
    }
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1..l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}

/// Get the dependencies of the crate at the given path using `cargo metadata`.
fn get_deps(path: &Path, cargo: &Path) -> Resolve {
    // Run `cargo metadata` to get the set of dependencies
    let output = Command::new(cargo)
        .arg("metadata")
        .arg("--format-version")
        .arg("1")
        .arg("--manifest-path")
        .arg(path.join("Cargo.toml"))
        .output()
        .expect("Unable to run `cargo metadata`")
        .stdout;
    let output = String::from_utf8_lossy(&output);
    let output: Output = serde_json::from_str(&output).unwrap();

    output.resolve
}

/// Checks the dependencies of the given crate from the given cargo metadata to see if they are on
/// the whitelist. Returns a list of illegal dependencies.
fn check_crate_whitelist<'a, 'b>(
    whitelist: &'a HashSet<Crate>,
    resolve: &'a Resolve,
    visited: &'b mut BTreeSet<CrateVersion<'a>>,
    krate: CrateVersion<'a>,
    must_be_on_whitelist: bool,
) -> BTreeSet<Crate<'a>> {
    // Will contain bad deps
    let mut unapproved = BTreeSet::new();

    // Check if we have already visited this crate
    if visited.contains(&krate) {
        return unapproved;
    }

    visited.insert(krate);

    // If this path is in-tree, we don't require it to be on the whitelist
    if must_be_on_whitelist {
        // If this dependency is not on the WHITELIST, add to bad set
        if !whitelist.contains(&krate.into()) {
            unapproved.insert(krate.into());
        }
    }

    // Do a DFS in the crate graph (it's a DAG, so we know we have no cycles!)
    let to_check = resolve
        .nodes
        .iter()
        .find(|n| n.id.starts_with(&krate.id_str()))
        .expect("crate does not exist");

    for dep in to_check.dependencies.iter() {
        let (krate, is_path_dep) = CrateVersion::from_str(dep);

        let mut bad = check_crate_whitelist(whitelist, resolve, visited, krate, !is_path_dep);
        unapproved.append(&mut bad);
    }

    unapproved
}
<|endoftext|>


<commit_before><commit_msg>Fix: Renaming entries should also remove the old entry<commit_after><|endoftext|>


<commit_before><commit_msg>mir-borrowck: Add tests for `describe_lvalue()`<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

// revisions: ast mir
//[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir

pub struct Foo {
  x: u32
}

pub struct Bar(u32);

pub enum Baz {
    X(u32)
}

union U {
    a: u8,
    b: u64,
}

impl Foo {
  fn x(&mut self) -> &mut u32 { &mut self.x }
}

impl Bar {
    fn x(&mut self) -> &mut u32 { &mut self.0 }
}

impl Baz {
    fn x(&mut self) -> &mut u32 {
        match *self {
            Baz::X(ref mut value) => value
        }
    }
}

static mut sfoo : Foo = Foo{x: 23 };
static mut sbar : Bar = Bar(23);
static mut stuple : (i32, i32) = (24, 25);
static mut senum : Baz = Baz::X(26);
static mut sunion : U = U { a: 0 };

fn main() {
    // Local and field from struct
    {
        let mut f = Foo { x: 22 };
        let _x = f.x();
        f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `f.x` because it was mutably borrowed (Mir)
    }
    // Local and field from tuple-struct
    {
        let mut g = Bar(22);
        let _0 = g.x();
        g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `g.0` because it was mutably borrowed (Mir)
    }
    // Local and field from tuple
    {
        let mut h = (22, 23);
        let _0 = &mut h.0;
        h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `h.0` because it was mutably borrowed (Mir)
    }
    // Local and field from enum
    {
        let mut e = Baz::X(2);
        let _e0 = e.x();
        match e {
            Baz::X(value) => value
            //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
            //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed (Ast)
            //[mir]~| ERROR cannot use `e.0` because it was mutably borrowed (Mir)
        };
    }
    // Local and field from union
    unsafe {
        let mut u = U { b: 0 };
        let _ra = &mut u.a;
        u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `u.a` because it was mutably borrowed (Mir)
    }
    // Static and field from struct
    unsafe {
        let _x = sfoo.x();
        sfoo.x; //[mir]~ ERROR cannot use `sfoo.x` because it was mutably borrowed (Mir)
    }
    // Static and field from tuple-struct
    unsafe {
        let _0 = sbar.x();
        sbar.0; //[mir]~ ERROR cannot use `sbar.0` because it was mutably borrowed (Mir)
    }
    // Static and field from tuple
    unsafe {
        let _0 = &mut stuple.0;
        stuple.0; //[mir]~ ERROR cannot use `stuple.0` because it was mutably borrowed (Mir)
    }
    // Static and field from enum
    unsafe {
        let _e0 = senum.x();
        match senum {
            Baz::X(value) => value
            //[mir]~^ ERROR cannot use `senum.0` because it was mutably borrowed (Mir)
        };
    }
    // Static and field from union
    unsafe {
        let _ra = &mut sunion.a;
        sunion.a; //[mir]~ ERROR cannot use `sunion.a` because it was mutably borrowed (Mir)
    }
    // Deref and field from struct
    {
        let mut f = Box::new(Foo { x: 22 });
        let _x = f.x();
        f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `f.x` because it was mutably borrowed (Mir)
    }
    // Deref and field from tuple-struct
    {
        let mut g = Box::new(Bar(22));
        let _0 = g.x();
        g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `g.0` because it was mutably borrowed (Mir)
    }
    // Deref and field from tuple
    {
        let mut h = Box::new((22, 23));
        let _0 = &mut h.0;
        h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `h.0` because it was mutably borrowed (Mir)
    }
    // Deref and field from enum
    {
        let mut e = Box::new(Baz::X(3));
        let _e0 = e.x();
        match *e {
            Baz::X(value) => value
            //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
            //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed (Ast)
            //[mir]~| ERROR cannot use `e.0` because it was mutably borrowed (Mir)
        };
    }
    // Deref and field from union
    unsafe {
        let mut u = Box::new(U { b: 0 });
        let _ra = &mut u.a;
        u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
             //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed (Ast)
             //[mir]~| ERROR cannot use `u.a` because it was mutably borrowed (Mir)
    }
}
<|endoftext|>


<commit_before><commit_msg>Simplify: Move default header generation from Value extension to Entry type<commit_after><|endoftext|>


<commit_before><commit_msg>add a preliminary existential test; not really enough<commit_after>// edition:2018
// run-pass
// revisions: migrate mir
//[mir]compile-flags: -Z borrowck=mir

trait Trait<'a, 'b> { }
impl<T> Trait<'_, '_> for T { }

// Here we wind up selecting `'a` and `'b` in the hidden type because
// those are the types that appear inth e original values.

existential type Foo<'a, 'b>: Trait<'a, 'b>;

fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> {
    // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like
    //
    // ```
    // 'a: '0
    // 'b: '1
    // '0 in ['a, 'b]
    // '1 in ['a, 'b]
    // ```
    //
    // We use the fact that `'a: 0'` must hold (combined with the in
    // constraint) to determine that `'0 = 'a` must be the answer.
    (a, b)
}

fn main() { }
<|endoftext|>


<commit_before><commit_msg>build: fix `BuildFile` test<commit_after><|endoftext|>


<commit_before><commit_msg>Integration test for Compress filter (#179)<commit_after>/*
 * Copyright 2021 Google LLC All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#[cfg(test)]
mod tests {
    use std::net::SocketAddr;

    use slog::info;
    use tokio::time::{timeout, Duration};

    use quilkin::config::{Builder, EndPoint, Filter};
    use quilkin::extensions::filters::CompressFactory;
    use quilkin::extensions::FilterFactory;
    use quilkin::test_utils::{logger, TestHelper};

    #[tokio::test]
    async fn client_and_server() {
        let log = logger();
        let mut t = TestHelper::default();
        let echo = t.run_echo_server().await;

        // create server configuration as
        let server_port = 12356;
        let yaml = "
direction: DOWNSTREAM
";
        let server_config = Builder::empty()
            .with_port(server_port)
            .with_static(
                vec![Filter {
                    name: CompressFactory::new(&log).name(),
                    config: serde_yaml::from_str(yaml).unwrap(),
                }],
                vec![EndPoint::new(echo)],
            )
            .build();
        assert_eq!(Ok(()), server_config.validate());
        // Run server proxy.
        t.run_server(server_config);

        // create a local client
        let client_port = 12357;
        let yaml = "
direction: UPSTREAM
";
        let client_config = Builder::empty()
            .with_port(client_port)
            .with_static(
                vec![Filter {
                    name: CompressFactory::new(&log).name(),
                    config: serde_yaml::from_str(yaml).unwrap(),
                }],
                vec![EndPoint::new(
                    format!("127.0.0.1:{}", server_port).parse().unwrap(),
                )],
            )
            .build();
        assert_eq!(Ok(()), client_config.validate());
        // Run client proxy.
        t.run_server(client_config);

        // let's send the packet
        let (mut rx, tx) = t.open_socket_and_recv_multiple_packets().await;

        // game_client
        let local_addr: SocketAddr = format!("127.0.0.1:{}", client_port).parse().unwrap();
        info!(t.log, "Sending hello"; "addr" => local_addr);
        tx.send_to(b"hello", &local_addr).await.unwrap();

        let expected = timeout(Duration::from_secs(5), rx.recv())
            .await
            .expect("should have received a packet")
            .unwrap();
        assert_eq!("hello", expected);
    }
}
<|endoftext|>


<commit_before><commit_msg>chore: removes unneeded function<commit_after><|endoftext|>


<commit_before><commit_msg>Improved display of assignment op in error messages.<commit_after><|endoftext|>


<commit_before><commit_msg>Add diff! macro to reduce macro calls when diffing assignments/courses<commit_after><|endoftext|>


<commit_before><commit_msg>(fix) Call the main handlers catch method.<commit_after><|endoftext|>


<commit_before><commit_msg>Dont use "return" keyword at end of function<commit_after><|endoftext|>


<commit_before><commit_msg>Cleanup main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Changed postgres connection string logging to debug only<commit_after><|endoftext|>