<commit_before>
/*!
Parse packet captures as a 'header' and list of 'records'

# Usage:
```rust,no_run
extern crate ether;
use ether::pcap;

fn run() -> std::io::Result<()> {
    use std::fs::File;
    use std::io::Read;

    let mut buffer = Vec::new();
    let mut file = try!(File::open("capture.pcap"));
    try!(file.read_to_end(&mut buffer));

    let pcap = pcap::PacketCapture::new(buffer);
    match pcap.parse().unwrap() {
       (pcap::Header { network: pcap::Link::Ethernet, .. }, records) => {
           for pcap::Record { payload, .. } in records {
               println!("ethernet: {:?}", payload);
           }
       }
       _ => {}
    }

    Ok(())
}

fn main() {
   run().unwrap();
}
```
*/

mod pcap;
pub use self::pcap::*;
<commit_msg>Update pcap docs.<commit_after>
/*!
Parse packet captures as a 'header' and list of 'records'

# Usage:
```rust,no_run
extern crate ether;
use ether::pcap;

fn run() -> std::io::Result<()> {
    use std::fs::File;
    use std::io::Read;

    let mut buffer = Vec::new();
    let mut file = try!(File::open("capture.pcap"));
    try!(file.read_to_end(&mut buffer));

    let pcap = pcap::PacketCapture::new(buffer);
    let (_, records) = pcap.parse().unwrap();
    for record in records {
        match record {
            Ok(pcap::Record { payload, .. }) => println!("payload: {:?}", payload),
            _ => panic!("Failed to parse record!"),
        }
    }

    Ok(())
}

fn main() {
   run().unwrap();
}
```
*/

mod pcap;
pub use self::pcap::*;
<|endoftext|>


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

use WindowWrapper;
use blob;
use std::sync::mpsc::{channel, Receiver, Sender};
use webrender::api::*;
use wrench::Wrench;

pub struct RawtestHarness<'a> {
    wrench: &'a mut Wrench,
    rx: Receiver<()>,
    window: &'a mut WindowWrapper,
}

impl<'a> RawtestHarness<'a> {
    pub fn new(wrench: &'a mut Wrench, window: &'a mut WindowWrapper) -> RawtestHarness<'a> {
        // setup a notifier so we can wait for frames to be finished
        struct Notifier {
            tx: Sender<()>,
        };
        impl RenderNotifier for Notifier {
            fn new_frame_ready(&mut self) {
                self.tx.send(()).unwrap();
            }
            fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {}
        }
        let (tx, rx) = channel();
        wrench
            .renderer
            .set_render_notifier(Box::new(Notifier { tx: tx }));

        RawtestHarness {
            wrench: wrench,
            rx: rx,
            window: window,
        }
    }

    pub fn run(mut self) {
        self.retained_blob_images_test();
        self.tile_decomposition();
    }

    fn render_and_get_pixels(&mut self, window_rect: DeviceUintRect) -> Vec<u8> {
        self.rx.recv().unwrap();
        self.wrench.render();
        self.wrench.renderer.read_pixels_rgba8(window_rect)
    }

    fn tile_decomposition(&mut self) {
        // This exposes a crash in tile decomposition
        let layout_size = LayoutSize::new(800., 800.);
        let mut resources = ResourceUpdates::new();

        let blob_img = self.wrench.api.generate_image_key();
        resources.add_image(
            blob_img,
            ImageDescriptor::new(151, 56, ImageFormat::BGRA8, true),
            ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
            Some(128),
        );

        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);

        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(448.899994, 74.0), LayoutSize::new(151.000031, 56.)));

        // setup some malicious image size parameters
        builder.push_image(
            &info,
            LayoutSize::new(151., 56.0),
            LayoutSize::new(151.0, 56.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            self.wrench.document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench
            .api
            .generate_frame(self.wrench.document_id, None);

        self.rx.recv().unwrap();
        self.wrench.render();
    }

    fn retained_blob_images_test(&mut self) {
        let blob_img;
        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);
        let document_id = self.wrench.document_id;

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let mut resources = ResourceUpdates::new();
        {
            let api = &self.wrench.api;

            blob_img = api.generate_image_key();
            resources.add_image(
                blob_img,
                ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true),
                ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
                None,
            );
        }
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        // draw the blob the first time
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)));

        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench.api.generate_frame(document_id, None);

        // draw the blob image a second time at a different location

        // make a new display list that refers to the first image
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(1.0, 60.0), LayoutSize::new(200.0, 200.0)));
        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(1),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            ResourceUpdates::new(),
        );

        self.wrench.api.generate_frame(document_id, None);

        let pixels_first = self.render_and_get_pixels(window_rect);
        let pixels_second = self.render_and_get_pixels(window_rect);

        // use png;
        // png::save_flipped("out1.png", &pixels_first, window_rect.size);
        // png::save_flipped("out2.png", &pixels_second, window_rect.size);

        assert!(pixels_first != pixels_second);
    }
}
<commit_msg>Add rawtest for save-restore functionality<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use WindowWrapper;
use blob;
use std::sync::mpsc::{channel, Receiver, Sender};
use webrender::api::*;
use wrench::Wrench;

pub struct RawtestHarness<'a> {
    wrench: &'a mut Wrench,
    rx: Receiver<()>,
    window: &'a mut WindowWrapper,
}

impl<'a> RawtestHarness<'a> {
    pub fn new(wrench: &'a mut Wrench, window: &'a mut WindowWrapper) -> RawtestHarness<'a> {
        // setup a notifier so we can wait for frames to be finished
        struct Notifier {
            tx: Sender<()>,
        };
        impl RenderNotifier for Notifier {
            fn new_frame_ready(&mut self) {
                self.tx.send(()).unwrap();
            }
            fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {}
        }
        let (tx, rx) = channel();
        wrench
            .renderer
            .set_render_notifier(Box::new(Notifier { tx: tx }));

        RawtestHarness {
            wrench: wrench,
            rx: rx,
            window: window,
        }
    }

    pub fn run(mut self) {
        self.retained_blob_images_test();
        self.tile_decomposition();
        self.save_restore();
    }

    fn render_and_get_pixels(&mut self, window_rect: DeviceUintRect) -> Vec<u8> {
        self.rx.recv().unwrap();
        self.wrench.render();
        self.wrench.renderer.read_pixels_rgba8(window_rect)
    }

    fn tile_decomposition(&mut self) {
        // This exposes a crash in tile decomposition
        let layout_size = LayoutSize::new(800., 800.);
        let mut resources = ResourceUpdates::new();

        let blob_img = self.wrench.api.generate_image_key();
        resources.add_image(
            blob_img,
            ImageDescriptor::new(151, 56, ImageFormat::BGRA8, true),
            ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
            Some(128),
        );

        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);

        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(448.899994, 74.0), LayoutSize::new(151.000031, 56.)));

        // setup some malicious image size parameters
        builder.push_image(
            &info,
            LayoutSize::new(151., 56.0),
            LayoutSize::new(151.0, 56.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            self.wrench.document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench
            .api
            .generate_frame(self.wrench.document_id, None);

        self.rx.recv().unwrap();
        self.wrench.render();
    }

    fn retained_blob_images_test(&mut self) {
        let blob_img;
        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);
        let document_id = self.wrench.document_id;

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let mut resources = ResourceUpdates::new();
        {
            let api = &self.wrench.api;

            blob_img = api.generate_image_key();
            resources.add_image(
                blob_img,
                ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true),
                ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
                None,
            );
        }
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        // draw the blob the first time
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)));

        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench.api.generate_frame(document_id, None);

        // draw the blob image a second time at a different location

        // make a new display list that refers to the first image
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(1.0, 60.0), LayoutSize::new(200.0, 200.0)));
        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(1),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            ResourceUpdates::new(),
        );

        self.wrench.api.generate_frame(document_id, None);

        let pixels_first = self.render_and_get_pixels(window_rect);
        let pixels_second = self.render_and_get_pixels(window_rect);

        // use png;
        // png::save_flipped("out1.png", &pixels_first, window_rect.size);
        // png::save_flipped("out2.png", &pixels_second, window_rect.size);

        assert!(pixels_first != pixels_second);
    }

    // Ensures that content doing a save-restore produces the same results as not
    fn save_restore(&mut self) {
        fn rect(x: f32, y: f32, w: f32, h: f32) -> LayoutRect {
            LayoutRect::new(
                    LayoutPoint::new(x, y),
                    LayoutSize::new(w, h))
        }

        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        let mut do_test = |should_try_and_fail| {
            let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);

            let clip = builder.define_clip(None, rect(110., 120., 200., 200.),
                                           None::<ComplexClipRegion>, None);
            builder.push_clip_id(clip);
            builder.push_rect(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
                              ColorF::new(0.0, 0.0, 1.0, 1.0));

            if should_try_and_fail {
                let save_state = builder.save();
                let clip = builder.define_clip(None, rect(80., 80., 90., 90.),
                                           None::<ComplexClipRegion>, None);
                builder.push_clip_id(clip);
                builder.push_rect(&PrimitiveInfo::new(rect(110., 110., 50., 50.)),
                              ColorF::new(0.0, 1.0, 0.0, 1.0));
                builder.push_shadow(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
                    Shadow {
                        offset: LayoutVector2D::new(1.0, 1.0),
                        blur_radius: 1.0,
                        color: ColorF::new(0.0, 0.0, 0.0, 1.0),
                    });
                builder.push_line(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
                                  110., 110., 160., LineOrientation::Horizontal, 2.0,
                                  ColorF::new(0.0, 0.0, 0.0, 1.0), LineStyle::Solid);
                builder.restore(save_state);
            }

            let clip = builder.define_clip(None, rect(80., 80., 100., 100.),
                                           None::<ComplexClipRegion>, None);
            builder.push_clip_id(clip);
            builder.push_rect(&PrimitiveInfo::new(rect(150., 150., 100., 100.)),
                              ColorF::new(0.0, 0.0, 1.0, 1.0));

            builder.pop_clip_id();
            builder.pop_clip_id();

            self.wrench.api.set_display_list(
                self.wrench.document_id,
                Epoch(0),
                root_background_color,
                layout_size,
                builder.finalize(),
                false,
                ResourceUpdates::new(),
            );
            self.wrench
                .api
                .generate_frame(self.wrench.document_id, None);

            self.render_and_get_pixels(window_rect)
        };

        let first = do_test(false);
        let second = do_test(true);

        assert_eq!(first, second);
    }
}
<|endoftext|>


<commit_before>#![feature(box_syntax)]

use irc::event_stream::{Action, HandlerAction, Response};
use irc::protocol;
use regex::Regex;
use rand::{thread_rng, Rng};
use std::ascii::AsciiExt;
use std::collections::{hash_map, HashMap};
use std::env;
use std::str::FromStr;
use std::sync::{Arc, Mutex};

extern crate env_logger;
extern crate getopts;
extern crate irc;
extern crate rand;
extern crate regex;

#[macro_use]
extern crate log;

fn main() {
    env_logger::init().unwrap();

    let mut opts = getopts::Options::new();
    opts.reqopt("", "host", "irc server hostname", "HOSTNAME");
    opts.optopt("", "port", "irc server port", "PORT");
    opts.reqopt("n", "nick", "nickname", "NICK");
    opts.optmulti("c", "chan", "channels to join", "CHAN");

    let args: Vec<String> = env::args().collect();
    let matches = opts.parse(&args[1..]).unwrap();

    let host = matches.opt_str("host").expect("must provide --host");
    let mut port = 6667;
    if matches.opt_present("port") {
        port = u16::from_str(&matches.opt_str("port").expect("must provide argument to --port")).unwrap();
    }

    let addr = (host.as_ref(), port);
    let nick = matches.opt_str("nick").expect("must provide --nick");
    let channels = matches.opt_strs("chan");

    let knowledge_mutex: Arc<Mutex<HashMap<String, Vec<String>>>> = Arc::new(Mutex::new(HashMap::new()));

    let choice_nick = nick.clone();
    let choice_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line).and_then(|pm| pm.targeted_msg(&choice_nick)) {
            let choices: Vec<_> = Regex::new(r"\s+or\s+").unwrap()
                .split(pm.msg)
                .map(|s| s.trim())
                .filter(|s| !s.is_empty())
                .collect();
            if choices.len() > 1 {
                let mut rng = thread_rng();
                if let Some(reply_to) = pm.reply_target(&choice_nick) {
                    return Response::respond(protocol::Privmsg::new(reply_to, rng.choose(&choices).unwrap()).format());
                }
            }
        }
        Response::nothing()
    };

    let knowledge_mutex_1 = knowledge_mutex.clone();
    let learning_nick = nick.clone();
    let learning_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line).and_then(|pm| pm.targeted_msg(&learning_nick)) {
            let assignment: Vec<_> = Regex::new(r"\s+is\s+").unwrap()
                .splitn(pm.msg, 2)
                .map(|s| s.trim())
                .filter(|s| !s.is_empty())
                .collect();
            if assignment.len() == 2 {
                let mut knowledge = knowledge_mutex_1.lock().unwrap();
                match knowledge.entry(assignment[0].to_string()) {
                    hash_map::Entry::Occupied(mut e) => {
                        e.get_mut().push(assignment[1].to_string());
                    },
                    hash_map::Entry::Vacant(e) => {
                        e.insert(vec![assignment[1].to_string()]);
                    }
                }
            }
        }
        Response::nothing()
    };

    let knowledge_mutex_2 = knowledge_mutex.clone();
    let info_nick = nick.clone();
    let info_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line) {
            if let Some(reply_to) = pm.reply_target(&info_nick) {
                let knowledge = knowledge_mutex_2.lock().unwrap();
                if let Some(choices) = knowledge.get(pm.msg) {
                    let mut rng = thread_rng();
                    return Response::respond(protocol::Privmsg::new(reply_to, rng.choose(choices).unwrap()).format());
                }
            }
        }
        Response::nothing()
    };

    let echo_nick = nick.clone();
    let echo_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line).and_then(|pm| pm.targeted_msg(&echo_nick)) {
            if Regex::new(r"^[Hh]i$").ok().expect("bad regex").is_match(pm.msg) {
                if let Some(reply_to) = pm.reply_target(&echo_nick) {
                    if let Some(protocol::Source::User(ref user_info)) = pm.src {
                        return Response::respond(protocol::Privmsg::new(reply_to, &format!("Hi, {}!", user_info.nick)).format());
                    }
                }
            } else if Regex::new(r"^go away$").unwrap().is_match(pm.msg) {
                return Response(None, HandlerAction::Keep, Action::Stop);
            }
        }
        Response::nothing()
    };

    let (mut client, join_handle) = irc::Client::connect(
        &addr, &nick, &channels.iter().map(|s| s.as_ref()).collect::<Vec<&str>>(), "leifw_rustbot", "leifw's rust robot")
        .ok().expect(&format!("Error connecting to {:?}.", addr));

    client.add_handler(choice_handler);
    client.add_handler(learning_handler);
    client.add_handler(info_handler);
    client.add_handler(echo_handler);
    join_handle.join().unwrap_or_else(|_| { error!("Unknown error!"); });
}
<commit_msg>added join/part handlers<commit_after>#![feature(box_syntax)]

use irc::event_stream::{Action, HandlerAction, Response};
use irc::protocol;
use regex::Regex;
use rand::{thread_rng, Rng};
use std::ascii::AsciiExt;
use std::collections::{hash_map, HashMap};
use std::env;
use std::str::FromStr;
use std::sync::{Arc, Mutex};

extern crate env_logger;
extern crate getopts;
extern crate irc;
extern crate rand;
extern crate regex;

#[macro_use]
extern crate log;

fn main() {
    env_logger::init().unwrap();

    let mut opts = getopts::Options::new();
    opts.reqopt("", "host", "irc server hostname", "HOSTNAME");
    opts.optopt("", "port", "irc server port", "PORT");
    opts.reqopt("n", "nick", "nickname", "NICK");
    opts.optmulti("c", "chan", "channels to join", "CHAN");

    let args: Vec<String> = env::args().collect();
    let matches = opts.parse(&args[1..]).unwrap();

    let host = matches.opt_str("host").expect("must provide --host");
    let mut port = 6667;
    if matches.opt_present("port") {
        port = u16::from_str(&matches.opt_str("port").expect("must provide argument to --port")).unwrap();
    }

    let addr = (host.as_ref(), port);
    let nick = matches.opt_str("nick").expect("must provide --nick");
    let channels = matches.opt_strs("chan");

    let knowledge_mutex: Arc<Mutex<HashMap<String, Vec<String>>>> = Arc::new(Mutex::new(HashMap::new()));

    let choice_nick = nick.clone();
    let choice_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line).and_then(|pm| pm.targeted_msg(&choice_nick)) {
            let choices: Vec<_> = Regex::new(r"\s+or\s+").unwrap()
                .split(pm.msg)
                .map(|s| s.trim())
                .filter(|s| !s.is_empty())
                .collect();
            if choices.len() > 1 {
                let mut rng = thread_rng();
                if let Some(reply_to) = pm.reply_target(&choice_nick) {
                    return Response::respond(protocol::Privmsg::new(reply_to, rng.choose(&choices).unwrap()).format());
                }
            }
        }
        Response::nothing()
    };

    let knowledge_mutex_1 = knowledge_mutex.clone();
    let learning_nick = nick.clone();
    let learning_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line).and_then(|pm| pm.targeted_msg(&learning_nick)) {
            let assignment: Vec<_> = Regex::new(r"\s+is\s+").unwrap()
                .splitn(pm.msg, 2)
                .map(|s| s.trim())
                .filter(|s| !s.is_empty())
                .collect();
            if assignment.len() == 2 {
                let mut knowledge = knowledge_mutex_1.lock().unwrap();
                match knowledge.entry(assignment[0].to_string()) {
                    hash_map::Entry::Occupied(mut e) => {
                        e.get_mut().push(assignment[1].to_string());
                    },
                    hash_map::Entry::Vacant(e) => {
                        e.insert(vec![assignment[1].to_string()]);
                    }
                }
            }
        }
        Response::nothing()
    };

    let knowledge_mutex_2 = knowledge_mutex.clone();
    let info_nick = nick.clone();
    let info_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line) {
            if let Some(reply_to) = pm.reply_target(&info_nick) {
                let knowledge = knowledge_mutex_2.lock().unwrap();
                if let Some(choices) = knowledge.get(pm.msg) {
                    let mut rng = thread_rng();
                    return Response::respond(protocol::Privmsg::new(reply_to, rng.choose(choices).unwrap()).format());
                }
            }
        }
        Response::nothing()
    };

    let join_nick = nick.clone();
    let join_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line).and_then(|pm| pm.targeted_msg(&join_nick)) {
            if let Some(c) = Regex::new(r"^(join|part) (#[^\s]+)").unwrap().captures(pm.msg) {
                let action = c.at(1).expect("Bad match group");
                let chan = c.at(2).expect("Bad match group");
                let success_msg = format!("{} channel {}!", if action == "join" { "Joined" } else { "Left" }, chan);
                if let Ok(joined_regex) = Regex::new(&format!(r"{}\s+:?{}", action.to_ascii_uppercase(), chan)) {
                    let joined_handler = box move |joined_line: &str| {
                        if joined_regex.is_match(joined_line) {
                            info!("{}", success_msg);
                            return Response(None, HandlerAction::Remove, Action::Skip);
                        }
                        Response::nothing()
                    };
                    info!("{} channel {}...", if action == "join" { "Joining" } else { "Leaving" }, chan);
                    return Response(Some(format!("{} {}", action.to_ascii_uppercase(), chan)), HandlerAction::Add(joined_handler), Action::Skip);
                }
            }
        }
        Response::nothing()
    };

    let echo_nick = nick.clone();
    let echo_handler = box move |line: &str| {
        if let Some(pm) = protocol::Privmsg::parse(line).and_then(|pm| pm.targeted_msg(&echo_nick)) {
            if Regex::new(r"^[Hh]i$").ok().expect("bad regex").is_match(pm.msg) {
                if let Some(reply_to) = pm.reply_target(&echo_nick) {
                    if let Some(protocol::Source::User(ref user_info)) = pm.src {
                        return Response::respond(protocol::Privmsg::new(reply_to, &format!("Hi, {}!", user_info.nick)).format());
                    }
                }
            } else if Regex::new(r"^go away$").unwrap().is_match(pm.msg) {
                return Response(None, HandlerAction::Keep, Action::Stop);
            }
        }
        Response::nothing()
    };

    let (mut client, join_handle) = irc::Client::connect(
        &addr, &nick, &channels.iter().map(|s| s.as_ref()).collect::<Vec<&str>>(), "leifw_rustbot", "leifw's rust robot")
        .ok().expect(&format!("Error connecting to {:?}.", addr));

    client.add_handler(choice_handler);
    client.add_handler(learning_handler);
    client.add_handler(info_handler);
    client.add_handler(join_handler);
    client.add_handler(echo_handler);
    join_handle.join().unwrap_or_else(|_| { error!("Unknown error!"); });
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use crate::internal::prelude::*;
use crate::model::prelude::*;

/// A builder to optionally edit certain fields of a [`Guild`]. This is meant
/// for usage with [`Guild::edit`].
///
/// **Note**: Editing a guild requires that the current user have the
/// [Manage Guild] permission.
///
/// [`Guild::edit`]: crate::model::guild::Guild::edit
/// [`Guild`]: crate::model::guild::Guild
/// [Manage Guild]: crate::model::permissions::Permissions::MANAGE_GUILD
#[derive(Clone, Debug, Default)]
pub struct EditGuild(pub HashMap<&'static str, Value>);

impl EditGuild {
    /// Set the "AFK voice channel" that users are to move to if they have been
    /// AFK for an amount of time, configurable by [`afk_timeout`].
    ///
    /// The given channel must be either some valid voice channel, or `None` to
    /// not set an AFK channel. The library does not check if a channel is
    /// valid.
    ///
    /// [`afk_timeout`]: Self::afk_timeout
    #[inline]
    pub fn afk_channel<C: Into<ChannelId>>(&mut self, channel: Option<C>) -> &mut Self {
        self._afk_channel(channel.map(Into::into));
        self
    }

    fn _afk_channel(&mut self, channel: Option<ChannelId>) {
        self.0.insert("afk_channel_id", match channel {
            Some(channel) => Value::Number(Number::from(channel.0)),
            None => Value::Null,
        });
    }

    /// Set the amount of time a user is to be moved to the AFK channel -
    /// configured via [`afk_channel`] - after being AFK.
    ///
    /// [`afk_channel`]: Self::afk_channel
    pub fn afk_timeout(&mut self, timeout: u64) -> &mut Self {
        self.0.insert("afk_timeout", Value::Number(Number::from(timeout)));
        self
    }

    /// Set the icon of the guild. Pass `None` to remove the icon.
    ///
    /// # Examples
    ///
    /// Using the utility function - [`utils::read_image`] - to read an image
    /// from the cwd and encode it in base64 to send to Discord.
    ///
    /// ```rust,no_run
    /// # use serenity::{http::Http, model::id::GuildId};
    /// #
    /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
    /// #     let http = Http::default();
    /// #     let mut guild = GuildId(0).to_partial_guild(&http).await?;
    /// use serenity::utils;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// let base64_icon = utils::read_image("./guild_icon.png")?;
    ///
    /// guild.edit(&http, |mut g| {
    ///     g.icon(Some(&base64_icon))
    /// })
    /// .await?;
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`utils::read_image`]: crate::utils::read_image
    pub fn icon(&mut self, icon: Option<&str>) -> &mut Self {
        self.0.insert("icon", icon.map_or_else(|| Value::Null, |x| Value::String(x.to_string())));
        self
    }

    /// Set the name of the guild.
    ///
    /// **Note**: Must be between (and including) 2-100 chracters.
    pub fn name<S: ToString>(&mut self, name: S) -> &mut Self {
        self.0.insert("name", Value::String(name.to_string()));
        self
    }

    /// Transfers the ownership of the guild to another user by Id.
    ///
    /// **Note**: The current user must be the owner of the guild.
    #[inline]
    pub fn owner<U: Into<UserId>>(&mut self, user_id: U) -> &mut Self {
        self._owner(user_id.into());
        self
    }

    fn _owner(&mut self, user_id: UserId) {
        let id = Value::Number(Number::from(user_id.0));
        self.0.insert("owner_id", id);
    }

    /// Set the voice region of the server.
    ///
    /// # Examples
    ///
    /// Setting the region to [`Region::UsWest`]:
    ///
    /// ```rust,no_run
    /// # use serenity::{http::Http, model::id::GuildId};
    /// #
    /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
    /// #     let http = Http::default();
    /// #     let mut guild = GuildId(0).to_partial_guild(&http).await?;
    /// use serenity::model::guild::Region;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// guild.edit(&http, |g| {
    ///     g.region(Region::UsWest)
    /// })
    /// .await?;
    /// #     Ok(())
    /// # }
    /// ```
    pub fn region(&mut self, region: Region) -> &mut Self {
        self.0.insert("region", Value::String(region.name().to_string()));
        self
    }

    /// Set the splash image of the guild on the invitation page.
    ///
    /// Requires that the guild have the `INVITE_SPLASH` feature enabled.
    /// You can check this through a guild's [`features`] list.
    ///
    /// [`features`]: crate::model::guild::Guild::features
    pub fn splash(&mut self, splash: Option<&str>) -> &mut Self {
        let splash = splash.map_or(Value::Null, |x| Value::String(x.to_string()));
        self.0.insert("splash", splash);
        self
    }

    /// Set the verification level of the guild. This can restrict what a
    /// user must have prior to being able to send messages in a guild.
    ///
    /// Refer to the documentation for [`VerificationLevel`] for more
    /// information on each variant.
    ///
    ///
    /// # Examples
    ///
    /// Setting the verification level to [`High`][`VerificationLevel::High`]:
    ///
    /// ```rust,no_run
    /// # use serenity::{http::Http, model::id::GuildId};
    /// #
    /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
    /// #     let http = Http::default();
    /// #     let mut guild = GuildId(0).to_partial_guild(&http).await?;
    /// use serenity::model::guild::VerificationLevel;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// let edit = guild.edit(&http, |g| {
    ///     g.verification_level(VerificationLevel::High)
    /// })
    /// .await;
    ///
    /// if let Err(why) = edit {
    ///     println!("Error setting verification level: {:?}", why);
    /// }
    /// #     Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn verification_level<V>(&mut self, verification_level: V) -> &mut Self
    where
        V: Into<VerificationLevel>,
    {
        self._verification_level(verification_level.into());
        self
    }

    fn _verification_level(&mut self, verification_level: VerificationLevel) {
        let num = Value::Number(Number::from(verification_level.num()));
        self.0.insert("verification_level", num);
    }
}
<commit_msg>Update `EditGuild` to match current Discord API (#1265)<commit_after>use std::collections::HashMap;

use crate::internal::prelude::*;
use crate::model::prelude::*;

/// A builder to optionally edit certain fields of a [`Guild`]. This is meant
/// for usage with [`Guild::edit`].
///
/// **Note**: Editing a guild requires that the current user have the
/// [Manage Guild] permission.
///
/// [`Guild::edit`]: crate::model::guild::Guild::edit
/// [`Guild`]: crate::model::guild::Guild
/// [Manage Guild]: crate::model::permissions::Permissions::MANAGE_GUILD
#[derive(Clone, Debug, Default)]
pub struct EditGuild(pub HashMap<&'static str, Value>);

impl EditGuild {
    /// Set the "AFK voice channel" that users are to move to if they have been
    /// AFK for an amount of time, configurable by [`afk_timeout`].
    ///
    /// The given channel must be either some valid voice channel, or `None` to
    /// not set an AFK channel. The library does not check if a channel is
    /// valid.
    ///
    /// [`afk_timeout`]: Self::afk_timeout
    #[inline]
    pub fn afk_channel<C: Into<ChannelId>>(&mut self, channel: Option<C>) -> &mut Self {
        self._afk_channel(channel.map(Into::into));
        self
    }

    fn _afk_channel(&mut self, channel: Option<ChannelId>) {
        self.0.insert("afk_channel_id", match channel {
            Some(channel) => Value::Number(Number::from(channel.0)),
            None => Value::Null,
        });
    }

    /// Set the amount of time a user is to be moved to the AFK channel -
    /// configured via [`afk_channel`] - after being AFK.
    ///
    /// [`afk_channel`]: Self::afk_channel
    pub fn afk_timeout(&mut self, timeout: u64) -> &mut Self {
        self.0.insert("afk_timeout", Value::Number(Number::from(timeout)));
        self
    }

    /// Set the icon of the guild. Pass `None` to remove the icon.
    ///
    /// # Examples
    ///
    /// Using the utility function - [`utils::read_image`] - to read an image
    /// from the cwd and encode it in base64 to send to Discord.
    ///
    /// ```rust,no_run
    /// # use serenity::{http::Http, model::id::GuildId};
    /// #
    /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
    /// #     let http = Http::default();
    /// #     let mut guild = GuildId(0).to_partial_guild(&http).await?;
    /// use serenity::utils;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// let base64_icon = utils::read_image("./guild_icon.png")?;
    ///
    /// guild.edit(&http, |mut g| {
    ///     g.icon(Some(&base64_icon))
    /// })
    /// .await?;
    /// #     Ok(())
    /// # }
    /// ```
    ///
    /// [`utils::read_image`]: crate::utils::read_image
    pub fn icon(&mut self, icon: Option<&str>) -> &mut Self {
        self.0.insert("icon", icon.map_or_else(|| Value::Null, |x| Value::String(x.to_string())));
        self
    }

    /// Set the name of the guild.
    ///
    /// **Note**: Must be between (and including) 2-100 chracters.
    pub fn name<S: ToString>(&mut self, name: S) -> &mut Self {
        self.0.insert("name", Value::String(name.to_string()));
        self
    }

    /// Transfers the ownership of the guild to another user by Id.
    ///
    /// **Note**: The current user must be the owner of the guild.
    #[inline]
    pub fn owner<U: Into<UserId>>(&mut self, user_id: U) -> &mut Self {
        self._owner(user_id.into());
        self
    }

    fn _owner(&mut self, user_id: UserId) {
        let id = Value::Number(Number::from(user_id.0));
        self.0.insert("owner_id", id);
    }

    /// Set the voice region of the server.
    ///
    /// # Examples
    ///
    /// Setting the region to [`Region::UsWest`]:
    ///
    /// ```rust,no_run
    /// # use serenity::{http::Http, model::id::GuildId};
    /// #
    /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
    /// #     let http = Http::default();
    /// #     let mut guild = GuildId(0).to_partial_guild(&http).await?;
    /// use serenity::model::guild::Region;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// guild.edit(&http, |g| {
    ///     g.region(Region::UsWest)
    /// })
    /// .await?;
    /// #     Ok(())
    /// # }
    /// ```
    pub fn region(&mut self, region: Region) -> &mut Self {
        self.0.insert("region", Value::String(region.name().to_string()));
        self
    }

    /// Set the splash image of the guild on the invitation page.
    ///
    /// The `splash` must be base64-encoded 1024x1024 png/jpeg/gif image-data.
    ///
    /// Requires that the guild have the `INVITE_SPLASH` feature enabled.
    /// You can check this through a guild's [`features`] list.
    ///
    /// [`features`]: crate::model::guild::Guild::features
    pub fn splash(&mut self, splash: Option<&str>) -> &mut Self {
        let splash = splash.map_or(Value::Null, |x| Value::String(x.to_string()));
        self.0.insert("splash", splash);
        self
    }

    /// Set the banner image of the guild, it appears on the left side-bar.
    ///
    /// The `banner` must be base64-encoded 16:9 png/jpeg image data.
    ///
    /// Requires that the guild have the `BANNER` feature enabled.
    /// You can check this through a guild's [`features`] list.
    ///
    /// [`features`]: crate::model::guild::Guild::features
    pub fn banner(&mut self, banner: Option<&str>) -> &mut Self {
        let banner = banner.map_or(Value::Null, |x| Value::String(x.to_string()));
        self.0.insert("banner", banner);
        self
    }

    /// Set the channel ID where welcome messages and boost events will be
    /// posted.
    ///
    /// **Note**:
    /// This feature is for Community guilds only.
    pub fn system_channel_id(&mut self, channel_id: Option<ChannelId>) -> &mut Self {
        let channel_id = channel_id.map_or(Value::Null, |x| Value::from(x.0));
        self.0.insert("system_channel_id", channel_id);
        self
    }

    /// Set the channel ID of the rules and guidelines channel.
    ///
    /// **Note**:
    /// This feature is for Community guilds only.
    pub fn rules_channel_id(&mut self, channel_id: Option<ChannelId>) -> &mut Self {
        let channel_id = channel_id.map_or(Value::Null, |x| Value::from(x.0));
        self.0.insert("rules_channel_id", channel_id);
        self
    }

    /// Set the channel ID where admins and moderators receive update messages
    /// from Discord.
    ///
    /// **Note**:
    /// This feature is for Community guilds only.
    pub fn public_updates_channel_id(&mut self, channel_id: Option<ChannelId>) -> &mut Self {
        let channel_id = channel_id.map_or(Value::Null, |x| Value::from(x.0));
        self.0.insert("public_updates_channel_id", channel_id);
        self
    }

    /// Set the preferred locale used in Server Discovery and update messages
    /// from Discord.
    ///
    /// If this is not set, the locale will default to "en-US";
    ///
    /// **Note**:
    /// This feature is for Community guilds only.
    pub fn preferred_locale(&mut self, locale: Option<&str>) -> &mut Self {
        let locale = locale.map_or(Value::Null, |x| Value::String(x.to_string()));
        self.0.insert("preferred_locale", locale);
        self
    }

    /// Set the content filter level.
    pub fn explicit_content_filter(&mut self, level: Option<ExplicitContentFilter>) -> &mut Self {
        let level = level.map_or(Value::Null, |x| Value::from(x as u8));
        self.0.insert("explicit_content_filter", level);
        self
    }

    /// Set the default message notification level.
    pub fn default_message_notifications(
        &mut self,
        level: Option<DefaultMessageNotificationLevel>,
    ) -> &mut Self {
        let level = level.map_or(Value::Null, |x| Value::from(x as u8));
        self.0.insert("default_message_notifications", level);
        self
    }

    /// Set the verification level of the guild. This can restrict what a
    /// user must have prior to being able to send messages in a guild.
    ///
    /// Refer to the documentation for [`VerificationLevel`] for more
    /// information on each variant.
    ///
    ///
    /// # Examples
    ///
    /// Setting the verification level to [`High`][`VerificationLevel::High`]:
    ///
    /// ```rust,no_run
    /// # use serenity::{http::Http, model::id::GuildId};
    /// #
    /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
    /// #     let http = Http::default();
    /// #     let mut guild = GuildId(0).to_partial_guild(&http).await?;
    /// use serenity::model::guild::VerificationLevel;
    ///
    /// // assuming a `guild` has already been bound
    ///
    /// let edit = guild.edit(&http, |g| {
    ///     g.verification_level(VerificationLevel::High)
    /// })
    /// .await;
    ///
    /// if let Err(why) = edit {
    ///     println!("Error setting verification level: {:?}", why);
    /// }
    /// #     Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn verification_level<V>(&mut self, verification_level: V) -> &mut Self
    where
        V: Into<VerificationLevel>,
    {
        self._verification_level(verification_level.into());
        self
    }

    fn _verification_level(&mut self, verification_level: VerificationLevel) {
        let num = Value::Number(Number::from(verification_level.num()));
        self.0.insert("verification_level", num);
    }
}
<|endoftext|>


<commit_before><commit_msg>use body::None in encoder body<commit_after><|endoftext|>


<commit_before>use serde::Serialize;
use serde::Serializer;
use serde::Deserialize;
use serde::Deserializer;
use serde::de::Error;
use serde::de::Visitor;

#[derive(Debug, Clone, PartialEq)]
pub enum TaskPriority {
    Low,
    Medium,
    High,
}

impl Serialize for TaskPriority {

    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        serializer.serialize_str(
            match self {
                TaskPriority::Low    => "L",
                TaskPriority::Medium => "M",
                TaskPriority::High   => "H",
            }
        )
    }

}

impl Deserialize for TaskPriority {

    fn deserialize<D>(deserializer: &mut D) -> Result<TaskPriority, Error>
        where D: Deserializer
    {
        struct TaskPriorityVisitor;

        impl Visitor for TaskPriorityVisitor {
            type Value = TaskPriority;

            fn visit_str<E>(&mut self, value: &str) -> Result<TaskPriority, E>
                where E: Error
            {
                match value {
                    "L" => Ok(TaskPriority::Low),
                    "M" => Ok(TaskPriority::Medium),
                    "H" => Ok(TaskPriority::High),
                    _ => Err(Error::custom("expected one of 'L', 'M', 'H'")),
                }
            }
        }

        deserializer.deserialize(TaskPriorityVisitor)
    }
}

<commit_msg>Fixup prio<commit_after>use serde::Serialize;
use serde::ser::Serializer;
use serde::de::Deserialize;
use serde::de::Deserializer;
use serde::Error;
use serde::de::Visitor;

#[derive(Debug, Clone, PartialEq)]
pub enum TaskPriority {
    Low,
    Medium,
    High,
}

impl Serialize for TaskPriority {

    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        serializer.serialize_str(
            match self {
                &TaskPriority::Low    => "L",
                &TaskPriority::Medium => "M",
                &TaskPriority::High   => "H",
            }
        )
    }

}

impl Deserialize for TaskPriority {

    fn deserialize<D>(deserializer: &mut D) -> Result<TaskPriority, D::Error>
        where D: Deserializer
    {
        struct TaskPriorityVisitor;

        impl Visitor for TaskPriorityVisitor {
            type Value = TaskPriority;

            fn visit_str<E>(&mut self, value: &str) -> Result<TaskPriority, E>
                where E: Error
            {
                match value {
                    "L" => Ok(TaskPriority::Low),
                    "M" => Ok(TaskPriority::Medium),
                    "H" => Ok(TaskPriority::High),
                    _ => Err(Error::custom("expected one of 'L', 'M', 'H'")),
                }
            }
        }

        deserializer.deserialize(TaskPriorityVisitor)
    }
}

<|endoftext|>


<commit_before>extern crate postgres;
extern crate chrono;

#[cfg(test)]
mod tests;

use postgres::{Connection, SslMode, types};
use std::io::{self, Read};

#[derive(PartialEq, Debug)]
pub enum Align {
    Left,
    Right,
    Center,
}

#[allow(dead_code)]
#[derive(PartialEq, Debug)]
pub enum Color {
    White,
    BoldWhite,
    BoldRed,
    BoldGreen,
    BoldBlue,
}

struct TableDesc {
    names:  Vec<String>,
    types:  Vec<types::Type>,
    widths: Vec<usize>,
    data:   Vec<Vec<String>>,
}

impl TableDesc {
    fn new() -> TableDesc {
        TableDesc {
            names:  Vec::new(),
            types:  Vec::new(),
            widths: Vec::new(),
            data:   Vec::new(),
        }
    }

    fn register_column(&mut self, column: &postgres::stmt::Column) {
        let colname = String::from(column.name());

        self.widths.push(colname.len());
        self.names.push(colname);
        self.types.push(column.type_().clone());
    }

    fn parse_result(&self, column: &postgres::rows::Row, colpos: usize) -> String {
        let val: String = match self.types[colpos] {
            types::Type::Text | types::Type::Varchar => column.get(colpos),
            types::Type::Bool => {
                let tmpbool: bool = column.get(colpos);
                match tmpbool {
                    true  => String::from("true"),
                    false => String::from("false"),
                }
            },
            types::Type::Int2 | types::Type::Int4 => {
                let tmpint: i32 = column.get(colpos);
                tmpint.to_string()
            },
            types::Type::Int8 => {
                let tmpint: i64 = column.get(colpos);
                tmpint.to_string()
            },
            types::Type::Float4 => {
                let tmpflt: f32 = column.get(colpos);
                tmpflt.to_string()
            },
            types::Type::Float8 => {
                let tmpflt: f64 = column.get(colpos);
                tmpflt.to_string()
            },
            types::Type::Timestamp => {
                let tmpdate: chrono::NaiveDateTime = column.get(colpos);
                tmpdate.format("%Y-%m-%d %H:%M:%s").to_string()
            },
            types::Type::TimestampTZ => {
                let tmpdate: chrono::DateTime<chrono::UTC> = column.get(colpos);
                tmpdate.format("%Y-%m-%d %H:%M:%s").to_string()
            },
            types::Type::Date => {
                let tmpdate: chrono::NaiveDate = column.get(colpos);
                tmpdate.format("%Y-%m-%d").to_string()
            },
            _ => String::from(""),
        };

        val
    }

    fn append(&mut self, row: &postgres::rows::Row) {
        let mut colvals: Vec<String> = Vec::new();

        for i in 0..row.len() {
            let ret = row.get_bytes(i);
            let col = match ret.is_some() {
                true    => self.parse_result(&row, i),
                false   => String::from(""),
            };

            self.widths[i] = match col.len() > self.widths[i] {
                true    => col.len(),
                false   => self.widths[i]
            };

            colvals.push(col);
        }

        self.data.push(colvals);
    }

    fn print_row(&self, rowdata: &Vec<String>, is_header: bool) {
        for (i, col) in rowdata.iter().enumerate() {
            if i > 0 {
                print!("{}", TableDesc::color_text("|", Color::BoldWhite));
            }

            match is_header {
                false   => print!(" {} ", TableDesc::format_field(&col,
                                                            self.widths[i],
                                                            TableDesc::get_alignment(&self.types[i]))),
                true    => print!(" {} ", TableDesc::color_text(&TableDesc::format_field(&col,
                                                                             self.widths[i],
                                                                             Align::Center),
                                                          Color::BoldWhite)),
            };
        }

        println!("");

        match is_header {
            false   => {},
            true    => {
                for (i, col) in self.widths.iter().enumerate() {
                    if i > 0 {
                        print!("{}", TableDesc::color_text("+", Color::BoldWhite));
                    }

                    print!("{}", TableDesc::color_text(&TableDesc::pad_gen(col+2, "-"), Color::BoldWhite));
                }

                println!("");
            },
        };

    }

    fn print(&self) {
        self.print_row(&self.names, true);
        for rowdata in &self.data {
            self.print_row(&rowdata, false);
        }
    }
}

/* public functions, for string formatting, etc. */
impl TableDesc {
    pub fn get_alignment(coltype: &types::Type) -> Align {
        match coltype {
            &types::Type::Int2          => Align::Right,
            &types::Type::Int4          => Align::Right,
            &types::Type::Int8          => Align::Right,
            &types::Type::Float4        => Align::Right,
            &types::Type::Float8        => Align::Right,
            &types::Type::Date          => Align::Right,
            &types::Type::Timestamp     => Align::Right,
            &types::Type::TimestampTZ   => Align::Right,
            _                           => Align::Left,
        }
    }

    pub fn pad_gen(len: usize, pad: &str) -> String {
        let mut padstr = String::from("");

        for _ in 0..len {
            padstr = padstr + pad;
        }

        padstr
    }

    pub fn format_field(column: &str, width: usize, align: Align) -> String {
        let padlen: usize = width - column.len();
        let extra: usize = padlen % 2;

        let ret: String = match align {
            Align::Right    => { format!("{}{}", TableDesc::pad_gen(padlen, " "), column) },
            Align::Left     => { format!("{}{}", column, TableDesc::pad_gen(padlen, " ")) },
            Align::Center   => { format!("{}{}{}", TableDesc::pad_gen(padlen/2, " "), column,
                                                   TableDesc::pad_gen((padlen/2)+extra, " ")) },
        };

        ret
    }

    pub fn color_text(text: &str, color: Color) -> String {
        let clrstr = match color {
            Color::White       => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[37m", text)        },
            Color::BoldWhite   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[37m", text) },
            Color::BoldRed     => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[31m", text) },
            Color::BoldGreen   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[32m", text) },
            Color::BoldBlue    => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[34m", text) },
        };

        clrstr
    }
}

fn main() {
    let mut buf = String::new();
    let mut tdesc = TableDesc::new();
    let mut args = std::env::args();

    if args.len() == 1 {
        println!("{} {}", TableDesc::color_text("error:", Color::BoldRed),
                          TableDesc::color_text("a DBURI is required!", Color::BoldWhite));
        println!("{} cat file.sql | first [DBURI]", TableDesc::color_text("usage:", Color::BoldBlue));
        std::process::exit(1);
    }

    let connstr: String = args.nth(1).unwrap();
    io::stdin().read_to_string(&mut buf);

    let conn = Connection::connect(&connstr as &str, SslMode::None).unwrap();
    let res = &conn.query(&mut buf, &[]).unwrap();

    for col in res.columns() {
        tdesc.register_column(&col);
    }

    for row in res.iter() {
        tdesc.append(&row);
    }

    tdesc.print();
}
<commit_msg>format dates properly<commit_after>extern crate postgres;
extern crate chrono;

#[cfg(test)]
mod tests;

use postgres::{Connection, SslMode, types};
use std::io::{self, Read};

#[derive(PartialEq, Debug)]
pub enum Align {
    Left,
    Right,
    Center,
}

#[allow(dead_code)]
#[derive(PartialEq, Debug)]
pub enum Color {
    White,
    BoldWhite,
    BoldRed,
    BoldGreen,
    BoldBlue,
}

struct TableDesc {
    names:  Vec<String>,
    types:  Vec<types::Type>,
    widths: Vec<usize>,
    data:   Vec<Vec<String>>,
}

impl TableDesc {
    fn new() -> TableDesc {
        TableDesc {
            names:  Vec::new(),
            types:  Vec::new(),
            widths: Vec::new(),
            data:   Vec::new(),
        }
    }

    fn register_column(&mut self, column: &postgres::stmt::Column) {
        let colname = String::from(column.name());

        self.widths.push(colname.len());
        self.names.push(colname);
        self.types.push(column.type_().clone());
    }

    fn parse_result(&self, column: &postgres::rows::Row, colpos: usize) -> String {
        let val: String = match self.types[colpos] {
            types::Type::Text | types::Type::Varchar => column.get(colpos),
            types::Type::Bool => {
                let tmpbool: bool = column.get(colpos);
                match tmpbool {
                    true  => String::from("true"),
                    false => String::from("false"),
                }
            },
            types::Type::Int2 | types::Type::Int4 => {
                let tmpint: i32 = column.get(colpos);
                tmpint.to_string()
            },
            types::Type::Int8 => {
                let tmpint: i64 = column.get(colpos);
                tmpint.to_string()
            },
            types::Type::Float4 => {
                let tmpflt: f32 = column.get(colpos);
                tmpflt.to_string()
            },
            types::Type::Float8 => {
                let tmpflt: f64 = column.get(colpos);
                tmpflt.to_string()
            },
            types::Type::Timestamp => {
                let tmpdate: chrono::NaiveDateTime = column.get(colpos);
                tmpdate.format("%Y-%m-%d %H:%M:%S").to_string()
            },
            types::Type::TimestampTZ => {
                let tmpdate: chrono::DateTime<chrono::UTC> = column.get(colpos);
                tmpdate.format("%Y-%m-%d %H:%M:%s").to_string()
            },
            types::Type::Date => {
                let tmpdate: chrono::NaiveDate = column.get(colpos);
                tmpdate.format("%Y-%m-%d").to_string()
            },
            _ => String::from(""),
        };

        val
    }

    fn append(&mut self, row: &postgres::rows::Row) {
        let mut colvals: Vec<String> = Vec::new();

        for i in 0..row.len() {
            let ret = row.get_bytes(i);
            let col = match ret.is_some() {
                true    => self.parse_result(&row, i),
                false   => String::from(""),
            };

            self.widths[i] = match col.len() > self.widths[i] {
                true    => col.len(),
                false   => self.widths[i]
            };

            colvals.push(col);
        }

        self.data.push(colvals);
    }

    fn print_row(&self, rowdata: &Vec<String>, is_header: bool) {
        for (i, col) in rowdata.iter().enumerate() {
            if i > 0 {
                print!("{}", TableDesc::color_text("|", Color::BoldWhite));
            }

            match is_header {
                false   => print!(" {} ", TableDesc::format_field(&col,
                                                            self.widths[i],
                                                            TableDesc::get_alignment(&self.types[i]))),
                true    => print!(" {} ", TableDesc::color_text(&TableDesc::format_field(&col,
                                                                             self.widths[i],
                                                                             Align::Center),
                                                          Color::BoldWhite)),
            };
        }

        println!("");

        match is_header {
            false   => {},
            true    => {
                for (i, col) in self.widths.iter().enumerate() {
                    if i > 0 {
                        print!("{}", TableDesc::color_text("+", Color::BoldWhite));
                    }

                    print!("{}", TableDesc::color_text(&TableDesc::pad_gen(col+2, "-"), Color::BoldWhite));
                }

                println!("");
            },
        };

    }

    fn print(&self) {
        self.print_row(&self.names, true);
        for rowdata in &self.data {
            self.print_row(&rowdata, false);
        }
    }
}

/* public functions, for string formatting, etc. */
impl TableDesc {
    pub fn get_alignment(coltype: &types::Type) -> Align {
        match coltype {
            &types::Type::Int2          => Align::Right,
            &types::Type::Int4          => Align::Right,
            &types::Type::Int8          => Align::Right,
            &types::Type::Float4        => Align::Right,
            &types::Type::Float8        => Align::Right,
            &types::Type::Date          => Align::Right,
            &types::Type::Timestamp     => Align::Right,
            &types::Type::TimestampTZ   => Align::Right,
            _                           => Align::Left,
        }
    }

    pub fn pad_gen(len: usize, pad: &str) -> String {
        let mut padstr = String::from("");

        for _ in 0..len {
            padstr = padstr + pad;
        }

        padstr
    }

    pub fn format_field(column: &str, width: usize, align: Align) -> String {
        let padlen: usize = width - column.len();
        let extra: usize = padlen % 2;

        let ret: String = match align {
            Align::Right    => { format!("{}{}", TableDesc::pad_gen(padlen, " "), column) },
            Align::Left     => { format!("{}{}", column, TableDesc::pad_gen(padlen, " ")) },
            Align::Center   => { format!("{}{}{}", TableDesc::pad_gen(padlen/2, " "), column,
                                                   TableDesc::pad_gen((padlen/2)+extra, " ")) },
        };

        ret
    }

    pub fn color_text(text: &str, color: Color) -> String {
        let clrstr = match color {
            Color::White       => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[37m", text)        },
            Color::BoldWhite   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[37m", text) },
            Color::BoldRed     => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[31m", text) },
            Color::BoldGreen   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[32m", text) },
            Color::BoldBlue    => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[34m", text) },
        };

        clrstr
    }
}

fn main() {
    let mut buf = String::new();
    let mut tdesc = TableDesc::new();
    let mut args = std::env::args();

    if args.len() == 1 {
        println!("{} {}", TableDesc::color_text("error:", Color::BoldRed),
                          TableDesc::color_text("a DBURI is required!", Color::BoldWhite));
        println!("{} cat file.sql | first [DBURI]", TableDesc::color_text("usage:", Color::BoldBlue));
        std::process::exit(1);
    }

    let connstr: String = args.nth(1).unwrap();
    io::stdin().read_to_string(&mut buf);

    let conn = Connection::connect(&connstr as &str, SslMode::None).unwrap();
    let res = &conn.query(&mut buf, &[]).unwrap();

    for col in res.columns() {
        tdesc.register_column(&col);
    }

    for row in res.iter() {
        tdesc.append(&row);
    }

    tdesc.print();
}
<|endoftext|>


<commit_before>use internal::{ Color, ColorComponent };
use math::{
    hsv,
    margin_rectangle,
    relative_rectangle,
    relative_source_rectangle,
    Scalar,
};
use radians::Radians;
use Line;

/// Implemented by contexts that contains color.
pub trait Colored: Sized {
    /// Multiplies with red, green, blue and alpha values.
    fn mul_rgba(
        self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self;

    /// Mixes the current color with white.
    ///
    /// 0 is black and 1 is white.
    #[inline(always)]
    fn tint(self, f: ColorComponent) -> Self {
        self.mul_rgba(f, f, f, 1.0)
    }

    /// Mixes the current color with black.
    ///
    /// 0 is white and 1 is black.
    #[inline(always)]
    fn shade(self, f: ColorComponent) -> Self {
        let f = 1.0 - f;
        self.mul_rgba(f, f, f, 1.0)
    }

    /// Rotates hue by degrees.
    #[inline(always)]
    fn hue_deg(self, angle: ColorComponent) -> Self {
        let pi: ColorComponent = Radians::_180();
        self.hue_rad(angle * pi / 180.0)
    }

    /// Rotates hue by radians.
    fn hue_rad(self, angle: ColorComponent) -> Self;
}

impl Colored for Color {
    #[inline(always)]
    fn mul_rgba(
        self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self {
        [self[0] * r, self[1] * g, self[2] * b, self[3] * a]
    }

    #[inline(always)]
    fn hue_rad(self, angle: ColorComponent) -> Self {
        hsv(self, angle, 1.0, 1.0)
    }
}

impl Colored for Line {
    #[inline(always)]
    fn mul_rgba(
        mut self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self {
        self.color = self.color.mul_rgba(r, g, b, a);
        self
    }

    #[inline(always)]
    fn hue_rad(mut self, angle: ColorComponent) -> Self {
        self.color = self.color.hue_rad(angle);
        self
    }
}

/// Should be implemented by contexts that have rectangle information.
pub trait Rectangled: Sized {
    /// Shrinks the current rectangle equally by all sides.
    fn margin(&self, m: Scalar) -> Self;

    /// Expands the current rectangle equally by all sides.
    #[inline(always)]
    fn expand(&self, m: Scalar) -> Self {
        self.margin(-m)
    }

    /// Moves to a relative rectangle using the current rectangle as tile.
    fn rel(&self, x: Scalar, y: Scalar) -> Self;
}

/*
impl<T: Get<Rect> + Set<Rect> + Clone> Rectangled for T {
    #[inline(always)]
    fn margin(&self, m: Scalar) -> Self {
        let Rect(val) = self.get();
        self.clone().set(Rect(margin_rectangle(val, m)))
    }

    #[inline(always)]
    fn rel(&self, x: Scalar, y: Scalar) -> Self {
        let Rect(val) = self.get();
        self.clone().set(Rect(relative_rectangle(val, [x, y])))
    }
}
*/

/// Should be implemented by contexts that
/// have source rectangle information.
pub trait SourceRectangled {
    /// Adds a source rectangle.
    fn src_rect(&self, x: i32, y: i32, w: i32, h: i32) -> Self;

    /// Moves to a relative source rectangle using
    /// the current source rectangle as tile.
    fn src_rel(&self, x: i32, y: i32) -> Self;

    /// Flips the source rectangle horizontally.
    fn src_flip_h(&self) -> Self;

    /// Flips the source rectangle vertically.
    fn src_flip_v(&self) -> Self;

    /// Flips the source rectangle horizontally and vertically.
    fn src_flip_hv(&self) -> Self;
}

/*
impl<T: Get<SrcRect>
      + Set<SrcRect>
      + Clone
> SourceRectangled for T {
    #[inline(always)]
    fn src_rect(&self, x: i32, y: i32, w: i32, h: i32) -> Self {
        self.clone().set(SrcRect([x, y, w, h]))
    }

    #[inline(always)]
    fn src_rel(&self, x: i32, y: i32) -> Self {
        let SrcRect(val) = self.get();
        self.clone().set(SrcRect(
            relative_source_rectangle(val, x, y)
        ))
    }

    #[inline(always)]
    fn src_flip_h(&self) -> Self {
        let SrcRect(source_rect) = self.get();
        self.clone().set(SrcRect([
            source_rect[0] + source_rect[2],
            source_rect[1],
            -source_rect[2],
            source_rect[3]
        ]))
    }

    #[inline(always)]
    fn src_flip_v(&self) -> Self {
        let SrcRect(source_rect) = self.get();
        self.clone().set(SrcRect([
            source_rect[0],
            source_rect[1] + source_rect[3],
            source_rect[2],
            -source_rect[3]
        ]))
    }

    #[inline(always)]
    fn src_flip_hv(&self) -> Self {
        let SrcRect(source_rect) = self.get();
        self.clone().set(SrcRect([
            source_rect[0] + source_rect[2],
            source_rect[1] + source_rect[3],
            -source_rect[2],
            -source_rect[3]
        ]))
    }
}
*/
<commit_msg>Implemented `Colored` for `Ellipse` and `Rectangle`<commit_after>use internal::{ Color, ColorComponent };
use math::{
    hsv,
    margin_rectangle,
    relative_rectangle,
    relative_source_rectangle,
    Scalar,
};
use radians::Radians;
use { Ellipse, Line, Rectangle };

/// Implemented by contexts that contains color.
pub trait Colored: Sized {
    /// Multiplies with red, green, blue and alpha values.
    fn mul_rgba(
        self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self;

    /// Mixes the current color with white.
    ///
    /// 0 is black and 1 is white.
    #[inline(always)]
    fn tint(self, f: ColorComponent) -> Self {
        self.mul_rgba(f, f, f, 1.0)
    }

    /// Mixes the current color with black.
    ///
    /// 0 is white and 1 is black.
    #[inline(always)]
    fn shade(self, f: ColorComponent) -> Self {
        let f = 1.0 - f;
        self.mul_rgba(f, f, f, 1.0)
    }

    /// Rotates hue by degrees.
    #[inline(always)]
    fn hue_deg(self, angle: ColorComponent) -> Self {
        let pi: ColorComponent = Radians::_180();
        self.hue_rad(angle * pi / 180.0)
    }

    /// Rotates hue by radians.
    fn hue_rad(self, angle: ColorComponent) -> Self;
}

impl Colored for Color {
    #[inline(always)]
    fn mul_rgba(
        self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self {
        [self[0] * r, self[1] * g, self[2] * b, self[3] * a]
    }

    #[inline(always)]
    fn hue_rad(self, angle: ColorComponent) -> Self {
        hsv(self, angle, 1.0, 1.0)
    }
}

impl Colored for Line {
    #[inline(always)]
    fn mul_rgba(
        mut self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self {
        self.color = self.color.mul_rgba(r, g, b, a);
        self
    }

    #[inline(always)]
    fn hue_rad(mut self, angle: ColorComponent) -> Self {
        self.color = self.color.hue_rad(angle);
        self
    }
}

impl Colored for Ellipse {
    #[inline(always)]
    fn mul_rgba(
        mut self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self {
        self.color = self.color.mul_rgba(r, g, b, a);
        self
    }

    #[inline(always)]
    fn hue_rad(mut self, angle: ColorComponent) -> Self {
        self.color = self.color.hue_rad(angle);
        self
    }
}

impl Colored for Rectangle {
    #[inline(always)]
    fn mul_rgba(
        mut self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> Self {
        self.color = self.color.mul_rgba(r, g, b, a);
        self
    }

    #[inline(always)]
    fn hue_rad(mut self, angle: ColorComponent) -> Self {
        self.color = self.color.hue_rad(angle);
        self
    }
}

/// Should be implemented by contexts that have rectangle information.
pub trait Rectangled: Sized {
    /// Shrinks the current rectangle equally by all sides.
    fn margin(&self, m: Scalar) -> Self;

    /// Expands the current rectangle equally by all sides.
    #[inline(always)]
    fn expand(&self, m: Scalar) -> Self {
        self.margin(-m)
    }

    /// Moves to a relative rectangle using the current rectangle as tile.
    fn rel(&self, x: Scalar, y: Scalar) -> Self;
}

/*
impl<T: Get<Rect> + Set<Rect> + Clone> Rectangled for T {
    #[inline(always)]
    fn margin(&self, m: Scalar) -> Self {
        let Rect(val) = self.get();
        self.clone().set(Rect(margin_rectangle(val, m)))
    }

    #[inline(always)]
    fn rel(&self, x: Scalar, y: Scalar) -> Self {
        let Rect(val) = self.get();
        self.clone().set(Rect(relative_rectangle(val, [x, y])))
    }
}
*/

/// Should be implemented by contexts that
/// have source rectangle information.
pub trait SourceRectangled {
    /// Adds a source rectangle.
    fn src_rect(&self, x: i32, y: i32, w: i32, h: i32) -> Self;

    /// Moves to a relative source rectangle using
    /// the current source rectangle as tile.
    fn src_rel(&self, x: i32, y: i32) -> Self;

    /// Flips the source rectangle horizontally.
    fn src_flip_h(&self) -> Self;

    /// Flips the source rectangle vertically.
    fn src_flip_v(&self) -> Self;

    /// Flips the source rectangle horizontally and vertically.
    fn src_flip_hv(&self) -> Self;
}

/*
impl<T: Get<SrcRect>
      + Set<SrcRect>
      + Clone
> SourceRectangled for T {
    #[inline(always)]
    fn src_rect(&self, x: i32, y: i32, w: i32, h: i32) -> Self {
        self.clone().set(SrcRect([x, y, w, h]))
    }

    #[inline(always)]
    fn src_rel(&self, x: i32, y: i32) -> Self {
        let SrcRect(val) = self.get();
        self.clone().set(SrcRect(
            relative_source_rectangle(val, x, y)
        ))
    }

    #[inline(always)]
    fn src_flip_h(&self) -> Self {
        let SrcRect(source_rect) = self.get();
        self.clone().set(SrcRect([
            source_rect[0] + source_rect[2],
            source_rect[1],
            -source_rect[2],
            source_rect[3]
        ]))
    }

    #[inline(always)]
    fn src_flip_v(&self) -> Self {
        let SrcRect(source_rect) = self.get();
        self.clone().set(SrcRect([
            source_rect[0],
            source_rect[1] + source_rect[3],
            source_rect[2],
            -source_rect[3]
        ]))
    }

    #[inline(always)]
    fn src_flip_hv(&self) -> Self {
        let SrcRect(source_rect) = self.get();
        self.clone().set(SrcRect([
            source_rect[0] + source_rect[2],
            source_rect[1] + source_rect[3],
            -source_rect[2],
            -source_rect[3]
        ]))
    }
}
*/
<|endoftext|>


<commit_before>use console;
use glium;
use mvp;
use shaders;
use units;
use utils;

fn get_screen_size(display: &glium::backend::glutin_backend::GlutinFacade) -> units::Size2D {
    let factor = display.get_window().unwrap().hidpi_factor();
    let (width, height) = display.get_framebuffer_dimensions();
    units::Size2D::new(
        (width as f32 / factor) as i32,
        (height as f32 / factor) as i32,
    )
}

pub struct Renderer<'a> {
    pub screen_size: units::Size2D,
    pub size: units::Size2D,
    pub display: &'a glium::backend::glutin_backend::GlutinFacade,
    pub program: glium::Program,
    pub indices: glium::IndexBuffer<u16>,
    pub texture: glium::texture::Texture2d,
    pub vertex_buffer: console::VertexBuffer,
}

impl<'a> Renderer<'a> {
    pub fn new(
        display: &'a glium::backend::glutin_backend::GlutinFacade,
        tile_size: i32,
        texture_path: &str,
    ) -> Self {
        let screen_size = get_screen_size(display);
        let size = units::Size2D::new(
            (screen_size.width / tile_size),
            (screen_size.height / tile_size),
        );

        let program = program(display);
        let indices = indices(display, size);
        let texture = texture(display, texture_path);
        let vertex_buffer = console::VertexBuffer::new(size);

        Renderer {
            size: size,
            screen_size: screen_size,
            display: display,
            program: program,
            indices: indices,
            texture: texture,
            vertex_buffer: vertex_buffer,
        }
    }

    pub fn render(&self) {
        use glium::Surface;

        let vb = glium::VertexBuffer::new(self.display, &self.vertex_buffer.data()).unwrap();

        let cam_uniforms = {
            let mat4_id = utils::mat4_id();
            let ortho_projection = utils::ortho_projection(self.screen_size);

            // 1, 0, 0, X
            // 0, 1, 0, Y
            // 0, 0, 1, 0
            // 0, 0, 0, 1

            let cam = [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0],
            ]; // X, Y

            let tileset = self.texture
                .sampled()
                .magnify_filter(glium::uniforms::MagnifySamplerFilter::Nearest);

            uniform! {
                mvp: mvp::model_view_projection(mat4_id, cam, ortho_projection),
                tileset: tileset,
            }
        };

        let mut target = self.display.draw();
        target.clear_color(0.0, 0.0, 0.0, 1.0);
        target
            .draw(
                &vb,
                &self.indices,
                &self.program,
                &cam_uniforms,
                &Default::default(),
            )
            .unwrap();
        target.finish().unwrap();
    }

    pub fn set(&mut self, screen_loc: units::ScreenTile2D, tile: console::Tile) {
        self.vertex_buffer.set(screen_loc, tile);
    }
}

fn program(display: &glium::backend::glutin_backend::GlutinFacade) -> glium::Program {
    glium::Program::from_source(
        display as &glium::backend::Facade,
        &shaders::VERTEX,
        &shaders::FRAGMENT,
        None,
    )
            .unwrap()
}

fn indices(
    display: &glium::backend::glutin_backend::GlutinFacade,
    size: units::Size2D,
) -> glium::IndexBuffer<u16> {
    use glium::index::PrimitiveType;

    let indices = utils::indices((size.width * size.height) as usize);
    glium::IndexBuffer::new(
        display as &glium::backend::Facade,
        PrimitiveType::TrianglesList,
        &indices,
    )
            .unwrap()
}

fn texture(
    display: &glium::backend::glutin_backend::GlutinFacade,
    path: &str,
) -> glium::texture::Texture2d {
    let png = utils::read_bytes(path).expect(&format!("Texture not found: {}", path)[..]);
    let texture = utils::read_png_to_texture(&png[..]);
    glium::texture::Texture2d::new(display as &glium::backend::Facade, texture).unwrap()
}
<commit_msg>chore(Glutin): rename facade trait<commit_after>use console;
use glium;

use glium::backend::glutin_backend::GlutinFacade as Display;
use mvp;
use shaders;
use units;
use utils;

fn get_screen_size(display: &Display) -> units::Size2D {
    let factor = display.get_window().unwrap().hidpi_factor();
    let (width, height) = display.get_framebuffer_dimensions();
    units::Size2D::new(
        (width as f32 / factor) as i32,
        (height as f32 / factor) as i32,
    )
}

pub struct Renderer<'a> {
    pub screen_size: units::Size2D,
    pub size: units::Size2D,
    pub display: &'a Display,
    pub program: glium::Program,
    pub indices: glium::IndexBuffer<u16>,
    pub texture: glium::texture::Texture2d,
    pub vertex_buffer: console::VertexBuffer,
}

impl<'a> Renderer<'a> {
    pub fn new(display: &'a Display, tile_size: i32, texture_path: &str) -> Self {
        let screen_size = get_screen_size(display);
        let size = units::Size2D::new(
            (screen_size.width / tile_size),
            (screen_size.height / tile_size),
        );

        let program = program(display);
        let indices = indices(display, size);
        let texture = texture(display, texture_path);
        let vertex_buffer = console::VertexBuffer::new(size);

        Renderer {
            size: size,
            screen_size: screen_size,
            display: display,
            program: program,
            indices: indices,
            texture: texture,
            vertex_buffer: vertex_buffer,
        }
    }

    pub fn render(&self) {
        use glium::Surface;

        let vb = glium::VertexBuffer::new(self.display, &self.vertex_buffer.data()).unwrap();

        let cam_uniforms = {
            let mat4_id = utils::mat4_id();
            let ortho_projection = utils::ortho_projection(self.screen_size);

            // 1, 0, 0, X
            // 0, 1, 0, Y
            // 0, 0, 1, 0
            // 0, 0, 0, 1

            let cam = [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0],
            ]; // X, Y

            let tileset = self.texture
                .sampled()
                .magnify_filter(glium::uniforms::MagnifySamplerFilter::Nearest);

            uniform! {
                mvp: mvp::model_view_projection(mat4_id, cam, ortho_projection),
                tileset: tileset,
            }
        };

        let mut target = self.display.draw();
        target.clear_color(0.0, 0.0, 0.0, 1.0);
        target
            .draw(
                &vb,
                &self.indices,
                &self.program,
                &cam_uniforms,
                &Default::default(),
            )
            .unwrap();
        target.finish().unwrap();
    }

    pub fn set(&mut self, screen_loc: units::ScreenTile2D, tile: console::Tile) {
        self.vertex_buffer.set(screen_loc, tile);
    }
}

fn program(display: &Display) -> glium::Program {
    glium::Program::from_source(
        display as &glium::backend::Facade,
        &shaders::VERTEX,
        &shaders::FRAGMENT,
        None,
    )
            .unwrap()
}

fn indices(display: &Display, size: units::Size2D) -> glium::IndexBuffer<u16> {
    use glium::index::PrimitiveType;

    let indices = utils::indices((size.width * size.height) as usize);
    glium::IndexBuffer::new(
        display as &glium::backend::Facade,
        PrimitiveType::TrianglesList,
        &indices,
    )
            .unwrap()
}

fn texture(display: &Display, path: &str) -> glium::texture::Texture2d {
    let png = utils::read_bytes(path).expect(&format!("Texture not found: {}", path)[..]);
    let texture = utils::read_png_to_texture(&png[..]);
    glium::texture::Texture2d::new(display as &glium::backend::Facade, texture).unwrap()
}
<|endoftext|>


<commit_before>use futures::Finished;
use tokio_core::net::TcpStream;
use tk_bufstream::{Flushed, IoBuf};
use minihttp::{self, Status};
use cookie::Cookie;

use std::fmt::Display;
use std::fs;
use std::io::{self, Read, Write};
use std::path::Path;

pub struct ResponseWriter {
    res_writer: minihttp::ResponseWriter<TcpStream>,
}

impl ResponseWriter {
    pub fn new(res: minihttp::ResponseWriter<TcpStream>) -> ResponseWriter {
        ResponseWriter { res_writer: res }
    }

    pub fn status(&mut self, status: Status) {
        self.res_writer.status(status)
    }

    pub fn custom_status(&mut self, code: u16, reason: &str) {
        self.res_writer.custom_status(code, reason)
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn add_header<V: AsRef<[u8]>>(&mut self, name: &str, value: V) {
        if !self.is_started() {
            self.status(Status::Ok);
        }
        self.res_writer.add_header(name, value).unwrap()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn format_header<D: Display>(&mut self, name: &str, value: D) {
        self.res_writer.format_header(name, value).unwrap()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn add_length(&mut self, n: u64) {
        self.res_writer.add_length(n).unwrap()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn add_chunked(&mut self) {
        self.res_writer.add_chunked().unwrap()
    }

    pub fn is_started(&self) -> bool {
        self.res_writer.is_started()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn done_headers(&mut self) -> bool {
        self.res_writer.done_headers().unwrap()
    }

    pub fn write_body(&mut self, data: &[u8]) {
        self.res_writer.write_body(data)
    }

    pub fn is_complete(&self) -> bool {
        self.res_writer.is_complete()
    }

    pub fn done<E>(self) -> Finished<IoBuf<TcpStream>, E> {
        self.res_writer.done()
    }

    pub fn steal_socket(self) -> Flushed<TcpStream> {
        self.res_writer.steal_socket()
    }

    pub fn send_file<P: AsRef<Path>>(&mut self, filename: P) -> io::Result<()> {
        let mut file = fs::File::open(filename)?;
        let mut buf = Vec::new();
        file.read_to_end(&mut buf)?;
        self.write_all(&buf)
    }

    pub fn redirect(&mut self, status: Status, location: &[u8], data: &[u8]) -> io::Result<()> {
        if !self.is_started() {
            self.status(status);
        }
        self.add_header("Location", location);
        self.write_all(data)
    }

    pub fn set_cookie(&mut self, cookie: &Cookie) {
        if !self.is_started() {
            self.status(Status::Ok);
        }
        let cookie = cookie.as_bytes();
        self.add_header("Set-Cookie", &cookie);
    }
}

impl Write for ResponseWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let len = buf.len();
        if !self.is_started() {
            self.status(Status::Ok);
        }
        // TODO(nokaa): We want to make sure that the `Content-Type` header
        // has not already been set.
        self.add_header("Content-Type", b"text/html; charset=utf-8");
        self.add_length(len as u64);
        if self.done_headers() {
            self.write_body(buf);
            Ok((buf.len()))
        } else {
            Ok(0)
        }

    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}
<commit_msg>Stop setting default Content-Type header<commit_after>use futures::Finished;
use tokio_core::net::TcpStream;
use tk_bufstream::{Flushed, IoBuf};
use minihttp::{self, Status};
use cookie::Cookie;

use std::fmt::Display;
use std::fs;
use std::io::{self, Read, Write};
use std::path::Path;

pub struct ResponseWriter {
    res_writer: minihttp::ResponseWriter<TcpStream>,
}

impl ResponseWriter {
    pub fn new(res: minihttp::ResponseWriter<TcpStream>) -> ResponseWriter {
        ResponseWriter { res_writer: res }
    }

    pub fn status(&mut self, status: Status) {
        self.res_writer.status(status)
    }

    pub fn custom_status(&mut self, code: u16, reason: &str) {
        self.res_writer.custom_status(code, reason)
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn add_header<V: AsRef<[u8]>>(&mut self, name: &str, value: V) {
        if !self.is_started() {
            self.status(Status::Ok);
        }
        self.res_writer.add_header(name, value).unwrap()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn format_header<D: Display>(&mut self, name: &str, value: D) {
        self.res_writer.format_header(name, value).unwrap()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn add_length(&mut self, n: u64) {
        self.res_writer.add_length(n).unwrap()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn add_chunked(&mut self) {
        self.res_writer.add_chunked().unwrap()
    }

    pub fn is_started(&self) -> bool {
        self.res_writer.is_started()
    }

    // TODO(nokaa): currently if the called function returns an error, we are panicking.
    // We want to return the normal value, but the used Error is not exported from minihttp
    pub fn done_headers(&mut self) -> bool {
        self.res_writer.done_headers().unwrap()
    }

    pub fn write_body(&mut self, data: &[u8]) {
        self.res_writer.write_body(data)
    }

    pub fn is_complete(&self) -> bool {
        self.res_writer.is_complete()
    }

    pub fn done<E>(self) -> Finished<IoBuf<TcpStream>, E> {
        self.res_writer.done()
    }

    pub fn steal_socket(self) -> Flushed<TcpStream> {
        self.res_writer.steal_socket()
    }

    pub fn send_file<P: AsRef<Path>>(&mut self, filename: P) -> io::Result<()> {
        let mut file = fs::File::open(filename)?;
        let mut buf = Vec::new();
        file.read_to_end(&mut buf)?;
        self.write_all(&buf)
    }

    pub fn redirect(&mut self, status: Status, location: &[u8], data: &[u8]) -> io::Result<()> {
        if !self.is_started() {
            self.status(status);
        }
        self.add_header("Location", location);
        self.write_all(data)
    }

    pub fn set_cookie(&mut self, cookie: &Cookie) {
        if !self.is_started() {
            self.status(Status::Ok);
        }
        let cookie = cookie.as_bytes();
        self.add_header("Set-Cookie", &cookie);
    }
}

impl Write for ResponseWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let len = buf.len();
        if !self.is_started() {
            self.status(Status::Ok);
        }
        self.add_length(len as u64);
        if self.done_headers() {
            self.write_body(buf);
            Ok((buf.len()))
        } else {
            Ok(0)
        }

    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::sync::{Arc, RWLock};
use std::collections::HashMap;
use std::io::{IoResult, File};
use std::io::util::copy;
use std::path::BytesContainer;
use serialize::Encodable;
use http;
use http::server::ResponseWriter;
use time;
use mimes::get_media_type;
use mustache;
use mustache::{Template, Encoder, Error};

///A container for the response
pub struct Response<'a, 'b: 'a> {
    ///the original `http::server::ResponseWriter`
    pub origin: &'a mut ResponseWriter<'b>,
    templates: Arc<RWLock<HashMap<&'static str, Template>>>
}

impl<'a, 'b> Response<'a, 'b> {
    pub fn from_internal<'c, 'd>(response: &'c mut ResponseWriter<'d>,
                                 templates: Arc<RWLock<HashMap<&'static str, Template>>>)
                                -> Response<'c, 'd> {
        Response {
            origin: response,
            templates: templates
        }
    }

    /// Writes a response
    ///
    /// # Example
    /// ```{rust,ignore}
    /// response.send("hello world");
    /// ```
    pub fn send<T: BytesContainer> (&mut self, text: T) {
        // TODO: This needs to be more sophisticated to return the correct headers
        // not just "some headers" :)
        Response::set_headers(self.origin);
        let _ = self.origin.write(text.container_as_bytes());
    }

    /// sets the content type by it's short form.
    ///
    /// # Example
    /// ```{rust,ignore}
    /// response.set_content_type("html");
    /// ```
    pub fn content_type(&mut self, text: &str) -> &mut Response<'a,'b> {
        // TODO: make this a chaining API. (Fight the lifetime hell!)
        self.origin.headers.content_type = get_media_type(text);
        self
    }

    fn set_headers(response_writer: &mut http::server::ResponseWriter) {
        let ref mut headers = response_writer.headers;
        headers.date = Some(time::now_utc());

        // we don't need to set this https://github.com/Ogeon/rustful/issues/3#issuecomment-44787613
        headers.content_length = None;
        if headers.content_type.is_none() {
            headers.content_type = get_media_type("txt");
        }

        headers.server = Some(String::from_str("Nickel"));
    }

    pub fn send_file(&mut self, path: &Path) -> IoResult<()> {
        let mut file = try!(File::open(path));
        self.origin.headers.content_length = None;

        self.origin.headers.content_type = path.extension_str().and_then(get_media_type);
        self.origin.headers.server = Some(String::from_str("Nickel"));
        copy(&mut file, self.origin)
    }

    /// Renders the given template bound with the given data.
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut data = HashMap::<&'static str, &'static str>::new();
    /// data.insert("name", "user");
    /// response.render("examples/assets/template.tpl", &data);
    /// ```
    pub fn render<'a, T: Encodable<Encoder<'a>, Error>>
        (&mut self, path: &'static str, data: &T) {
        // Fast path doesn't need writer lock
        let _ = match self.templates.read().find(&path) {
            Some(template) => template.render(self.origin, data),
            None => {
                // Search again incase there was a race to compile the template
                let mut templates = self.templates.write();
                let template = templates.find_or_insert_with(path, |_| {
                    let mut file = File::open(&Path::new(path));
                    let raw_template = file.read_to_string()
                                            .ok()
                                            .expect(format!("Couldn't open the template file: {}",
                                                            path).as_slice());
                    mustache::compile_str(raw_template.as_slice())
                });

                template.render(self.origin, data)
            }
        };
    }
}

#[test]
fn matches_content_type () {
    let path = &Path::new("test.txt");
    let content_type = path.extension_str().and_then(get_media_type).unwrap();

    assert_eq!(content_type.type_.as_slice(), "text");
    assert_eq!(content_type.subtype.as_slice(), "plain");
}
<commit_msg>docs(response): fixup doc for content_type<commit_after>use std::sync::{Arc, RWLock};
use std::collections::HashMap;
use std::io::{IoResult, File};
use std::io::util::copy;
use std::path::BytesContainer;
use serialize::Encodable;
use http;
use http::server::ResponseWriter;
use time;
use mimes::get_media_type;
use mustache;
use mustache::{Template, Encoder, Error};

///A container for the response
pub struct Response<'a, 'b: 'a> {
    ///the original `http::server::ResponseWriter`
    pub origin: &'a mut ResponseWriter<'b>,
    templates: Arc<RWLock<HashMap<&'static str, Template>>>
}

impl<'a, 'b> Response<'a, 'b> {
    pub fn from_internal<'c, 'd>(response: &'c mut ResponseWriter<'d>,
                                 templates: Arc<RWLock<HashMap<&'static str, Template>>>)
                                -> Response<'c, 'd> {
        Response {
            origin: response,
            templates: templates
        }
    }

    /// Writes a response
    ///
    /// # Example
    /// ```{rust,ignore}
    /// response.send("hello world");
    /// ```
    pub fn send<T: BytesContainer> (&mut self, text: T) {
        // TODO: This needs to be more sophisticated to return the correct headers
        // not just "some headers" :)
        Response::set_headers(self.origin);
        let _ = self.origin.write(text.container_as_bytes());
    }

    /// Sets the content type by it's short form.
    /// Returns the response for chaining.
    ///
    /// # Example
    /// ```{rust,ignore}
    /// response.content_type("html");
    /// ```
    pub fn content_type(&mut self, text: &str) -> &mut Response<'a,'b> {
        // TODO: make this a chaining API. (Fight the lifetime hell!)
        self.origin.headers.content_type = get_media_type(text);
        self
    }

    fn set_headers(response_writer: &mut http::server::ResponseWriter) {
        let ref mut headers = response_writer.headers;
        headers.date = Some(time::now_utc());

        // we don't need to set this https://github.com/Ogeon/rustful/issues/3#issuecomment-44787613
        headers.content_length = None;
        if headers.content_type.is_none() {
            headers.content_type = get_media_type("txt");
        }

        headers.server = Some(String::from_str("Nickel"));
    }

    pub fn send_file(&mut self, path: &Path) -> IoResult<()> {
        let mut file = try!(File::open(path));
        self.origin.headers.content_length = None;

        self.origin.headers.content_type = path.extension_str().and_then(get_media_type);
        self.origin.headers.server = Some(String::from_str("Nickel"));
        copy(&mut file, self.origin)
    }

    /// Renders the given template bound with the given data.
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut data = HashMap::<&'static str, &'static str>::new();
    /// data.insert("name", "user");
    /// response.render("examples/assets/template.tpl", &data);
    /// ```
    pub fn render<'a, T: Encodable<Encoder<'a>, Error>>
        (&mut self, path: &'static str, data: &T) {
        // Fast path doesn't need writer lock
        let _ = match self.templates.read().find(&path) {
            Some(template) => template.render(self.origin, data),
            None => {
                // Search again incase there was a race to compile the template
                let mut templates = self.templates.write();
                let template = templates.find_or_insert_with(path, |_| {
                    let mut file = File::open(&Path::new(path));
                    let raw_template = file.read_to_string()
                                            .ok()
                                            .expect(format!("Couldn't open the template file: {}",
                                                            path).as_slice());
                    mustache::compile_str(raw_template.as_slice())
                });

                template.render(self.origin, data)
            }
        };
    }
}

#[test]
fn matches_content_type () {
    let path = &Path::new("test.txt");
    let content_type = path.extension_str().and_then(get_media_type).unwrap();

    assert_eq!(content_type.type_.as_slice(), "text");
    assert_eq!(content_type.subtype.as_slice(), "plain");
}
<|endoftext|>