<commit_before>extern crate iron;
extern crate router;
extern crate urlencoded;
extern crate redis;
extern crate image;
extern crate num;
extern crate time;

use std::io;
use time::precise_time_ns;
use iron::prelude::*;
use iron::{
    BeforeMiddleware,
    AfterMiddleware,
    typemap
};
use iron::mime::Mime;
use iron::status;
use iron::modifier::Modifier;
use iron::response;
use urlencoded::UrlEncodedQuery;
use router::Router;
use redis::Commands;
use image::{
    ImageBuffer,
};
use num::complex::Complex;

fn fetch_an_integer(key: &str, inc: bool) -> redis::RedisResult<i64> {
    // connect to redis
    let client = try!(redis::Client::open("redis://127.0.0.1/"));
    let con = try!(client.get_connection());
    if inc {
        let cur = con.get(key).unwrap_or(0i64);
        let _ : () = try!(con.set(key, cur+1));
    }
    con.get(key)
}

// from: https://github.com/iron/iron/blob/master/examples/time.rs
struct ResponseTime;

impl typemap::Key for ResponseTime { type Value = u64; }

impl BeforeMiddleware for ResponseTime {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<ResponseTime>(precise_time_ns());
        Ok(())
    }
}

impl AfterMiddleware for ResponseTime {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        let delta = precise_time_ns() - *req.extensions.get::<ResponseTime>().unwrap();
        println!("Request took: {} ms", (delta as f64) / 1000000.0);
        Ok(res)
    }
}

// ImgWriter writes a generated image out to the request
struct ImgWriter {
    img: ImageBuffer<image::Luma<u8>, Vec<u8>>
}

impl Modifier<Response> for ImgWriter {
    fn modify(self, res: &mut Response) {
        res.body = Some(Box::new(self));
    }
}

impl response::WriteBody for ImgWriter {
    fn write_body(&mut self, res: &mut response::ResponseBody) -> io::Result<()> {
        image::ImageLuma8(self.img.clone()).save(res, image::PNG)
            .map_err(|err| io::Error::new(io::ErrorKind::Other, err))
    }
}

fn main() {
	fn handler(_: &mut Request) -> IronResult<Response> {
        let content = "Peekaboo server";
        let content_type = "text/html".parse::<Mime>().unwrap();
		Ok(Response::with((content_type, status::Ok, content)))
	}

    fn peek_handler(r: &mut Request) -> IronResult<Response> {
        {
            let id = r.extensions.get::<Router>().unwrap().find("id").unwrap();
            let _ = fetch_an_integer(id, true).unwrap_or(0i64);
        }

        let mut img = ImageBuffer::new(512, 512);

        match r.get_ref::<UrlEncodedQuery>() {
            Ok(ref hashmap) => {
                match hashmap.get("t").map(|t| &t[0]) {
                    Some(t) => {
                        if t == "mandelbrot" {
                            apply_mandelbrot(&mut img, 500);
                        } else if t == "julia" {
                            apply_julia(&mut img, 500);
                        }
                    },
                    None => {
                        return Ok(Response::with((status::NotFound, "type not found")))
                    },
                }
            },
            Err(ref e) => {
                return Ok(Response::with((status::NotFound, format!("type parameter missing: {}", e))))
            }
        }

        let content_type = "image/png".parse::<Mime>().unwrap();
        Ok(Response::with((content_type, status::Ok, ImgWriter{img: img})))
    }

    fn peek_info_handler(r: &mut Request) -> IronResult<Response> {
        let id = r.extensions.get::<Router>().unwrap().find("id").unwrap();
        let val = fetch_an_integer(id, false).unwrap_or(0i64);

        Ok(Response::with((status::Ok, format!("'{}' has had {} visitors!", id, val))))
    }

    let mut peek_chain = Chain::new(peek_handler);
    peek_chain.link_before(ResponseTime);
    peek_chain.link_after(ResponseTime);

    let mut router = Router::new();
    router.get("/", handler);
    router.get("/peek/:id", peek_chain);
    router.get("/peek/:id/info", peek_info_handler);

	Iron::new(router).http("localhost:2829").unwrap();
}

fn apply_mandelbrot(img: &mut ImageBuffer<image::Luma<u8>, Vec<u8>>, max_iters: i64) {

    // from: https://en.wikipedia.org/wiki/Mandelbrot_set#Escape_time_algorithm

    let scalex = 3.5 / img.width() as f32;
    let scaley = 2.0 / img.height() as f32;

    for (x, y, pixel) in img.enumerate_pixels_mut() {

        let x0 = x as f32 * scalex - 2.5;
        let y0 = y as f32 * scaley - 1.0;

        let mut z = Complex::new(x0, y0);
        // let c = z.clone();

        let mut iters = 0;
        for _ in 0..max_iters {
            if z.norm() > 2.0 {
                break
            }
            let xt = z.re * z.re - z.im * z.im + x0;
            z.im = 2.0*z.re*z.im + y0;
            z.re = xt;

            // for some reason this is about 2x slower
            // z = z * z + c;

            iters += 1;
        }

        *pixel = image::Luma([iters as u8]);
    }
}

fn apply_julia(img: &mut ImageBuffer<image::Luma<u8>, Vec<u8>>, max_iters: i64) {

    // from: https://github.com/PistonDevelopers/image#62-generating-fractals

    let scalex = 4.0 / img.width() as f32;
    let scaley = 4.0 / img.height() as f32;

    for (x, y, pixel) in img.enumerate_pixels_mut() {

        let cy = y as f32 * scaley - 2.0;
        let cx = x as f32 * scalex - 2.0;

        let mut z = Complex::new(cx, cy);
        let c = Complex::new(-0.4, 0.6);

        let mut i = 0;

        for t in 0..max_iters {
            if z.norm() > 2.0 {
                break
            }
            z = z * z + c;
            i = t;
        }

        // Create an 8bit pixel of type Luma and value i
        // and assign in to the pixel at position (x, y)
        *pixel = image::Luma([i as u8]);
    }
}
<commit_msg>add default single pixel image response<commit_after>extern crate iron;
extern crate router;
extern crate urlencoded;
extern crate redis;
extern crate image;
extern crate num;
extern crate time;

use std::io;
use time::precise_time_ns;
use iron::prelude::*;
use iron::{
    BeforeMiddleware,
    AfterMiddleware,
    typemap
};
use iron::mime::Mime;
use iron::status;
use iron::modifier::Modifier;
use iron::response;
use urlencoded::UrlEncodedQuery;
use router::Router;
use redis::Commands;
use image::{
    ImageBuffer,
};
use num::complex::Complex;

fn fetch_an_integer(key: &str, inc: bool) -> redis::RedisResult<i64> {
    // connect to redis
    let client = try!(redis::Client::open("redis://127.0.0.1/"));
    let con = try!(client.get_connection());
    if inc {
        let cur = con.get(key).unwrap_or(0i64);
        let _ : () = try!(con.set(key, cur+1));
    }
    con.get(key)
}

// from: https://github.com/iron/iron/blob/master/examples/time.rs
struct ResponseTime;

impl typemap::Key for ResponseTime { type Value = u64; }

impl BeforeMiddleware for ResponseTime {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<ResponseTime>(precise_time_ns());
        Ok(())
    }
}

impl AfterMiddleware for ResponseTime {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        let delta = precise_time_ns() - *req.extensions.get::<ResponseTime>().unwrap();
        println!("Request took: {} ms", (delta as f64) / 1000000.0);
        Ok(res)
    }
}

// ImgWriter writes a generated image out to the request
struct ImgWriter {
    img: ImageBuffer<image::Luma<u8>, Vec<u8>>
}

impl Modifier<Response> for ImgWriter {
    fn modify(self, res: &mut Response) {
        res.body = Some(Box::new(self));
    }
}

impl response::WriteBody for ImgWriter {
    fn write_body(&mut self, res: &mut response::ResponseBody) -> io::Result<()> {
        image::ImageLuma8(self.img.clone()).save(res, image::PNG)
            .map_err(|err| io::Error::new(io::ErrorKind::Other, err))
    }
}

fn main() {
	fn handler(_: &mut Request) -> IronResult<Response> {
        let content = "Peekaboo server";
        let content_type = "text/html".parse::<Mime>().unwrap();
		Ok(Response::with((content_type, status::Ok, content)))
	}

    fn peek_handler(r: &mut Request) -> IronResult<Response> {
        {
            let id = r.extensions.get::<Router>().unwrap().find("id").unwrap();
            let _ = fetch_an_integer(id, true).unwrap_or(0i64);
        }

        let mut img = ImageBuffer::new(512, 512);
        let content_type = "image/png".parse::<Mime>().unwrap();

        match r.get_ref::<UrlEncodedQuery>() {
            Ok(ref hashmap) => {
                match hashmap.get("t").map(|t| &t[0]) {
                    Some(t) => {
                        if t == "mandelbrot" {
                            apply_mandelbrot(&mut img, 500);
                        } else if t == "julia" {
                            apply_julia(&mut img, 500);
                        }
                    },
                    None => {
                        return Ok(Response::with((status::NotFound, "type not found")))
                    },
                }
            },
            Err(urlencoded::UrlDecodingError::EmptyQuery) => {
                // turn the image white
                let mut img_sm = ImageBuffer::new(1, 1);
                apply_color(&mut img_sm, 255);
                return Ok(Response::with((content_type, status::Ok, ImgWriter{img: img_sm})))
            },
            Err(ref e) => {
                return Ok(Response::with((status::BadRequest, format!("invalid query: {}", e))))
            }
        }

        Ok(Response::with((content_type, status::Ok, ImgWriter{img: img})))
    }

    fn peek_info_handler(r: &mut Request) -> IronResult<Response> {
        let id = r.extensions.get::<Router>().unwrap().find("id").unwrap();
        let val = fetch_an_integer(id, false).unwrap_or(0i64);

        Ok(Response::with((status::Ok, format!("'{}' has had {} visitors!", id, val))))
    }

    let mut peek_chain = Chain::new(peek_handler);
    peek_chain.link_before(ResponseTime);
    peek_chain.link_after(ResponseTime);

    let mut router = Router::new();
    router.get("/", handler);
    router.get("/peek/:id", peek_chain);
    router.get("/peek/:id/info", peek_info_handler);

	Iron::new(router).http("localhost:2829").unwrap();
}

fn apply_color(img: &mut ImageBuffer<image::Luma<u8>, Vec<u8>>, value: u8) {
    for (_, _, pixel) in img.enumerate_pixels_mut() {
        *pixel = image::Luma([value]);
    }
}

fn apply_mandelbrot(img: &mut ImageBuffer<image::Luma<u8>, Vec<u8>>, max_iters: i64) {

    // from: https://en.wikipedia.org/wiki/Mandelbrot_set#Escape_time_algorithm

    let scalex = 3.5 / img.width() as f32;
    let scaley = 2.0 / img.height() as f32;

    for (x, y, pixel) in img.enumerate_pixels_mut() {

        let x0 = x as f32 * scalex - 2.5;
        let y0 = y as f32 * scaley - 1.0;

        let mut z = Complex::new(x0, y0);
        // let c = z.clone();

        let mut iters = 0;
        for _ in 0..max_iters {
            if z.norm() > 2.0 {
                break
            }
            let xt = z.re * z.re - z.im * z.im + x0;
            z.im = 2.0*z.re*z.im + y0;
            z.re = xt;

            // for some reason this is about 2x slower
            // z = z * z + c;

            iters += 1;
        }

        *pixel = image::Luma([iters as u8]);
    }
}

fn apply_julia(img: &mut ImageBuffer<image::Luma<u8>, Vec<u8>>, max_iters: i64) {

    // from: https://github.com/PistonDevelopers/image#62-generating-fractals

    let scalex = 4.0 / img.width() as f32;
    let scaley = 4.0 / img.height() as f32;

    for (x, y, pixel) in img.enumerate_pixels_mut() {

        let cy = y as f32 * scaley - 2.0;
        let cx = x as f32 * scalex - 2.0;

        let mut z = Complex::new(cx, cy);
        let c = Complex::new(-0.4, 0.6);

        let mut i = 0;

        for t in 0..max_iters {
            if z.norm() > 2.0 {
                break
            }
            z = z * z + c;
            i = t;
        }

        // Create an 8bit pixel of type Luma and value i
        // and assign in to the pixel at position (x, y)
        *pixel = image::Luma([i as u8]);
    }
}
<|endoftext|>


<commit_before>
#![feature(globs)]

extern crate graphics;
extern crate piston;
extern crate sdl2_game_window;
extern crate opengl_graphics;

use std::rc::Rc;

use opengl_graphics::{
    Gl,
    Texture,
};
use sdl2_game_window::WindowSDL2;
use graphics::*;
use piston::{
    AssetStore,
    EventIterator,
    EventSettings,
    WindowSettings,
    Render,
    Update,
    Input,
};
use piston::sprite::*;
use piston::input;
use piston::image;
use piston::image::{
    GenericImage,
};
use piston::event::{
    Action,
    Sequence,
    Wait,
};

fn get_window_size(asset_store: &AssetStore) -> (u32, u32) {
    let path = asset_store.path("img/bg_0.png").unwrap();
    image::open(&path).unwrap().dimensions()
}

fn main() {
    let asset_store = AssetStore::from_folder("../bin/assets");
    let (width, height) = get_window_size(&asset_store);
    let opengl = piston::shader_version::opengl::OpenGL_3_2;
    let mut window = WindowSDL2::new(
        opengl,
        WindowSettings {
            title: "Swing Copters (Rust Clone)".to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let mut main_scene = Scene::new();

    // load resources
    let bg_tex = Rc::new(Texture::from_path(&asset_store.path("img/bg_0.png").unwrap()).unwrap());
    let mut bg = Sprite::from_texture(bg_tex.clone());
    bg.set_anchor(0.0, 0.0);
    main_scene.add_child(bg);

    let cloud_tex = Rc::new(Texture::from_path(&asset_store.path("img/cloud_0.png").unwrap()).unwrap());
    let mut cloud = Sprite::from_texture(cloud_tex.clone());
    cloud.set_anchor(0.5, 0.0);
    cloud.set_position(width as f64 / 2.0, 0.0);
    main_scene.add_child(cloud);

    let land_tex = Rc::new(Texture::from_path(&asset_store.path("img/land.png").unwrap()).unwrap());
    let (_, land_tex_height) = land_tex.get_size();
    let mut land = Sprite::from_texture(land_tex.clone());
    land.set_anchor(0.0, 0.0);
    land.set_position(0.0, (height - land_tex_height) as f64);
    main_scene.add_child(land);

    let mut wheel_textures = Vec::new();
    for i in range(0i, 4) {
        let path = asset_store.path(format!("img/wheels_{}.png", i).as_slice()).unwrap();
        wheel_textures.push(Rc::new(Texture::from_path(&path).unwrap()));
    }
    let mut wheel_texture_index = 0.0;
    let ref wheel_tex = wheel_textures[wheel_texture_index as uint];
    let mut wheel = Sprite::from_texture(wheel_tex.clone());
    wheel.set_anchor(0.5, 0.3);

    let copter_tex = Rc::new(Texture::from_path(&asset_store.path("img/bear_0_0_0.png").unwrap()).unwrap());
    let mut copter = Sprite::from_texture(copter_tex.clone());
    copter.set_anchor(0.5, 0.3);
    copter.set_position(width as f64 / 2.0, height as f64 / 2.0);
    copter.set_rotation(10.0);

    let wheel_id = copter.add_child(wheel);
    let copter_id = main_scene.add_child(copter);

    // Test actions
    main_scene.run_action(copter_id, &Sequence(vec![
        Action(Ease(EaseQuadraticOut, box MoveBy(2.0, 0.0, -200.0))),
        //Action(MoveBy(2.0, 0.0, -200.0)),
        Action(Ease(EaseQuinticIn, box ScaleTo(2.0, 2.0, 2.0))),
        Action(Blink(2.0, 5)),
        Action(FlipX(true)),
        Wait(2.0),
        Action(FlipX(false)),
        Action(Ease(EaseQuadraticIn, box FadeOut(2.0))),
        Action(Ease(EaseQuinticOut, box FadeIn(2.0))),
    ]));
    let a = Action(Ease(EaseQuadraticInOut, box RotateTo(4.0, 180.0)));
    main_scene.run_action(copter_id, &a);

    main_scene.run_action(wheel_id, &Sequence(vec![
        Action(Hide),
        Wait(2.0),
        Action(Show),
    ]));

    let event_settings = EventSettings {
        updates_per_second: 120,
        max_frames_per_second: 60,
    };
    let ref mut gl = Gl::new(opengl);
    for e in EventIterator::new(&mut window, &event_settings) {
        main_scene.update(&e);
        match e {
            Render(args) => {
                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = Context::abs(args.width as f64, args.height as f64);

                main_scene.draw(&c, gl);
            },
            Update(args) => {
                wheel_texture_index = wheel_texture_index + args.dt * 20.0;
                let ref tex = wheel_textures[wheel_texture_index as uint % wheel_textures.len()];
                match main_scene.child_mut(wheel_id) {
                    Some(s) => s.set_texture(tex.clone()),
                    _ => {},
                }
            },
            Input(input::Press(_)) => {
                //main_scene.toggle_action(copter_id, &a);
                main_scene.remove_child(copter_id);
                println!("{}", main_scene.running_actions());
            },
            _ => {},
        }
    }
}

<commit_msg>Upgraded to latest piston-sprite<commit_after>
#![feature(globs)]

extern crate graphics;
extern crate piston;
extern crate sdl2_game_window;
extern crate opengl_graphics;

use std::rc::Rc;

use opengl_graphics::{
    Gl,
    Texture,
};
use sdl2_game_window::WindowSDL2;
use graphics::*;
use piston::{
    AssetStore,
    EventIterator,
    EventSettings,
    WindowSettings,
    Render,
    Update,
    Input,
};
use piston::sprite::*;
use piston::input;
use piston::image;
use piston::image::{
    GenericImage,
};
use piston::event::{
    Action,
    Sequence,
    Wait,
};

fn get_window_size(asset_store: &AssetStore) -> (u32, u32) {
    let path = asset_store.path("img/bg_0.png").unwrap();
    image::open(&path).unwrap().dimensions()
}

fn main() {
    let asset_store = AssetStore::from_folder("../bin/assets");
    let (width, height) = get_window_size(&asset_store);
    let opengl = piston::shader_version::opengl::OpenGL_3_2;
    let mut window = WindowSDL2::new(
        opengl,
        WindowSettings {
            title: "Swing Copters (Rust Clone)".to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let mut main_scene = Scene::new();

    // load resources
    let bg_tex = Rc::new(Texture::from_path(&asset_store.path("img/bg_0.png").unwrap()).unwrap());
    let mut bg = Sprite::from_texture(bg_tex.clone());
    bg.set_anchor(0.0, 0.0);
    main_scene.add_child(bg);

    let cloud_tex = Rc::new(Texture::from_path(&asset_store.path("img/cloud_0.png").unwrap()).unwrap());
    let mut cloud = Sprite::from_texture(cloud_tex.clone());
    cloud.set_anchor(0.5, 0.0);
    cloud.set_position(width as f64 / 2.0, 0.0);
    main_scene.add_child(cloud);

    let land_tex = Rc::new(Texture::from_path(&asset_store.path("img/land.png").unwrap()).unwrap());
    let (_, land_tex_height) = land_tex.get_size();
    let mut land = Sprite::from_texture(land_tex.clone());
    land.set_anchor(0.0, 0.0);
    land.set_position(0.0, (height - land_tex_height) as f64);
    main_scene.add_child(land);

    let mut wheel_textures = Vec::new();
    for i in range(0i, 4) {
        let path = asset_store.path(format!("img/wheels_{}.png", i).as_slice()).unwrap();
        wheel_textures.push(Rc::new(Texture::from_path(&path).unwrap()));
    }
    let mut wheel_texture_index = 0.0;
    let ref wheel_tex = wheel_textures[wheel_texture_index as uint];
    let mut wheel = Sprite::from_texture(wheel_tex.clone());
    wheel.set_anchor(0.5, 0.3);

    let copter_tex = Rc::new(Texture::from_path(&asset_store.path("img/bear_0_0_0.png").unwrap()).unwrap());
    let mut copter = Sprite::from_texture(copter_tex.clone());
    copter.set_anchor(0.5, 0.3);
    copter.set_position(width as f64 / 2.0, height as f64 / 2.0);
    copter.set_rotation(10.0);

    let wheel_id = copter.add_child(wheel);
    let copter_id = main_scene.add_child(copter);

    // Test actions
    main_scene.run(copter_id, &Sequence(vec![
        Action(Ease(EaseQuadraticOut, box MoveBy(2.0, 0.0, -200.0))),
        //Action(MoveBy(2.0, 0.0, -200.0)),
        Action(Ease(EaseQuinticIn, box ScaleTo(2.0, 2.0, 2.0))),
        Action(Blink(2.0, 5)),
        Action(FlipX(true)),
        Wait(2.0),
        Action(FlipX(false)),
        Action(Ease(EaseQuadraticIn, box FadeOut(2.0))),
        Action(Ease(EaseQuinticOut, box FadeIn(2.0))),
    ]));
    let a = Action(Ease(EaseQuadraticInOut, box RotateTo(4.0, 180.0)));
    main_scene.run(copter_id, &a);

    main_scene.run(wheel_id, &Sequence(vec![
        Action(Hide),
        Wait(2.0),
        Action(Show),
    ]));

    let event_settings = EventSettings {
        updates_per_second: 120,
        max_frames_per_second: 60,
    };
    let ref mut gl = Gl::new(opengl);
    for e in EventIterator::new(&mut window, &event_settings) {
        main_scene.update(&e);
        match e {
            Render(args) => {
                gl.viewport(0, 0, args.width as i32, args.height as i32);

                let c = Context::abs(args.width as f64, args.height as f64);

                main_scene.draw(&c, gl);
            },
            Update(args) => {
                wheel_texture_index = wheel_texture_index + args.dt * 20.0;
                let ref tex = wheel_textures[wheel_texture_index as uint % wheel_textures.len()];
                match main_scene.child_mut(wheel_id) {
                    Some(s) => s.set_texture(tex.clone()),
                    _ => {},
                }
            },
            Input(input::Press(_)) => {
                //main_scene.toggle_action(copter_id, &a);
                main_scene.remove_child(copter_id);
                println!("{}", main_scene.running());
            },
            _ => {},
        }
    }
}

<|endoftext|>


<commit_before>#![feature(io)]
#![feature(path)]
#![feature(collections)]
#![feature(core)]
extern crate docopt;
#[macro_use]
extern crate standard_error;

use docopt::Docopt;
use standard_error::StandardResult as Result;
use std::rc::Rc;
use std::borrow::Cow;

mod config;

static CONFIG_PATH: &'static str = "./partners.cfg";

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: partners info
       partners list
       partners add --nick=<nick> --name=<name> [--email=<email>]
       partners add

Options:
    -a, --archive  Copy everything.
";

#[derive(Debug)]
struct Config {
  domain: String,
  prefix: String,
  separator: String,
}

#[derive(Debug)]
struct Author {
  config: Rc<Config>,
  nick: String,
  name: String,
  email: Option<String>,
}

impl Author {
  fn get_email(&self) -> std::string::CowString {
    match self.email {
      Some(ref email) => Cow::Borrowed(email.as_slice()),
      None => Cow::Owned(format!("{}@{}", self.nick, self.config.domain)),
    }
  }
}

fn print_author_list(list: &[Author]) {
  for item in list.iter() {
    println!("{}:", item.nick);
    println!("  Name:  {}", item.name);
    println!("  Email: {}", item.get_email());
  }
}

fn parse_author_line(config: &Rc<Config>, line: &str) -> Result<Author> {
  let mut parts = line.splitn(1, ' ');
  let nick = parts.next().unwrap().split('.').nth(1).unwrap().to_string();
  let name = parts.next().unwrap().to_string();
  let email = config::get(&format!("author.{}.email", nick)[]).ok();

  Ok(Author { config: config.clone(), nick: nick, name: name, email: email })
}

fn get_authors(config: &Rc<Config>) -> Result<Vec<Author>> {
  let lines = try!(config::list("author.\\w+.name"));
  lines.iter().map(|line| parse_author_line(config, &line[])).collect()
}

fn write_author(author: &Author) -> Result<()> {
  try!(config::set(&*format!("author.{}.name", author.nick), &*author.name));
  if let Some(ref email) = author.email {
    try!(config::set(&*format!("author.{}.email", author.nick), &**email));
  }
  Ok(())
}

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

  let config = Rc::new(Config {
    domain: config::get("config.domain").unwrap_or_else(|_| "example.com".to_string()),
    prefix: config::get("config.prefix").unwrap_or_else(|_| "dev".to_string()),
    separator: config::get("config.separator").unwrap_or_else(|_| "+".to_string()),
  });

  if args.get_bool("list") {
    let authors = get_authors(&config).unwrap();
    print_author_list(&authors[]);
  } else if args.get_bool("add") {
    let email = args.get_str("--email").to_string();

    let email = if email.is_empty() { None } else { Some(email) };

    let author = Author {
      config: config.clone(),
      nick: args.get_str("--nick").to_string(),
      name: args.get_str("--name").to_string(),
      email: email,
    };
    write_author(&author).unwrap();
  }
}
<commit_msg>Move out cmd parsing<commit_after>#![feature(io)]
#![feature(path)]
#![feature(collections)]
#![feature(core)]
extern crate docopt;
#[macro_use]
extern crate standard_error;

use docopt::Docopt;
use standard_error::StandardResult as Result;
use std::rc::Rc;
use std::borrow::Cow;

mod config;

static CONFIG_PATH: &'static str = "./partners.cfg";

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: partners info
       partners list
       partners add --nick=<nick> --name=<name> [--email=<email>]
       partners add

Options:
    -a, --archive  Copy everything.
";

#[derive(Debug)]
struct Config {
  domain: String,
  prefix: String,
  separator: String,
}

#[derive(Debug)]
struct Author {
  config: Rc<Config>,
  nick: String,
  name: String,
  email: Option<String>,
}

impl Author {
  fn get_email(&self) -> std::string::CowString {
    match self.email {
      Some(ref email) => Cow::Borrowed(email.as_slice()),
      None => Cow::Owned(format!("{}@{}", self.nick, self.config.domain)),
    }
  }
}

fn print_author_list(list: &[Author]) {
  for item in list.iter() {
    println!("{}:", item.nick);
    println!("  Name:  {}", item.name);
    println!("  Email: {}", item.get_email());
  }
}

fn parse_author_line(config: &Rc<Config>, line: &str) -> Result<Author> {
  let mut parts = line.splitn(1, ' ');
  let nick = parts.next().unwrap().split('.').nth(1).unwrap().to_string();
  let name = parts.next().unwrap().to_string();
  let email = config::get(&format!("author.{}.email", nick)[]).ok();

  Ok(Author { config: config.clone(), nick: nick, name: name, email: email })
}

fn get_authors(config: &Rc<Config>) -> Result<Vec<Author>> {
  let lines = try!(config::list("author.\\w+.name"));
  lines.iter().map(|line| parse_author_line(config, &line[])).collect()
}

fn write_author(author: &Author) -> Result<()> {
  try!(config::set(&*format!("author.{}.name", author.nick), &*author.name));
  if let Some(ref email) = author.email {
    try!(config::set(&*format!("author.{}.email", author.nick), &**email));
  }
  Ok(())
}

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

  let config = Rc::new(Config {
    domain: config::get("config.domain").unwrap_or_else(|_| "example.com".to_string()),
    prefix: config::get("config.prefix").unwrap_or_else(|_| "dev".to_string()),
    separator: config::get("config.separator").unwrap_or_else(|_| "+".to_string()),
  });

  if args.get_bool("list") {
    let authors = get_authors(&config).unwrap();
    print_author_list(&authors[]);
  } else if args.get_bool("add") {
    let email = args.get_str("--email");
    let nick = args.get_str("--nick");
    let name = args.get_str("--name");

    let email = if email.is_empty() { None } else { Some(email.to_string()) };

    let author = Author { config: config.clone(), nick: nick.to_string(), name: name.to_string(), email: email };
    write_author(&author).unwrap();
  }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
extern crate getopts;
extern crate image;
extern crate time;

extern crate rusttracer;

use std::env;
use std::path::Path;

use getopts::Options;

use rusttracer::mesh_loader::MeshLoader;
use rusttracer::{number_of_successful_triangle_intersections, number_of_triangle_intersections,
                 Camera, Color, Config, IllumninationModel, Material, MaterialTemplate, Renderer,
                 Scene, SuperSampling};

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt(
        "c",
        "config-path",
        "config file path, uses `default.json` if not specified",
        "CONFIG_PATH",
    );
    opts.optflag(
        "b",
        "benchmark",
        "Benchmark by rendering the scene multiple times",
    );
    opts.optflag("h", "help", "prints this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let benchmark = matches.opt_present("b");
    let config_path = matches.opt_str("c").expect("No config provided");

    let config = Config::new_from_file(&config_path).expect("Invalid configuration");

    let scene_path = Path::new(&config_path).parent().unwrap();
    let mesh_loader = MeshLoader::new(scene_path.to_path_buf());
    let template = MaterialTemplate::new(
        Color::blue() * 0.02,
        Color::black(),
        Color::black(),
        0.0,
        IllumninationModel::DiffuseSpecular,
        None,
        None,
    );
    let floor_material = template.build_material(|material| {
        material.ambient_color = Color::white() * 0.05;
        material.diffuse_color = Color::white() * 0.6;
    });

    let materials = config
        .materials
        .iter()
        .map(|material_config| Material::new_from_config(material_config))
        .collect();
    let scene = Scene::new_from_config(
        &config.scenes.first().unwrap(),
        &materials,
        &mesh_loader,
        floor_material,
    ).expect("Invalid scene");
    let camera_config = config.cameras.first().unwrap();
    let camera = Camera::from_config(camera_config);
    let renderer = Renderer::new(&scene, &camera, SuperSampling::On(2));

    if benchmark {
        for _ in 0..10 {
            let _ = renderer.render(config.max_depth);
        }

        return;
    }

    let buffer = renderer.render(config.max_depth);
    println!(
        "Performed {} ray-triangle intersection tests",
        number_of_triangle_intersections()
    );
    println!(
        "{} ray-triangle intersections were successful",
        number_of_successful_triangle_intersections()
    );

    let timestamp = time::get_time().sec;
    let filename = format!("images/{}.png", timestamp);
    image::save_buffer(
        &Path::new(&filename),
        &buffer[..],
        camera_config.width,
        camera_config.height,
        image::RGB(8),
    ).unwrap();
}
<commit_msg>[refactor] Pass by reference instead of value<commit_after>#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
extern crate getopts;
extern crate image;
extern crate time;

extern crate rusttracer;

use std::env;
use std::path::Path;

use getopts::Options;

use rusttracer::mesh_loader::MeshLoader;
use rusttracer::{number_of_successful_triangle_intersections, number_of_triangle_intersections,
                 Camera, Color, Config, IllumninationModel, Material, MaterialTemplate, Renderer,
                 Scene, SuperSampling};

fn print_usage(program: &str, opts: &Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt(
        "c",
        "config-path",
        "config file path, uses `default.json` if not specified",
        "CONFIG_PATH",
    );
    opts.optflag(
        "b",
        "benchmark",
        "Benchmark by rendering the scene multiple times",
    );
    opts.optflag("h", "help", "prints this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(&program, &opts);
        return;
    }

    let benchmark = matches.opt_present("b");
    let config_path = matches.opt_str("c").expect("No config provided");

    let config = Config::new_from_file(&config_path).expect("Invalid configuration");

    let scene_path = Path::new(&config_path).parent().unwrap();
    let mesh_loader = MeshLoader::new(scene_path.to_path_buf());
    let template = MaterialTemplate::new(
        Color::blue() * 0.02,
        Color::black(),
        Color::black(),
        0.0,
        IllumninationModel::DiffuseSpecular,
        None,
        None,
    );
    let floor_material = template.build_material(|material| {
        material.ambient_color = Color::white() * 0.05;
        material.diffuse_color = Color::white() * 0.6;
    });

    let materials = config
        .materials
        .iter()
        .map(|material_config| Material::new_from_config(material_config))
        .collect();
    let scene = Scene::new_from_config(
        &config.scenes.first().unwrap(),
        &materials,
        &mesh_loader,
        floor_material,
    ).expect("Invalid scene");
    let camera_config = config.cameras.first().unwrap();
    let camera = Camera::from_config(camera_config);
    let renderer = Renderer::new(&scene, &camera, SuperSampling::On(2));

    if benchmark {
        for _ in 0..10 {
            let _ = renderer.render(config.max_depth);
        }

        return;
    }

    let buffer = renderer.render(config.max_depth);
    println!(
        "Performed {} ray-triangle intersection tests",
        number_of_triangle_intersections()
    );
    println!(
        "{} ray-triangle intersections were successful",
        number_of_successful_triangle_intersections()
    );

    let timestamp = time::get_time().sec;
    let filename = format!("images/{}.png", timestamp);
    image::save_buffer(
        &Path::new(&filename),
        &buffer[..],
        camera_config.width,
        camera_config.height,
        image::RGB(8),
    ).unwrap();
}
<|endoftext|>


<commit_before>extern crate mio;

use mio::*;
use mio::net::{SockAddr};
use mio::net::tcp::{TcpSocket, TcpAcceptor};
use std::thread::Thread;
use std::old_io;

fn main() {
    struct EchoHandler;
    impl Handler<(), String> for EchoHandler {
        fn notify(&mut self, event_loop: &mut EventLoop<(), String>, msg: String) {
            if msg.as_slice() == "done\n" {
                event_loop.shutdown();
            }
        }
    }
    let mut event_loop = EventLoop::new().unwrap();
    let sender = event_loop.channel();
    // Send the notification from another thread
    Thread::spawn(move || {
        let mut stdin = old_io::stdin();
        loop {
            for line in stdin.lock().lines() {
                let _ = sender.send(line.unwrap());
            }
        }
    });
    let _ = event_loop.run(EchoHandler);
}
<commit_msg>No need for unused var assignment.<commit_after>extern crate mio;

use mio::*;
use mio::net::{SockAddr};
use mio::net::tcp::{TcpSocket, TcpAcceptor};
use std::thread::Thread;
use std::old_io;

fn main() {
    struct EchoHandler;
    impl Handler<(), String> for EchoHandler {
        fn notify(&mut self, event_loop: &mut EventLoop<(), String>, msg: String) {
            print!("{}", msg);
            if msg.as_slice() == "done\n" {
                event_loop.shutdown();
            }
        }
    }
    let mut event_loop = EventLoop::new().unwrap();
    let sender = event_loop.channel();
    // Send the notification from another thread
    Thread::spawn(move || {
        let mut stdin = old_io::stdin();
        loop {
            for line in stdin.lock().lines() {
                sender.send(line.unwrap());
            }
        }
    });

    event_loop.run(EchoHandler);
}
<|endoftext|>


<commit_before>#![deny(rust_2018_idioms, unused, unused_import_braces, unused_qualifications, warnings)]

use {
    std::{
        collections::HashMap,
        convert::Infallible,
        fmt,
        fs::File,
        io
    },
    bitbar::{
        ContentItem,
        Image,
        Menu,
        MenuItem
    },
    css_color_parser::ColorParseError,
    derive_more::From,
    image::{
        FilterType,
        ImageError,
        ImageFormat
    },
    mime::Mime,
    num_traits::One,
    serde::{
        Deserialize,
        Deserializer,
        Serialize,
        de::Visitor
    },
    url::Url,
    crate::{
        model::*,
        util::{
            EntryExt as _,
            ResponseExt as _,
            ResultNeverExt as _
        }
    }
};

mod model;
mod util;

#[derive(Debug, From)]
enum Error {
    ColorParse(ColorParseError),
    Header(reqwest::header::ToStrError),
    InvalidMime(Mime),
    Image(ImageError),
    Io(io::Error),
    Json(serde_json::Error),
    MimeFromStr(mime::FromStrError),
    Reqwest(reqwest::Error),
    Url(url::ParseError),
    Xdg(xdg_basedir::Error)
}

impl From<Infallible> for Error {
    fn from(never: Infallible) -> Error {
        match never {}
    }
}

#[derive(Debug)]
enum VersionLink {
    Enabled,
    Alternate,
    Disabled
}

impl Default for VersionLink {
    fn default() -> VersionLink {
        VersionLink::Enabled
    }
}

impl<'de> Deserialize<'de> for VersionLink {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<VersionLink, D::Error> {
        deserializer.deserialize_any(VersionLinkVisitor)
    }
}

struct VersionLinkVisitor;

impl<'de> Visitor<'de> for VersionLinkVisitor {
    type Value = VersionLink;

    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "a boolean or the string \"alt\"")
    }

    fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<VersionLink, E> {
        Ok(if v { VersionLink::Enabled } else { VersionLink::Disabled })
    }

    fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<VersionLink, E> {
        if v == "alt" {
            Ok(VersionLink::Alternate)
        } else {
            Err(E::invalid_value(serde::de::Unexpected::Str(v), &self))
        }
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Config {
    #[serde(default)]
    defer: Vec<String>,
    #[serde(default)]
    show_if_empty: bool,
    #[serde(default)]
    show_if_offline: bool,
    #[serde(default = "make_true")]
    single_color: bool,
    #[serde(default)]
    version_link: VersionLink,
    #[serde(default = "One::one")]
    zoom: u8
}

impl Config {
    fn load() -> Result<Config, Error> {
        let dirs = xdg_basedir::get_config_home().into_iter().chain(xdg_basedir::get_config_dirs());
        for cfg_dir in dirs {
            let path = cfg_dir.join("bitbar/plugins/wurstmineberg.json");
            if path.exists() {
                return Ok(serde_json::from_reader(File::open(path)?)?);
            }
        }
        Ok(Config::default())
    }
}

impl Default for Config {
    fn default() -> Config {
        Config {
            defer: Vec::default(),
            show_if_empty: false,
            show_if_offline: false,
            single_color: true,
            version_link: VersionLink::Enabled,
            zoom: 1
        }
    }
}

#[derive(Debug, Default, Deserialize, Serialize)]
#[serde(transparent)]
struct Cache(HashMap<Uid, Vec<u8>>);

impl Cache {
    fn load() -> Result<Cache, Error> {
        let path = xdg_basedir::get_cache_home()?.join("bitbar/plugin/wurstmineberg/avatars.json");
        if path.exists() {
            return Ok(serde_json::from_reader(File::open(path)?)?);
        } else {
            Ok(Cache::default())
        }
    }

    fn save(self) -> Result<(), Error> {
        let path = xdg_basedir::get_cache_home()?.join("bitbar/plugin/wurstmineberg/avatars.json");
        Ok(serde_json::to_writer(File::create(path)?, &self)?)
    }

    fn get_img(&mut self, uid: Uid, _ /*zoom*/: u8) -> Result<Image, Error> {
        self.0.entry(uid.clone())
            .or_try_insert_with(|| {
                let avatar_info = reqwest::blocking::get(&format!("https://wurstmineberg.de/api/v3/person/{}/avatar.json", uid))?
                    .error_for_status()?
                    .json::<AvatarInfo>()?;
                let image = reqwest::blocking::get(avatar_info.url)?
                    .error_for_status()?
                    .image()?;
                //TODO resize to 16 * zoom and write with DPI 72 * zoom, see https://github.com/image-rs/image/issues/911
                let mut buf = Vec::default();
                image.resize_exact(16, 16, FilterType::Nearest).write_to(&mut buf, ImageFormat::PNG)?;
                Ok(buf)
            })
            .map(|buf| (&buf).into())
    }
}

#[derive(Debug, Deserialize)]
struct Status {
    #[serde(default)]
    list: Vec<Uid>,
    running: bool,
    version: String
}

impl Status {
    fn load() -> Result<Status, Error> {
        Ok(
            reqwest::blocking::get("https://wurstmineberg.de/api/v3/world/wurstmineberg/status.json")?
                .error_for_status()?
                .json()?
        )
    }
}

#[derive(Debug, Deserialize)]
struct People {
    people: HashMap<Uid, Person>
}

impl People {
    fn load() -> Result<People, Error> {
        Ok(
            reqwest::blocking::get("https://wurstmineberg.de/api/v3/people.json")?
                .error_for_status()?
                .json()?
        )
    }

    fn get(&self, uid: impl Into<Uid>) -> Option<&Person> {
        self.people.get(&uid.into())
    }
}

#[derive(Debug, Deserialize)]
struct AvatarInfo {
    url: Url
}

fn bitbar() -> Result<Menu, Error> {
    let config = Config::load()?;
    let status = Status::load()?;
    if !config.show_if_offline && !status.running { return Ok(Menu::default()); }
    if !config.show_if_empty && status.list.is_empty() { return Ok(Menu::default()); }
    let people = People::load()?;
    let mut cache = Cache::load()?;
    let menu = vec![
        {
            let head = ContentItem::new(if !status.running {
                "!".to_owned()
            } else if status.list.is_empty() {
                "".to_owned()
            } else {
                status.list.len().to_string()
            }).template_image(wurstpick(config.zoom))?;
            if config.single_color && status.list.len() == 1 && people.get(&status.list[0]).map_or(false, |person| person.fav_color.is_some()) {
                head.color(people.get(&status.list[0]).unwrap().fav_color.as_ref().unwrap())?
            } else {
                head
            }.into()
        },
        MenuItem::Sep,
        {
            let version_item = ContentItem::new(format!("Version: {}", status.version));
            match config.version_link {
                VersionLink::Enabled => version_item.href(format!("https://minecraft.gamepedia.com/Java_Edition_{}", status.version))?,
                VersionLink::Alternate => version_item.alt(ContentItem::new(format!("Version: {}", status.version)).color("blue")?.href(format!("https://minecraft.gamepedia.com/Java_Edition_{}", status.version))?),
                VersionLink::Disabled => version_item
            }.into()
        }
    ].into_iter()
        .chain(status.list.iter().map(|uid| {
            let person = people.get(uid).cloned().unwrap_or_default();
            let mut item = ContentItem::new(person.name.map_or_else(|| uid.to_string(), |name| name.to_string()))
                .href(format!("https://wurstmineberg.de/people/{}", uid))?
                .image(cache.get_img(uid.clone(), config.zoom)?)?;
            if let Some(fav_color) = person.fav_color {
                item = item.color(fav_color)?;
            }
            if let Some(discord) = person.discord {
                item = item.alt(ContentItem::new(format!("@{}", discord.name())).color("blue")?.href(discord.url())?);
            }
            Ok(item.into())
        }).collect::<Result<Vec<MenuItem>, Error>>()?)
        .chain(vec![
            MenuItem::Sep,
            ContentItem::new("Start Minecraft")
                .command(("/usr/bin/open", "-a", "Minecraft"))
                .alt(ContentItem::new("Open in Discord").color("blue")?.href("https://discordapp.com/channels/88318761228054528/388412978677940226")?)
                .into()
        ])
        //TODO “Defer” submenu if configured
        .collect();
    cache.save()?;
    Ok(menu)
}

fn make_true() -> bool { true }

fn wurstpick(zoom: u8) -> Image {
    if zoom >= 2 {
        Image::template(&include_bytes!("../assets/wurstpick-2x.png")[..]).never_unwrap()
    } else {
        Image::template(&include_bytes!("../assets/wurstpick.png")[..]).never_unwrap()
    }
}

fn main() {
    match bitbar() {
        Ok(menu) => { print!("{}", menu); }
        Err(e) => {
            let zoom = Config::load().map(|config| config.zoom).unwrap_or(1);
            print!("{}", Menu(vec![
                ContentItem::new("?").template_image(wurstpick(zoom)).never_unwrap().into(),
                MenuItem::Sep,
                MenuItem::new(format!("{:?}", e))
            ]));
        }
    }
}
<commit_msg>Don't hide avatars in alt mode<commit_after>#![deny(rust_2018_idioms, unused, unused_import_braces, unused_qualifications, warnings)]

use {
    std::{
        collections::HashMap,
        convert::Infallible,
        fmt,
        fs::File,
        io
    },
    bitbar::{
        ContentItem,
        Image,
        Menu,
        MenuItem
    },
    css_color_parser::ColorParseError,
    derive_more::From,
    image::{
        FilterType,
        ImageError,
        ImageFormat
    },
    mime::Mime,
    num_traits::One,
    serde::{
        Deserialize,
        Deserializer,
        Serialize,
        de::Visitor
    },
    url::Url,
    crate::{
        model::*,
        util::{
            EntryExt as _,
            ResponseExt as _,
            ResultNeverExt as _
        }
    }
};

mod model;
mod util;

#[derive(Debug, From)]
enum Error {
    ColorParse(ColorParseError),
    Header(reqwest::header::ToStrError),
    InvalidMime(Mime),
    Image(ImageError),
    Io(io::Error),
    Json(serde_json::Error),
    MimeFromStr(mime::FromStrError),
    Reqwest(reqwest::Error),
    Url(url::ParseError),
    Xdg(xdg_basedir::Error)
}

impl From<Infallible> for Error {
    fn from(never: Infallible) -> Error {
        match never {}
    }
}

#[derive(Debug)]
enum VersionLink {
    Enabled,
    Alternate,
    Disabled
}

impl Default for VersionLink {
    fn default() -> VersionLink {
        VersionLink::Enabled
    }
}

impl<'de> Deserialize<'de> for VersionLink {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<VersionLink, D::Error> {
        deserializer.deserialize_any(VersionLinkVisitor)
    }
}

struct VersionLinkVisitor;

impl<'de> Visitor<'de> for VersionLinkVisitor {
    type Value = VersionLink;

    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "a boolean or the string \"alt\"")
    }

    fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<VersionLink, E> {
        Ok(if v { VersionLink::Enabled } else { VersionLink::Disabled })
    }

    fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<VersionLink, E> {
        if v == "alt" {
            Ok(VersionLink::Alternate)
        } else {
            Err(E::invalid_value(serde::de::Unexpected::Str(v), &self))
        }
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Config {
    #[serde(default)]
    defer: Vec<String>,
    #[serde(default)]
    show_if_empty: bool,
    #[serde(default)]
    show_if_offline: bool,
    #[serde(default = "make_true")]
    single_color: bool,
    #[serde(default)]
    version_link: VersionLink,
    #[serde(default = "One::one")]
    zoom: u8
}

impl Config {
    fn load() -> Result<Config, Error> {
        let dirs = xdg_basedir::get_config_home().into_iter().chain(xdg_basedir::get_config_dirs());
        for cfg_dir in dirs {
            let path = cfg_dir.join("bitbar/plugins/wurstmineberg.json");
            if path.exists() {
                return Ok(serde_json::from_reader(File::open(path)?)?);
            }
        }
        Ok(Config::default())
    }
}

impl Default for Config {
    fn default() -> Config {
        Config {
            defer: Vec::default(),
            show_if_empty: false,
            show_if_offline: false,
            single_color: true,
            version_link: VersionLink::Enabled,
            zoom: 1
        }
    }
}

#[derive(Debug, Default, Deserialize, Serialize)]
#[serde(transparent)]
struct Cache(HashMap<Uid, Vec<u8>>);

impl Cache {
    fn load() -> Result<Cache, Error> {
        let path = xdg_basedir::get_cache_home()?.join("bitbar/plugin/wurstmineberg/avatars.json");
        if path.exists() {
            return Ok(serde_json::from_reader(File::open(path)?)?);
        } else {
            Ok(Cache::default())
        }
    }

    fn save(self) -> Result<(), Error> {
        let path = xdg_basedir::get_cache_home()?.join("bitbar/plugin/wurstmineberg/avatars.json");
        Ok(serde_json::to_writer(File::create(path)?, &self)?)
    }

    fn get_img(&mut self, uid: Uid, _ /*zoom*/: u8) -> Result<Image, Error> {
        self.0.entry(uid.clone())
            .or_try_insert_with(|| {
                let avatar_info = reqwest::blocking::get(&format!("https://wurstmineberg.de/api/v3/person/{}/avatar.json", uid))?
                    .error_for_status()?
                    .json::<AvatarInfo>()?;
                let image = reqwest::blocking::get(avatar_info.url)?
                    .error_for_status()?
                    .image()?;
                //TODO resize to 16 * zoom and write with DPI 72 * zoom, see https://github.com/image-rs/image/issues/911
                let mut buf = Vec::default();
                image.resize_exact(16, 16, FilterType::Nearest).write_to(&mut buf, ImageFormat::PNG)?;
                Ok(buf)
            })
            .map(|buf| (&buf).into())
    }
}

#[derive(Debug, Deserialize)]
struct Status {
    #[serde(default)]
    list: Vec<Uid>,
    running: bool,
    version: String
}

impl Status {
    fn load() -> Result<Status, Error> {
        Ok(
            reqwest::blocking::get("https://wurstmineberg.de/api/v3/world/wurstmineberg/status.json")?
                .error_for_status()?
                .json()?
        )
    }
}

#[derive(Debug, Deserialize)]
struct People {
    people: HashMap<Uid, Person>
}

impl People {
    fn load() -> Result<People, Error> {
        Ok(
            reqwest::blocking::get("https://wurstmineberg.de/api/v3/people.json")?
                .error_for_status()?
                .json()?
        )
    }

    fn get(&self, uid: impl Into<Uid>) -> Option<&Person> {
        self.people.get(&uid.into())
    }
}

#[derive(Debug, Deserialize)]
struct AvatarInfo {
    url: Url
}

fn bitbar() -> Result<Menu, Error> {
    let config = Config::load()?;
    let status = Status::load()?;
    if !config.show_if_offline && !status.running { return Ok(Menu::default()); }
    if !config.show_if_empty && status.list.is_empty() { return Ok(Menu::default()); }
    let people = People::load()?;
    let mut cache = Cache::load()?;
    let menu = vec![
        {
            let head = ContentItem::new(if !status.running {
                "!".to_owned()
            } else if status.list.is_empty() {
                "".to_owned()
            } else {
                status.list.len().to_string()
            }).template_image(wurstpick(config.zoom))?;
            if config.single_color && status.list.len() == 1 && people.get(&status.list[0]).map_or(false, |person| person.fav_color.is_some()) {
                head.color(people.get(&status.list[0]).unwrap().fav_color.as_ref().unwrap())?
            } else {
                head
            }.into()
        },
        MenuItem::Sep,
        {
            let version_item = ContentItem::new(format!("Version: {}", status.version));
            match config.version_link {
                VersionLink::Enabled => version_item.href(format!("https://minecraft.gamepedia.com/Java_Edition_{}", status.version))?,
                VersionLink::Alternate => version_item.alt(ContentItem::new(format!("Version: {}", status.version)).color("blue")?.href(format!("https://minecraft.gamepedia.com/Java_Edition_{}", status.version))?),
                VersionLink::Disabled => version_item
            }.into()
        }
    ].into_iter()
        .chain(status.list.iter().map(|uid| {
            let person = people.get(uid).cloned().unwrap_or_default();
            let mut item = ContentItem::new(person.name.map_or_else(|| uid.to_string(), |name| name.to_string()))
                .href(format!("https://wurstmineberg.de/people/{}", uid))?
                .image(cache.get_img(uid.clone(), config.zoom)?)?;
            if let Some(fav_color) = person.fav_color {
                item = item.color(fav_color)?;
            }
            if let Some(discord) = person.discord {
                item = item.alt(
                    ContentItem::new(format!("@{}", discord.name()))
                        .color("blue")?
                        .href(discord.url())?
                        .image(cache.get_img(uid.clone(), config.zoom)?)?
                );
            }
            Ok(item.into())
        }).collect::<Result<Vec<MenuItem>, Error>>()?)
        .chain(vec![
            MenuItem::Sep,
            ContentItem::new("Start Minecraft")
                .command(("/usr/bin/open", "-a", "Minecraft"))
                .alt(ContentItem::new("Open in Discord").color("blue")?.href("https://discordapp.com/channels/88318761228054528/388412978677940226")?)
                .into()
        ])
        //TODO “Defer” submenu if configured
        .collect();
    cache.save()?;
    Ok(menu)
}

fn make_true() -> bool { true }

fn wurstpick(zoom: u8) -> Image {
    if zoom >= 2 {
        Image::template(&include_bytes!("../assets/wurstpick-2x.png")[..]).never_unwrap()
    } else {
        Image::template(&include_bytes!("../assets/wurstpick.png")[..]).never_unwrap()
    }
}

fn main() {
    match bitbar() {
        Ok(menu) => { print!("{}", menu); }
        Err(e) => {
            let zoom = Config::load().map(|config| config.zoom).unwrap_or(1);
            print!("{}", Menu(vec![
                ContentItem::new("?").template_image(wurstpick(zoom)).never_unwrap().into(),
                MenuItem::Sep,
                MenuItem::new(format!("{:?}", e))
            ]));
        }
    }
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate rand;
extern crate stopwatch;
use piston_window::*;
use piston_window::types::Color;
use std::f64::consts::PI;
use std::f64;
use std::thread;
use std::sync::mpsc;
use std::time::Duration;
use rand::{thread_rng, Rng};
use stopwatch::Stopwatch;
// speed of object
enum Speed {
    Go { scala: f64 },
    None,
}
// object spawn side
enum Side {
    None,
    Center,
    Up,
    Down,
    Right,
    Left,
}
// direction of the object
struct Arrow {
    theta: f64,
    sin: f64,
    cos: f64,
}
impl Arrow {
    fn new(theta: f64) -> Self {
        // caculate the sin,cos of the angle
        Arrow {
            theta: theta,
            sin: (PI * theta).sin(),
            cos: (PI * theta).cos(),
        }
    }
}
// object info
pub struct Object {
    // evironment sixe
    background: (u32, u32),
    current_speed: Speed,
    // object's position
    current_state: (f64, f64),
    size: (f64, f64),
    spawn: Side,
    arrow: Arrow,
    color: Color,
}
impl Object {
    pub fn new(width: f64, height: f64) -> Self {
        Object {
            background: (0, 0),
            current_state: (0.0, 0.0),
            current_speed: Speed::None,
            size: (width, height),
            spawn: Side::None,
            arrow: Arrow::new(0.0),
            color: [0.0, 0.0, 0.0, 0.0],
        }
    }
    // set the environment size
    fn set_place(&mut self, r: &RenderArgs) {
        self.background = (r.width, r.height);
    }
    // set object speed
    pub fn set_speed(&mut self, scala: f64) {
        self.current_speed = Speed::Go { scala: scala };
    }
    // this is for setting the spawn postion
    fn set_pos(&mut self, r: &RenderArgs, pos: Side) {
        let position_x = thread_rng().gen_range(0.0, r.width as f64 - self.size.0);
        let position_y = thread_rng().gen_range(0.0, r.height as f64 - self.size.1);
        self.current_state = match pos {
            Side::Up => (position_x, 0.0),
            Side::Right => (r.width as f64 - self.size.0, position_y),
            Side::Down => (position_x, r.height as f64 - self.size.1),
            Side::Left => (0.0, position_y),
            Side::Center => (r.width as f64 / 2.0, r.height as f64 / 2.0),
            _ => panic!("system error"),
        };
        self.spawn = pos;
    }
    // set the object color
    pub fn set_color(&mut self, color: Color) {
        self.color = color;
    }
    // set position for some other function
    fn inner_set_pos(&mut self, pos: (f64, f64)) {
        self.current_state = pos;
    }//set the direction according to angle (theta: 0.0~2.0)
    pub fn arrow_set(&mut self, theta: f64) {
        self.arrow = Arrow::new(theta);
    }
    // set direction for ramdome
    fn random_arrow_set(&mut self) {
        let theta = match self.spawn {
            Side::Up => thread_rng().gen_range(0.0, 1.0),
            Side::Right => thread_rng().gen_range(0.5, 1.5),
            Side::Down => thread_rng().gen_range(1.0, 2.0),
            Side::Left => thread_rng().gen_range(-0.5, 0.5),
            Side::Center => thread_rng().gen_range(0.0, 2.0),
            _ => panic!("system error"),
        };
        self.arrow = Arrow::new(theta);
    }
    // update the current state
    fn update(&mut self, args: &UpdateArgs) {
        let before_pos = self.current_state;
        match self.current_speed {
            Speed::Go { scala } => {
                self.current_state.0 += scala * self.arrow.cos * args.dt;
                self.current_state.1 += scala * self.arrow.sin * args.dt;
            }
            Speed::None => {}
        };
        // if object hit the wall then reflect
        if !self.is_wall() {
            // this is the reflect function
            self.collide();
            // and set the before position
            self.inner_set_pos(before_pos);
        }
    }
    // manage the key control
    fn move_it(&mut self, control: &Button) {
        let theta = match *control {
            Button::Keyboard(key) => {
                match key {
                    Key::Right => 0.0,
                    Key::Left => 1.0,
                    Key::Up => 1.5,
                    Key::Down => 0.5,
                    _ => self.arrow.theta,
                }
            }
            _ => self.arrow.theta,
        };
        self.arrow = Arrow::new(theta);
    }
    // if object goes outside the window then it turns the false
    fn is_wall(&mut self) -> bool {
        let available_x = self.background.0 as f64 - self.size.0;
        let available_y = self.background.1 as f64 - self.size.1;
        between(0.0, available_x, self.current_state.0) &&
        between(0.0, available_y, self.current_state.1)
    }
    // set the new direction according to current position
    fn collide(&mut self) {
        let available_x = self.background.0 as f64 - self.size.0;
        let available_y = self.background.1 as f64 - self.size.1;
        let before_theta = self.arrow.theta;
        let plane_vec = match (between(0.0, available_x, self.current_state.0),
                               between(0.0, available_y, self.current_state.1)) {
            (false, true) => 1.0,
            (true, false) => 2.0,
            (false, false) => 2.0 * before_theta,
            (true, true) => {
                panic!("system error");
            }
        };
        let mut result = plane_vec - before_theta;
        // set theta range in 0.0~2.0
        loop {
            if result <= 0.0 {
                result += 2.0;
                continue;
            } else if result >= 2.0 {
                result -= 2.0;
                continue;
            } else {
                break;
            }
        }
        self.arrow = Arrow::new(result);
    }
    // if object hit with other object then return true
    fn is_hit(&self, other: &Object) -> bool {
        let (result_x, result_y) = (self.current_state.0 - other.current_state.0,
                                    self.current_state.1 - other.current_state.1);
        match (result_x < 0.0, result_y < 0.0) {
            (false, false) => result_x <= other.size.0 && result_y <= other.size.1,
            (true, false) => result_x.abs() <= self.size.0 && result_y <= other.size.1,
            (false, true) => result_x <= other.size.0 && result_y.abs() <= self.size.1,
            (true, true) => result_x.abs() <= self.size.0 && result_y.abs() <= self.size.1,
        }
    }
}
// return treu if target is in the range
fn between(x: f64, y: f64, target: f64) -> bool {
    x <= target && target <= y
}
// MAXINUM number of other particles
const MAXINUM: u32 = 150;
// time limit of channel
const TIME_LIMIT: u64 = 2000;
fn main() {
    let opengls = OpenGL::V4_5;
    // set piston window
    let mut window: PistonWindow = WindowSettings::new("machine_dodge", [800, 800])
        .opengl(opengls)
        .exit_on_esc(true)
        .build()
        .unwrap();
    let (tx, rx) = mpsc::channel();
    let mut start: bool = true;
    let mut game_end: bool = false;
    let mut count = 0;
    // create main object
    let mut machine = Object::new(20.0, 20.0);
    // create other objects
    let mut obstacles: Vec<Object> = Vec::new();
    let time_limit = Duration::from_millis(TIME_LIMIT);
    // start stopwatch
    let mut sw = Stopwatch::start_new();
    // make the eventloop of window
    while let Some(e) = window.next() {
        // rnader the window
        if let Some(r) = e.render_args() {
            if start {
                // setting the main object
                machine.set_pos(&r, Side::Center);
                machine.set_speed(50.0);
                machine.set_color([0.0, 1.0, 0.0, 1.0]);
                start = false;
            }
            // if game is over then run this code and restart
            if game_end {
                start = true;
                game_end = false;
                count = 0;
                obstacles.clear();
                let result = sw.elapsed_ms();
                let (t_x, b_x) = (result / 1000, result % 1000);
                // print the surviving time
                println!("THE END \ntime:{}.{}", t_x, b_x);
                sw.restart();
                continue;
            }
            if count < MAXINUM {
                let rng = thread_rng().gen_range(1, 4);
                count += rng;
                // spawn randome number of obstacles
                for _ in 0..rng {
                    let tx = tx.clone();
                    thread::spawn(move || {
                        let mut obstacle = Object::new(10.0, 10.0);
                        let position = match thread_rng().gen_range(0, 4) {
                            0 => Side::Up,
                            1 => Side::Right,
                            2 => Side::Down,
                            3 => Side::Left,
                            _ => {
                                panic!("system error");
                            }
                        };
                        obstacle.set_pos(&r, position);
                        obstacle.set_speed(30.0);
                        obstacle.set_color([0.0, 0.0, 1.0, 1.0]);
                        obstacle.random_arrow_set();
                        tx.send(obstacle).unwrap();
                    });
                    let temp = match rx.recv_timeout(time_limit) {
                        Ok(result) => result,
                        Err(_) => {
                            panic!("send fail");
                        }
                    };
                    obstacles.push(temp);
                }
            }
            // draw the object
            window.draw_2d(&e, |c, g| {
                // set postion of main object
                let transform = c.transform.trans(machine.current_state.0, machine.current_state.1);
                machine.set_place(&r);
                // clear the background
                clear([0.0, 0.0, 0.0, 1.0], g);
                // draw the rectangle
                Rectangle::new(machine.color).draw([0.0, 0.0, machine.size.0, machine.size.1],
                                                   &c.draw_state,
                                                   transform,
                                                   g);
                for obstacle in obstacles.iter_mut() {
                    // set postion of obstacles
                    let transform = c.transform
                        .trans(obstacle.current_state.0, obstacle.current_state.1);
                    obstacle.set_place(&r);
                    // draw the rectangle
                    Rectangle::new(obstacle.color)
                        .draw([0.0, 0.0, obstacle.size.0, obstacle.size.1],
                              &c.draw_state,
                              transform,
                              g);
                }
            });
        }
        // if there is the press event then run this code
        if let Some(b) = e.press_args() {
            machine.move_it(&b);
        }
        // if there is the update event then run this code
        if let Some(u) = e.update_args() {
            machine.update(&u);
            for obstacle in obstacles.iter_mut() {
                {
                    // compare withe main and obstacles
                    game_end = machine.is_hit(&obstacle);
                    if game_end {
                        break;
                    }
                }
                obstacle.update(&u);
            }
        }
    }
}
<commit_msg>fix the bug <commit_after>extern crate piston_window;
extern crate rand;
extern crate stopwatch;
use piston_window::*;
use piston_window::types::Color;
use std::f64::consts::PI;
use std::f64;
use std::thread;
use std::sync::mpsc;
use std::time::Duration;
use rand::{thread_rng, Rng};
use stopwatch::Stopwatch;
// speed of object
enum Speed {
    Go { scala: f64 },
    None,
}
// object spawn side
enum Side {
    None,
    Center,
    Up,
    Down,
    Right,
    Left,
}
// direction of the object
struct Arrow {
    theta: f64,
    sin: f64,
    cos: f64,
}
impl Arrow {
    fn new(theta: f64) -> Self {
        // caculate the sin,cos of the angle
        Arrow {
            theta: theta,
            sin: (PI * theta).sin(),
            cos: (PI * theta).cos(),
        }
    }
}
// object info
pub struct Object {
    // evironment sixe
    background: (u32, u32),
    current_speed: Speed,
    // object's position
    current_state: (f64, f64),
    size: (f64, f64),
    spawn: Side,
    arrow: Arrow,
    color: Color,
}
impl Object {
    pub fn new(width: f64, height: f64) -> Self {
        Object {
            background: (0, 0),
            current_state: (0.0, 0.0),
            current_speed: Speed::None,
            size: (width, height),
            spawn: Side::None,
            arrow: Arrow::new(0.0),
            color: [0.0, 0.0, 0.0, 0.0],
        }
    }
    // set the environment size
    fn set_place(&mut self, r: &RenderArgs) {
        self.background = (r.width, r.height);
    }
    // set object speed
    pub fn set_speed(&mut self, scala: f64) {
        self.current_speed = Speed::Go { scala: scala };
    }
    // this is for setting the spawn postion
    fn set_pos(&mut self, r: &RenderArgs, pos: Side) {
        let position_x = thread_rng().gen_range(0.0, r.width as f64 - self.size.0);
        let position_y = thread_rng().gen_range(0.0, r.height as f64 - self.size.1);
        self.current_state = match pos {
            Side::Up => (position_x, 0.0),
            Side::Right => (r.width as f64 - self.size.0, position_y),
            Side::Down => (position_x, r.height as f64 - self.size.1),
            Side::Left => (0.0, position_y),
            Side::Center => (r.width as f64 / 2.0, r.height as f64 / 2.0),
            _ => panic!("system error"),
        };
        self.spawn = pos;
    }
    // set the object color
    pub fn set_color(&mut self, color: Color) {
        self.color = color;
    }
    // set position for some other function
    fn inner_set_pos(&mut self, pos: (f64, f64)) {
        self.current_state = pos;
    }//set the direction according to angle (theta: 0.0~2.0)
    pub fn arrow_set(&mut self, theta: f64) {
        self.arrow = Arrow::new(theta);
    }
    // set direction for ramdome
    fn random_arrow_set(&mut self) {
        let theta = match self.spawn {
            Side::Up => thread_rng().gen_range(0.0, 1.0),
            Side::Right => thread_rng().gen_range(0.5, 1.5),
            Side::Down => thread_rng().gen_range(1.0, 2.0),
            Side::Left => thread_rng().gen_range(-0.5, 0.5),
            Side::Center => thread_rng().gen_range(0.0, 2.0),
            _ => panic!("system error"),
        };
        self.arrow = Arrow::new(theta);
    }
    // update the current state
    fn update(&mut self, args: &UpdateArgs) {
        let before_pos = self.current_state;
        match self.current_speed {
            Speed::Go { scala } => {
                self.current_state.0 += scala * self.arrow.cos * args.dt;
                self.current_state.1 += scala * self.arrow.sin * args.dt;
            }
            Speed::None => {}
        };
        // if object hit the wall then reflect
        if !self.is_wall() {
            // this is the reflect function
            self.collide();
            // and set the before position
            self.inner_set_pos(before_pos);
        }
    }
    // manage the key control
    fn move_it(&mut self, control: &Button) {
        let theta = match *control {
            Button::Keyboard(key) => {
                match key {
                    Key::Right => 0.0,
                    Key::Left => 1.0,
                    Key::Up => 1.5,
                    Key::Down => 0.5,
                    _ => self.arrow.theta,
                }
            }
            _ => self.arrow.theta,
        };
        self.arrow = Arrow::new(theta);
    }
    // if object goes outside the window then it turns the false
    fn is_wall(&mut self) -> bool {
        let available_x = self.background.0 as f64 - self.size.0;
        let available_y = self.background.1 as f64 - self.size.1;
        between(0.0, available_x, self.current_state.0) &&
        between(0.0, available_y, self.current_state.1)
    }
    // set the new direction according to current position
    fn collide(&mut self) {
        let available_x = self.background.0 as f64 - self.size.0;
        let available_y = self.background.1 as f64 - self.size.1;
        let before_theta = self.arrow.theta;
        let plane_vec = match (between(0.0, available_x, self.current_state.0),
                               between(0.0, available_y, self.current_state.1)) {
            (false, true) => 1.0,
            (true, false) => 2.0,
            (false, false) => 2.0 * before_theta,
            (true, true) => {
                panic!("system error");
            }
        };
        let mut result = plane_vec - before_theta;
        // set theta range in 0.0~2.0
        loop {
            if result < 0.0 {
                result += 2.0;
                continue;
            } else if result > 2.0 {
                result -= 2.0;
                continue;
            } else {
                break;
            }
        }
        self.arrow = Arrow::new(result);
    }
    // if object hit with other object then return true
    fn is_hit(&self, other: &Object) -> bool {
        let (result_x, result_y) = (self.current_state.0 - other.current_state.0,
                                    self.current_state.1 - other.current_state.1);
        match (result_x < 0.0, result_y < 0.0) {
            (false, false) => result_x <= other.size.0 && result_y <= other.size.1,
            (true, false) => result_x.abs() <= self.size.0 && result_y <= other.size.1,
            (false, true) => result_x <= other.size.0 && result_y.abs() <= self.size.1,
            (true, true) => result_x.abs() <= self.size.0 && result_y.abs() <= self.size.1,
        }
    }
}
// return treu if target is in the range
fn between(x: f64, y: f64, target: f64) -> bool {
    x <= target && target <= y
}
// MAXINUM number of other particles
const MAXINUM: u32 = 150;
// time limit of channel
const TIME_LIMIT: u64 = 2000;
fn main() {
    let opengls = OpenGL::V4_5;
    // set piston window
    let mut window: PistonWindow = WindowSettings::new("machine_dodge", [800, 800])
        .opengl(opengls)
        .exit_on_esc(true)
        .build()
        .unwrap();
    let (tx, rx) = mpsc::channel();
    let mut start: bool = true;
    let mut game_end: bool = false;
    let mut count = 0;
    // create main object
    let mut machine = Object::new(20.0, 20.0);
    // create other objects
    let mut obstacles: Vec<Object> = Vec::new();
    let time_limit = Duration::from_millis(TIME_LIMIT);
    // start stopwatch
    let mut sw = Stopwatch::start_new();
    // make the eventloop of window
    while let Some(e) = window.next() {
        // rnader the window
        if let Some(r) = e.render_args() {
            if start {
                // setting the main object
                machine.set_pos(&r, Side::Center);
                machine.set_speed(50.0);
                machine.set_color([0.0, 1.0, 0.0, 1.0]);
                start = false;
            }
            // if game is over then run this code and restart
            if game_end {
                start = true;
                game_end = false;
                count = 0;
                obstacles.clear();
                let result = sw.elapsed_ms();
                let (t_x, b_x) = (result / 1000, result % 1000);
                // print the surviving time
                println!("THE END \ntime:{}.{}", t_x, b_x);
                sw.restart();
                continue;
            }
            if count < MAXINUM {
                let rng = thread_rng().gen_range(1, 4);
                count += rng;
                // spawn randome number of obstacles
                for _ in 0..rng {
                    let tx = tx.clone();
                    thread::spawn(move || {
                        let mut obstacle = Object::new(10.0, 10.0);
                        let position = match thread_rng().gen_range(0, 4) {
                            0 => Side::Up,
                            1 => Side::Right,
                            2 => Side::Down,
                            3 => Side::Left,
                            _ => {
                                panic!("system error");
                            }
                        };
                        obstacle.set_pos(&r, position);
                        obstacle.set_speed(30.0);
                        obstacle.set_color([0.0, 0.0, 1.0, 1.0]);
                        obstacle.random_arrow_set();
                        tx.send(obstacle).unwrap();
                    });
                    let temp = match rx.recv_timeout(time_limit) {
                        Ok(result) => result,
                        Err(_) => {
                            panic!("send fail");
                        }
                    };
                    obstacles.push(temp);
                }
            }
            // draw the object
            window.draw_2d(&e, |c, g| {
                // set postion of main object
                let transform = c.transform.trans(machine.current_state.0, machine.current_state.1);
                machine.set_place(&r);
                // clear the background
                clear([0.0, 0.0, 0.0, 1.0], g);
                // draw the rectangle
                Rectangle::new(machine.color).draw([0.0, 0.0, machine.size.0, machine.size.1],
                                                   &c.draw_state,
                                                   transform,
                                                   g);
                for obstacle in obstacles.iter_mut() {
                    // set postion of obstacles
                    let transform = c.transform
                        .trans(obstacle.current_state.0, obstacle.current_state.1);
                    obstacle.set_place(&r);
                    // draw the rectangle
                    Rectangle::new(obstacle.color)
                        .draw([0.0, 0.0, obstacle.size.0, obstacle.size.1],
                              &c.draw_state,
                              transform,
                              g);
                }
            });
        }
        // if there is the press event then run this code
        if let Some(b) = e.press_args() {
            machine.move_it(&b);
        }
        // if there is the update event then run this code
        if let Some(u) = e.update_args() {
            machine.update(&u);
            for obstacle in obstacles.iter_mut() {
                {
                    // compare withe main and obstacles
                    game_end = machine.is_hit(&obstacle);
                    if game_end {
                        break;
                    }
                }
                obstacle.update(&u);
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate xml;

use std::os;

use std::io::{File, BufferedReader};
use std::fmt;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread::Thread;
use std::io::timer::sleep;
use std::time::duration::Duration;

use xml::reader::EventReader;
use xml::reader::events::XmlEvent;

fn main() {
	println!("XGConsole:");
	for arg in parse_command_line(os::args()).iter() {
		println!("  {}", arg);
	}
	sample();

	let (tx_result, rx_result): (Sender<String>, Receiver<String>) = channel();
	let (tx_task, rx_task): (Sender<String>, Receiver<String>) = channel();
	let mutex_rx_task = Arc::new(Mutex::new(rx_task));

	for cpu_id in range(0, std::os::num_cpus()) {
		let local_rx_task = mutex_rx_task.clone();
		let local_tx_result = tx_result .clone();
				Thread::spawn(move || {
				loop {
					let message: String;
					{
						match local_rx_task.lock().recv_opt() {
								Ok(v) => {message = v;}
								Err(_) => {break;}
							}
					}
					println!("{}: {}", cpu_id, message);
					sleep(Duration::milliseconds(100));
					local_tx_result.send(format!("Done {}", message));
				}
				println!("{}: done", cpu_id);
			}).detach();
	}
	free(tx_result);

	for task_id in range (0i, 50i) {
			tx_task.send(format!("Task {}", task_id));
	}
	free(tx_task);

	for message in rx_result.iter() {
		println!("B: {}", message);
	}
	println!("done");
}

fn free<T>(_:T) {
}

fn parse_command_line(args: Vec<String>) -> Vec<String> {
	let mut result: Vec<String> = Vec::new();
	for arg in args.slice(1, args.len()).iter() {
			result.push(arg.clone());
	}
	result
}

struct XgTask {
id: String,
title: Option<String>,
tool: String,
working_dir: String,
depends_on: Vec<String>,
}

impl fmt::Show for XgTask {
fn fmt(& self, f: &mut fmt::Formatter) -> fmt::Result {
	write!(f, "id={}, title={}, tool={}, working_dir={}, depends_on={}", self .id, self .title, self .tool, self .working_dir, self .depends_on)
}
}

struct XgTool {
id: String,
path: String,
params: String,
}

impl fmt::Show for XgTool {
fn fmt(& self, f: &mut fmt::Formatter) -> fmt::Result {
	write!(f, "id={}, path={}", self .id, self .path)
}
}

fn sample() {
	let file = File::open(&Path::new("tests/graph-parser.xml")).unwrap();
	let reader = BufferedReader::new(file);

	let mut parser = EventReader::new(reader);
	let mut tasks:Vec<XgTask> = vec![];
	let mut tools:HashMap<String, XgTool> = HashMap::new();
	for e in parser.events() {
		match e {
				XmlEvent::StartElement {name, attributes, ..} => {
				match name.local_name.as_slice() {
						"Task" =>
						{
							match xg_parse_task(&attributes) {
									Ok(task) =>
									{
											tasks.push(task);
									}
									Err(msg) =>
									{
										panic!(msg);
									}
								};
						}
						"Tool" =>
						{
							match xg_parse_tool(&attributes) {
									Ok(tool) =>
									{
											tools.insert(tool.id.to_string(), tool);
									}
									Err(msg) =>
									{
										panic!(msg);
									}
								};
						}
						_ => {}
					}
			}
				XmlEvent::EndElement{..} => {
			}
				_ => {
			}
			}
	}
}

fn map_attributes (attributes: &Vec<xml::attribute::OwnedAttribute>) -> HashMap< String, String> {
	let mut attrs: HashMap<String, String> = HashMap::new();
	for attr in attributes.iter() {
			attrs.insert(attr.name.local_name.clone(), attr.value.clone());
	}
	attrs
}

fn xg_parse_task (attributes: & Vec<xml::attribute::OwnedAttribute>)->Result<XgTask, String> {
	let mut attrs = map_attributes(attributes);
	// Name
	let id: String;
	match attrs.remove("Name") {
			Some(v) => {id = v;}
			_ => {return Err("Invalid task data: attribute @Name not found.".to_string());}
		}
	// Tool
	let tool: String;
	match attrs.remove("Tool") {
			Some(v) => {tool = v;}
			_ => {return Err("Invalid task data: attribute @Tool not found.".to_string());}
		}
	// WorkingDir
	let working_dir: String;
	match attrs.remove("WorkingDir") {
			Some(v) => {working_dir = v;}
			_ => {return Err("Invalid task data: attribute @WorkingDir not found.".to_string());}
		}
	// DependsOn
	let mut depends_on : Vec<String> = vec![];
	match attrs.remove("DependsOn") {
			Some(v) =>
			{
				for item in v.split_str(";").collect::<Vec<&str>>().iter() {
						depends_on.push(item.to_string())
				}
			}
			_ =>
			{
			}
		};

		Ok(XgTask {
	id: id.to_string(),
	title: attrs.remove("Caption"),
	tool: tool,
	working_dir: working_dir,
	depends_on: depends_on,
	})
}
fn xg_parse_tool (attributes: &Vec<xml::attribute::OwnedAttribute>)->Result<XgTool, String> {
	let mut attrs = map_attributes(attributes);
	// Name
	let id: String;
	match attrs.remove("Name") {
			Some(v) => {id = v;}
			_ => {return Err("Invalid task data: attribute @Name not found.".to_string());}
		}
	// Path
	let path: String;
	match attrs.remove("Path") {
			Some(v) => {path = v;}
			_ => {return Err("Invalid task data: attribute @Name not found.".to_string());}
		}

	Ok(XgTool {
	id: id,
	path: path,
	params: match attrs.remove("Params") {
			Some(v) => {v}
			_ => {"".to_string()}
		},
	})
}
<commit_msg>Create task graph.<commit_after>extern crate xml;
extern crate rustc;

use std::os;

use std::io::{File, BufferedReader};
use std::fmt;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread::Thread;
use std::io::timer::sleep;
use std::time::duration::Duration;

use rustc::middle::graph::{NodeIndex, Graph};

use xml::reader::EventReader;
use xml::reader::events::XmlEvent;

fn main() {
	println!("XGConsole:");
	for arg in parse_command_line(os::args()).iter() {
		println!("  {}", arg);
	}
	xg_parse();

	let (tx_result, rx_result): (Sender<String>, Receiver<String>) = channel();
	let (tx_task, rx_task): (Sender<String>, Receiver<String>) = channel();
	let mutex_rx_task = Arc::new(Mutex::new(rx_task));

	for cpu_id in range(0, std::os::num_cpus()) {
		let local_rx_task = mutex_rx_task.clone();
		let local_tx_result = tx_result .clone();
				Thread::spawn(move || {
				loop {
					let message: String;
					{
						match local_rx_task.lock().recv_opt() {
								Ok(v) => {message = v;}
								Err(_) => {break;}
							}
					}
					println!("{}: {}", cpu_id, message);
					sleep(Duration::milliseconds(100));
					local_tx_result.send(format!("Done {}", message));
				}
				println!("{}: done", cpu_id);
			}).detach();
	}
	free(tx_result);

	for task_id in range (0i, 50i) {
			tx_task.send(format!("Task {}", task_id));
	}
	free(tx_task);

	for message in rx_result.iter() {
		println!("B: {}", message);
	}
	println!("done");
}

fn free<T>(_:T) {
}

fn parse_command_line(args: Vec<String>) -> Vec<String> {
	let mut result: Vec<String> = Vec::new();
	for arg in args.slice(1, args.len()).iter() {
			result.push(arg.clone());
	}
	result
}

struct BuildTask {
working_dir: String,
}

struct XgTask {
id: Option<String>,
title: Option<String>,
tool: String,
working_dir: String,
depends_on: Vec<String>,
}

impl fmt::Show for XgTask {
fn fmt(& self, f: &mut fmt::Formatter) -> fmt::Result {
	write!(f, "id={}, title={}, tool={}, working_dir={}, depends_on={}", self .id, self .title, self .tool, self .working_dir, self .depends_on)
}
}

struct XgTool {
id: String,
path: String,
params: String,
}

impl fmt::Show for XgTool {
fn fmt(& self, f: &mut fmt::Formatter) -> fmt::Result {
	write!(f, "id={}, path={}", self .id, self .path)
}
}

fn xg_parse() -> Graph<BuildTask, ()> {
	let file = File::open(&Path::new("tests/graph-parser.xml")).unwrap();
	let reader = BufferedReader::new(file);

	let mut parser = EventReader::new(reader);
	let mut tasks:Vec<XgTask> = vec![];
	let mut tools:HashMap<String, XgTool> = HashMap::new();
	for e in parser.events() {
		match e {
				XmlEvent::StartElement {name, attributes, ..} => {
				match name.local_name.as_slice() {
						"Task" =>
						{
							match xg_parse_task(&attributes) {
									Ok(task) =>
									{
											tasks.push(task);
									}
									Err(msg) =>
									{
										panic!(msg);
									}
								};
						}
						"Tool" =>
						{
							match xg_parse_tool(&attributes) {
									Ok(tool) =>
									{
											tools.insert(tool.id.to_string(), tool);
									}
									Err(msg) =>
									{
										panic!(msg);
									}
								};
						}
						_ => {}
					}
			}
				XmlEvent::EndElement{..} => {
			}
				_ => {
			}
			}
	}
	xg_parse_create_graph(&tasks)
}

fn xg_parse_create_graph(tasks:&Vec<XgTask>) -> Graph<BuildTask, ()> {
	let mut graph: Graph<BuildTask, ()> = Graph::new();
	let mut nodes: Vec<NodeIndex> = vec![];
	let mut task_refs: HashMap<&str, NodeIndex> = HashMap::new();
	for task in tasks.iter() {
		let node = graph.add_node(BuildTask {
		working_dir : task.working_dir.clone(),
		});
		match task.id {
				Some(ref v) => {
					task_refs.insert(v.as_slice(), node);
			}
				_ => {}
			}
		nodes.push(node);
	}
	for idx in range(0, nodes.len()) {
		let ref task = tasks[idx];
		let ref node = nodes[idx];
		for id in task.depends_on.iter() {
			let dep_node = task_refs.get(id.as_slice());
			graph.add_edge(*node, *dep_node.unwrap(), ());
		}
	}
	graph
}

fn map_attributes (attributes: &Vec<xml::attribute::OwnedAttribute>) -> HashMap< String, String> {
	let mut attrs: HashMap<String, String> = HashMap::new();
	for attr in attributes.iter() {
			attrs.insert(attr.name.local_name.clone(), attr.value.clone());
	}
	attrs
}

fn xg_parse_task (attributes: & Vec<xml::attribute::OwnedAttribute>)->Result<XgTask, String> {
	let mut attrs = map_attributes(attributes);
	// Tool
	let tool: String;
	match attrs.remove("Tool") {
			Some(v) => {tool = v;}
			_ => {return Err("Invalid task data: attribute @Tool not found.".to_string());}
		}
	// WorkingDir
	let working_dir: String;
	match attrs.remove("WorkingDir") {
			Some(v) => {working_dir = v;}
			_ => {return Err("Invalid task data: attribute @WorkingDir not found.".to_string());}
		}
	// DependsOn
	let mut depends_on : Vec<String> = vec![];
	match attrs.remove("DependsOn") {
			Some(v) =>
			{
				for item in v.split_str(";").collect::<Vec<&str>>().iter() {
						depends_on.push(item.to_string())
				}
			}
			_ =>
			{
			}
		};

		Ok(XgTask {
	id: attrs.remove("Name"),
	title: attrs.remove("Caption"),
	tool: tool,
	working_dir: working_dir,
	depends_on: depends_on,
	})
}
fn xg_parse_tool (attributes: &Vec<xml::attribute::OwnedAttribute>)->Result<XgTool, String> {
	let mut attrs = map_attributes(attributes);
	// Name
	let id: String;
	match attrs.remove("Name") {
			Some(v) => {id = v;}
			_ => {return Err("Invalid task data: attribute @Name not found.".to_string());}
		}
	// Path
	let path: String;
	match attrs.remove("Path") {
			Some(v) => {path = v;}
			_ => {return Err("Invalid task data: attribute @Name not found.".to_string());}
		}

	Ok(XgTool {
	id: id,
	path: path,
	params: match attrs.remove("Params") {
			Some(v) => {v}
			_ => {"".to_string()}
		},
	})
}
<|endoftext|>


<commit_before>extern crate mmap;

use std::ptr;
use std::fs::OpenOptions;
use std::os::unix::fs::OpenOptionsExt;
use mmap::{MemoryMap, MapOption};
use std::os::unix::prelude::AsRawFd;

const BCM2708_PERI_BASE: u32 = 0x20000000;
const GPIO_BASE: u8 = (BCM2708_PERI_BASE + 0x200000) as u8;
const O_SYNC: u32 = 1052672;
const MAP_SHARED: i32 = 0x0001;
const BLOCK_SIZE: usize = (4*1024);

#[allow(dead_code)]
struct Bcm2835Peripheral {
    addr_p: *const u8,
    mem_fd: std::fs::File,
    map: mmap::MemoryMap,
    addr: *mut u8
}

impl Drop for Bcm2835Peripheral {
    fn drop(&mut self) {
        println!("Unmapped Peripheral {:?}", self.map.data())
    }
}

fn main() {
    let mut gpio = Bcm2835Peripheral { addr_p: &GPIO_BASE, mem_fd: OpenOptions::new().create(true).open("temp.txt").unwrap(), map: MemoryMap::new(1024, &[]).unwrap(), addr: ptr::null_mut()};
    map_peripheral(&mut gpio);
    unmap_peripheral(gpio);
}

fn map_peripheral(ref mut foo: &mut Bcm2835Peripheral) {
    foo.mem_fd = OpenOptions::new()
                    .read(true)
                    .write(true)
                    .mode(O_SYNC)
                    .open("/dev/mem")
                    .expect("unable to open /dev/mem, Are you root?");

    let map_opts = &[
        MapOption::MapNonStandardFlags(MAP_SHARED),
        MapOption::MapReadable,
        MapOption::MapWritable,
       // MapOption::MapAddr(foo.addr_p),
        MapOption::MapFd(foo.mem_fd.as_raw_fd())
    ];

   let mmap = match MemoryMap::new(BLOCK_SIZE, map_opts) {
     Ok(mmap) => mmap,
     Err(e) => panic!("ERR: {}", e)
    };
    foo.map = mmap;
    foo.addr = foo.map.data();
}

fn unmap_peripheral(foo: Bcm2835Peripheral) {
    drop(foo);
}

fn in_gpio(foo: &Bcm2835Peripheral, y: isize) {
  unsafe {
      let k = &foo.addr.offset(y/10);
      **k &= !(7<<(((y)%10)*3));
  }
}

fn out_gpio(foo: &Bcm2835Peripheral, y:isize) {
  unsafe {
      let k = &foo.addr.offset(y/10);
      **k |= (7<<(((y)%10)*3));
  }
}

fn set_gpio_alt(foo: &Bcm2835Peripheral, y:isize, a:u8) {
    unsafe {
        let k = &foo.addr.offset(y/10);
        **k |= match a {
            a if a<=3 => a+4,
            4         => 3,
            _         => 2,
        } << ((y % 10) * 3);
    }
}

fn set_gpio(foo: &Bcm2835Peripheral, val: *mut u8) {
    foo.addr.offset(7) = val;                            //Invalid left-hand side assignment
}
<commit_msg>reorganize code by moving free functions and impl them to Bcm2835Peripheral<commit_after>extern crate mmap;

use std::ptr;
use std::fs::OpenOptions;
use std::os::unix::fs::OpenOptionsExt;
use mmap::{MemoryMap, MapOption};
use std::os::unix::prelude::AsRawFd;

const BCM2708_PERI_BASE: u32 = 0x20000000;
const GPIO_BASE: u8 = (BCM2708_PERI_BASE + 0x200000) as u8;
const O_SYNC: u32 = 1052672;
const MAP_SHARED: i32 = 0x0001;
const BLOCK_SIZE: usize = (4*1024);

#[allow(dead_code)]
struct Bcm2835Peripheral {
    addr_p: *const u8,
    mem_fd: std::fs::File,
    map: mmap::MemoryMap,
    addr: *mut u8
}

impl Bcm2835Peripheral {
    fn map_peripheral(&mut self) {
        self.mem_fd = OpenOptions::new()
                        .read(true)
                        .write(true)
                        .mode(O_SYNC)
                        .open("/dev/mem")
                        .expect("unable to open /dev/mem, Are you root?");

        let map_opts = &[
            MapOption::MapNonStandardFlags(MAP_SHARED),
            MapOption::MapReadable,
            MapOption::MapWritable,
           // MapOption::MapAddr(self.addr_p),
            MapOption::MapFd(self.mem_fd.as_raw_fd())
        ];

       let mmap = match MemoryMap::new(BLOCK_SIZE, map_opts) {
         Ok(mmap) => mmap,
         Err(e) => panic!("ERR: {}", e)
        };
        self.map = mmap;
        self.addr = self.map.data();
    }

    fn unmap_peripheral(self) {
        drop(self);
    }

    unsafe fn in_gpio(&self, y: isize) {
        let k = &self.addr.offset(y/10);
        **k &= !(7<<(((y)%10)*3));
    }

    unsafe fn out_gpio(&self, y:isize) {
        let k = &self.addr.offset(y/10);
        **k |= (7<<(((y)%10)*3));
    }

    unsafe fn set_gpio_alt(&self, y:isize, a:u8) {
        let k = &self.addr.offset(y/10);
        **k |= match a {
            a if a<=3 => a+4,
            4         => 3,
            _         => 2,
        } << ((y % 10) * 3);
    }

    unsafe fn set_gpio(&self, val: u8) {
        *self.addr.offset(7) = val;
    }
    unsafe fn clear_gpio(&self, val: u8) {
        *self.addr.offset(10) = val;
    }
}

impl Drop for Bcm2835Peripheral {
    fn drop(&mut self) {
        println!("Unmapped Peripheral {:?}", self.map.data())
    }
}

fn main() {
    let mut gpio = Bcm2835Peripheral { addr_p: &GPIO_BASE, mem_fd: OpenOptions::new().create(true).open("temp.txt").unwrap(), map: MemoryMap::new(1024, &[]).unwrap(), addr: ptr::null_mut()};
    gpio.map_peripheral();
}
<|endoftext|>