<commit_before>use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::iter::Iterator;

/// Influxdb value, Please look at [this address](https://docs.influxdata.com/influxdb/v1.3/write_protocols/line_protocol_reference/)
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
pub enum Value {
    /// string
    String(String),
    /// Integer
    Integer(i64),
    /// float
    Float(f64),
    /// Bool
    Boolean(bool),
}

/// influxdb point
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Point {
    /// measurement
    pub measurement: String,
    /// tags
    pub tags: HashMap<String, Value>,
    /// fields
    pub fields: HashMap<String, Value>,
    /// timestamp
    pub timestamp: Option<i64>,
}

impl Point {
    /// Create a new point
    pub fn new(measurement: &str) -> Point {
        Point {
            measurement: String::from(measurement),
            tags: HashMap::new(),
            fields: HashMap::new(),
            timestamp: None,
        }
    }

    /// Add a tag and its value
    pub fn add_tag<T: Into<String>>(mut self, tag: T, value: Value) -> Self {
        self.tags.insert(tag.into(), value);
        self
    }

    /// Add a field and its value
    pub fn add_field<T: Into<String>>(mut self, field: T, value: Value) -> Self {
        self.fields.insert(field.into(), value);
        self
    }

    /// Set the specified timestamp
    pub fn add_timestamp(mut self, timestamp: i64) -> Self {
        self.timestamp = Some(timestamp);
        self
    }
}

/// Points
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Points {
    /// points
    pub point: Vec<Point>,
}

impl Points {
    /// Create a new points
    pub fn new(point: Point) -> Points {
        let mut points = Vec::new();
        points.push(point);
        Points { point: points }
    }

    /// Insert point into already existing points
    pub fn push(mut self, point: Point) -> Self {
        self.point.push(point);
        self
    }

    /// Create a multi Points more directly
    pub fn create_new(points: Vec<Point>) -> Points {
        Points { point: points }
    }
}

impl FromIterator<Point> for Points {
    fn from_iter<T: IntoIterator<Item = Point>>(iter: T) -> Self {
        let mut points = Vec::new();

        for point in iter {
            points.push(point);
        }

        Points { point: points }
    }
}

impl Iterator for Points {
    type Item = Point;

    fn next(&mut self) -> Option<Point> {
        self.point.pop()
    }
}

/// Query data
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Query {
    /// query results
    pub results: Option<Vec<Node>>,
    /// fail message
    pub error: Option<String>,
}

/// Chunked Query data
pub type ChunkedQuery<'de, T> = serde_json::StreamDeserializer<'de, T, Query>;

/// Query data node
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Node {
    /// id
    pub statement_id: Option<u64>,
    /// series
    pub series: Option<Vec<Series>>,
}

/// Query data series
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Series {
    /// measurement
    pub name: String,
    /// tag
    pub tags: Option<serde_json::Map<String, serde_json::Value>>,
    /// field names and time
    pub columns: Vec<String>,
    /// values
    pub values: Vec<Vec<serde_json::Value>>,
}

/// Time accuracy
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Precision {
    /// n
    Nanoseconds,
    /// u
    Microseconds,
    /// ms
    Milliseconds,
    /// s
    Seconds,
    /// m
    Minutes,
    /// h
    Hours,
}

impl Precision {
    /// Convert Precision to &str
    pub fn to_str(&self) -> &str {
        match *self {
            Precision::Nanoseconds => "n",
            Precision::Microseconds => "u",
            Precision::Milliseconds => "ms",
            Precision::Seconds => "s",
            Precision::Minutes => "m",
            Precision::Hours => "h",
        }
    }
}

/// Create Points by macro
#[macro_export]
macro_rules! points {
    ($($x:expr),+) => {
        {
            let mut temp_vec = Vec::new();
            $(temp_vec.push($x);)*
            Points { point: temp_vec }
        }
    };
}

/// Create Point by macro
#[macro_export]
macro_rules! point {
    ($x:expr) => {{
        Point::new($x)
    }};
    ($x:expr, $y:expr, $z:expr) => {{
        Point {
            measurement: String::from($x),
            tags: $y,
            fields: $z,
            timestamp: None,
        }
    }};
    ($x:expr, $y:expr, $z:expr, $a:expr) => {{
        Point {
            measurement: String::from($x),
            tags: $y,
            fields: $z,
            timestamp: Some($a),
        }
    }};
}
<commit_msg>make Series.name field optional<commit_after>use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::iter::Iterator;

/// Influxdb value, Please look at [this address](https://docs.influxdata.com/influxdb/v1.3/write_protocols/line_protocol_reference/)
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
pub enum Value {
    /// string
    String(String),
    /// Integer
    Integer(i64),
    /// float
    Float(f64),
    /// Bool
    Boolean(bool),
}

/// influxdb point
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Point {
    /// measurement
    pub measurement: String,
    /// tags
    pub tags: HashMap<String, Value>,
    /// fields
    pub fields: HashMap<String, Value>,
    /// timestamp
    pub timestamp: Option<i64>,
}

impl Point {
    /// Create a new point
    pub fn new(measurement: &str) -> Point {
        Point {
            measurement: String::from(measurement),
            tags: HashMap::new(),
            fields: HashMap::new(),
            timestamp: None,
        }
    }

    /// Add a tag and its value
    pub fn add_tag<T: Into<String>>(mut self, tag: T, value: Value) -> Self {
        self.tags.insert(tag.into(), value);
        self
    }

    /// Add a field and its value
    pub fn add_field<T: Into<String>>(mut self, field: T, value: Value) -> Self {
        self.fields.insert(field.into(), value);
        self
    }

    /// Set the specified timestamp
    pub fn add_timestamp(mut self, timestamp: i64) -> Self {
        self.timestamp = Some(timestamp);
        self
    }
}

/// Points
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Points {
    /// points
    pub point: Vec<Point>,
}

impl Points {
    /// Create a new points
    pub fn new(point: Point) -> Points {
        let mut points = Vec::new();
        points.push(point);
        Points { point: points }
    }

    /// Insert point into already existing points
    pub fn push(mut self, point: Point) -> Self {
        self.point.push(point);
        self
    }

    /// Create a multi Points more directly
    pub fn create_new(points: Vec<Point>) -> Points {
        Points { point: points }
    }
}

impl FromIterator<Point> for Points {
    fn from_iter<T: IntoIterator<Item = Point>>(iter: T) -> Self {
        let mut points = Vec::new();

        for point in iter {
            points.push(point);
        }

        Points { point: points }
    }
}

impl Iterator for Points {
    type Item = Point;

    fn next(&mut self) -> Option<Point> {
        self.point.pop()
    }
}

/// Query data
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Query {
    /// query results
    pub results: Option<Vec<Node>>,
    /// fail message
    pub error: Option<String>,
}

/// Chunked Query data
pub type ChunkedQuery<'de, T> = serde_json::StreamDeserializer<'de, T, Query>;

/// Query data node
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Node {
    /// id
    pub statement_id: Option<u64>,
    /// series
    pub series: Option<Vec<Series>>,
}

/// Query data series
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct Series {
    /// measurement
    pub name: Option<String>,
    /// tag
    pub tags: Option<serde_json::Map<String, serde_json::Value>>,
    /// field names and time
    pub columns: Vec<String>,
    /// values
    pub values: Vec<Vec<serde_json::Value>>,
}

/// Time accuracy
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Precision {
    /// n
    Nanoseconds,
    /// u
    Microseconds,
    /// ms
    Milliseconds,
    /// s
    Seconds,
    /// m
    Minutes,
    /// h
    Hours,
}

impl Precision {
    /// Convert Precision to &str
    pub fn to_str(&self) -> &str {
        match *self {
            Precision::Nanoseconds => "n",
            Precision::Microseconds => "u",
            Precision::Milliseconds => "ms",
            Precision::Seconds => "s",
            Precision::Minutes => "m",
            Precision::Hours => "h",
        }
    }
}

/// Create Points by macro
#[macro_export]
macro_rules! points {
    ($($x:expr),+) => {
        {
            let mut temp_vec = Vec::new();
            $(temp_vec.push($x);)*
            Points { point: temp_vec }
        }
    };
}

/// Create Point by macro
#[macro_export]
macro_rules! point {
    ($x:expr) => {{
        Point::new($x)
    }};
    ($x:expr, $y:expr, $z:expr) => {{
        Point {
            measurement: String::from($x),
            tags: $y,
            fields: $z,
            timestamp: None,
        }
    }};
    ($x:expr, $y:expr, $z:expr, $a:expr) => {{
        Point {
            measurement: String::from($x),
            tags: $y,
            fields: $z,
            timestamp: Some($a),
        }
    }};
}
<|endoftext|>


<commit_before>//! Draw Line

use internal;
use triangulation;
use Graphics;
use Color;
use math::Matrix2d;
use DrawState;

/// The shape of the line
#[derive(Copy, Clone)]
pub enum Shape {
    /// Square edges
    Square,
    /// Round edges
    Round,
    /// Bevel edges
    Bevel,
}

/// A colored line with a default border radius
#[derive(Copy, Clone)]
pub struct Line {
    /// The line color
    pub color: internal::Color,
    /// The line radius
    pub radius: internal::Radius,
    /// The line shape
    pub shape: Shape,
}

impl Line {
    /// Creates a new line
    pub fn new(color: internal::Color, radius: internal::Radius) -> Line {
        Line {
            color: color,
            radius: radius,
            shape: Shape::Square,
        }
    }

    /// Creates a new line
    pub fn round(color: internal::Color, radius: internal::Radius) -> Line {
        Line {
            color: color,
            radius: radius,
            shape: Shape::Round,
        }
    }

    /// Draw the line.
    pub fn draw<G>(
        &self,
        line: internal::Line,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G
    )
        where G: Graphics
    {
        match self.shape {
            Shape::Square => {
                g.tri_list(
                    draw_state,
                    &self.color,
                    |f|
                triangulation::with_round_border_line_tri_list(
                    2,
                    transform,
                    line,
                    self.radius,
                    |vertices| f(vertices)
                ));
            }
            Shape::Round => {
                g.tri_list(
                    draw_state,
                    &self.color,
                    |f|
                triangulation::with_round_border_line_tri_list(
                    64,
                    transform,
                    line,
                    self.radius,
                    |vertices| f(vertices)
                ));
            }
            Shape::Bevel => {
                g.tri_list(
                    draw_state,
                    &self.color,
                    |f|
                triangulation::with_round_border_line_tri_list(
                    3,
                    transform,
                    line,
                    self.radius,
                    |vertices| f(vertices)
                ));
            }
        }
    }

    /// Draws an arrow
    ///
    /// Head size is the sides of the triangle
    /// between the arrow hooks and the line
    pub fn draw_arrow<G>(
        &self,
        line: internal::Line,
        head_size: internal::Scalar,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G
    )
        where G: Graphics
    {
        use Transformed;

        self.draw(line, draw_state, transform, g);
        let diff = [line[2] - line[0], line[3] - line[1]];
        let arrow_head = transform
            .trans(line[2], line[3])
            .orient(diff[0], diff[1]);
        self.draw([-head_size, head_size, 0.0, 0.0], draw_state, arrow_head, g);
        self.draw([-head_size, -head_size, 0.0, 0.0], draw_state, arrow_head, g);
    }
}

/*
quack! {
    set:
        fn (val: Color) [] { l.color = val.0 }
        fn (val: Radius) [] { l.radius = val.0 }
        fn (val: Width) [] { l.radius = 0.5 * val.0 }
        fn (val: Shape) [] { l.shape = val }
    action:
}
*/

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

    #[test]
    fn test_line() {
        use Colored;

        let _line = Line::new([0.0; 4], 3.0)
            .set(Color([1.0; 4]))
            .set(Radius(3.0))
            .set(Shape::Round)
            .hue_deg(1.0);
        let Color(_) = _line.get();
    }
}
<commit_msg>Renamed `Line::round` to `Line::new_round`<commit_after>//! Draw Line

use internal;
use triangulation;
use Graphics;
use Color;
use math::Matrix2d;
use DrawState;

/// The shape of the line
#[derive(Copy, Clone)]
pub enum Shape {
    /// Square edges
    Square,
    /// Round edges
    Round,
    /// Bevel edges
    Bevel,
}

/// A colored line with a default border radius
#[derive(Copy, Clone)]
pub struct Line {
    /// The line color
    pub color: internal::Color,
    /// The line radius
    pub radius: internal::Radius,
    /// The line shape
    pub shape: Shape,
}

impl Line {
    /// Creates a new line
    pub fn new(color: internal::Color, radius: internal::Radius) -> Line {
        Line {
            color: color,
            radius: radius,
            shape: Shape::Square,
        }
    }

    /// Creates a new line
    pub fn new_round(color: internal::Color, radius: internal::Radius) -> Line {
        Line {
            color: color,
            radius: radius,
            shape: Shape::Round,
        }
    }

    /// Draw the line.
    pub fn draw<G>(
        &self,
        line: internal::Line,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G
    )
        where G: Graphics
    {
        match self.shape {
            Shape::Square => {
                g.tri_list(
                    draw_state,
                    &self.color,
                    |f|
                triangulation::with_round_border_line_tri_list(
                    2,
                    transform,
                    line,
                    self.radius,
                    |vertices| f(vertices)
                ));
            }
            Shape::Round => {
                g.tri_list(
                    draw_state,
                    &self.color,
                    |f|
                triangulation::with_round_border_line_tri_list(
                    64,
                    transform,
                    line,
                    self.radius,
                    |vertices| f(vertices)
                ));
            }
            Shape::Bevel => {
                g.tri_list(
                    draw_state,
                    &self.color,
                    |f|
                triangulation::with_round_border_line_tri_list(
                    3,
                    transform,
                    line,
                    self.radius,
                    |vertices| f(vertices)
                ));
            }
        }
    }

    /// Draws an arrow
    ///
    /// Head size is the sides of the triangle
    /// between the arrow hooks and the line
    pub fn draw_arrow<G>(
        &self,
        line: internal::Line,
        head_size: internal::Scalar,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G
    )
        where G: Graphics
    {
        use Transformed;

        self.draw(line, draw_state, transform, g);
        let diff = [line[2] - line[0], line[3] - line[1]];
        let arrow_head = transform
            .trans(line[2], line[3])
            .orient(diff[0], diff[1]);
        self.draw([-head_size, head_size, 0.0, 0.0], draw_state, arrow_head, g);
        self.draw([-head_size, -head_size, 0.0, 0.0], draw_state, arrow_head, g);
    }
}

/*
quack! {
    set:
        fn (val: Color) [] { l.color = val.0 }
        fn (val: Radius) [] { l.radius = val.0 }
        fn (val: Width) [] { l.radius = 0.5 * val.0 }
        fn (val: Shape) [] { l.shape = val }
    action:
}
*/

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

    #[test]
    fn test_line() {
        use Colored;

        let _line = Line::new([0.0; 4], 3.0)
            .set(Color([1.0; 4]))
            .set(Radius(3.0))
            .set(Shape::Round)
            .hue_deg(1.0);
        let Color(_) = _line.get();
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// 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/.

extern crate docopt;
#[macro_use] extern crate lazy_static;
extern crate pad;
extern crate rustc_serialize;
extern crate sqlite;

use docopt::Docopt;

mod db;
mod entry;
mod print;

const USAGE: &'static str = "
keep - it keeps shit, so you can look at it later

Usage:
    keep save [--tag=<t>] <item>
    keep list [--tag=<t>]
    keep rm [--all] [--tag=<t>] [<id>]
    keep -h | --help
    keep --version

Options:
    -a --all        Apply command to every entry.
    -t --tag=<t>    Name to help identify item.
    -h --help       Show this screen.
    --version       Show version.
";

const VERSION_STR: &'static str = "keep 0.1.1

Copyright (C) 2016 Nathan Sizemore <nathanrsizemore@gmail.com>
License: MPL-2.0 https://www.mozilla.org/en-US/MPL/2.0
This is free software: you are free to change and redistribute it.";

#[derive(Debug, RustcDecodable)]
pub struct Args {
    pub flag_all: bool,
    pub flag_tag: String,
    pub flag_version: bool,
    pub cmd_save: bool,
    pub cmd_list: bool,
    pub cmd_rm: bool,
    pub arg_item: String,
    pub arg_id: u64
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    db::init();

    handle_input(&args);
}

fn handle_input(args: &Args) {
    // println!("{:?}", args);

    if args.flag_version {
        println!("{}", VERSION_STR);
        return;
    }

    // Insert op
    if args.cmd_save {
        if args.flag_tag.len() > 0 {
            db::insert_with_tag(&args.flag_tag, &args.arg_item);
        } else {
            db::insert(&args.arg_item);
        }
        return;
    }

    // List op
    if args.cmd_list {
        let entries = if args.flag_tag.len() > 0 {
            db::get_with_tag(&args.flag_tag)
        } else {
            db::get_all()
        };

        print::print_entries(entries);
        return;
    }

    // Remove op
    if args.cmd_rm {
        if args.flag_tag.len() > 0 { // By tag
            db::rm_with_tag(&args.flag_tag);
        } else if args.flag_all { // Everything
            db::rm_all();
        } else { // By id
            db::rm_with_id(args.arg_id);
        }
    }
}
<commit_msg>Text edit in help output.<commit_after>// Copyright 2016 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// 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/.

extern crate docopt;
#[macro_use] extern crate lazy_static;
extern crate pad;
extern crate rustc_serialize;
extern crate sqlite;

use docopt::Docopt;

mod db;
mod entry;
mod print;

const USAGE: &'static str = "
keep - it keeps shit, so you can look at it later.

Usage:
    keep save [--tag=<t>] <item>
    keep list [--tag=<t>]
    keep rm [--all] [--tag=<t>] [<id>]
    keep -h | --help
    keep --version

Options:
    -a --all        Apply command to every entry.
    -t --tag=<t>    Name to help identify item.
    -h --help       Show this screen.
    --version       Show version.
";

const VERSION_STR: &'static str = "keep 0.1.1

Copyright (C) 2016 Nathan Sizemore <nathanrsizemore@gmail.com>
License: MPL-2.0 https://www.mozilla.org/en-US/MPL/2.0
This is free software: you are free to change and redistribute it.";

#[derive(Debug, RustcDecodable)]
pub struct Args {
    pub flag_all: bool,
    pub flag_tag: String,
    pub flag_version: bool,
    pub cmd_save: bool,
    pub cmd_list: bool,
    pub cmd_rm: bool,
    pub arg_item: String,
    pub arg_id: u64
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    db::init();

    handle_input(&args);
}

fn handle_input(args: &Args) {
    // println!("{:?}", args);

    if args.flag_version {
        println!("{}", VERSION_STR);
        return;
    }

    // Insert op
    if args.cmd_save {
        if args.flag_tag.len() > 0 {
            db::insert_with_tag(&args.flag_tag, &args.arg_item);
        } else {
            db::insert(&args.arg_item);
        }
        return;
    }

    // List op
    if args.cmd_list {
        let entries = if args.flag_tag.len() > 0 {
            db::get_with_tag(&args.flag_tag)
        } else {
            db::get_all()
        };

        print::print_entries(entries);
        return;
    }

    // Remove op
    if args.cmd_rm {
        if args.flag_tag.len() > 0 { // By tag
            db::rm_with_tag(&args.flag_tag);
        } else if args.flag_all { // Everything
            db::rm_all();
        } else { // By id
            db::rm_with_id(args.arg_id);
        }
    }
}
<|endoftext|>


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

#![recursion_limit="300"]
#![feature(const_fn)]
#![feature(plugin)]

// #![plugin(clippy)]
// #![allow(similar_names)]
// #![allow(new_without_default)]
// #![allow(many_single_char_names)]
// #![allow(if_not_else)]
// #![allow(float_cmp)]
// #![allow(single_char_pattern)]
// #![allow(too_many_arguments)]
// #![allow(cyclomatic_complexity)]

extern crate sdl2;
extern crate image;
extern crate time;
extern crate byteorder;
extern crate serde_json;
extern crate steven_openssl as openssl;
extern crate hyper;
extern crate flate2;
extern crate rand;
extern crate rustc_serialize;
extern crate cgmath;
#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate collision;
pub extern crate steven_blocks;
extern crate steven_shared as shared;

#[macro_use]
pub mod macros;

pub mod ecs;
pub mod protocol;
pub mod format;
pub mod nbt;
pub mod item;
pub mod gl;
pub mod types;
pub mod resources;
pub mod render;
pub mod ui;
pub mod screen;
#[macro_use]
pub mod console;
pub mod server;
pub mod world;
pub mod chunk_builder;
pub mod auth;
pub mod model;
pub mod entity;

use std::sync::{Arc, RwLock, Mutex};
use std::marker::PhantomData;
use std::thread;
use std::sync::mpsc;

const CL_BRAND: console::CVar<String> = console::CVar {
    ty: PhantomData,
    name: "cl_brand",
    description: "cl_brand has the value of the clients current 'brand'. e.g. \"Steven\" or \
                  \"Vanilla\"",
    mutable: false,
    serializable: false,
    default: &|| "Steven".to_owned(),
};

pub struct Game {
    renderer: render::Renderer,
    screen_sys: screen::ScreenSystem,
    resource_manager: Arc<RwLock<resources::Manager>>,
    console: Arc<Mutex<console::Console>>,
    should_close: bool,

    server: server::Server,
    focused: bool,
    chunk_builder: chunk_builder::ChunkBuilder,

    connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
}

impl Game {
    pub fn connect_to(&mut self, address: &str) {
        let (tx, rx) = mpsc::channel();
        self.connect_reply = Some(rx);
        let address = address.to_owned();
        let resources = self.resource_manager.clone();
        let console = self.console.clone();
        thread::spawn(move || {
            tx.send(server::Server::connect(resources, console, &address)).unwrap();
        });
    }

    pub fn tick(&mut self, delta: f64) {
        if !self.server.is_connected() {
            self.renderer.camera.pos = cgmath::Point3::new(0.5, 13.2, 0.5);
            self.renderer.camera.yaw += 0.005 * delta;
            if self.renderer.camera.yaw > ::std::f64::consts::PI * 2.0 {
                self.renderer.camera.yaw = 0.0;
            }
        }
        let mut clear_reply = false;
        if let Some(ref recv) = self.connect_reply {
            if let Ok(server) = recv.try_recv() {
                clear_reply = true;
                match server {
                    Ok(val) => {
                        self.screen_sys.pop_screen();
                        self.focused = true;
                        self.server.remove(&mut self.renderer);
                        self.server = val;
                    },
                    Err(err) => {
                        let msg = match err {
                            protocol::Error::Disconnect(val) => val,
                            err => {
                                let mut msg = format::TextComponent::new(&format!("{}", err));
                                msg.modifier.color = Some(format::Color::Red);
                                format::Component::Text(msg)
                            },
                        };
                        self.screen_sys.replace_screen(Box::new(screen::ServerList::new(
                            Some(msg)
                        )));
                    }
                }
            }
        }
        if clear_reply {
            self.connect_reply = None;
        }
    }
}

fn main() {
    let con = Arc::new(Mutex::new(console::Console::new()));
    {
        let mut con = con.lock().unwrap();
        con.register(CL_BRAND);
        auth::register_vars(&mut con);
        con.load_config();
        con.save_config();
    }

    let proxy = console::ConsoleProxy::new(con.clone());

    log::set_logger(|max_log_level| {
        max_log_level.set(log::LogLevelFilter::Trace);
        Box::new(proxy)
    }).unwrap();

    info!("Starting steven");

    let resource_manager = Arc::new(RwLock::new(resources::Manager::new()));
    {
        resource_manager.write().unwrap().tick();
    }

    let sdl = sdl2::init().unwrap();
    let sdl_video = sdl.video().unwrap();

    sdl_video.gl_set_swap_interval(1);

    let window = sdl2::video::WindowBuilder::new(&sdl_video, "Steven", 854, 480)
                            .opengl()
                            .resizable()
                            .build()
                            .expect("Could not create sdl window.");
    let gl_attr = sdl_video.gl_attr();
    gl_attr.set_stencil_size(0);
    gl_attr.set_depth_size(24);
    gl_attr.set_context_major_version(3);
    gl_attr.set_context_minor_version(2);
    gl_attr.set_context_profile(sdl2::video::GLProfile::Core);

    let gl_context = window.gl_create_context().unwrap();
    window.gl_make_current(&gl_context).expect("Could not set current context.");

    gl::init(&sdl_video);

    let renderer = render::Renderer::new(resource_manager.clone());
    let mut ui_container = ui::Container::new();

    let mut last_frame = time::now();
    let frame_time = (time::Duration::seconds(1).num_nanoseconds().unwrap() as f64) / 60.0;

    let mut screen_sys = screen::ScreenSystem::new();
    screen_sys.add_screen(Box::new(screen::Login::new(con.clone())));

    let textures = renderer.get_textures();
    let mut game = Game {
        server: server::Server::dummy_server(resource_manager.clone(), con.clone()),
        focused: false,
        renderer: renderer,
        screen_sys: screen_sys,
        resource_manager: resource_manager.clone(),
        console: con,
        should_close: false,
        chunk_builder: chunk_builder::ChunkBuilder::new(resource_manager, textures),
        connect_reply: None,
    };

    let mut events = sdl.event_pump().unwrap();
    while !game.should_close {
        let version = {
            let mut res = game.resource_manager.write().unwrap();
            res.tick();
            res.version()
        };

        let now = time::now();
        let diff = now - last_frame;
        last_frame = now;
        let delta = (diff.num_nanoseconds().unwrap() as f64) / frame_time;
        let (width, height) = window.size();

        game.tick(delta);
        game.server.tick(&mut game.renderer, delta);

        game.renderer.update_camera(width, height);
        game.server.world.compute_render_list(&mut game.renderer);
        game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, version);

        game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container);
        game.console
            .lock()
            .unwrap()
            .tick(&mut ui_container, &mut game.renderer, delta, width as f64);
        ui_container.tick(&mut game.renderer, delta, width as f64, height as f64);
        game.renderer.tick(&mut game.server.world, delta, width, height);

        window.gl_swap_window();

        for event in events.poll_iter() {
            handle_window_event(&window, &mut game, &mut ui_container, event)
        }
    }
}

fn handle_window_event(window: &sdl2::video::Window,
                       game: &mut Game,
                       ui_container: &mut ui::Container,
                       event: sdl2::event::Event) {
    use sdl2::event::Event;
    use sdl2::keyboard::Keycode;
    use sdl2::mouse::Mouse;
    use std::f64::consts::PI;

    let mouse = window.subsystem().sdl().mouse();

    match event {
        Event::Quit{..} => game.should_close = true,

        Event::MouseMotion{x, y, xrel, yrel, ..} => {
            let (width, height) = window.size();
            if game.focused {
                if !mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(true);
                }
                if let Some(player) = game.server.player {
                    let s = 2000.0 + 0.01;
                    let (rx, ry) = (xrel as f64 / s, yrel as f64 / s);
                    let rotation = game.server.entities.get_component_mut(player, game.server.rotation).unwrap();
                    rotation.yaw -= rx;
                    rotation.pitch -= ry;
                    if rotation.pitch < (PI/2.0) + 0.01 {
                        rotation.pitch = (PI/2.0) + 0.01;
                    }
                    if rotation.pitch > (PI/2.0)*3.0 - 0.01 {
                        rotation.pitch = (PI/2.0)*3.0 - 0.01;
                    }
                }
            } else {
                ui_container.hover_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseButtonUp{mouse_btn: Mouse::Left, x, y, ..} => {
            let (width, height) = window.size();

            if game.server.is_connected() && !game.focused {
                game.focused = true;
                mouse.set_relative_mouse_mode(true);
                mouse.warp_mouse_in_window(&window, (width/2) as i32, (height/2) as i32);
                return;
            }
            if !game.focused {
                ui_container.click_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseWheel{x, y, ..} => {
            game.screen_sys.on_scroll(x as f64, y as f64);
        }
        Event::KeyUp{keycode: Some(Keycode::Escape), ..} => {
            if game.focused {
                mouse.set_relative_mouse_mode(false);
                game.focused = false;
            }
        }
        Event::KeyDown{keycode: Some(Keycode::Backquote), ..} => {
            game.console.lock().unwrap().toggle();
        }
        Event::KeyDown{keycode: Some(key), ..} => {
            if game.focused {
                game.server.key_press(true, key);
            } else {
                ui_container.key_press(game, key, true);
            }
        }
        Event::KeyUp{keycode: Some(key), ..} => {
            if game.focused {
                game.server.key_press(false, key);
            } else {
                ui_container.key_press(game, key, false);
            }
        }
        Event::TextInput{text, ..} => {
            if !game.focused {
                for c in text.chars() {
                    ui_container.key_type(game, c);
                }
            }
        }
        _ => (),
    }
}
<commit_msg>Use drawable_size instead of size for rendering<commit_after>// Copyright 2016 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![recursion_limit="300"]
#![feature(const_fn)]
#![feature(plugin)]

// #![plugin(clippy)]
// #![allow(similar_names)]
// #![allow(new_without_default)]
// #![allow(many_single_char_names)]
// #![allow(if_not_else)]
// #![allow(float_cmp)]
// #![allow(single_char_pattern)]
// #![allow(too_many_arguments)]
// #![allow(cyclomatic_complexity)]

extern crate sdl2;
extern crate image;
extern crate time;
extern crate byteorder;
extern crate serde_json;
extern crate steven_openssl as openssl;
extern crate hyper;
extern crate flate2;
extern crate rand;
extern crate rustc_serialize;
extern crate cgmath;
#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate collision;
pub extern crate steven_blocks;
extern crate steven_shared as shared;

#[macro_use]
pub mod macros;

pub mod ecs;
pub mod protocol;
pub mod format;
pub mod nbt;
pub mod item;
pub mod gl;
pub mod types;
pub mod resources;
pub mod render;
pub mod ui;
pub mod screen;
#[macro_use]
pub mod console;
pub mod server;
pub mod world;
pub mod chunk_builder;
pub mod auth;
pub mod model;
pub mod entity;

use std::sync::{Arc, RwLock, Mutex};
use std::marker::PhantomData;
use std::thread;
use std::sync::mpsc;

const CL_BRAND: console::CVar<String> = console::CVar {
    ty: PhantomData,
    name: "cl_brand",
    description: "cl_brand has the value of the clients current 'brand'. e.g. \"Steven\" or \
                  \"Vanilla\"",
    mutable: false,
    serializable: false,
    default: &|| "Steven".to_owned(),
};

pub struct Game {
    renderer: render::Renderer,
    screen_sys: screen::ScreenSystem,
    resource_manager: Arc<RwLock<resources::Manager>>,
    console: Arc<Mutex<console::Console>>,
    should_close: bool,

    server: server::Server,
    focused: bool,
    chunk_builder: chunk_builder::ChunkBuilder,

    connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
}

impl Game {
    pub fn connect_to(&mut self, address: &str) {
        let (tx, rx) = mpsc::channel();
        self.connect_reply = Some(rx);
        let address = address.to_owned();
        let resources = self.resource_manager.clone();
        let console = self.console.clone();
        thread::spawn(move || {
            tx.send(server::Server::connect(resources, console, &address)).unwrap();
        });
    }

    pub fn tick(&mut self, delta: f64) {
        if !self.server.is_connected() {
            self.renderer.camera.pos = cgmath::Point3::new(0.5, 13.2, 0.5);
            self.renderer.camera.yaw += 0.005 * delta;
            if self.renderer.camera.yaw > ::std::f64::consts::PI * 2.0 {
                self.renderer.camera.yaw = 0.0;
            }
        }
        let mut clear_reply = false;
        if let Some(ref recv) = self.connect_reply {
            if let Ok(server) = recv.try_recv() {
                clear_reply = true;
                match server {
                    Ok(val) => {
                        self.screen_sys.pop_screen();
                        self.focused = true;
                        self.server.remove(&mut self.renderer);
                        self.server = val;
                    },
                    Err(err) => {
                        let msg = match err {
                            protocol::Error::Disconnect(val) => val,
                            err => {
                                let mut msg = format::TextComponent::new(&format!("{}", err));
                                msg.modifier.color = Some(format::Color::Red);
                                format::Component::Text(msg)
                            },
                        };
                        self.screen_sys.replace_screen(Box::new(screen::ServerList::new(
                            Some(msg)
                        )));
                    }
                }
            }
        }
        if clear_reply {
            self.connect_reply = None;
        }
    }
}

fn main() {
    let con = Arc::new(Mutex::new(console::Console::new()));
    {
        let mut con = con.lock().unwrap();
        con.register(CL_BRAND);
        auth::register_vars(&mut con);
        con.load_config();
        con.save_config();
    }

    let proxy = console::ConsoleProxy::new(con.clone());

    log::set_logger(|max_log_level| {
        max_log_level.set(log::LogLevelFilter::Trace);
        Box::new(proxy)
    }).unwrap();

    info!("Starting steven");

    let resource_manager = Arc::new(RwLock::new(resources::Manager::new()));
    {
        resource_manager.write().unwrap().tick();
    }

    let sdl = sdl2::init().unwrap();
    let sdl_video = sdl.video().unwrap();

    sdl_video.gl_set_swap_interval(1);

    let window = sdl2::video::WindowBuilder::new(&sdl_video, "Steven", 854, 480)
                            .opengl()
                            .resizable()
                            .build()
                            .expect("Could not create sdl window.");
    let gl_attr = sdl_video.gl_attr();
    gl_attr.set_stencil_size(0);
    gl_attr.set_depth_size(24);
    gl_attr.set_context_major_version(3);
    gl_attr.set_context_minor_version(2);
    gl_attr.set_context_profile(sdl2::video::GLProfile::Core);

    let gl_context = window.gl_create_context().unwrap();
    window.gl_make_current(&gl_context).expect("Could not set current context.");

    gl::init(&sdl_video);

    let renderer = render::Renderer::new(resource_manager.clone());
    let mut ui_container = ui::Container::new();

    let mut last_frame = time::now();
    let frame_time = (time::Duration::seconds(1).num_nanoseconds().unwrap() as f64) / 60.0;

    let mut screen_sys = screen::ScreenSystem::new();
    screen_sys.add_screen(Box::new(screen::Login::new(con.clone())));

    let textures = renderer.get_textures();
    let mut game = Game {
        server: server::Server::dummy_server(resource_manager.clone(), con.clone()),
        focused: false,
        renderer: renderer,
        screen_sys: screen_sys,
        resource_manager: resource_manager.clone(),
        console: con,
        should_close: false,
        chunk_builder: chunk_builder::ChunkBuilder::new(resource_manager, textures),
        connect_reply: None,
    };

    let mut events = sdl.event_pump().unwrap();
    while !game.should_close {
        let version = {
            let mut res = game.resource_manager.write().unwrap();
            res.tick();
            res.version()
        };

        let now = time::now();
        let diff = now - last_frame;
        last_frame = now;
        let delta = (diff.num_nanoseconds().unwrap() as f64) / frame_time;
        let (width, height) = window.drawable_size();

        game.tick(delta);
        game.server.tick(&mut game.renderer, delta);

        game.renderer.update_camera(width, height);
        game.server.world.compute_render_list(&mut game.renderer);
        game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, version);

        game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container);
        game.console
            .lock()
            .unwrap()
            .tick(&mut ui_container, &mut game.renderer, delta, width as f64);
        ui_container.tick(&mut game.renderer, delta, width as f64, height as f64);
        game.renderer.tick(&mut game.server.world, delta, width, height);

        window.gl_swap_window();

        for event in events.poll_iter() {
            handle_window_event(&window, &mut game, &mut ui_container, event)
        }
    }
}

fn handle_window_event(window: &sdl2::video::Window,
                       game: &mut Game,
                       ui_container: &mut ui::Container,
                       event: sdl2::event::Event) {
    use sdl2::event::Event;
    use sdl2::keyboard::Keycode;
    use sdl2::mouse::Mouse;
    use std::f64::consts::PI;

    let mouse = window.subsystem().sdl().mouse();

    match event {
        Event::Quit{..} => game.should_close = true,

        Event::MouseMotion{x, y, xrel, yrel, ..} => {
            let (width, height) = window.size();
            if game.focused {
                if !mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(true);
                }
                if let Some(player) = game.server.player {
                    let s = 2000.0 + 0.01;
                    let (rx, ry) = (xrel as f64 / s, yrel as f64 / s);
                    let rotation = game.server.entities.get_component_mut(player, game.server.rotation).unwrap();
                    rotation.yaw -= rx;
                    rotation.pitch -= ry;
                    if rotation.pitch < (PI/2.0) + 0.01 {
                        rotation.pitch = (PI/2.0) + 0.01;
                    }
                    if rotation.pitch > (PI/2.0)*3.0 - 0.01 {
                        rotation.pitch = (PI/2.0)*3.0 - 0.01;
                    }
                }
            } else {
                ui_container.hover_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseButtonUp{mouse_btn: Mouse::Left, x, y, ..} => {
            let (width, height) = window.size();

            if game.server.is_connected() && !game.focused {
                game.focused = true;
                mouse.set_relative_mouse_mode(true);
                mouse.warp_mouse_in_window(&window, (width/2) as i32, (height/2) as i32);
                return;
            }
            if !game.focused {
                ui_container.click_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseWheel{x, y, ..} => {
            game.screen_sys.on_scroll(x as f64, y as f64);
        }
        Event::KeyUp{keycode: Some(Keycode::Escape), ..} => {
            if game.focused {
                mouse.set_relative_mouse_mode(false);
                game.focused = false;
            }
        }
        Event::KeyDown{keycode: Some(Keycode::Backquote), ..} => {
            game.console.lock().unwrap().toggle();
        }
        Event::KeyDown{keycode: Some(key), ..} => {
            if game.focused {
                game.server.key_press(true, key);
            } else {
                ui_container.key_press(game, key, true);
            }
        }
        Event::KeyUp{keycode: Some(key), ..} => {
            if game.focused {
                game.server.key_press(false, key);
            } else {
                ui_container.key_press(game, key, false);
            }
        }
        Event::TextInput{text, ..} => {
            if !game.focused {
                for c in text.chars() {
                    ui_container.key_type(game, c);
                }
            }
        }
        _ => (),
    }
}
<|endoftext|>


<commit_before>#![feature(globs)]
extern crate libc;

use libc::{c_int, size_t};
use std::io;
use std::ptr;
use std::io::process::{Command, StdioContainer};

use termios::*;
use signal::*;
use constants::*;

mod termios;
mod signal;
mod constants;

#[allow(unused_variables)]
extern fn handle_sigint(signum:c_int, siginfo:*const SigInfo, context:size_t) {
    print!("^C");
    io::stdio::flush();
}

fn prepare_terminal(tios:&mut Termios) {
    tios.ldisable(ICANON);
    tios.ldisable(ECHO);
}

fn update_terminal(tios:Termios) -> bool {
    if !tios.set() {
        io::stderr().write_line("Warning: Could not set terminal mode").unwrap();
        return false;
    }
    return true;
}

fn handle_escape(stdin:&mut io::stdio::StdinReader,
                 line:&mut Vec<String>, word:&mut String,
                 part:&mut String, bpart:&mut String) {
    // Handle an ANSI escape sequence
    if stdin.read_char() != Ok(ANSI) {
        return;
    }
    match stdin.read_char() {
        Err(_) => return,
        Ok('D') => {
            // left
            match word.pop() {
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    part.push(c);
                    cursor_left();
                },
                None => match line.pop() {
                    Some(s) => {
                        part.push(' ');
                        word.clear();
                        word.push_str(s.as_slice());
                        cursor_left();
                    }
                    None => return
                }
            }
        },
        Ok('C') => {
            // right
            match part.pop() {
                Some(' ') => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    line.push(word.clone());
                    word.clear();
                    cursor_right();
                },
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    word.push(c);
                    cursor_right();
                },
                None => return
            }
        },
        Ok(_) => return
    }
}

fn build_string(ch:char, count:uint) -> String {
    let mut s = String::new();
    let mut i = 0u;
    loop {
        if i == count {
            return s;
        }
        i += 1;
        s.push(ch);
    }
}

fn cursor_left() {
    print!("{}", DEL);
}

fn cursor_right() {
    print!("{}{}C", ESC, ANSI);
}

fn draw_part(part:&String, bpart:&mut String) {
    // quick out if part is empty
    if part.is_empty() {
        return;
    }
    if bpart.is_empty() {
        // only calculate bpart when it needs to be recalculated
        let mut cpart = part.clone();
        loop {
            match cpart.pop() {
                Some(c) => bpart.push(c),
                None => break
            }
        }
    }
    print!("{}", bpart);
}

fn cursors_left(by:uint) {
    // move back by a given number of characters
    print!("{}", build_string(DEL, by));
}

fn idraw_part(part:&String, bpart:&mut String) {
    // in-place draw of the line part
    draw_part(part, bpart);
    cursors_left(part.len());
}

fn prepare_signals() {
    let mut sa = SigAction {
        handler: handle_sigint,
        mask: [0; SIGSET_NWORDS],
        flags: SA_RESTART | SA_SIGINFO
    };
    unsafe {
        if sigfillset(&mut sa.mask) != 0 {
            io::stderr().write_line("Warning: could not fill mask set for SIGINT handler").unwrap();
        }
        if sigaction(SIGINT, &sa, ptr::null_mut::<SigAction>()) != 0 {
            io::stderr().write_line("Warning: could not set handler for SIGINT").unwrap();
        }
    }
}

fn run_command(line:&Vec<String>) {
    let mut process = Command::new(&line[0]);
    process.args(line.slice_from(1));
    process.stdout(StdioContainer::InheritFd(STDOUT));
    process.stdin(StdioContainer::InheritFd(STDIN));
    process.stderr(StdioContainer::InheritFd(STDERR));
    let mut child = match process.spawn() {
        Err(e) => {
            io::stderr().write_line(format!("Couldn't spawn {}: {}", &line[0], e).as_slice()).unwrap();
            return;
        },
        Ok(child) => child
    };
    match child.wait() {
        Err(e) => {
            io::stderr().write_line(format!("Couldn't wait for child to exit: {}", e.desc).as_slice()).unwrap();
        },
        Ok(_) => {
            // nothing
        }
    };
}

fn main() {
    prepare_signals();
    let mut tios = Termios::new();
    tios.get();
    let old_tios = tios.clone();
    prepare_terminal(&mut tios);
    update_terminal(tios);
    let mut stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut line = Vec::<String>::new();
    let mut word = String::new();
    let mut part = String::new();
    // store bpart so we don't need to recalulate it every time
    let mut bpart = String::new();
    loop {
        // Note: in non-canonical mode
        match stdin.read_char() {
            Ok(EOF) => {
                if line.is_empty() && word.is_empty() {
                    break;
                }
            },
            Ok(NL) => {
                stdout.write_char(NL).unwrap();
                if !word.is_empty() {
                    line.push(word.clone());
                }
                if !line.is_empty() {
                    // run command
                    update_terminal(old_tios);
                    run_command(&line);
                    update_terminal(tios);
                }
                word.clear();
                line.clear();
                part.clear();
                bpart.clear();
            },
            Ok(DEL) => {
                if word.is_empty() {
                    word = match line.pop() {
                        Some(s) => s,
                        None => continue
                    };
                    cursor_left();
                } else {
                    word.pop();
                    cursor_left();
                    draw_part(&part, &mut bpart);
                    stdout.write_char(NL).unwrap();
                    cursors_left(part.len() + 1);
                }
            },
            Ok(ESC) => handle_escape(&mut stdin, &mut line,
                                     &mut word, &mut part,
                                     &mut bpart),
            Ok(SPC) => {
                line.push(word.clone());
                word.clear();
                stdout.write_char(SPC).unwrap();
                idraw_part(&part, &mut bpart);
            },
            Ok(c) => {
                word.push(c);
                stdout.write_char(c).unwrap();
                idraw_part(&part, &mut bpart);
            },
            Err(e) => {
                stdout.write_fmt(format_args!("Error: {}\n", e)).unwrap();
                break;
            }
        }
        // flush output
        stdout.flush().unwrap();
    }
    stdout.write_str("Exiting\n").unwrap();
    // restore old term state
    update_terminal(old_tios);
}
<commit_msg>Improve printing some more<commit_after>#![feature(globs)]
extern crate libc;

use libc::{c_int, size_t};
use std::io;
use std::ptr;
use std::io::process::{Command, StdioContainer};

use termios::*;
use signal::*;
use constants::*;

mod termios;
mod signal;
mod constants;

type Stdr = io::stdio::StdinReader;
type Stdw = io::LineBufferedWriter<io::stdio::StdWriter>;

#[allow(unused_variables)]
extern fn handle_sigint(signum:c_int, siginfo:*const SigInfo, context:size_t) {
    print!("^C");
    io::stdio::flush();
}

fn prepare_terminal(tios:&mut Termios) {
    tios.ldisable(ICANON);
    tios.ldisable(ECHO);
}

fn update_terminal(tios:Termios, stderr:&mut Stdw) -> bool {
    if !tios.set() {
        stderr.write_str("Warning: Could not set terminal mode\n").unwrap();
        return false;
    }
    return true;
}

fn handle_escape(stdin:&mut Stdr, stdout:&mut Stdw,
                 line:&mut Vec<String>, word:&mut String,
                 part:&mut String, bpart:&mut String) {
    // Handle an ANSI escape sequence
    if stdin.read_char() != Ok(ANSI) {
        return;
    }
    match stdin.read_char() {
        Err(_) => return,
        Ok('D') => {
            // left
            match word.pop() {
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    part.push(c);
                    cursor_left(stdout);
                },
                None => match line.pop() {
                    Some(s) => {
                        part.push(' ');
                        word.clear();
                        word.push_str(s.as_slice());
                        cursor_left(stdout);
                    }
                    None => return
                }
            }
        },
        Ok('C') => {
            // right
            match part.pop() {
                Some(' ') => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    line.push(word.clone());
                    word.clear();
                    cursor_right(stdout);
                },
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    word.push(c);
                    cursor_right(stdout);
                },
                None => return
            }
        },
        Ok(_) => return
    }
}

fn build_string(ch:char, count:uint) -> String {
    let mut s = String::new();
    let mut i = 0u;
    loop {
        if i == count {
            return s;
        }
        i += 1;
        s.push(ch);
    }
}

fn cursor_left(stdout:&mut Stdw) {
    stdout.write_char(DEL).unwrap();
}

fn cursor_right(stdout:&mut Stdw) {
    stdout.write(&[ESC as u8, ANSI as u8, 'C' as u8]).unwrap();
}

fn draw_part(part:&String, bpart:&mut String) {
    // quick out if part is empty
    if part.is_empty() {
        return;
    }
    if bpart.is_empty() {
        // only calculate bpart when it needs to be recalculated
        let mut cpart = part.clone();
        loop {
            match cpart.pop() {
                Some(c) => bpart.push(c),
                None => break
            }
        }
    }
    print!("{}", bpart);
}

fn cursors_left(by:uint) {
    // move back by a given number of characters
    print!("{}", build_string(DEL, by));
}

fn idraw_part(part:&String, bpart:&mut String) {
    // in-place draw of the line part
    draw_part(part, bpart);
    cursors_left(part.len());
}

fn prepare_signals(stderr:&mut Stdw) {
    let mut sa = SigAction {
        handler: handle_sigint,
        mask: [0; SIGSET_NWORDS],
        flags: SA_RESTART | SA_SIGINFO
    };
    unsafe {
        if sigfillset(&mut sa.mask) != 0 {
            stderr.write_str("Warning: could not fill mask set for SIGINT handler\n").unwrap();
        }
        if sigaction(SIGINT, &sa, ptr::null_mut::<SigAction>()) != 0 {
            stderr.write_str("Warning: could not set handler for SIGINT\n").unwrap();
        }
    }
}

fn run_command(line:&Vec<String>) {
    let mut process = Command::new(&line[0]);
    process.args(line.slice_from(1));
    process.stdout(StdioContainer::InheritFd(STDOUT));
    process.stdin(StdioContainer::InheritFd(STDIN));
    process.stderr(StdioContainer::InheritFd(STDERR));
    let mut child = match process.spawn() {
        Err(e) => {
            io::stderr().write_fmt(format_args!("Couldn't spawn {}: {}\n", &line[0], e)).unwrap();
            return;
        },
        Ok(child) => child
    };
    match child.wait() {
        Err(e) => {
            io::stderr().write_fmt(format_args!("Couldn't wait for child to exit: {}\n", e.desc)).unwrap();
        },
        Ok(_) => {
            // nothing
        }
    };
}

fn main() {
    let mut stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut stderr = io::stderr();
    prepare_signals(&mut stderr);
    let mut tios = Termios::new();
    tios.get();
    let old_tios = tios.clone();
    prepare_terminal(&mut tios);
    update_terminal(tios, &mut stderr);
    let mut line = Vec::<String>::new();
    let mut word = String::new();
    let mut part = String::new();
    // store bpart so we don't need to recalulate it every time
    let mut bpart = String::new();
    loop {
        // Note: in non-canonical mode
        match stdin.read_char() {
            Ok(EOF) => {
                if line.is_empty() && word.is_empty() {
                    break;
                }
            },
            Ok(NL) => {
                stdout.write_char(NL).unwrap();
                if !word.is_empty() {
                    line.push(word.clone());
                }
                if !line.is_empty() {
                    // run command
                    update_terminal(old_tios, &mut stderr);
                    run_command(&line);
                    update_terminal(tios, &mut stderr);
                }
                word.clear();
                line.clear();
                part.clear();
                bpart.clear();
            },
            Ok(DEL) => {
                if word.is_empty() {
                    word = match line.pop() {
                        Some(s) => s,
                        None => continue
                    };
                    cursor_left(&mut stdout);
                } else {
                    word.pop();
                    cursor_left(&mut stdout);
                    draw_part(&part, &mut bpart);
                    stdout.write_char(NL).unwrap();
                    cursors_left(part.len() + 1);
                }
            },
            Ok(ESC) => handle_escape(&mut stdin, &mut stdout,
                                     &mut line, &mut word,
                                     &mut part, &mut bpart),
            Ok(SPC) => {
                line.push(word.clone());
                word.clear();
                stdout.write_char(SPC).unwrap();
                idraw_part(&part, &mut bpart);
            },
            Ok(c) => {
                word.push(c);
                stdout.write_char(c).unwrap();
                idraw_part(&part, &mut bpart);
            },
            Err(e) => {
                stdout.write_fmt(format_args!("Error: {}\n", e)).unwrap();
                break;
            }
        }
        // flush output
        stdout.flush().unwrap();
    }
    stdout.write_str("Exiting\n").unwrap();
    // restore old term state
    update_terminal(old_tios, &mut stderr);
}
<|endoftext|>


<commit_before>
fn main() {
    if let Err(e) = sonde::run() {
        println!("error: {}", e);

        let mut err = &*e;

        while let Some(cause) = err.source() {
            println!("caused by: {}", cause);

            err = cause;
        }

        ::std::process::exit(1);
    }
}
<commit_msg>Fixe clippy lints format.<commit_after>fn main() {
    if let Err(e) = sonde::run() {
        println!("error: {}", e);

        let mut err = &*e;

        while let Some(cause) = err.source() {
            println!("caused by: {}", cause);

            err = cause;
        }

        ::std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>extern crate cgmath;
extern crate image;

use std::fs::File;

use cgmath::prelude::*;
use cgmath::vec3;

use camera::Camera;
use color::rgb;
use light::Light;
use material::Material;
use math::*;
use primitive::Primitive;
use raytracer::Raytracer;
use scene::Scene;

mod camera;
mod color;
mod intersection;
mod light;
mod material;
mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;
mod texture;

fn main() {
    let mut scene = Scene::new(vec3(0.05, 0.05, 0.10).into());

    scene.add_primitive(Primitive::plane(Material::solid(rgb(1.0, 1.0, 1.0), 1.0),
                                         vec3(0.0, -1.0, 0.0),
                                         Vector::unit_y()));
    scene.add_primitive(Primitive::sphere(Material::solid(rgb(1.0, 0.0, 0.0), 1.0),
                                          vec3(0.0, 0.0, 2.0),
                                          1.0));

    scene.add_light(Light::point(vec3(1.5, 1.5, 1.5).into(), vec3(0.0, 1.0, 0.5)));

    let raytracer = Raytracer {
        scene: scene,
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0f32.to_radians()),
    };

    let size = (512, 512);
    let mut buffer = image::ImageBuffer::new(size.0, size.1);
    for (x, y, pixel) in buffer.enumerate_pixels_mut() {
        let screen_coords = (x as f32 / size.0 as f32, y as f32 / size.1 as f32);
        let ray = raytracer.camera.primary_ray(screen_coords);
        let result = raytracer.trace(ray, 1);

        // assert!({
        //             let v: Vector = result.color.into();
        //             v.x >= 0.0 && v.y >= 0.0 && v.z >= 0.0
        //         },
        //         "{:?}",
        //         result.color);
        *pixel = result.color.into_pixel();
    }

    // TODO: add command line options to configure this.
    let mut output = File::create("output.png").expect("Couldn't create output file.");
    image::ImageRgb8(buffer).save(&mut output, image::PNG).expect("Couldn't write to output file.");
}
<commit_msg>Remove commented out code<commit_after>extern crate cgmath;
extern crate image;

use std::fs::File;

use cgmath::prelude::*;
use cgmath::vec3;

use camera::Camera;
use color::rgb;
use light::Light;
use material::Material;
use math::*;
use primitive::Primitive;
use raytracer::Raytracer;
use scene::Scene;

mod camera;
mod color;
mod intersection;
mod light;
mod material;
mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;
mod texture;

fn main() {
    let mut scene = Scene::new(vec3(0.05, 0.05, 0.10).into());

    scene.add_primitive(Primitive::plane(Material::solid(rgb(1.0, 1.0, 1.0), 1.0),
                                         vec3(0.0, -1.0, 0.0),
                                         Vector::unit_y()));
    scene.add_primitive(Primitive::sphere(Material::solid(rgb(1.0, 0.0, 0.0), 1.0),
                                          vec3(0.0, 0.0, 2.0),
                                          1.0));

    scene.add_light(Light::point(vec3(1.5, 1.5, 1.5).into(), vec3(0.0, 1.0, 0.5)));

    let raytracer = Raytracer {
        scene: scene,
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0f32.to_radians()),
    };

    let size = (512, 512);
    let mut buffer = image::ImageBuffer::new(size.0, size.1);
    for (x, y, pixel) in buffer.enumerate_pixels_mut() {
        let screen_coords = (x as f32 / size.0 as f32, y as f32 / size.1 as f32);
        let ray = raytracer.camera.primary_ray(screen_coords);
        let result = raytracer.trace(ray, 1);

        *pixel = result.color.into_pixel();
    }

    // TODO: add command line options to configure this.
    let mut output = File::create("output.png").expect("Couldn't create output file.");
    image::ImageRgb8(buffer).save(&mut output, image::PNG).expect("Couldn't write to output file.");
}
<|endoftext|>


<commit_before>// Copyright © 2016 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use std::collections::Bound;
use std::collections::range::RangeArgument;
use std::convert::AsRef;
use std::error::Error;
use std::fs::File;
use std::io::{BufReader, Cursor, Read};
use byteorder::{LittleEndian, ReadBytesExt};

#[derive(Debug)]
pub enum LoadError {
    Read,
    Range,
}

fn in_range<T>(x: T, range: &RangeArgument<T>) -> bool
    where T: PartialOrd + Copy
{
    match range.start() {
        Bound::Included(&s) => {
            if x < s {
                return false;
            }
        }
        Bound::Excluded(&s) => {
            if x <= s {
                return false;
            }
        }
        Bound::Unbounded => (),
    }

    match range.end() {
        Bound::Included(&e) => {
            if x > e {
                return false;
            }
        }
        Bound::Excluded(&e) => {
            if x >= e {
                return false;
            }
        }
        Bound::Unbounded => (),
    }

    true
}

pub trait Load: ReadBytesExt {
    fn load_u8(&mut self, range: Option<&RangeArgument<u8>>) -> Result<u8, LoadError> {
        let x = match ReadBytesExt::read_u8(self) {
            Ok(x) => x,
            Err(_) => return Err(LoadError::Read),
        };

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_u16le(&mut self, range: Option<&RangeArgument<u16>>) -> Result<u16, LoadError> {
        let x = match ReadBytesExt::read_u16::<LittleEndian>(self) {
            Ok(x) => x,
            Err(_) => return Err(LoadError::Read),
        };

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_i16le(&mut self, range: Option<&RangeArgument<i16>>) -> Result<i16, LoadError> {
        let x = match ReadBytesExt::read_i16::<LittleEndian>(self) {
            Ok(x) => x,
            Err(_) => return Err(LoadError::Read),
        };

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_u32le(&mut self, range: Option<&RangeArgument<u32>>) -> Result<u32, LoadError> {
        let x = match ReadBytesExt::read_u32::<LittleEndian>(self) {
            Ok(x) => x,
            Err(_) => return Err(LoadError::Read),
        };

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_i32le(&mut self, range: Option<&RangeArgument<i32>>) -> Result<i32, LoadError> {
        let x = match ReadBytesExt::read_i32::<LittleEndian>(self) {
            Ok(x) => x,
            Err(_) => return Err(LoadError::Read),
        };

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_f32le(&mut self, range: Option<&RangeArgument<f32>>) -> Result<f32, LoadError> {
        let x = match ReadBytesExt::read_f32::<LittleEndian>(self) {
            Ok(x) => x,
            Err(_) => return Err(LoadError::Read),
        };

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }
}

impl<R> Load for BufReader<R> where R: Read {}
impl<T> Load for Cursor<T> where T: AsRef<[u8]> {}
impl Load for File {}
impl<'a> Load for &'a [u8] {}
<commit_msg>Implement Error for LoadError<commit_after>// Copyright © 2016 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use std::collections::Bound;
use std::collections::range::RangeArgument;
use std::convert::{AsRef, From};
use std::error::Error;
use std::fmt;
use std::fs::File;
use std::io::{BufReader, Cursor, Error as IoError, Read};
use byteorder::{LittleEndian, ReadBytesExt};

#[derive(Debug)]
pub enum LoadError {
    Io(IoError),
    Range,
}

impl fmt::Display for LoadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LoadError::Io(ref err) => write!(f, "I/O error: {}", err),
            LoadError::Range => write!(f, "Range error"),
        }
    }
}

impl Error for LoadError {
    fn description(&self) -> &str {
        match *self {
            LoadError::Io(ref err) => err.description(),
            LoadError::Range => "Value out of valid range",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            LoadError::Io(ref err) => Some(err),
            LoadError::Range => None,
        }
    }
}

impl From<IoError> for LoadError {
    fn from(err: IoError) -> Self {
        LoadError::Io(err)
    }
}

fn in_range<T>(x: T, range: &RangeArgument<T>) -> bool
    where T: PartialOrd + Copy
{
    match range.start() {
        Bound::Included(&s) => {
            if x < s {
                return false;
            }
        }
        Bound::Excluded(&s) => {
            if x <= s {
                return false;
            }
        }
        Bound::Unbounded => (),
    }

    match range.end() {
        Bound::Included(&e) => {
            if x > e {
                return false;
            }
        }
        Bound::Excluded(&e) => {
            if x >= e {
                return false;
            }
        }
        Bound::Unbounded => (),
    }

    true
}

pub trait Load: ReadBytesExt {
    fn load_u8(&mut self, range: Option<&RangeArgument<u8>>) -> Result<u8, LoadError> {
        let x = ReadBytesExt::read_u8(self)?;
        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_u16le(&mut self, range: Option<&RangeArgument<u16>>) -> Result<u16, LoadError> {
        let x = ReadBytesExt::read_u16::<LittleEndian>(self)?;

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_i16le(&mut self, range: Option<&RangeArgument<i16>>) -> Result<i16, LoadError> {
        let x = ReadBytesExt::read_i16::<LittleEndian>(self)?;

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_u32le(&mut self, range: Option<&RangeArgument<u32>>) -> Result<u32, LoadError> {
        let x = ReadBytesExt::read_u32::<LittleEndian>(self)?;

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_i32le(&mut self, range: Option<&RangeArgument<i32>>) -> Result<i32, LoadError> {
        let x = ReadBytesExt::read_i32::<LittleEndian>(self)?;

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }

    fn load_f32le(&mut self, range: Option<&RangeArgument<f32>>) -> Result<f32, LoadError> {
        let x = ReadBytesExt::read_f32::<LittleEndian>(self)?;

        if let Some(r) = range {
            if !in_range(x, r) {
                return Err(LoadError::Range);
            }
        }

        Ok(x)
    }
}

impl<R> Load for BufReader<R> where R: Read {}
impl<T> Load for Cursor<T> where T: AsRef<[u8]> {}
impl Load for File {}
impl<'a> Load for &'a [u8] {}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"] // error_chain

extern crate websocket;
extern crate env_logger;
#[macro_use]
extern crate log;
#[macro_use]
extern crate error_chain;
extern crate url;
extern crate clap;

use std::thread;
use std::io::{stdin,stdout};

use websocket::{Message, Sender, Receiver, DataFrame};
use websocket::message::Type;
use websocket::client::request::Url;
use websocket::Client;

use std::borrow::Borrow;
use std::io::{Error as IoError, ErrorKind as IoErrorKind, Write, Read};

error_chain! {
    foreign_links {
        Io(::std::io::Error);
        Log(log::SetLoggerError);
        Url(::url::ParseError);
        Ws(::websocket::result::WebSocketError);
        VarError(::std::env::VarError);
        RE(std::sync::mpsc::RecvError);
    }
}

// Initialize logger with default "info" log level:
fn init_logger() -> Result<()> {
    let mut builder = env_logger::LogBuilder::new();
    builder.filter(None, log::LogLevelFilter::Info);
    if ::std::env::var("RUST_LOG").is_ok() {
       builder.parse(&::std::env::var("RUST_LOG")?);
    }
    builder.init()?;
    Ok(())
}

struct SenderWrapper<T: Sender> (T);

impl<T: Sender> ::std::io::Write for SenderWrapper<T> {
    fn write(&mut self, buf: &[u8]) -> ::std::io::Result<usize> {
        let message = Message::binary(buf);
        let ret;
        let len = buf.len();
        if len > 0 {
            debug!("Sending message of {} bytes", len);
            ret = self.0.send_message(&message);
        } else {
            // Interpret zero length buffer is request
            // to close communication

            debug!("Sending the closing message");
            ret = self.0.send_message(&Message::close());
        }
        ret.map_err(|e|IoError::new(IoErrorKind::BrokenPipe, e))?;
        Ok(len)
    }
    fn flush(&mut self) -> ::std::io::Result<()> {
        Ok(())
    }
}

struct ReceiverWrapper<T: Receiver<DataFrame>> (T);

impl<T:Receiver<DataFrame>> ::std::io::Read for ReceiverWrapper<T> {
    fn read(&mut self, buf: &mut [u8]) -> ::std::io::Result<usize> {
        let ret = self.0.recv_message();
        let msg : Message = ret.map_err(|e|IoError::new(IoErrorKind::BrokenPipe, e))?;

        match msg.opcode {
            Type::Close => {
                Ok(0)
            }
            Type::Ping => {
                // Sender used to be in a separate thread with a channel
                // now there's no channel, so trickier to combine ping replies
                // and usual data exchange
                unimplemented!();
            }
            _ => {
                let msgpayload : &[u8] = msg.payload.borrow();
                let len = msgpayload.len();
                debug!("Received message of {} bytes", len);

                assert!(buf.len() >= len);

                buf[0..len].copy_from_slice(msgpayload);

                Ok(len)
            }
        }
    }
}

struct Peer<R, W>
    where R : Read + Send + 'static, W: Write + Send + 'static
{
    reader: R,
    writer: W,
}

struct DataExchangeSession<R1, R2, W1, W2>
    where R1 : Read  + Send + 'static,
          R2 : Read  + Send + 'static,
          W1 : Write + Send + 'static,
          W2 : Write + Send + 'static,
{
    peer1: Peer<R1, W1>,
    peer2: Peer<R2, W2>,
}

impl<R1,R2,W1,W2> DataExchangeSession<R1,R2,W1,W2>
    where R1 : Read  + Send + 'static,
          R2 : Read  + Send + 'static,
          W1 : Write + Send + 'static,
          W2 : Write + Send + 'static,
{
    fn data_exchange(self) -> Result<()> {

        let mut reader1 = self.peer1.reader;
        let mut writer1 = self.peer1.writer;
        let mut reader2 = self.peer2.reader;
        let mut writer2 = self.peer2.writer;

        let receive_loop = thread::spawn(move || -> Result<()> {
            // Actual data transfer happens here
            ::std::io::copy(&mut reader1, &mut writer2)?;
            writer2.write(b"")?; // signal close
            Ok(())
        });

        // Actual data transfer happens here
        ::std::io::copy(&mut reader2, &mut writer1)?;
        writer1.write(b"")?; // Signal close

        info!("Waiting for child threads to exit");

        receive_loop.join().map_err(|x|format!("{:?}",x))?
    }
}

fn get_websocket_peer(urlstr: &str) -> Result<
        Peer<
            ReceiverWrapper<websocket::client::Receiver<websocket::WebSocketStream>>,
            SenderWrapper<websocket::client::Sender<websocket::WebSocketStream>>>
        > {
    let url = Url::parse(urlstr)?;

    info!("Connecting to {}", url);

    let request = Client::connect(url)?;

    let response = request.send()?; // Send the request and retrieve a response

    info!("Validating response...");

    response.validate()?; // Validate the response

    info!("Successfully connected");

    let (sender, receiver) = response.begin().split();

    let peer = Peer {
        reader : ReceiverWrapper(receiver),
        writer : SenderWrapper(sender),
    };
    Ok(peer)
}

fn get_stdio_peer() -> Result<Peer<std::io::Stdin, std::io::Stdout>> {
    Ok(
        Peer {
            reader : stdin(),
            writer : stdout(),
        }
    )
}

fn try_main() -> Result<()> {
    //env_logger::init()?;
    init_logger()?;

    // setup command line arguments
    let matches = ::clap::App::new("WS Command Line Client")
        .version("0.1")
        .author("Vitaly \"_Vi\" Shukela <vi0oss@gmail.com>")
        .about("Send binary data from stdin to a WebSocket and back to stdout.")
        .arg(::clap::Arg::with_name("URL")
             .help("The URL of the WebSocket server.")
             .required(true)
             .index(1)).get_matches();

    let url = matches.value_of("URL").ok_or("no URL")?;
    let wspeer = get_websocket_peer(url)?;
    let stdiopeer = get_stdio_peer()?;

    let des = DataExchangeSession {
        peer1 : wspeer,
        peer2 : stdiopeer,
    };

    des.data_exchange()?;

    info!("Exited");
    Ok(())
}

fn main() {
    if let Err(x) = try_main() {
        let _ = writeln!(::std::io::stderr(), "{:?}", x);
    }
}

<commit_msg>Indirection<commit_after>#![recursion_limit = "1024"] // error_chain

extern crate websocket;
extern crate env_logger;
#[macro_use]
extern crate log;
#[macro_use]
extern crate error_chain;
extern crate url;
extern crate clap;

use std::thread;
use std::io::{stdin,stdout};

use websocket::{Message, Sender, Receiver, DataFrame};
use websocket::message::Type;
use websocket::client::request::Url;
use websocket::Client;

use std::borrow::Borrow;
use std::io::{Error as IoError, ErrorKind as IoErrorKind, Write, Read};

error_chain! {
    foreign_links {
        Io(::std::io::Error);
        Log(log::SetLoggerError);
        Url(::url::ParseError);
        Ws(::websocket::result::WebSocketError);
        VarError(::std::env::VarError);
        RE(std::sync::mpsc::RecvError);
    }
    errors {
        InvalidSpecifier(t : String) {
            description("invalid specifier")
            display("Invalid client or server specifier `{}`", t)
        }
    }
}

// Initialize logger with default "info" log level:
fn init_logger() -> Result<()> {
    let mut builder = env_logger::LogBuilder::new();
    builder.filter(None, log::LogLevelFilter::Info);
    if ::std::env::var("RUST_LOG").is_ok() {
       builder.parse(&::std::env::var("RUST_LOG")?);
    }
    builder.init()?;
    Ok(())
}

struct SenderWrapper<T: Sender> (T);

impl<T: Sender> ::std::io::Write for SenderWrapper<T> {
    fn write(&mut self, buf: &[u8]) -> ::std::io::Result<usize> {
        let message = Message::binary(buf);
        let ret;
        let len = buf.len();
        if len > 0 {
            debug!("Sending message of {} bytes", len);
            ret = self.0.send_message(&message);
        } else {
            // Interpret zero length buffer is request
            // to close communication

            debug!("Sending the closing message");
            ret = self.0.send_message(&Message::close());
        }
        ret.map_err(|e|IoError::new(IoErrorKind::BrokenPipe, e))?;
        Ok(len)
    }
    fn flush(&mut self) -> ::std::io::Result<()> {
        Ok(())
    }
}

struct ReceiverWrapper<T: Receiver<DataFrame>> (T);

impl<T:Receiver<DataFrame>> ::std::io::Read for ReceiverWrapper<T> {
    fn read(&mut self, buf: &mut [u8]) -> ::std::io::Result<usize> {
        let ret = self.0.recv_message();
        let msg : Message = ret.map_err(|e|IoError::new(IoErrorKind::BrokenPipe, e))?;

        match msg.opcode {
            Type::Close => {
                Ok(0)
            }
            Type::Ping => {
                // Sender used to be in a separate thread with a channel
                // now there's no channel, so trickier to combine ping replies
                // and usual data exchange
                unimplemented!();
            }
            _ => {
                let msgpayload : &[u8] = msg.payload.borrow();
                let len = msgpayload.len();
                debug!("Received message of {} bytes", len);

                assert!(buf.len() >= len);

                buf[0..len].copy_from_slice(msgpayload);

                Ok(len)
            }
        }
    }
}

struct Peer<R, W>
    where R : Read + Send + 'static, W: Write + Send + 'static
{
    reader: R,
    writer: W,
}

type IPeer = Peer<Box<Read+Send>, Box<Write+Send>>;

struct DataExchangeSession<R1, R2, W1, W2>
    where R1 : Read  + Send + 'static,
          R2 : Read  + Send + 'static,
          W1 : Write + Send + 'static,
          W2 : Write + Send + 'static,
{
    peer1: Peer<R1, W1>,
    peer2: Peer<R2, W2>,
}

impl<R1,R2,W1,W2> DataExchangeSession<R1,R2,W1,W2>
    where R1 : Read  + Send + 'static,
          R2 : Read  + Send + 'static,
          W1 : Write + Send + 'static,
          W2 : Write + Send + 'static,
{
    fn data_exchange(self) -> Result<()> {

        let mut reader1 = self.peer1.reader;
        let mut writer1 = self.peer1.writer;
        let mut reader2 = self.peer2.reader;
        let mut writer2 = self.peer2.writer;

        let receive_loop = thread::spawn(move || -> Result<()> {
            // Actual data transfer happens here
            ::std::io::copy(&mut reader1, &mut writer2)?;
            writer2.write(b"")?; // signal close
            Ok(())
        });

        // Actual data transfer happens here
        ::std::io::copy(&mut reader2, &mut writer1)?;
        writer1.write(b"")?; // Signal close

        debug!("Waiting for receiver side to exit");

        receive_loop.join().map_err(|x|format!("{:?}",x))?
    }
}

fn get_websocket_peer(urlstr: &str) -> Result<
        Peer<
            ReceiverWrapper<websocket::client::Receiver<websocket::WebSocketStream>>,
            SenderWrapper<websocket::client::Sender<websocket::WebSocketStream>>>
        > {
    let url = Url::parse(urlstr)?;

    info!("Connecting to {}", url);

    let request = Client::connect(url)?;

    let response = request.send()?; // Send the request and retrieve a response

    info!("Validating response...");

    response.validate()?; // Validate the response

    info!("Successfully connected");

    let (sender, receiver) = response.begin().split();

    let peer = Peer {
        reader : ReceiverWrapper(receiver),
        writer : SenderWrapper(sender),
    };
    Ok(peer)
}

fn get_stdio_peer() -> Result<Peer<std::io::Stdin, std::io::Stdout>> {
    Ok(
        Peer {
            reader : stdin(),
            writer : stdout(),
        }
    )
}

impl<R,W> Peer<R,W>
    where R : Read + Send + 'static, W: Write + Send + 'static
{
    fn upcast(self) -> IPeer  {
        Peer {
            reader: Box::new(self.reader) as Box<Read +Send>,
            writer: Box::new(self.writer) as Box<Write+Send>,
        }
    }
}

fn get_peer_by_spec(specifier: &str, server: bool) -> Result<IPeer> {
    let _ = server;
    match specifier {
        x if x == "-"             => Ok(get_stdio_peer()?.upcast()),
        x if x.starts_with("ws:") => Ok(get_websocket_peer(x)?.upcast()),
        x => Err(ErrorKind::InvalidSpecifier(x.to_string()).into()),
    }
}

fn try_main() -> Result<()> {
    //env_logger::init()?;
    init_logger()?;

    // setup command line arguments
    let matches = ::clap::App::new("WS Command Line Client")
        .version("0.1")
        .author("Vitaly \"_Vi\" Shukela <vi0oss@gmail.com>")
        .about("Send binary data from stdin to a WebSocket and back to stdout.")
        .arg(::clap::Arg::with_name("listener_spec")
             .help("Listener specifier.")
             .required(true)
             .index(1))
        .arg(::clap::Arg::with_name("connector_spec")
             .help("Connector specifier.")
             .required(true)
             .index(2))
        .get_matches();

    let listener_spec  = matches.value_of("listener_spec") .ok_or("no listener_spec" )?;
    let connector_spec = matches.value_of("connector_spec").ok_or("no connector_spec")?;

    let des = DataExchangeSession {
        peer1 : get_peer_by_spec(listener_spec,  true )?,
        peer2 : get_peer_by_spec(connector_spec, false)?,
    };

    des.data_exchange()?;

    debug!("Exited");
    Ok(())
}

fn main() {
    if let Err(x) = try_main() {
        let _ = writeln!(::std::io::stderr(), "{:?}", x);
    }
}

<|endoftext|>


<commit_before>extern crate hyper;

use std::io::Read;
use hyper::Client;
use hyper::header::Connection;

static WEEKDAY_WEBSITE: &'static str = "http://www.hvilkenukeerdet.no";

fn main() {
    let client = Client::new();

    let mut res = client
                    .get(WEEKDAY_WEBSITE)
                    .header(Connection::close())
                    .send().unwrap();

    let mut body = String::new();
    res.read_to_string(&mut body).unwrap();

    let parse: Vec<&str> = body
                            .rsplitn(2, "<body>")
                            .collect();

    let week_number: Vec<&str> = parse[0].matches(char::is_numeric).collect();

    if week_number.len() > 1 {
        println!("{}{}", week_number[0], week_number[1]);
    } else {
        println!("{}", week_number[0]);
    }
}
<commit_msg>Simplify parsing of web page<commit_after>extern crate hyper;

use std::io::Read;
use hyper::Client;
use hyper::header::Connection;

static WEEKDAY_WEBSITE: &'static str = "http://www.hvilkenukeerdet.no";

fn main() {
    let client = Client::new();

    let mut res = client
                    .get(WEEKDAY_WEBSITE)
                    .header(Connection::close())
                    .send()
                    .unwrap();

    let mut body = String::new();
    res.read_to_string(&mut body).unwrap();

    let body_index = body.find("<body>\n").unwrap() + "<body>\n".len();
    let break_index = body.find("<br />").unwrap();

    let week_number = &body[body_index..break_index];
    println!("{}", week_number);
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate schemamama;
extern crate schemamama_postgres;
extern crate postgres;
mod schema;

#[macro_use]
extern crate log;
extern crate log4rs;

extern crate iron;
extern crate router;
extern crate logger;

use iron::prelude::*;
use iron::status;
use router::Router;
use logger::Logger;
use std::io::Read;
use iron::modifiers::Redirect;

use std::env;
use std::ops::Deref;

extern crate uuid;
use uuid::Uuid;
extern crate serde_json;
use serde_json::Value;

extern crate r2d2;
extern crate r2d2_postgres;
extern crate persistent;
use persistent::Read as PRead;

#[macro_use]mod db;
#[macro_use]mod server_id;

use std::error::Error;
use std::fmt::{self, Debug};
#[derive(Debug)]
struct StringError(String);

impl Error for StringError {
    fn description(&self) -> &str {
        &*self.0
    }
}

impl fmt::Display for StringError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self, f)
    }
}

struct Log {
    id: Uuid,
    owner: Uuid,
    next: Option<Uuid>,
    prev: Option<Uuid>,
    data: Value,
}

fn log_status(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "Hello World!")))
}

fn new_log(req: &mut Request) -> IronResult<Response> {
    let conn = get_pg_connection!(&req);
    let body_string = {
        let mut body = String::new();
        req.body.read_to_string(&mut body).expect("could read from body");
        body
    };
    let json: Value = match serde_json::de::from_str(&body_string) {
        Ok(val) => val,
        Err(err) => return Err(IronError::new(err, (status::BadRequest, "Bad JSON"))),
    };
    let id = Uuid::new_v4();
    let hyphenated = id.hyphenated().to_string();
    let server_id = get_server_id!(&req);
    conn.execute("INSERT INTO log (id, owner, data) VALUES ($1, $2, $3)",
                 &[&id, server_id.deref(), &json])
        .expect("insert worked");
    let new_url = {
        let req_url = req.url.clone();
        let base_url = req_url.into_generic_url();
        base_url.join(&format!("/log/{}", &hyphenated)).expect("join url works")
    };
    Ok(Response::with((status::Found,
                       Redirect(iron::Url::from_generic_url(new_url).expect("URL parsed ok")))))
}

fn get_log(req: &mut Request) -> IronResult<Response> {
    let ref query = req.extensions
        .get::<Router>()
        .unwrap()
        .find("entry_id")
        .unwrap_or("/");
    let conn = get_pg_connection!(&req);
    let stmt = conn.prepare("SELECT data from log").unwrap();
    let results = stmt.query(&[]).unwrap();
    if results.is_empty() {
        Ok(Response::with((status::NotFound, format!("No log {}", query))))
    } else {
        Ok(Response::with((status::Ok, format!("Get log {}", query))))
    }
}

fn main() {
    log4rs::init_file("log.yaml", Default::default()).unwrap();
    let db_url: &str = &env::var("DATABASE_URL").expect("Needed DATABASE_URL");
    let pool = db::get_pool(db_url);
    let conn = pool.get().unwrap();
    schema::up(&conn).unwrap();
    let (logger_before, logger_after) = Logger::new(None);
    let mut router = Router::new();
    router.get("/log", log_status);
    router.post("/log", new_log);
    router.get("/log/:entry_id", get_log);
    let mut chain = Chain::new(router);
    chain.link_before(logger_before);
    chain.link_after(logger_after);
    chain.link_before(PRead::<server_id::ServerId>::one(server_id::setup()));
    chain.link(PRead::<db::PostgresDB>::both(pool));
    Iron::new(chain).http("localhost:8000").unwrap();
}
<commit_msg>Return real data on GET<commit_after>#[macro_use]
extern crate schemamama;
extern crate schemamama_postgres;
extern crate postgres;
mod schema;

#[macro_use]
extern crate log;
extern crate log4rs;

extern crate iron;
extern crate router;
extern crate logger;

use iron::prelude::*;
use iron::status;
use router::Router;
use logger::Logger;
use std::io::Read;
use iron::modifiers::Redirect;

use std::env;
use std::ops::Deref;

extern crate uuid;
use uuid::Uuid;
extern crate serde_json;
use serde_json::Value;

extern crate r2d2;
extern crate r2d2_postgres;
extern crate persistent;
use persistent::Read as PRead;

#[macro_use]mod db;
#[macro_use]mod server_id;

use std::error::Error;
use std::fmt::{self, Debug};
#[derive(Debug)]
struct StringError(String);

impl Error for StringError {
    fn description(&self) -> &str {
        &*self.0
    }
}

impl fmt::Display for StringError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self, f)
    }
}

struct Log {
    id: Uuid,
    owner: Uuid,
    next: Option<Uuid>,
    prev: Option<Uuid>,
    data: Value,
}

fn log_status(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "Hello World!")))
}

fn new_log(req: &mut Request) -> IronResult<Response> {
    let conn = get_pg_connection!(&req);
    let body_string = {
        let mut body = String::new();
        req.body.read_to_string(&mut body).expect("could read from body");
        body
    };
    let json: Value = match serde_json::de::from_str(&body_string) {
        Ok(val) => val,
        Err(err) => return Err(IronError::new(err, (status::BadRequest, "Bad JSON"))),
    };
    let id = Uuid::new_v4();
    let hyphenated = id.hyphenated().to_string();
    let server_id = get_server_id!(&req);
    conn.execute("INSERT INTO log (id, owner, data) VALUES ($1, $2, $3)",
                 &[&id, server_id.deref(), &json])
        .expect("insert worked");
    let new_url = {
        let req_url = req.url.clone();
        let base_url = req_url.into_generic_url();
        base_url.join(&format!("/log/{}", &hyphenated)).expect("join url works")
    };
    Ok(Response::with((status::Found,
                       Redirect(iron::Url::from_generic_url(new_url).expect("URL parsed ok")))))
}

fn get_log(req: &mut Request) -> IronResult<Response> {
    let ref query = req.extensions
        .get::<Router>()
        .unwrap()
        .find("entry_id")
        .unwrap_or("/");
    let query_id = Uuid::parse_str(&query).expect("Dodgy UUID");
    let conn = get_pg_connection!(&req);
    let stmt = conn.prepare("SELECT data from log where id=$1").expect("prepare failure");
    let results = stmt.query(&[&query_id]).expect("bad query");
    if results.is_empty() {
        Ok(Response::with((status::NotFound, format!("No log {}", query))))
    } else {
        let row = results.get(0);
        let data: Value = row.get("data");
        Ok(Response::with((status::Ok, serde_json::ser::to_string(&data).unwrap())))
    }
}

fn main() {
    log4rs::init_file("log.yaml", Default::default()).unwrap();
    let db_url: &str = &env::var("DATABASE_URL").expect("Needed DATABASE_URL");
    let pool = db::get_pool(db_url);
    let conn = pool.get().unwrap();
    schema::up(&conn).unwrap();
    let (logger_before, logger_after) = Logger::new(None);
    let mut router = Router::new();
    router.get("/log", log_status);
    router.post("/log", new_log);
    router.get("/log/:entry_id", get_log);
    let mut chain = Chain::new(router);
    chain.link_before(logger_before);
    chain.link_after(logger_after);
    chain.link_before(PRead::<server_id::ServerId>::one(server_id::setup()));
    chain.link(PRead::<db::PostgresDB>::both(pool));
    Iron::new(chain).http("localhost:8000").unwrap();
}
<|endoftext|>