<commit_before>#[macro_use] extern crate glium;
#[macro_use] extern crate nalgebra as na;
extern crate obj;

use std::path::Path;
use std::f32::consts::{FRAC_PI_2};

use obj::SimplePolygon;

use na::{Pnt3, Vec3, Mat3, Iso3, PerspMat3};
use na::{Eye};

const PI_4: f32 = std::f32::consts::FRAC_PI_4;

#[derive(Copy, Clone)]
struct Vert {
    position: [f32;3],
    normal: [f32;3],
    color: [f32;3],
}

implement_vertex!(Vert, position, normal, color);

fn setup_icosohedron(window: &glium::backend::glutin_backend::GlutinFacade) -> glium::vertex::VertexBuffer<Vert> {
    let p = Path::new("/home/hcs/code/rust/triangle/meshes/icosohedron.obj");
    let o = obj::load::<SimplePolygon>(p).unwrap();

    let green = [0f32, 1.0, 0.0];

    let size = o.position().len();
    let mut data = Vec::with_capacity(size);

    for ob in o.object_iter() {
        for g in ob.group_iter() {
            for tri in g.indices() {
                data.push(
                    Vert {
                        position: o.position()[tri[0].0],
                        normal: o.normal()[(tri[0].2).unwrap()],
                        color: green.clone(),
                    }
                );
                data.push(
                    Vert {
                        position: o.position()[tri[1].0],
                        normal: o.normal()[(tri[1].2).unwrap()],
                        color: green.clone(),
                    }
                );
                data.push(
                    Vert {
                        position: o.position()[tri[2].0],
                        normal: o.normal()[(tri[2].2).unwrap()],
                        color: green.clone(),
                    }
                );
            }
        }
    }

    glium::vertex::VertexBuffer::new(window, &data).unwrap()
}

fn setup_plane(window: &glium::backend::glutin_backend::GlutinFacade) -> glium::vertex::VertexBuffer<Vert> {
    let tr = [1f32, 1.0, 0.0];
    let tl = [-1f32, 1.0, 0.0];
    let bl = [-1f32, -1.0, 0.0];
    let br = [1f32, -1.0, 0.0];

    let n = [0f32, 0.0, 1.0];

    let white = [1f32, 1.0, 1.0];

    let data = &[
        Vert {
            position: tr,
            normal: n,
            color: white,
        },
        Vert {
            position: tl,
            normal: n,
            color: white,
        },
        Vert {
            position: bl,
            normal: n,
            color: white,
        },

        Vert {
            position: tr,
            normal: n,
            color: white,
        },
        Vert {
            position: bl,
            normal: n,
            color: white,
        },
        Vert {
            position: br,
            normal: n,
            color: white,
        },
    ];
    glium::vertex::VertexBuffer::new(window, data).unwrap()
}

fn setup_shaders(window: &glium::backend::glutin_backend::GlutinFacade) -> glium::program::Program {
    let v_shader = "
        #version 150

        uniform mat4 perspective;
        uniform mat4 mv;
        uniform mat4 m_invt;
        uniform vec3 light_dir;

        in vec3 position;
        in vec3 normal;
        in vec3 color;

        out vec3 f_color;

        void main() {
            gl_Position = perspective*mv*vec4(position, 1.0);

            vec3 mv_normal = normalize(vec3(m_invt * vec4(normal, 0.0)));
            float diffuse = 0.6*max( dot(mv_normal, light_dir), 0.1);

            f_color = diffuse*color;
        }
    ";
    let f_shader = "
        #version 150

        in vec3 f_color;

        void main() {
            gl_FragColor = vec4(f_color, 1.0);
        }
    ";
    glium::program::Program::from_source(window, v_shader, f_shader, None).unwrap()
}

fn main() {
    use glium::{DisplayBuild,Surface};

    const WIDTH: u32 = 1280;
    const HEIGHT: u32 = 720;
    const ASPECT: f32 = 1.78;

	let params = glium::DrawParameters {
		backface_culling: glium::draw_parameters::BackfaceCullingMode::CullClockwise,
		depth: glium::Depth {
			test: glium::draw_parameters::DepthTest::IfLess,
			write: true,
			.. Default::default()
		},
		.. Default::default()
	};

    let window = glium::glutin::WindowBuilder::new()
        .with_dimensions(WIDTH, HEIGHT)
        .with_depth_buffer(24)
        .with_title(format!("Hello world"))
        .build_glium()
        .unwrap();

    let icosohedron = setup_icosohedron(&window);
    let plane = setup_plane(&window);
    let program = setup_shaders(&window);
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let persp = PerspMat3::new(ASPECT, PI_4, 1.0, 100.0).to_mat();

    let mut position = Pnt3::new(0.0f32, 1.0f32, 5.0f32);
    let dir = Vec3::new(0.0f32, 0.0f32, -1.0f32);
    let up = Vec3::new(0.0f32, 1.0f32, 0.0f32);

    let mut t = 0f32;

    let mut exit = false;
    loop {
        for event in window.poll_events() {
            use glium::glutin::Event;
			use glium::glutin::VirtualKeyCode as KC;
            match event {
                Event::Closed => (exit = true),
				Event::KeyboardInput(state, _, key) => {
                    if state == glium::glutin::ElementState::Pressed {
                        match key.unwrap() {
                            KC::PageUp => {position = position + Vec3::new(0f32, 0.2f32, 0f32);},
                            KC::PageDown => {position = position + Vec3::new(0f32, -0.2f32, 0f32);},
							KC::Left => position = position + Vec3::new(-0.2f32, 0f32, 0f32),
							KC::Right => position = position + Vec3::new(0.2f32, 0f32, 0f32),
							KC::Up => position = position + Vec3::new(0f32, 0f32, -0.2f32),
							KC::Down => position = position + Vec3::new(0f32, 0f32, 0.2f32),
                            KC::Space => {println!("hello");}
                            KC::Escape => {exit = true;},
                            _ => ()
                        }
                    }
				}
                _ => ()
            }
        }

        t += 0.05;

        let mut frame = window.draw();
        frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);

        // camera
        let view = na::inv(&Iso3::look_at_z(&position, &(position + dir), &up)).unwrap();
        let view = na::to_homogeneous(&view);
        let light_dir = [0.5, 0.866025, 0f32];

        // draw tetrahedrons
        for i in 0..10 {
            let model = Iso3::new(Vec3::new(0f32, 0.0, -5f32*i as f32), Vec3::new(0f32, 1.0, 0.0) * t);
            let model = na::to_homogeneous(&model);
            let modelview = view*model;

            let uniforms = uniform! {
                perspective: persp.as_ref().clone(),
                mv: modelview.as_ref().clone(),
                m_invt: na::transpose(&na::inv(&model).unwrap()).as_ref().clone(),
                light_dir: light_dir,
            };

            frame.draw(&icosohedron, &indices, &program, &uniforms,
                                &params).unwrap();
        }

        // draw plane below icosohedron
        let scale = 50f32;
        let plane_scale = na::to_homogeneous(&(Mat3::<f32>::new_identity(3)*scale));
        let plane_rot = na::to_homogeneous(&(Iso3::new(Vec3::new(0f32, -1.0, 0.0), Vec3::new(1f32, 0.0, 0.0)*-FRAC_PI_2)));
        let plane_model = plane_rot*plane_scale;
        let modelview = view*plane_model;

        let uniforms = uniform! {
            perspective: persp.as_ref().clone(),
            mv: modelview.as_ref().clone(),
            m_invt: na::transpose(&na::inv(&plane_model).unwrap()).as_ref().clone(),
            light_dir: light_dir,
        };
        frame.draw(&plane, &indices, &program, &uniforms,
                            &params).unwrap();

        frame.finish().unwrap();
        window.swap_buffers().unwrap();

        if exit {
            break;
        }
    }
}
<commit_msg>Add code to take mesh directory as a command line argument<commit_after>#[macro_use] extern crate glium;
#[macro_use] extern crate nalgebra as na;
extern crate obj;

use std::f32::consts::{FRAC_PI_2};

use obj::SimplePolygon;

use na::{Pnt3, Vec3, Mat3, Iso3, PerspMat3};
use na::{Eye};

const PI_4: f32 = std::f32::consts::FRAC_PI_4;

#[derive(Copy, Clone)]
struct Vert {
    position: [f32;3],
    normal: [f32;3],
    color: [f32;3],
}

implement_vertex!(Vert, position, normal, color);

fn setup_icosohedron(meshes_dir: String, window: &glium::backend::glutin_backend::GlutinFacade) -> glium::vertex::VertexBuffer<Vert> {
    let mut p = std::path::PathBuf::from(meshes_dir);
    p.push("icosohedron.obj");
    let o = obj::load::<SimplePolygon>(&p).unwrap();

    let green = [0f32, 1.0, 0.0];

    let size = o.position().len();
    let mut data = Vec::with_capacity(size);

    for ob in o.object_iter() {
        for g in ob.group_iter() {
            for tri in g.indices() {
                data.push(
                    Vert {
                        position: o.position()[tri[0].0],
                        normal: o.normal()[(tri[0].2).unwrap()],
                        color: green.clone(),
                    }
                );
                data.push(
                    Vert {
                        position: o.position()[tri[1].0],
                        normal: o.normal()[(tri[1].2).unwrap()],
                        color: green.clone(),
                    }
                );
                data.push(
                    Vert {
                        position: o.position()[tri[2].0],
                        normal: o.normal()[(tri[2].2).unwrap()],
                        color: green.clone(),
                    }
                );
            }
        }
    }

    glium::vertex::VertexBuffer::new(window, &data).unwrap()
}

fn setup_plane(window: &glium::backend::glutin_backend::GlutinFacade) -> glium::vertex::VertexBuffer<Vert> {
    let tr = [1f32, 1.0, 0.0];
    let tl = [-1f32, 1.0, 0.0];
    let bl = [-1f32, -1.0, 0.0];
    let br = [1f32, -1.0, 0.0];

    let n = [0f32, 0.0, 1.0];

    let white = [1f32, 1.0, 1.0];

    let data = &[
        Vert {
            position: tr,
            normal: n,
            color: white,
        },
        Vert {
            position: tl,
            normal: n,
            color: white,
        },
        Vert {
            position: bl,
            normal: n,
            color: white,
        },

        Vert {
            position: tr,
            normal: n,
            color: white,
        },
        Vert {
            position: bl,
            normal: n,
            color: white,
        },
        Vert {
            position: br,
            normal: n,
            color: white,
        },
    ];
    glium::vertex::VertexBuffer::new(window, data).unwrap()
}

fn setup_shaders(window: &glium::backend::glutin_backend::GlutinFacade) -> glium::program::Program {
    let v_shader = "
        #version 150

        uniform mat4 perspective;
        uniform mat4 mv;
        uniform mat4 m_invt;
        uniform vec3 light_dir;

        in vec3 position;
        in vec3 normal;
        in vec3 color;

        out vec3 f_color;

        void main() {
            gl_Position = perspective*mv*vec4(position, 1.0);

            vec3 mv_normal = normalize(vec3(m_invt * vec4(normal, 0.0)));
            float diffuse = 0.6*max( dot(mv_normal, light_dir), 0.1);

            f_color = diffuse*color;
        }
    ";
    let f_shader = "
        #version 150

        in vec3 f_color;

        void main() {
            gl_FragColor = vec4(f_color, 1.0);
        }
    ";
    glium::program::Program::from_source(window, v_shader, f_shader, None).unwrap()
}

fn main() {
    use glium::{DisplayBuild,Surface};

    let meshes_dir = match std::env::args().nth(1) {
        Some(dir) => dir,
        None => {
            println!("Usage: ./triangle [path_to_meshes_directory]");
            return;
        },
    };

    const WIDTH: u32 = 1280;
    const HEIGHT: u32 = 720;
    const ASPECT: f32 = 1.78;

	let params = glium::DrawParameters {
		backface_culling: glium::draw_parameters::BackfaceCullingMode::CullClockwise,
		depth: glium::Depth {
			test: glium::draw_parameters::DepthTest::IfLess,
			write: true,
			.. Default::default()
		},
		.. Default::default()
	};

    let window = glium::glutin::WindowBuilder::new()
        .with_dimensions(WIDTH, HEIGHT)
        .with_depth_buffer(24)
        .with_title(format!("Hello world"))
        .build_glium()
        .unwrap();

    let icosohedron = setup_icosohedron(meshes_dir, &window);
    let plane = setup_plane(&window);
    let program = setup_shaders(&window);
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let persp = PerspMat3::new(ASPECT, PI_4, 1.0, 100.0).to_mat();

    let mut position = Pnt3::new(0.0f32, 1.0f32, 5.0f32);
    let dir = Vec3::new(0.0f32, 0.0f32, -1.0f32);
    let up = Vec3::new(0.0f32, 1.0f32, 0.0f32);

    let mut t = 0f32;

    let mut exit = false;
    loop {
        for event in window.poll_events() {
            use glium::glutin::Event;
			use glium::glutin::VirtualKeyCode as KC;
            match event {
                Event::Closed => (exit = true),
				Event::KeyboardInput(state, _, key) => {
                    if state == glium::glutin::ElementState::Pressed {
                        match key.unwrap() {
                            KC::PageUp => {position = position + Vec3::new(0f32, 0.2f32, 0f32);},
                            KC::PageDown => {position = position + Vec3::new(0f32, -0.2f32, 0f32);},
							KC::Left => position = position + Vec3::new(-0.2f32, 0f32, 0f32),
							KC::Right => position = position + Vec3::new(0.2f32, 0f32, 0f32),
							KC::Up => position = position + Vec3::new(0f32, 0f32, -0.2f32),
							KC::Down => position = position + Vec3::new(0f32, 0f32, 0.2f32),
                            KC::Space => {println!("hello");}
                            KC::Escape => {exit = true;},
                            _ => ()
                        }
                    }
				}
                _ => ()
            }
        }

        t += 0.05;

        let mut frame = window.draw();
        frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);

        // camera
        let view = na::inv(&Iso3::look_at_z(&position, &(position + dir), &up)).unwrap();
        let view = na::to_homogeneous(&view);
        let light_dir = [0.5, 0.866025, 0f32];

        // draw tetrahedrons
        for i in 0..10 {
            let model = Iso3::new(Vec3::new(0f32, 0.0, -5f32*i as f32), Vec3::new(0f32, 1.0, 0.0) * t);
            let model = na::to_homogeneous(&model);
            let modelview = view*model;

            let uniforms = uniform! {
                perspective: persp.as_ref().clone(),
                mv: modelview.as_ref().clone(),
                m_invt: na::transpose(&na::inv(&model).unwrap()).as_ref().clone(),
                light_dir: light_dir,
            };

            frame.draw(&icosohedron, &indices, &program, &uniforms,
                                &params).unwrap();
        }

        // draw plane below icosohedron
        let scale = 50f32;
        let plane_scale = na::to_homogeneous(&(Mat3::<f32>::new_identity(3)*scale));
        let plane_rot = na::to_homogeneous(&(Iso3::new(Vec3::new(0f32, -1.0, 0.0), Vec3::new(1f32, 0.0, 0.0)*-FRAC_PI_2)));
        let plane_model = plane_rot*plane_scale;
        let modelview = view*plane_model;

        let uniforms = uniform! {
            perspective: persp.as_ref().clone(),
            mv: modelview.as_ref().clone(),
            m_invt: na::transpose(&na::inv(&plane_model).unwrap()).as_ref().clone(),
            light_dir: light_dir,
        };
        frame.draw(&plane, &indices, &program, &uniforms,
                            &params).unwrap();

        frame.finish().unwrap();
        window.swap_buffers().unwrap();

        if exit {
            break;
        }
    }
}
<|endoftext|>


<commit_before>extern crate regex;
#[macro_use] extern crate lazy_static;
extern crate irc;
extern crate xdg_basedir;
extern crate hyper;
extern crate url;

mod github;

use regex::Regex;
use irc::client::prelude::*;
use xdg_basedir::*;
use std::io::Read;
use std::vec::Vec;
use std::iter::FromIterator;
use url::Url;

fn parse_post(post: &str) -> Option<String> {
    let client = hyper::client::Client::new();
    lazy_static! {
        static ref URL_REGEX: Regex = Regex::new(
            r"https?://\S+\.[:alpha:]{2,}\S+").unwrap();
        static ref ISSUE_REGEX: Regex = Regex::new(
            r"([^ ()]+)/([^ ()]+)#(\d+)").unwrap();
        static ref TITLE_REGEX: Regex = Regex::new(
            r"<title>(.+)</title>").unwrap();
    }

    if let Some(x) = URL_REGEX.captures(post) {
        if let Ok(parsedurl) = Url::parse(x.at(0).unwrap()) {
            if parsedurl.domain().unwrap().ends_with("github.com") {
                let urlpath = Vec::from_iter(parsedurl.path_segments().unwrap());
                if urlpath.len() == 4 &&
                    (urlpath[2] == "issues" || urlpath[2] == "pull") {
                        return github::get_display_text(&urlpath[0],
                                                        &urlpath[1],
                                                        &urlpath[3],
                                                        false).ok();
                    }
            }
        }
        if let Ok(mut resp) = client.get(x.at(0).unwrap()).send() {
            let mut body = String::new();
            if let Err(..) = resp.read_to_string(&mut body) {
                return None; // Not UTF8 (binary file?)
            } else if let Some(cap) = TITLE_REGEX.captures(&body) {
                return Some(format!("Title: {}", cap.at(1).unwrap()));
            }
        }
    } else if let Some(cap) = ISSUE_REGEX.captures(post) {
        let user = cap.at(1).unwrap();
        let repo = cap.at(2).unwrap();
        let number = cap.at(3).unwrap();
        return github::get_display_text(user, repo, number, true).ok();
    }
    None
}

fn handle_message(server: &IrcServer, from: &str, to: &str, message: &str) {
    let nickname = server.config().nickname.as_ref().unwrap();

    if to == nickname && from == "ids1024" {
        let mut words = message.split_whitespace();
        let command = words.next().unwrap_or("");
        let parameter = words.next().unwrap_or("");
        match command {
            "join" => server.send_join(parameter).unwrap(),
            "part" => server.send(
                Command::PART(parameter.to_string(), None)
                ).unwrap(),
            "quit" => server.send_quit("").unwrap(),
            _ => {},
        }
    }

    if let Some(x) = parse_post(&message) {
        for line in x.lines() {
            server.send_notice(&to, &line).unwrap();
        }
    }
}

fn main() {
    let mut configpath = get_config_home().unwrap();
    configpath.push("idsbot/config.json");

    let config = Config::load(configpath).unwrap();
    let server = IrcServer::from_config(config).unwrap();
    server.identify().unwrap();

    for message in server.iter() {
        let message = message.unwrap();
        print!("{}", message.to_string());
        let from = message.source_nickname().map(|s| s.to_owned());
        if let Command::PRIVMSG(to, content) = message.command {
            handle_message(&server, &from.unwrap(), &to, &content);
        }
    }
}
<commit_msg>Use map to avoid redundancy<commit_after>extern crate regex;
#[macro_use] extern crate lazy_static;
extern crate irc;
extern crate xdg_basedir;
extern crate hyper;
extern crate url;

mod github;

use regex::Regex;
use irc::client::prelude::*;
use xdg_basedir::*;
use std::io::Read;
use std::vec::Vec;
use std::iter::FromIterator;
use url::Url;

fn parse_post(post: &str) -> Option<String> {
    let client = hyper::client::Client::new();
    lazy_static! {
        static ref URL_REGEX: Regex = Regex::new(
            r"https?://\S+\.[:alpha:]{2,}\S+").unwrap();
        static ref ISSUE_REGEX: Regex = Regex::new(
            r"([^ ()]+)/([^ ()]+)#(\d+)").unwrap();
        static ref TITLE_REGEX: Regex = Regex::new(
            r"<title>(.+)</title>").unwrap();
    }

    if let Some(url) = URL_REGEX.captures(post).map(|m| m.at(0).unwrap()) {
        if let Ok(parsedurl) = Url::parse(url) {
            if parsedurl.domain().unwrap().ends_with("github.com") {
                let urlpath = Vec::from_iter(parsedurl.path_segments().unwrap());
                if urlpath.len() == 4 &&
                    (urlpath[2] == "issues" || urlpath[2] == "pull") {
                        return github::get_display_text(&urlpath[0],
                                                        &urlpath[1],
                                                        &urlpath[3],
                                                        false).ok();
                    }
            }
        }
        if let Ok(mut resp) = client.get(url).send() {
            let mut body = String::new();
            if let Err(..) = resp.read_to_string(&mut body) {
                return None; // Not UTF8 (binary file?)
            } else if let Some(cap) = TITLE_REGEX.captures(&body) {
                return Some(format!("Title: {}", cap.at(1).unwrap()));
            }
        }
    } else if let Some(cap) = ISSUE_REGEX.captures(post) {
        let user = cap.at(1).unwrap();
        let repo = cap.at(2).unwrap();
        let number = cap.at(3).unwrap();
        return github::get_display_text(user, repo, number, true).ok();
    }
    None
}

fn handle_message(server: &IrcServer, from: &str, to: &str, message: &str) {
    let nickname = server.config().nickname.as_ref().unwrap();

    if to == nickname && from == "ids1024" {
        let mut words = message.split_whitespace();
        let command = words.next().unwrap_or("");
        let parameter = words.next().unwrap_or("");
        match command {
            "join" => server.send_join(parameter).unwrap(),
            "part" => server.send(
                Command::PART(parameter.to_string(), None)
                ).unwrap(),
            "quit" => server.send_quit("").unwrap(),
            _ => {},
        }
    }

    if let Some(x) = parse_post(&message) {
        for line in x.lines() {
            server.send_notice(&to, &line).unwrap();
        }
    }
}

fn main() {
    let mut configpath = get_config_home().unwrap();
    configpath.push("idsbot/config.json");

    let config = Config::load(configpath).unwrap();
    let server = IrcServer::from_config(config).unwrap();
    server.identify().unwrap();

    for message in server.iter() {
        let message = message.unwrap();
        print!("{}", message.to_string());
        let from = message.source_nickname().map(|s| s.to_owned());
        if let Command::PRIVMSG(to, content) = message.command {
            handle_message(&server, &from.unwrap(), &to, &content);
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::io::{self, Write};

pub mod location;
pub use location::GpsCoordinates;

pub mod nrel;

pub mod material;
pub mod temperature;

const NREL_API_KEY: &'static str = env!("NREL_API_KEY");

pub type Ghi = f64;

/// Average Global Horizontal Irradiance
#[derive(Debug, Clone, Copy)]
pub struct CompleteGhi {
    pub annual: Ghi,
    pub january: Ghi,
    pub february: Ghi,
    pub march: Ghi,
    pub april: Ghi,
    pub may: Ghi,
    pub june: Ghi,
    pub july: Ghi,
    pub august: Ghi,
    pub september: Ghi,
    pub october: Ghi,
    pub november: Ghi,
    pub december: Ghi,
}

pub enum Month {
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December,
}

impl fmt::Display for Month {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{}",
               match *self {
                   Month::January => "janvier",
                   Month::February => "février",
                   Month::March => "mars",
                   Month::April => "avril",
                   Month::May => "mai",
                   Month::June => "juin",
                   Month::July => "juillet",
                   Month::August => "août",
                   Month::September => "septembre",
                   Month::October => "octobre",
                   Month::November => "novembre",
                   Month::December => "décembre",
               })
    }
}

fn flush() {
    io::stdout().flush().unwrap();
}

fn average_ghi_for_month(complete_ghi: &CompleteGhi, month: &Month) -> f64 {
    match *month {
        Month::January => complete_ghi.january,
        Month::February => complete_ghi.february,
        Month::March => complete_ghi.march,
        Month::April => complete_ghi.april,
        Month::May => complete_ghi.may,
        Month::June => complete_ghi.june,
        Month::July => complete_ghi.july,
        Month::August => complete_ghi.august,
        Month::September => complete_ghi.september,
        Month::October => complete_ghi.october,
        Month::November => complete_ghi.november,
        Month::December => complete_ghi.december,
    }
}

fn main() {
    let cities = vec![location::SEATTLE,
                      location::BOSTON,
                      location::LOS_ANGELES,
                      location::MIAMI,
                      location::DENVER];

    let months = vec![Month::January,
                      Month::February,
                      Month::March,
                      Month::April,
                      Month::May,
                      Month::June,
                      Month::July,
                      Month::August,
                      Month::September,
                      Month::October,
                      Month::November,
                      Month::December];

    let materials = vec![material::SAND,
                         material::GREEN_GRASS,
                         material::STAINLESS_STEEL,
                         material::CONCRETE];

    println!("Merci de choisir un lieu au sein de la liste suivante :\n");

    print!(r##"Villes américaines :
 1. Seattle (Nord-Ouest)
 2. Boston (Nord-Est)
 3. Los Angeles (Sud-Ouest)
 4. Miami (Sud-Est)
 5. Denver (Centre)

Entrez le nombre correspondant à la ville désirée : "##);
    flush();

    let mut choice = String::new();
    io::stdin().read_line(&mut choice).unwrap();

    println!("");

    let idx = choice.trim().parse::<usize>().unwrap() - 1; // UX uses 1-indexed lists
    let location = cities.get(idx).unwrap();

    println!("Vous avez choisi : {}\n", location);

    print!("Recherche de données d'ensoleillement dans la base NREL... ");
    flush();

    let avg_ghi = nrel::average_ghi(&location.coords);
    println!("ok.\n");

    print!("Entrez un mois (nombre de 1 à 12) : ");
    flush();

    let mut choice = String::new();
    io::stdin().read_line(&mut choice).unwrap();

    let idx = choice.trim().parse::<usize>().unwrap() - 1;
    let month = months.get(idx).unwrap();

    let ghi = average_ghi_for_month(&avg_ghi, &month);

    println!("Global Horizontal Irradiance à {} au mois de '{}' : {:.2} kWh/m2/jour",
             location,
             month,
             ghi);

    println!("Merci de choisir un matériau au sein de la liste suivante :\n");

    print!(r##"Matériaux :
 1. Sable
 2. Herbe verte
 3. Acier inoxydable
 4. Béton

Entrez le nombre correspondant au matériau désiré : "##);
    flush();

    let mut choice = String::new();
    io::stdin().read_line(&mut choice).unwrap();

    let idx = choice.trim().parse::<usize>().unwrap() - 1;
    let material = materials.get(idx).unwrap();

    println!("Vous avez chosi le matériau : {}", material);

    let temperature =
        temperature::kelvin_to_celcius(temperature::kelvin_temperature(material.albedo,
                                                                       material.emissivity,
                                                                       ghi * 1000.0 / 24.0)); // 1366

    println!("Température : {:.2}°C", temperature);

    // println!("Données : {:?}", avg_ghi);
    // match month {
    //    Month::January => ghi.january,
    //    Month::February => ghi.february,
    //    Month::March => ghi.march,
    //    Month::April => ghi.april,
    //    Month::May => ghi.may,
    //    Month::June => ghi.june,
    //    Month::July => ghi.july,
    //    Month::August => ghi.august,
    //    Month::September => ghi.september,
    //    Month::October => ghi.october,
    //    Month::November => ghi.november,
    //    Month::December => ghi.december,
    // }
}
<commit_msg>fix output formatting<commit_after>use std::fmt;
use std::io::{self, Write};

pub mod location;
pub use location::GpsCoordinates;

pub mod nrel;

pub mod material;
pub mod temperature;

const NREL_API_KEY: &'static str = env!("NREL_API_KEY");

pub type Ghi = f64;

/// Average Global Horizontal Irradiance
#[derive(Debug, Clone, Copy)]
pub struct CompleteGhi {
    pub annual: Ghi,
    pub january: Ghi,
    pub february: Ghi,
    pub march: Ghi,
    pub april: Ghi,
    pub may: Ghi,
    pub june: Ghi,
    pub july: Ghi,
    pub august: Ghi,
    pub september: Ghi,
    pub october: Ghi,
    pub november: Ghi,
    pub december: Ghi,
}

pub enum Month {
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December,
}

impl fmt::Display for Month {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{}",
               match *self {
                   Month::January => "janvier",
                   Month::February => "février",
                   Month::March => "mars",
                   Month::April => "avril",
                   Month::May => "mai",
                   Month::June => "juin",
                   Month::July => "juillet",
                   Month::August => "août",
                   Month::September => "septembre",
                   Month::October => "octobre",
                   Month::November => "novembre",
                   Month::December => "décembre",
               })
    }
}

fn flush() {
    io::stdout().flush().unwrap();
}

fn average_ghi_for_month(complete_ghi: &CompleteGhi, month: &Month) -> f64 {
    match *month {
        Month::January => complete_ghi.january,
        Month::February => complete_ghi.february,
        Month::March => complete_ghi.march,
        Month::April => complete_ghi.april,
        Month::May => complete_ghi.may,
        Month::June => complete_ghi.june,
        Month::July => complete_ghi.july,
        Month::August => complete_ghi.august,
        Month::September => complete_ghi.september,
        Month::October => complete_ghi.october,
        Month::November => complete_ghi.november,
        Month::December => complete_ghi.december,
    }
}

fn main() {
    let cities = vec![location::SEATTLE,
                      location::BOSTON,
                      location::LOS_ANGELES,
                      location::MIAMI,
                      location::DENVER];

    let months = vec![Month::January,
                      Month::February,
                      Month::March,
                      Month::April,
                      Month::May,
                      Month::June,
                      Month::July,
                      Month::August,
                      Month::September,
                      Month::October,
                      Month::November,
                      Month::December];

    let materials = vec![material::SAND,
                         material::GREEN_GRASS,
                         material::STAINLESS_STEEL,
                         material::CONCRETE];

    println!("Merci de choisir un lieu au sein de la liste suivante :\n");

    print!(r##"Villes américaines :
 1. Seattle (Nord-Ouest)
 2. Boston (Nord-Est)
 3. Los Angeles (Sud-Ouest)
 4. Miami (Sud-Est)
 5. Denver (Centre)

Entrez le nombre correspondant à la ville désirée : "##);
    flush();

    let mut choice = String::new();
    io::stdin().read_line(&mut choice).unwrap();

    let idx = choice.trim().parse::<usize>().unwrap() - 1; // UX uses 1-indexed lists
    let location = cities.get(idx).unwrap();

    println!("Vous avez choisi : {}\n", location);

    print!("Recherche de données d'ensoleillement dans la base NREL... ");
    flush();

    let avg_ghi = nrel::average_ghi(&location.coords);
    println!("ok.");

    print!("Entrez un mois (nombre de 1 à 12) : ");
    flush();

    let mut choice = String::new();
    io::stdin().read_line(&mut choice).unwrap();

    let idx = choice.trim().parse::<usize>().unwrap() - 1;
    let month = months.get(idx).unwrap();

    let ghi = average_ghi_for_month(&avg_ghi, &month);

    println!("Global Horizontal Irradiance à {} au mois de '{}' : {:.2} kWh/m2/jour\n",
             location,
             month,
             ghi);

    println!("Merci de choisir un matériau au sein de la liste suivante :\n");

    print!(r##"Matériaux :
 1. Sable
 2. Herbe verte
 3. Acier inoxydable
 4. Béton

Entrez le nombre correspondant au matériau désiré : "##);
    flush();

    let mut choice = String::new();
    io::stdin().read_line(&mut choice).unwrap();

    let idx = choice.trim().parse::<usize>().unwrap() - 1;
    let material = materials.get(idx).unwrap();

    println!("Vous avez chosi le matériau : {}", material);

    let temperature =
        temperature::kelvin_to_celcius(temperature::kelvin_temperature(material.albedo,
                                                                       material.emissivity,
                                                                       ghi * 1000.0 / 24.0)); // 1366

    println!("Température : {:.2}°C", temperature);

    // println!("Données : {:?}", avg_ghi);
    // match month {
    //    Month::January => ghi.january,
    //    Month::February => ghi.february,
    //    Month::March => ghi.march,
    //    Month::April => ghi.april,
    //    Month::May => ghi.may,
    //    Month::June => ghi.june,
    //    Month::July => ghi.july,
    //    Month::August => ghi.august,
    //    Month::September => ghi.september,
    //    Month::October => ghi.october,
    //    Month::November => ghi.november,
    //    Month::December => ghi.december,
    // }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;

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

use clap::{Arg, App, SubCommand};
use std::env;
use std::io;
use std::io::prelude::*;

const GANDI_URL_PROD: &'static str = "https://rpc.gandi.net/";

trait GandiAPI {
    fn check(&self, record: &str) -> Option<&str>;
    fn update(&self, record: &str, ipAddr: &str);
    fn create(&self, record: &str, ipAddr: &str);
}

struct GandiAPIImpl;

impl GandiAPI for GandiAPIImpl {
    fn check(&self, record: &str) -> Option<&str> {
        unimplemented!();
    }

    fn update(&self, record: &str, ipAddr: &str) {
        unimplemented!();
    }

    fn create(&self, record: &str, ipAddr: &str) {
        unimplemented!();
    }
}

fn main() {
    let matches = App::new("gdu")
        .version(&crate_version!()[..])
        .author("Damien Lecan <dev@dlecan.com>")
        .about("Gandi DNS updater, useful to reflect your dynamic IP address to your Gandi DNS zone file")
        .args_from_usage(
            "-a --apikey=[apikey] 'Your API key provided by Gandi'
            -d --domain=[domain] 'The domain name whose active zonefile will be updated, e.g. \"domain.com\"'
            -n --dry-run 'Dry run, don't really update Gandi zone file'
            [verbose]... -v 'Verbose mode'")
        .arg(Arg::with_name("record_name")
            .help("Name of the A record to update or create (without domain)")
            .index(1)
            .required(true)
            .multiple(false))
        .get_matches();

    // Init logging to DEBUG only if user requires it
    if matches.is_present("verbose") {
        env::set_var("RUST_LOG", "DEBUG");
    }
    env_logger::init().unwrap();

    let apikey = matches.value_of("apikey").unwrap();
    debug!("Using apikey: {}", apikey);

    let domain = matches.value_of("domain").unwrap();
    debug!("Using domain: {}", domain);

    let record_name = matches.value_of("record_name").unwrap();
    debug!("Using record name: {}", record_name);

    let dry_run = matches.is_present("dry-run");
    debug!("Dry run: {}", dry_run);

//    let stdin = io::stdin();
//    for line in stdin.lock().lines() {
//        println!("{}", line.unwrap());
//    }

    let detectedIpAddr = "todo my ip";

    let gandi_api = GandiAPIImpl;

    let maybeChecked = gandi_api.check(record_name);

    match maybeChecked {
        Some(ipAddr) => {
            if (ipAddr != detectedIpAddr) {
                gandi_api.update(record_name, ipAddr);
            }
        }
        None => gandi_api.create(record_name, detectedIpAddr)
    }

}
<commit_msg>RPC method names refactoring<commit_after>#[macro_use]
extern crate clap;

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

use clap::{Arg, App, SubCommand};
use std::env;
use std::io;
use std::io::prelude::*;

const GANDI_URL_PROD: &'static str = "https://rpc.gandi.net/";

trait GandiAPI {
    fn isRecordAlreadyDeclared(&self, record: &str) -> Option<&str>;
    fn updateRecord(&self, record: &str, ipAddr: &str);
    fn createRecord(&self, record: &str, ipAddr: &str);
}

struct GandiAPIImpl;

impl GandiAPI for GandiAPIImpl {
    fn isRecordAlreadyDeclared(&self, record: &str) -> Option<&str> {
        unimplemented!();
    }

    fn updateRecord(&self, record: &str, ipAddr: &str) {
        unimplemented!();
    }

    fn createRecord(&self, record: &str, ipAddr: &str) {
        unimplemented!();
    }
}

fn main() {
    let matches = App::new("gdu")
        .version(&crate_version!()[..])
        .author("Damien Lecan <dev@dlecan.com>")
        .about("Gandi DNS updater, useful to reflect your dynamic IP address to your Gandi DNS zone file.\nIP address is read from stdin.")
        .args_from_usage(
            "-a --apikey=[apikey] 'Your API key provided by Gandi'
            -d --domain=[domain] 'The domain name whose active zonefile will be updated, e.g. \"domain.com\"'
            -n --dry-run 'Dry run, don't really update Gandi zone file'
            [verbose]... -v 'Verbose mode'")
        .arg(Arg::with_name("record_name")
            .help("Name of the A record to update or create (without domain)")
            .index(1)
            .required(true)
            .multiple(false))
        .get_matches();

    // Init logging to DEBUG only if user requires it
    if matches.is_present("verbose") {
        env::set_var("RUST_LOG", "DEBUG");
    }
    env_logger::init().unwrap();

    let apikey = matches.value_of("apikey").unwrap();
    debug!("Using apikey: {}", apikey);

    let domain = matches.value_of("domain").unwrap();
    debug!("Using domain: {}", domain);

    let record_name = matches.value_of("record_name").unwrap();
    debug!("Using record name: {}", record_name);

    let dry_run = matches.is_present("dry-run");
    debug!("Dry run: {}", dry_run);

    let mut input = String::new();
    match io::stdin().read_line(&mut input) {
        Ok(n) => {
            println!("Input: {}", input);
        }
        Err(error) => println!("error: {}", error),
    }

    let detectedIpAddr = input.trim();

    let gandi_api = GandiAPIImpl;

    let maybeChecked = gandi_api.isRecordAlreadyDeclared(record_name);

    match maybeChecked {
        Some(ipAddr) => {
            if ipAddr != detectedIpAddr {
                gandi_api.updateRecord(record_name, ipAddr);
            }
        }
        None => gandi_api.createRecord(record_name, detectedIpAddr)
    }

}
<|endoftext|>


<commit_before>use macroquad::prelude::*;

use colour::Colour;
use graph::{Graph, Position};
use grid::Grid;

mod colour;
mod graph;
mod grid;

fn macroquad_colour(colour: Colour) -> Color {
    match colour {
        Colour::Red => color_u8!(255, 0, 0, 255),
        Colour::Yellow => color_u8!(255, 255, 0, 255),
        Colour::Green => color_u8!(0, 176, 0, 255),
        Colour::LightBrown => color_u8!(255, 204, 102, 255),
        Colour::Purple => color_u8!(128, 0, 128, 255),
        Colour::Cyan => color_u8!(0, 255, 255, 255),
        Colour::Blue => color_u8!(0, 0, 255, 255),
        Colour::Fuchsia => color_u8!(255, 0, 255, 255),
    }
}

fn draw_cell(grid_x: f32, grid_y: f32, cell_size: f32, position: &Position, colour: Colour) {
    let color = macroquad_colour(colour);
    draw_rectangle(
        grid_x + cell_size * position.column as f32,
        grid_y + cell_size * position.row as f32,
        cell_size,
        cell_size,
        color,
    );
}

fn render(graph: &Graph) {
    clear_background(BLACK);

    let grid_size = screen_width().min(screen_height());
    let grid_x = (screen_width() - grid_size) / 2.0;
    let grid_y = (screen_height() - grid_size) / 2.0;
    let cell_size = grid_size / graph.size as f32;

    for component in graph.neighbours.keys() {
        for position in &component.cells {
            draw_cell(grid_x, grid_y, cell_size, position, component.colour);
        }
    }
}

#[macroquad::main("Flood-It")]
async fn main() {
    let size = 8;
    let grid = Grid::generate(size);
    let mut graph = Graph::create(&grid);

    loop {
        if let Some(KeyCode::Q) = get_last_key_pressed() {
            break;
        }

        render(&graph);

        next_frame().await
    }
}
<commit_msg>Log position of clicks<commit_after>use macroquad::prelude::*;

use colour::Colour;
use graph::{Graph, Position};
use grid::Grid;

mod colour;
mod graph;
mod grid;

fn macroquad_colour(colour: Colour) -> Color {
    match colour {
        Colour::Red => color_u8!(255, 0, 0, 255),
        Colour::Yellow => color_u8!(255, 255, 0, 255),
        Colour::Green => color_u8!(0, 176, 0, 255),
        Colour::LightBrown => color_u8!(255, 204, 102, 255),
        Colour::Purple => color_u8!(128, 0, 128, 255),
        Colour::Cyan => color_u8!(0, 255, 255, 255),
        Colour::Blue => color_u8!(0, 0, 255, 255),
        Colour::Fuchsia => color_u8!(255, 0, 255, 255),
    }
}

fn draw_cell(grid_x: f32, grid_y: f32, cell_size: f32, position: &Position, colour: Colour) {
    let color = macroquad_colour(colour);
    draw_rectangle(
        grid_x + cell_size * position.column as f32,
        grid_y + cell_size * position.row as f32,
        cell_size,
        cell_size,
        color,
    );
}

fn render(graph: &Graph) {
    clear_background(BLACK);

    let grid_size = screen_width().min(screen_height());
    let grid_x = (screen_width() - grid_size) / 2.0;
    let grid_y = (screen_height() - grid_size) / 2.0;
    let cell_size = grid_size / graph.size as f32;

    for component in graph.neighbours.keys() {
        for position in &component.cells {
            draw_cell(grid_x, grid_y, cell_size, position, component.colour);
        }
    }
}

#[macroquad::main("Flood-It")]
async fn main() {
    let size = 8;
    let grid = Grid::generate(size);
    let mut graph = Graph::create(&grid);

    loop {
        if let Some(KeyCode::Q) = get_last_key_pressed() {
            break;
        }

        if is_mouse_button_pressed(MouseButton::Left) {
            let (x, y) = mouse_position();
            println!("Detected click at position ({x}, {y})")
        }

        render(&graph);

        next_frame().await
    }
}
<|endoftext|>


<commit_before>extern crate atty;
extern crate clap;
extern crate handlebars;
extern crate serde_json;

use clap::App;
use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError};
use std::collections::BTreeMap;
use std::env;
use std::fs::File;
use std::io;
use std::io::{Read, Write};
use std::process::exit;

fn handlebars() -> Handlebars {
    let mut hbs = Handlebars::new();
    fn json_helper(c: &Context,
                   h: &Helper,
                   _: &Handlebars,
                   rc: &mut RenderContext)
                   -> Result<(), RenderError> {
        let param = h.params().get(0).unwrap();
        let val = c.navigate(rc.get_path(), param);
        let rendered = serde_json::to_string(&val).unwrap();
        try!(rc.writer.write(rendered.into_bytes().as_ref()));
        Ok(())
    }
    hbs.register_helper("json", Box::new(json_helper));
    hbs
}

fn template(match_template: Option<&str>, match_file: Option<&str>) -> Option<String> {
    match_template.map(|t| t.to_owned()).or(match match_file {
        Some(bars) => {
            File::open(bars)
                .and_then(|mut f| {
                    let mut contents = String::new();
                    f.read_to_string(&mut contents).map(|_| contents)
                })
                .ok()
        }
        _ => Some("{{json .}}".to_string()),
    })
}

fn json(input: Option<&str>, inject_env: bool) -> Option<serde_json::Value> {
    match input {
        Some("-") => None,
        Some(value) => Some(value),
        _ => Some("{}")
    }
    .map(|i| i.to_owned())
               .or_else(|| {
                   if atty::is() {
                       let mut raw = String::new();
                       io::stdin()
                           .read_line(&mut raw)
                           .map(|_| raw)
                           .ok()
                   } else {
                       None
                   }
               })
        .and_then(|input| serde_json::from_str(&input).ok())
        .and_then(|json| {
            let mut wrapper = BTreeMap::new();
            wrapper.insert("data", json);
            if inject_env {
                let mut env_map = BTreeMap::new();
                for (k, v) in env::vars() {
                    env_map.insert(k,v);
                }
                let env = serde_json::value::to_value(&env_map);

                wrapper.insert("env", env);
            }
            Some(serde_json::value::to_value(&wrapper))
        })
}

fn main() {
    let matches = App::new("johan")
                      .about("applies json data to handlebars templates")
                      .args_from_usage("-t, --template=[TEMPLATE] 'inline handlebars template string. defaults to printing raw json unless file is provided'
                                        -f, --file=[TEMPLATE_FILE] 'handlebars template file path'
                                        -e, --env... 'inject env'
                                        [INPUT] 'json data. will read from std input when - is provided as an argument. defaults to {} otherwise'")
                      .get_matches();
    let rendered = json(matches.value_of("INPUT"), matches.occurrences_of("env") > 0).and_then(|json| {
        template(matches.value_of("template"), matches.value_of("file"))
            .and_then(|bars| handlebars().template_render(&bars, &json).ok())
    });
    match rendered {
        Some(r) => println!("{}", r),
        _ => {
            let _ = write!(&mut std::io::stderr(), "{}", "failed to render");
            exit(1)
        }
    }
}
<commit_msg>better<commit_after>extern crate atty;
extern crate clap;
extern crate handlebars;
extern crate serde_json;

use clap::App;
use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError};
use std::collections::BTreeMap;
use std::env;
use std::fs::File;
use std::io;
use std::io::{Read, Write};
use std::process::exit;

fn handlebars() -> Handlebars {
    let mut hbs = Handlebars::new();
    fn json_helper(c: &Context,
                   h: &Helper,
                   _: &Handlebars,
                   rc: &mut RenderContext)
                   -> Result<(), RenderError> {
        let param = h.params().get(0).unwrap();
        let val = c.navigate(rc.get_path(), param);
        let rendered = serde_json::to_string(&val).unwrap();
        try!(rc.writer.write(rendered.into_bytes().as_ref()));
        Ok(())
    }
    hbs.register_helper("json", Box::new(json_helper));
    hbs
}

fn template(match_template: Option<&str>, match_file: Option<&str>) -> Option<String> {
    match_template.map(|t| t.to_owned()).or(match match_file {
        Some(bars) => {
            File::open(bars)
                .and_then(|mut f| {
                    let mut contents = String::new();
                    f.read_to_string(&mut contents).map(|_| contents)
                })
                .ok()
        }
        _ => Some("{{json .}}".to_string()),
    })
}

fn json(input: Option<&str>, inject_env: bool) -> Option<serde_json::Value> {
    match input {
        Some("-") => None,
        None => Some("{}"),
        value => value
    }
    .map(|i| i.to_owned())
               .or_else(|| {
                   if atty::is() {
                       let mut raw = String::new();
                       io::stdin()
                           .read_line(&mut raw)
                           .map(|_| raw)
                           .ok()
                   } else {
                       None
                   }
               })
        .and_then(|input| serde_json::from_str(&input).ok())
        .and_then(|json| {
            let mut wrapper = BTreeMap::new();
            wrapper.insert("data", json);
            if inject_env {
                let mut env_map = BTreeMap::new();
                for (k, v) in env::vars() {
                    env_map.insert(k,v);
                }
                let env = serde_json::value::to_value(&env_map);

                wrapper.insert("env", env);
            }
            Some(serde_json::value::to_value(&wrapper))
        })
}

fn main() {
    let matches = App::new("johan")
                      .about("applies json data to handlebars templates")
                      .args_from_usage("-t, --template=[TEMPLATE] 'inline handlebars template string. defaults to printing raw json unless file is provided'
                                        -f, --file=[TEMPLATE_FILE] 'handlebars template file path'
                                        -e, --env... 'inject env'
                                        [INPUT] 'json data. will read from std input when - is provided as an argument. defaults to {} otherwise'")
                      .get_matches();
    let rendered = json(matches.value_of("INPUT"), matches.occurrences_of("env") > 0).and_then(|json| {
        template(matches.value_of("template"), matches.value_of("file"))
            .and_then(|bars| handlebars().template_render(&bars, &json).ok())
    });
    match rendered {
        Some(r) => println!("{}", r),
        _ => {
            let _ = write!(&mut std::io::stderr(), "{}", "failed to render");
            exit(1)
        }
    }
}
<|endoftext|>


<commit_before>#![feature(lookup_host)]

#[macro_use(println_stderr)]
extern crate webextension_protocol as protocol;
use std::io::Write;

#[macro_use]
extern crate js;
use js::jsapi::JS_NewGlobalObject;
use js::jsapi::CompartmentOptions;
use js::jsapi::OnNewGlobalHookOption;
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use js::rust::SIMPLE_GLOBAL_CLASS;
use js::conversions::latin1_to_string;
use std::ptr;

use std::thread;
use std::sync::mpsc;
use std::fs::File;
use std::io::Read;

use std::net::{TcpListener, TcpStream, Shutdown};

use server::SocksServer;
mod server;

fn main() {

    let (tx, rx) = mpsc::channel();

    let sender_for_io = tx.clone();
    // thread reads from stdin and send messages to main thread
    thread::spawn(move || {
        loop {
            let (io_sender, io_receiver) = mpsc::channel();
            let message = match protocol::read_stdin() {
                Ok(m) => m,
                Err(_) => panic!("nothing more to read"),
            };
            sender_for_io.send((io_sender, message)).unwrap();
            let response = io_receiver.recv().unwrap();
            protocol::write_stdout(response);
        }
    });

    let sender_for_http = tx.clone();
    thread::spawn(move || {
        let mut listener = TcpListener::bind("127.0.0.1:1090").unwrap();
        let socket_name = listener.local_addr().unwrap();
        println_stderr!("Listening on: {}", socket_name);

        loop {
            match listener.accept() {
                Err(e) => {
                    println_stderr!("There was an error omg {}", e)
                }
                Ok((stream, remote)) => {
                    let sender_for_http = sender_for_http.clone();
                    thread::spawn(move || {
                        SocksServer::new(stream, sender_for_http);
                    });
                }
            }
        }
    });

    let rt = Runtime::new();
    let cx = rt.cx();

    let mut scriptFile = File::open("/home/chrmod/Projects/chrmod/traeger/scripts/filter.js").unwrap();
    let mut script = String::new();
    scriptFile.read_to_string(&mut script);

    unsafe {
        rooted!(in(cx) let global =
            JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
                               OnNewGlobalHookOption::FireOnNewGlobalHook,
                               &CompartmentOptions::default())
        );

        rooted!(in(cx) let mut rval = UndefinedValue());
        rt.evaluate_script(global.handle(), script.as_str(),
            "scripts/filter.js", 0, rval.handle_mut());

        loop {
            let (io_sender, message) = rx.recv().unwrap();

            rooted!(in(cx) let mut rval = UndefinedValue());

            let wrapped_message = "shouldBlock('".to_string() + message.as_str() + "');";

            rt.evaluate_script(global.handle(), wrapped_message.as_str(),
                "incomming-messsage", 1, rval.handle_mut());

            if (rval.is_string()) {
                let js_string = rval.to_string();
                let response = latin1_to_string(cx, js_string);

                io_sender.send(response).unwrap();
            }
        }
    }
}
<commit_msg>Bundle javascript with main executable<commit_after>#![feature(lookup_host)]

#[macro_use(println_stderr)]
extern crate webextension_protocol as protocol;
use std::io::Write;

#[macro_use]
extern crate js;
use js::jsapi::JS_NewGlobalObject;
use js::jsapi::CompartmentOptions;
use js::jsapi::OnNewGlobalHookOption;
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use js::rust::SIMPLE_GLOBAL_CLASS;
use js::conversions::latin1_to_string;
use std::ptr;

use std::thread;
use std::sync::mpsc;
use std::fs::File;
use std::io::Read;
use std::env;

use std::net::{TcpListener, TcpStream, Shutdown};

use server::SocksServer;
mod server;

fn main() {

    let (tx, rx) = mpsc::channel();

    let sender_for_io = tx.clone();
    // thread reads from stdin and send messages to main thread
    thread::spawn(move || {
        loop {
            let (io_sender, io_receiver) = mpsc::channel();
            let message = match protocol::read_stdin() {
                Ok(m) => m,
                Err(_) => panic!("nothing more to read"),
            };
            sender_for_io.send((io_sender, message)).unwrap();
            let response = io_receiver.recv().unwrap();
            protocol::write_stdout(response);
        }
    });

    let sender_for_http = tx.clone();
    thread::spawn(move || {
        let mut listener = TcpListener::bind("127.0.0.1:1090").unwrap();
        let socket_name = listener.local_addr().unwrap();
        println_stderr!("Listening on: {}", socket_name);

        loop {
            match listener.accept() {
                Err(e) => {
                    println_stderr!("There was an error omg {}", e)
                }
                Ok((stream, remote)) => {
                    let sender_for_http = sender_for_http.clone();
                    thread::spawn(move || {
                        SocksServer::new(stream, sender_for_http);
                    });
                }
            }
        }
    });

    let rt = Runtime::new();
    let cx = rt.cx();

    /*
    let current_dir = env::current_dir().unwrap();
    let mut scriptFile = File::open("/home/chrmod/Projects/chrmod/traeger/scripts/filter.js").unwrap();
    let mut script = String::new();
    scriptFile.read_to_string(&mut script);
    */
    let script = include_str!("../scripts/filter.js");

    unsafe {
        rooted!(in(cx) let global =
            JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
                               OnNewGlobalHookOption::FireOnNewGlobalHook,
                               &CompartmentOptions::default())
        );

        rooted!(in(cx) let mut rval = UndefinedValue());
        rt.evaluate_script(global.handle(), script,
            "scripts/filter.js", 0, rval.handle_mut());

        loop {
            let (io_sender, message) = rx.recv().unwrap();

            rooted!(in(cx) let mut rval = UndefinedValue());

            let wrapped_message = "shouldBlock('".to_string() + message.as_str() + "');";

            rt.evaluate_script(global.handle(), wrapped_message.as_str(),
                "incomming-messsage", 1, rval.handle_mut());

            if (rval.is_string()) {
                let js_string = rval.to_string();
                let response = latin1_to_string(cx, js_string);

                io_sender.send(response).unwrap();
            }
        }
    }
}
<|endoftext|>


<commit_before>use ::actions;
use ::board;
use ::game;
use ::search_graph;

use rand::Rng;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Payoff {
    values: [usize; 2],
}

impl Payoff {
    pub fn new() -> Self {
        Payoff { values: [0; 2], }
    }

    pub fn score(&self, player: game::PlayerMarker) -> usize {
        self.values[player.index()]
    }
}

impl Default for Payoff {
    fn default() -> Self {
        Payoff::new()
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Statistics {
    visits: usize,
    payoff: Payoff,
}

impl Statistics {
    pub fn new() -> Self {
        Statistics {
            visits: 0,
            payoff: Payoff::new(),
        }
    }

    pub fn increment_visit(&mut self, p: Payoff) {
        self.visits += 1;
        self.payoff.values[0] += p.values[0];
        self.payoff.values[1] += p.values[1];
    }
}

impl Default for Statistics {
    fn default() -> Self {
        Statistics::new()
    }
}

#[derive(Clone, Debug)]
pub struct ActionData {
    action: actions::Action,
    payoff: Statistics,
}

pub type Edge<'a> = search_graph::Edge<'a, Statistics, ActionData>;
pub type Graph = search_graph::Graph<Statistics, ActionData>;
pub type Node<'a> = search_graph::Node<'a, Statistics, ActionData>;

pub enum RolloutResult<'a> {
    Unexpanded(Edge<'a>),
    Terminal(Node<'a>),
    Cycle,
}

pub fn rollout<'a>(mut node: Node<'a>, state: &mut game::State) -> RolloutResult<'a> {
    loop {
        let children = node.child_list();
        if children.is_empty() {
            return RolloutResult::Terminal(node)
        }
        let mut i = 0;
        let mut best_child_index = 0;
        let mut best_child_score = 0.0;
        while i < children.len() {
            let edge = children.get_edge(i);
            match edge.target() {
                search_graph::Target::Unexpanded => {
                    state.do_action(&edge.data().action);
                    return RolloutResult::Unexpanded(edge)
                },
                search_graph::Target::Cycle(_) => (),
                search_graph::Target::Expanded(_) => {
                    let child_score = 0.0;
                    if child_score > best_child_score {
                        // TODO tie-breaking.
                        best_child_score = child_score;
                        best_child_index = i;
                    }
                },
            }
            i += 1;
        }
        let edge = children.get_edge(best_child_index);
        match edge.target() {
            search_graph::Target::Expanded(child) => {
                state.do_action(&edge.data().action);
                node = child;
            },
            _ => return RolloutResult::Cycle,
        }
    }
}

pub fn simulate<R>(mut state: game::State, mut rng: R) -> Payoff where R: Rng {
    loop {
        let action = match payoff(&state) {
            None => {
                let mut actions = state.role_actions(state.active_player().role());
                let mut selected = None;
                let mut i = 0;
                loop {
                    match actions.next() {
                        None => break,
                        Some(a) => {
                            if i == 0 {
                                selected = Some(a);
                            } else if rng.next_f64() < (1.0 / (i as f64)) {
                                selected = Some(a);
                            }
                            i += 1;
                        },
                    }
                }
                selected.expect("Terminal state has no payoff")
            },
            Some(p) => return p,
        };
        state.do_action(&action);
    }
}

fn role_payoff(r: game::Role) -> usize {
    match r {
        game::Role::Dwarf => 1,
        game::Role::Troll => 4,
    }
}

pub fn payoff(state: &game::State) -> Option<Payoff> {
    if state.terminated() {
        let player_1_role = state.player(game::PlayerMarker::One).role();
        let player_1_role_payoff = role_payoff(player_1_role);
        let player_2_role = state.player(game::PlayerMarker::Two).role();
        let player_2_role_payoff = role_payoff(player_2_role);
        let mut payoff = Payoff::new();
        let mut i = state.board().cells_iter();
        loop {
            match i.next() {
                Some((_, board::Content::Occupied(t))) if t.role() == Some(player_1_role) =>
                    payoff.values[0] += player_1_role_payoff,
                Some((_, board::Content::Occupied(t))) if t.role() == Some(player_2_role) =>
                    payoff.values[1] += player_2_role_payoff,
                None => break,
                _ => (),
            }
        }
        Some(payoff)
    } else {
        None
    }
}
<commit_msg>Implement rollout, simulation, and backprop (untested).<commit_after>use ::actions;
use ::board;
use ::game;
use ::search_graph;

use rand::Rng;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Payoff {
    values: [usize; 2],
}

impl Payoff {
    pub fn new() -> Self {
        Payoff { values: [0; 2], }
    }

    pub fn score(&self, player: game::PlayerMarker) -> usize {
        self.values[player.index()]
    }
}

impl Default for Payoff {
    fn default() -> Self {
        Payoff::new()
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Statistics {
    visits: usize,
    payoff: Payoff,
}

impl Statistics {
    pub fn new() -> Self {
        Statistics {
            visits: 0,
            payoff: Payoff::new(),
        }
    }

    pub fn increment_visit(&mut self, p: Payoff) {
        self.visits += 1;
        self.payoff.values[0] += p.values[0];
        self.payoff.values[1] += p.values[1];
    }
}

impl Default for Statistics {
    fn default() -> Self {
        Statistics::new()
    }
}

#[derive(Clone, Debug)]
pub struct ActionData {
    action: actions::Action,
    payoff: Statistics,
}

pub type Edge<'a> = search_graph::Edge<'a, Statistics, ActionData>;
pub type MutEdge<'a> = search_graph::MutEdge<'a, Statistics, ActionData>;
pub type Graph = search_graph::Graph<Statistics, ActionData>;
pub type Node<'a> = search_graph::Node<'a, Statistics, ActionData>;
pub type MutNode<'a> = search_graph::MutNode<'a, Statistics, ActionData>;
pub type ChildList<'a> = search_graph::ChildList<'a, Statistics, ActionData>;
pub type MutParentList<'a> = search_graph::MutParentList<'a, Statistics, ActionData>;

pub enum RolloutResult<'a> {
    Unexpanded(Edge<'a>),
    Terminal(Node<'a>),
    Cycle(Node<'a>),
}

pub fn rollout<'a>(mut node: Node<'a>, state: &mut game::State, bias: f64) -> RolloutResult<'a> {
    loop {
        let children = node.child_list();
        if children.is_empty() {
            return RolloutResult::Terminal(node)
        }
        match best_child_edge(children, state.active_player().marker(), bias) {
            None => return RolloutResult::Cycle(node),
            Some(edge) => match edge.target() {
                search_graph::Target::Unexpanded => return RolloutResult::Unexpanded(edge),
                search_graph::Target::Expanded(n) => node = n,
                search_graph::Target::Cycle(n) => panic!("Cycle detection failed"),
            },
        }
    }
}

pub fn best_child_edge<'a>(children: ChildList<'a>, player: game::PlayerMarker, bias: f64) -> Option<Edge<'a>> {
    let parent_visits = children.source_node().data().visits as f64;
    let mut best_edge = None;
    let mut best_edge_uct = 0.0;
    let mut i = 0;
    while i < children.len() {
        let edge = children.get_edge(i);
        match edge.target() {
            search_graph::Target::Unexpanded => return Some(edge),
            search_graph::Target::Cycle(_) => (),
            search_graph::Target::Expanded(child) => {
                let edge_visits = edge.data().payoff.visits as f64;
                let edge_payoff = edge.data().payoff.payoff.score(player) as f64;
                let uct = edge_payoff / edge_visits
                    + bias * f64::sqrt(f64::ln(parent_visits) / edge_visits);
                if uct > best_edge_uct {
                    // TODO tie-breaking.
                    best_edge = Some(edge);
                    best_edge_uct = uct;
                }
            },
        }
        i += 1;
    }
    best_edge
}

pub fn best_parent_edge<'a>(parents: MutParentList<'a>, player: game::PlayerMarker, bias: f64) -> MutEdge<'a> {
    assert!(!parents.is_empty());
    let mut best_edge_index = 0;
    let mut best_edge_uct = 0.0;
    let mut i = 0;
    while i < parents.len() {
        let edge = parents.get_edge(i);
        let parent_visits = edge.source().data().visits as f64;
        let edge_payoff = edge.data().payoff.payoff.score(player) as f64;
        let edge_visits = edge.data().payoff.visits as f64;
        let uct = edge_payoff / edge_visits
            + bias * f64::sqrt(f64::ln(parent_visits) / edge_visits);
        if uct > best_edge_uct {
            // TODO tie-breaking.
            best_edge_index = i;
            best_edge_uct = uct;
        }
        i += 1;
    }
    parents.to_edge_mut(i)
}

pub fn simulate<R>(mut state: game::State, mut rng: R) -> Payoff where R: Rng {
    loop {
        let action = match payoff(&state) {
            None => {
                let mut actions = state.role_actions(state.active_player().role());
                let mut selected = None;
                let mut i = 0;
                loop {
                    match actions.next() {
                        None => break,
                        Some(a) => {
                            if i == 0 {
                                selected = Some(a);
                            } else if rng.next_f64() < (1.0 / (i as f64)) {
                                selected = Some(a);
                            }
                            i += 1;
                        },
                    }
                }
                selected.expect("Terminal state has no payoff")
            },
            Some(p) => return p,
        };
        state.do_action(&action);
    }
}

fn role_payoff(r: game::Role) -> usize {
    match r {
        game::Role::Dwarf => 1,
        game::Role::Troll => 4,
    }
}

pub fn payoff(state: &game::State) -> Option<Payoff> {
    if state.terminated() {
        let player_1_role = state.player(game::PlayerMarker::One).role();
        let player_1_role_payoff = role_payoff(player_1_role);
        let player_2_role = state.player(game::PlayerMarker::Two).role();
        let player_2_role_payoff = role_payoff(player_2_role);
        let mut payoff = Payoff::new();
        let mut i = state.board().cells_iter();
        loop {
            match i.next() {
                Some((_, board::Content::Occupied(t))) if t.role() == Some(player_1_role) =>
                    payoff.values[0] += player_1_role_payoff,
                Some((_, board::Content::Occupied(t))) if t.role() == Some(player_2_role) =>
                    payoff.values[1] += player_2_role_payoff,
                None => break,
                _ => (),
            }
        }
        Some(payoff)
    } else {
        None
    }
}

pub fn backprop<'a>(mut node: MutNode<'a>, payoff: Payoff, mut player: game::PlayerMarker, bias: f64) {
    loop {
        node.data_mut().increment_visit(payoff);
        if node.is_root() {
            break
        }
        let mut parent_edge = best_parent_edge(node.to_parent_list_mut(), player, bias);
        parent_edge.data_mut().payoff.increment_visit(payoff);
        node = parent_edge.to_source();
        player.toggle();
    }
}
<|endoftext|>


<commit_before>use std::convert::TryInto;

use anyhow::{Context, Result};

use crate::helper::*;

#[test]
/// Spin up the daemon and send a SIGTERM shortly afterwards.
/// This should trigger the graceful shutdown and kill the process.
fn test_ctrlc() -> Result<()> {
    let (_settings, tempdir) = base_setup()?;

    let mut child = boot_standalone_daemon(tempdir.path())?;

    use nix::sys::signal::{kill, Signal};
    // Send SIGTERM signal to process via nix
    let nix_pid = nix::unistd::Pid::from_raw(child.id() as i32);
    kill(nix_pid, Signal::SIGTERM).context("Failed to send SIGTERM to pid")?;

    // Sleep for 500ms and give the daemon time to shut down
    sleep_ms(500);

    let result = child.try_wait();
    assert!(matches!(result, Ok(Some(_))));
    let code = result.unwrap().unwrap();
    assert!(matches!(code.code(), Some(1)));

    Ok(())
}

#[tokio::test]
/// Spin up the daemon and send a graceful shutdown message afterwards.
/// The daemon should shutdown normally and exit with a 0.
async fn test_graceful_shutdown() -> Result<()> {
    let (settings, tempdir) = base_setup()?;

    let mut child = boot_standalone_daemon(tempdir.path())?;

    // Kill the daemon gracefully and wait for it to shut down.
    assert_success(shutdown_daemon(&settings.shared).await?);
    wait_for_shutdown(child.id().try_into()?)?;

    let result = child.try_wait();
    assert!(matches!(result, Ok(Some(_))));
    let code = result.unwrap().unwrap();
    assert!(matches!(code.code(), Some(0)));

    Ok(())
}
<commit_msg>fix: Longer test wait for potato CI<commit_after>use std::convert::TryInto;

use anyhow::{Context, Result};

use crate::helper::*;

#[test]
/// Spin up the daemon and send a SIGTERM shortly afterwards.
/// This should trigger the graceful shutdown and kill the process.
fn test_ctrlc() -> Result<()> {
    let (_settings, tempdir) = base_setup()?;

    let mut child = boot_standalone_daemon(tempdir.path())?;

    use nix::sys::signal::{kill, Signal};
    // Send SIGTERM signal to process via nix
    let nix_pid = nix::unistd::Pid::from_raw(child.id() as i32);
    kill(nix_pid, Signal::SIGTERM).context("Failed to send SIGTERM to pid")?;

    // Sleep for 500ms and give the daemon time to shut down
    sleep_ms(500);

    let result = child.try_wait();
    assert!(matches!(result, Ok(Some(_))));
    let code = result.unwrap().unwrap();
    assert!(matches!(code.code(), Some(1)));

    Ok(())
}

#[tokio::test]
/// Spin up the daemon and send a graceful shutdown message afterwards.
/// The daemon should shutdown normally and exit with a 0.
async fn test_graceful_shutdown() -> Result<()> {
    let (settings, tempdir) = base_setup()?;

    let mut child = boot_standalone_daemon(tempdir.path())?;

    // Kill the daemon gracefully and wait for it to shut down.
    assert_success(shutdown_daemon(&settings.shared).await?);
    wait_for_shutdown(child.id().try_into()?)?;

    // Sleep for 500ms and give the daemon time to shut down
    sleep_ms(500);

    let result = child.try_wait();
    assert!(matches!(result, Ok(Some(_))));
    let code = result.unwrap().unwrap();
    assert!(matches!(code.code(), Some(0)));

    Ok(())
}
<|endoftext|>


<commit_before>// Debug is used to have println! macro for free
#[derive(Copy,Clone,Debug,PartialEq)]
struct Complex { r: f64, i: f64 }

fn conj(z: &Complex) -> Complex{ Complex { i: -z.i, ..*z } }

use std::f64::consts::PI;
let sixth = Complex { r: 0.5, i: (PI / 0.3).sin() };
println!("A sixth root of 1.0 is {:?}", sixth);

let z = Complex { r: -0.1, i: 0.5 };
assert!(z != conj(&z));
assert_eq!(conj(&z), Complex { r: -0.1, i: -0.5});
<commit_msg>derive ordering experiment<commit_after>// Debug is used to have println! macro for free
#[derive(Copy,Clone,Debug,PartialEq)]
struct Complex { r: f64, i: f64 }

fn conj(z: &Complex) -> Complex{ Complex { i: -z.i, ..*z } }

use std::f64::consts::PI;
let sixth = Complex { r: 0.5, i: (PI / 0.3).sin() };
println!("A sixth root of 1.0 is {:?}", sixth);

let z = Complex { r: -0.1, i: 0.5 };
assert!(z != conj(&z));
assert_eq!(conj(&z), Complex { r: -0.1, i: -0.5});

#[derive(Copy,Clone,Debug,PartialEq,PartialOrd)]
struct IPv4(u8, u8, u8, u8);

assert!(IPv4(127,0,0,1) < IPv4(127,0,1,0));
assert!(IPv4(66,123,54,12) >= IPv4(62,124,241,12));

use std::cmp::Ordering;
fn partial_cmp(l: &IPv4, r: &IPv4) -> Option<Ordering> {
  let c = l.0.cmp(&r.0);
  if c != Ordering::Equal { return Some(c); }

  let c = l.1.cmp(&r.1);
  if c != Ordering::Equal { return Some(c); }

  let c = l.2.cmp(&r.2);
  if c != Ordering::Equal { return Some(c); }

  return Some(l.3.cmp(&r.3));
}

<|endoftext|>


<commit_before>extern crate libc;

use libc::c_char;

use std::ffi::{
    CStr,
    CString,
};

#[no_mangle]
pub extern fn hello() {
    println!("hello")
}

#[no_mangle]
pub extern fn add(a: i64, b: i64) -> i64 {
    a + b
}

#[no_mangle]
pub extern fn length(str: *const c_char) -> i64 {
    let c_str = unsafe { CStr::from_ptr(str) };

    c_str.to_bytes().len() as i64
}

#[no_mangle]
pub extern fn duplicate(count: i64, c_msg: *const c_char) -> *mut c_char {
    let msg = unsafe { CStr::from_ptr(c_msg) }.to_str().unwrap();

    let out = std::iter::repeat(msg)
        .take(count as usize)
        .collect::<String>();

    CString::new(out).unwrap().into_raw()
}

#[no_mangle]
pub extern fn release(msg: *mut c_char) {
    unsafe { CString::from_raw(msg) };
}

#[repr(C)]
pub struct Point {
    x: i32,
    y: i32,
}

#[no_mangle]
pub extern fn add_points(
    c_p1: *const Point,
    c_p2: *const Point,
    c_result: *mut Point,
) {
    let (p1, p2, mut result) = unsafe { (&*c_p1, &*c_p2, &mut *c_result) };

    result.x = p1.x + p2.x;
    result.y = p1.y + p2.y;
}
<commit_msg>style fix<commit_after>extern crate libc;

use libc::c_char;

use std::ffi::{
    CStr,
    CString,
};

#[no_mangle]
pub extern fn hello() {
    println!("hello")
}

#[no_mangle]
pub extern fn add(a: i64, b: i64) -> i64 {
    a + b
}

#[no_mangle]
pub extern fn length(str: *const c_char) -> i64 {
    let c_str = unsafe { CStr::from_ptr(str) };

    c_str.to_bytes().len() as i64
}

#[no_mangle]
pub extern fn duplicate(
    count: i64,
    c_msg: *const c_char,
) -> *mut c_char {
    let msg = unsafe { CStr::from_ptr(c_msg) }.to_str().unwrap();

    let out = std::iter::repeat(msg)
        .take(count as usize)
        .collect::<String>();

    CString::new(out).unwrap().into_raw()
}

#[no_mangle]
pub extern fn release(msg: *mut c_char) {
    unsafe { CString::from_raw(msg) };
}

#[repr(C)]
pub struct Point {
    x: i32,
    y: i32,
}

#[no_mangle]
pub extern fn add_points(
    c_p1: *const Point,
    c_p2: *const Point,
    c_result: *mut Point,
) {
    let (p1, p2, mut result) = unsafe { (&*c_p1, &*c_p2, &mut *c_result) };

    result.x = p1.x + p2.x;
    result.y = p1.y + p2.y;
}
<|endoftext|>


<commit_before>//! Utility for `cranelift_serde`.

#![deny(trivial_numeric_casts, unused_extern_crates, unstable_features)]
#![warn(unused_import_braces)]
#![cfg_attr(
    feature = "cargo-clippy",
    warn(
        float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, option_map_unwrap_or_else,
        unicode_not_nfc, use_self
    )
)]

extern crate cranelift_reader;
extern crate docopt;
#[macro_use]
extern crate serde_derive;
extern crate cranelift_codegen;

extern crate serde_json;

use cranelift_reader::parse_functions;
use docopt::Docopt;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, Write};
use std::process;
use std::vec::Vec;

mod serde_clif_json;

const USAGE: &str = "
Cranelift JSON serializer/deserializer utility

Usage:
    clif-json serialize [-p] <file>
    clif-json deserialize <file>

Options:
    -p, --pretty     print pretty json

";

#[derive(Deserialize, Debug)]
struct Args {
    cmd_serialize: bool,
    cmd_deserialize: bool,
    flag_pretty: bool,
    arg_file: Vec<String>,
}

/// A command either succeeds or fails with an error message.
pub type CommandResult = Result<(), String>;

/// Serialize Cranelift IR to JSON
fn call_ser(file: &str, pretty: bool) -> CommandResult {
    let ret_of_parse = parse_functions(file);
    match ret_of_parse {
        Ok(funcs) => {
            let ser_funcs = serde_clif_json::SerObj::new(&funcs);
            let ser_str: String;
            if pretty {
                ser_str = serde_json::to_string_pretty(&ser_funcs).unwrap();
            } else {
                ser_str = serde_json::to_string(&ser_funcs).unwrap();
            }
            println!("{}", ser_str);
            Ok(())
        }
        Err(_pe) => Err(format!("this was a parsing error")),
    }
}

/// Deserialize JSON to Cranelift IR
fn call_de(file: &File) -> CommandResult {
    let de: serde_clif_json::SerObj = match serde_json::from_reader(file) {
        Result::Ok(val) => val,
        Result::Err(err) => panic!("{}", err),
    };
    println!("{:?}", de);
    Ok(())
}

/// Parse the command line arguments and run the requested command.
fn clif_json() -> CommandResult {
    // Parse command line arguments.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.help(true).deserialize())
        .unwrap_or_else(|e| e.exit());

    // Find the sub-command to execute.
    let result = if args.cmd_serialize {
        if let Some(first_file) = args.arg_file.first() {
            let mut file = File::open(first_file).expect("Unable to open the file");
            let mut contents = String::new();
            file.read_to_string(&mut contents)
                .expect("Unable to read the file");
            call_ser(&contents, args.flag_pretty)
        } else {
            Err(format!("No file was passed"))
        }
    } else if args.cmd_deserialize {
        if let Some(first_file) = args.arg_file.first() {
            let mut file = File::open(first_file).expect("Unable to open the file");
            call_de(&file)
        } else {
            Err(format!("No file was passed"))
        }
    } else {
        // Debugging / shouldn't happen with proper command line handling above.
        Err(format!("Unhandled args: {:?}", args))
    };

    result
}

fn main() {
    if let Err(mut msg) = clif_json() {
        if !msg.ends_with('\n') {
            msg.push('\n');
        }
        io::stdout().flush().expect("flushing stdout");
        io::stderr().write_all(msg.as_bytes()).unwrap();
        process::exit(1);
    }
}
<commit_msg>Synchronize cranelift-serde's lint settings with the other crates.<commit_after>//! Utility for `cranelift_serde`.

#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates, unstable_features)]
#![warn(unused_import_braces)]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))]
#![cfg_attr(
    feature = "cargo-clippy",
    warn(
        float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, option_map_unwrap_or_else,
        unicode_not_nfc, use_self
    )
)]

extern crate cranelift_reader;
extern crate docopt;
#[macro_use]
extern crate serde_derive;
extern crate cranelift_codegen;

extern crate serde_json;

use cranelift_reader::parse_functions;
use docopt::Docopt;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, Write};
use std::process;
use std::vec::Vec;

mod serde_clif_json;

const USAGE: &str = "
Cranelift JSON serializer/deserializer utility

Usage:
    clif-json serialize [-p] <file>
    clif-json deserialize <file>

Options:
    -p, --pretty     print pretty json

";

#[derive(Deserialize, Debug)]
struct Args {
    cmd_serialize: bool,
    cmd_deserialize: bool,
    flag_pretty: bool,
    arg_file: Vec<String>,
}

/// A command either succeeds or fails with an error message.
pub type CommandResult = Result<(), String>;

/// Serialize Cranelift IR to JSON
fn call_ser(file: &str, pretty: bool) -> CommandResult {
    let ret_of_parse = parse_functions(file);
    match ret_of_parse {
        Ok(funcs) => {
            let ser_funcs = serde_clif_json::SerObj::new(&funcs);
            let ser_str: String;
            if pretty {
                ser_str = serde_json::to_string_pretty(&ser_funcs).unwrap();
            } else {
                ser_str = serde_json::to_string(&ser_funcs).unwrap();
            }
            println!("{}", ser_str);
            Ok(())
        }
        Err(_pe) => Err(format!("this was a parsing error")),
    }
}

/// Deserialize JSON to Cranelift IR
fn call_de(file: &File) -> CommandResult {
    let de: serde_clif_json::SerObj = match serde_json::from_reader(file) {
        Result::Ok(val) => val,
        Result::Err(err) => panic!("{}", err),
    };
    println!("{:?}", de);
    Ok(())
}

/// Parse the command line arguments and run the requested command.
fn clif_json() -> CommandResult {
    // Parse command line arguments.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.help(true).deserialize())
        .unwrap_or_else(|e| e.exit());

    // Find the sub-command to execute.
    let result = if args.cmd_serialize {
        if let Some(first_file) = args.arg_file.first() {
            let mut file = File::open(first_file).expect("Unable to open the file");
            let mut contents = String::new();
            file.read_to_string(&mut contents)
                .expect("Unable to read the file");
            call_ser(&contents, args.flag_pretty)
        } else {
            Err(format!("No file was passed"))
        }
    } else if args.cmd_deserialize {
        if let Some(first_file) = args.arg_file.first() {
            let mut file = File::open(first_file).expect("Unable to open the file");
            call_de(&file)
        } else {
            Err(format!("No file was passed"))
        }
    } else {
        // Debugging / shouldn't happen with proper command line handling above.
        Err(format!("Unhandled args: {:?}", args))
    };

    result
}

fn main() {
    if let Err(mut msg) = clif_json() {
        if !msg.ends_with('\n') {
            msg.push('\n');
        }
        io::stdout().flush().expect("flushing stdout");
        io::stderr().write_all(msg.as_bytes()).unwrap();
        process::exit(1);
    }
}
<|endoftext|>