<commit_before>extern crate getopts;

use getopts::Options;

use std::str;
use lib::custom_error::*;
mod lib;

use std::io;
use std::env;

enum Action {
	Encode(u8, u8), // k and n parameter
	Decode
}

// a try!-like macro for Option<T> expressions that takes
// a &'static str as error message as 2nd parameter
// and creates an Error out of it if necessary.
macro_rules! otry {
	($o:expr, $e:expr) => (
		match $o {
			Some(thing_) => thing_,
			None => return Err(convert::From::from(Error::new($e, None)))
		}
	)
}

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

	let mut opts = Options::new();
	opts.optflag("h", "help", "print this help text");
	opts.optflag("d", "decode", "for decoding");
	opts.optopt("e", "encode", "for encoding, K is the required number of \
	                            shares for decoding, N is the number of shares \
	                            to generate. 1 <= K <= N <= 255", "K,N");
	let opt_matches = match opts.parse(&args[1..]) {
		Ok(m) => m,
		Err(f) => {
			drop(writeln!(&mut stderr, "Error: {}", f));
			// env::set_exit_status(1); // FIXME: unstable feature
			return;
		}
	};

	if args.len() < 2 || opt_matches.opt_present("h") {
		println!(
"The program secretshare is an implementation of Shamir's secret sharing scheme.\n\
 It is applied byte-wise within a finite field for arbitrarily long secrets.\n");
		println!("{}", opts.usage("Usage: rustysecrets [options]"));
		println!("Input is read from STDIN and output is written to STDOUT.");
 		return;
	}

	let action: Result<_,_> =
		match (opt_matches.opt_present("e"), opt_matches.opt_present("d")) {
			(false, false) => Err("Nothing to do! Use -e or -d"),
			(true, true) => Err("Use either -e or -d and not both"),
			(false, true) => Ok(Action::Decode),
			(true, false) => {
				if let Some(param) = opt_matches.opt_str("e") {
					if let Ok((k,n)) = parse_k_n(&*param) {
						if 0 < k && k <= n {
							Ok(Action::Encode(k,n))
						} else {
							Err("Invalid encoding parameters K,N")
						}
					} else {
						Err("Could not parse K,N parameters")
					}
				} else {
					Err("No parameter for -e or -d provided")
				}
			}
		};

	let result =
		match action {
			Ok(Action::Encode(k,n)) => perform_encode_from_io(k, n),
			Ok(Action::Decode) => perform_decode_from_io(),
			Err(e) => Err(other_io_err(e, None))
		};

	if let Err(e) = result {
		drop(writeln!(&mut stderr, "{}", e));
		// env::set_exit_status(1); // FIXME: unstable feature
	}
}

fn perform_encode_from_io(k: u8, n: u8) -> io::Result<()> {
	let secret = {
        let limit: usize = 0x10000;
        let stdin = io::stdin();
        let mut locked = stdin.lock();
        let mut tmp: Vec<u8> = Vec::new();
        try!(locked.by_ref().take(limit as u64).read_to_end(&mut tmp));
        if tmp.len() == limit {
            let mut dummy = [0u8];
            if try!(locked.read(&mut dummy)) > 0 {
                return Err(other_io_err("Secret too large",
                                        Some(format!("My limit is at {} bytes.", limit))));
            }
        }
        tmp
    };
	match lib::generate_shares(k, n, secret) {
		Ok(shares) => {
			for share in shares {println!("{:?}", str::from_utf8(&share).unwrap())};
		}
		Err(e) => { return Err(e) as io::Result<()>; }
	}

	return Ok(()) as io::Result<()>;
}

fn perform_decode_from_io() -> io::Result<()> {
	let stdin = io::stdin();
	let stdin = io::BufReader::new(stdin.lock());
	let mut shares: Vec<String> = Vec::new();

	for line in stdin.lines() {
		match line {
			Ok(share) => shares.push(share),
			Err(_) => {}
		}
	}

	return match lib::recover_secret(shares) {
		Ok(secret) => {
			let mut out = io::stdout();
			try!(out.write_all(&*secret));
			out.flush()
		}
		Err(e) => {Err(e) as io::Result<()>}
	};
}

fn parse_k_n(s: &str) -> io::Result<(u8, u8)> {
	let mut iter = s.split(',');
	let msg = "K and N have to be separated with a comma";
	let s1 = otry!(iter.next(), msg).trim();
	let s2 = otry!(iter.next(), msg).trim();
	let k = try!(s1.parse().map_err(pie2io));
	let n = try!(s2.parse().map_err(pie2io));
	Ok((k, n))
}
<commit_msg>Removing last char from command line.<commit_after>extern crate getopts;

use getopts::Options;

use std::str;
use lib::custom_error::*;
mod lib;

use std::io;
use std::env;

enum Action {
	Encode(u8, u8), // k and n parameter
	Decode
}

// a try!-like macro for Option<T> expressions that takes
// a &'static str as error message as 2nd parameter
// and creates an Error out of it if necessary.
macro_rules! otry {
	($o:expr, $e:expr) => (
		match $o {
			Some(thing_) => thing_,
			None => return Err(convert::From::from(Error::new($e, None)))
		}
	)
}

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

	let mut opts = Options::new();
	opts.optflag("h", "help", "print this help text");
	opts.optflag("d", "decode", "for decoding");
	opts.optopt("e", "encode", "for encoding, K is the required number of \
	                            shares for decoding, N is the number of shares \
	                            to generate. 1 <= K <= N <= 255", "K,N");
	let opt_matches = match opts.parse(&args[1..]) {
		Ok(m) => m,
		Err(f) => {
			drop(writeln!(&mut stderr, "Error: {}", f));
			// env::set_exit_status(1); // FIXME: unstable feature
			return;
		}
	};

	if args.len() < 2 || opt_matches.opt_present("h") {
		println!(
"The program secretshare is an implementation of Shamir's secret sharing scheme.\n\
 It is applied byte-wise within a finite field for arbitrarily long secrets.\n");
		println!("{}", opts.usage("Usage: rustysecrets [options]"));
		println!("Input is read from STDIN and output is written to STDOUT.");
 		return;
	}

	let action: Result<_,_> =
		match (opt_matches.opt_present("e"), opt_matches.opt_present("d")) {
			(false, false) => Err("Nothing to do! Use -e or -d"),
			(true, true) => Err("Use either -e or -d and not both"),
			(false, true) => Ok(Action::Decode),
			(true, false) => {
				if let Some(param) = opt_matches.opt_str("e") {
					if let Ok((k,n)) = parse_k_n(&*param) {
						if 0 < k && k <= n {
							Ok(Action::Encode(k,n))
						} else {
							Err("Invalid encoding parameters K,N")
						}
					} else {
						Err("Could not parse K,N parameters")
					}
				} else {
					Err("No parameter for -e or -d provided")
				}
			}
		};

	let result =
		match action {
			Ok(Action::Encode(k,n)) => perform_encode_from_io(k, n),
			Ok(Action::Decode) => perform_decode_from_io(),
			Err(e) => Err(other_io_err(e, None))
		};

	if let Err(e) = result {
		drop(writeln!(&mut stderr, "{}", e));
		// env::set_exit_status(1); // FIXME: unstable feature
	}
}

fn perform_encode_from_io(k: u8, n: u8) -> io::Result<()> {
	let secret = {
        let limit: usize = 0x10000;
        let stdin = io::stdin();
        let mut locked = stdin.lock();
        let mut tmp: Vec<u8> = Vec::new();
        try!(locked.by_ref().take(limit as u64).read_to_end(&mut tmp));
        if tmp.len() == limit {
            let mut dummy = [0u8];
            if try!(locked.read(&mut dummy)) > 0 {
                return Err(other_io_err("Secret too large",
                                        Some(format!("My limit is at {} bytes.", limit))));
            }
        }
        tmp.pop();
		tmp
    };
	match lib::generate_shares(k, n, secret) {
		Ok(shares) => {
			for share in shares {println!("{:?}", str::from_utf8(&share).unwrap())};
		}
		Err(e) => { return Err(e) as io::Result<()>; }
	}

	return Ok(()) as io::Result<()>;
}

fn perform_decode_from_io() -> io::Result<()> {
	let stdin = io::stdin();
	let stdin = io::BufReader::new(stdin.lock());
	let mut shares: Vec<String> = Vec::new();

	for line in stdin.lines() {
		match line {
			Ok(share) => shares.push(share),
			Err(_) => {}
		}
	}

	return match lib::recover_secret(shares) {
		Ok(secret) => {
			let mut out = io::stdout();
			try!(out.write_all(&*secret));
			out.flush()
		}
		Err(e) => {Err(e) as io::Result<()>}
	};
}

fn parse_k_n(s: &str) -> io::Result<(u8, u8)> {
	let mut iter = s.split(',');
	let msg = "K and N have to be separated with a comma";
	let s1 = otry!(iter.next(), msg).trim();
	let s2 = otry!(iter.next(), msg).trim();
	let k = try!(s1.parse().map_err(pie2io));
	let n = try!(s2.parse().map_err(pie2io));
	Ok((k, n))
}
<|endoftext|>


<commit_before>extern crate gfx_gl as gl;
extern crate camera_controllers;
extern crate collada;
extern crate env_logger;
extern crate gfx;
extern crate gfx_debug_draw;
extern crate gfx_device_gl;
extern crate piston;
extern crate sdl2;
extern crate sdl2_window;
extern crate shader_version;
extern crate skeletal_animation;
extern crate vecmath;
extern crate dev_menu;

use std::path::Path;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;

use gfx::traits::*;

use gfx_debug_draw::DebugRenderer;

use piston::window::{
    WindowSettings,
    OpenGLWindow,
};

use piston::event::*;

use vecmath::{Matrix4, mat4_id};

use sdl2_window::Sdl2Window;

use camera_controllers::{
    OrbitZoomCamera,
    OrbitZoomCameraSettings,
    CameraPerspective,
    model_view_projection
};

use skeletal_animation::*;
use collada::document::ColladaDocument;

mod sdl2_window_output;

pub struct Settings {
    pub draw_skeleton: bool,
    pub draw_labels: bool,
    pub draw_mesh: bool,
    pub playback_speed: f32,

    pub params: HashMap<String, f32>,
}

fn main() {

    env_logger::init().unwrap();

    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        shader_version::OpenGL::_3_2,
        WindowSettings::new(
            "Skeletal Animation Demo".to_string(),
            piston::window::Size { width: 640, height: 480 }
        ).exit_on_esc(true)
    );

    let mut graphics = gfx_device_gl::create(|s| window.get_proc_address(s)).into_graphics();

    let window = Rc::new(RefCell::new(window));

    let window_output = sdl2_window_output::WindowOutput::new(window.clone(), graphics.factory.get_main_frame_buffer());

    let clear = gfx::ClearData {
        color: [0.3, 0.3, 0.3, 1.0],
        depth: 1.0,
        stencil: 0
    };

    let mut debug_renderer = DebugRenderer::new(&mut graphics, [win_width as u32, win_height as u32], 64, None, None).ok().unwrap();

    // TODO - these are (usually) available in the COLLADA file, associated with a <mesh> element in a somewhat convoluted way
    let texture_paths = vec![
        "assets/young_lightskinned_male_diffuse.png",
        "assets/suit01lres_diffuse.png",
        "assets/male02_diffuse_black.png",
        "assets/brown_eye.png",
        "assets/eyebrow009.png",
        "assets/eyelashes01.png",
    ];

    let collada_document = ColladaDocument::from_path(&Path::new("assets/suit_guy.dae")).unwrap();

    // TODO better.. we keep reloading the same document over and over for different things...
    let skeleton = {
        let skeleton_set = collada_document.get_skeletons().unwrap();
        Skeleton::from_collada(&skeleton_set[0])
    };

    let skeleton = Rc::new(skeleton);

    let mut asset_manager = AssetManager::new();
    asset_manager.load_animations("assets/clips.json");

    let controller_def = AssetManager::load_def_from_path("assets/human_controller.json").unwrap();
    let mut controller = AnimationController::new(controller_def, skeleton.clone(), &asset_manager.animation_clips);

    let mut skinned_renderer = SkinnedRenderer::from_collada(&mut graphics, collada_document, texture_paths).unwrap();

    let model = mat4_id();
    let mut projection = CameraPerspective {
        fov: 90.0f32,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: (win_width as f32) / (win_height as f32)
    }.projection();

    let mut orbit_zoom_camera: OrbitZoomCamera<f32> = OrbitZoomCamera::new(
        [0.0, 0.0, 0.0],
        OrbitZoomCameraSettings::default()
    );

    // Start event loop

    let mut settings = Settings {

        draw_skeleton: true,
        draw_labels: false,
        draw_mesh: true,
        playback_speed: 1.0,

        params: HashMap::new(),
    };

    let mut menu = dev_menu::Menu::<Settings>::new();

    menu.add_item(dev_menu::MenuItem::action_item(
        "Toggle Skeleton",
        Box::new( |ref mut settings| { settings.draw_skeleton = !settings.draw_skeleton; })
    ));

    menu.add_item(dev_menu::MenuItem::action_item(
        "Toggle Joint Labels",
        Box::new( |ref mut settings| { settings.draw_labels = !settings.draw_labels; })
    ));

    menu.add_item(dev_menu::MenuItem::action_item(
        "Toggle Mesh",
        Box::new( |ref mut settings| { settings.draw_mesh = !settings.draw_mesh; })
    ));

    menu.add_item(dev_menu::MenuItem::slider_item(
        "Playback Speed = ",
        [-5.0, 5.0],
        0.01,
        Box::new( |ref settings| { settings.playback_speed }),
        Box::new( |ref mut settings, value| { settings.playback_speed = value }),
    ));

    for (param, &value) in controller.get_parameters().iter() {
        settings.params.insert(param.clone(), value);

        // Apparently need to make our own string copies to move into each closure..
        let param_copy_1 = param.clone();
        let param_copy_2 = param.clone();

        menu.add_item(dev_menu::MenuItem::slider_item(
            &format!("Param[{}] = ", param)[..],
            [0.0, 1.0],
            0.01,
            Box::new( move |ref settings| {
                settings.params[&param_copy_1[..]]
            }),
            Box::new( move |ref mut settings, value| {
                settings.params.insert(param_copy_2.clone(), value);
            }),
        ));
    }

    for e in window.events() {

        orbit_zoom_camera.event(&e);
        menu.event(&e, &mut settings);

        e.resize(|width, height| {
            debug_renderer.resize(width, height);

            // Update projection matrix
            projection = CameraPerspective {
                fov: 90.0f32,
                near_clip: 0.1,
                far_clip: 1000.0,
                aspect_ratio: (width as f32) / (height as f32)
            }.projection();
        });

        e.update(|args| {

            controller.set_playback_speed(settings.playback_speed as f64);

            for (param, &value) in settings.params.iter() {
                controller.set_param_value(param, value);
            }

            controller.update(args.dt);
        });

        e.render(|args| {

            graphics.clear(clear, gfx::COLOR | gfx::DEPTH, &window_output);

            let camera_view = orbit_zoom_camera.camera(args.ext_dt).orthogonal();

            let camera_projection = model_view_projection(
                model,
                camera_view,
                projection
            );

            // Draw axes
            debug_renderer.draw_line([0.0, 0.0, 0.0], [5.0, 0.0, 0.0], [1.0, 0.0, 0.0, 1.0]);
            debug_renderer.draw_line([0.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, 1.0, 0.0, 1.0]);
            debug_renderer.draw_line([0.0, 0.0, 0.0], [0.0, 0.0, 5.0], [0.0, 0.0, 1.0, 1.0]);

            debug_renderer.draw_text_at_position(
                "X",
                [6.0, 0.0, 0.0],
                [1.0, 0.0, 0.0, 1.0],
            );

            debug_renderer.draw_text_at_position(
                "Y",
                [0.0, 6.0, 0.0],
                [0.0, 1.0, 0.0, 1.0],
            );

            debug_renderer.draw_text_at_position(
                "Z",
                [0.0, 0.0, 6.0],
                [0.0, 0.0, 1.0, 1.0],
            );

            let mut global_poses: [Matrix4<f32>; 64] = [ mat4_id(); 64 ];

            controller.get_output_pose(args.ext_dt, &mut global_poses[0 .. skeleton.joints.len()]);

            if settings.draw_mesh {
                skinned_renderer.render(&mut graphics, &window_output, camera_view, camera_projection, &global_poses);
            }

            if settings.draw_skeleton {
                skeleton.draw(&global_poses, &mut debug_renderer, settings.draw_labels);
            }

            menu.draw(&settings, &mut debug_renderer);

            debug_renderer.render(&mut graphics, &window_output, camera_projection);

            graphics.end_frame();

        });
    }
}
<commit_msg>No longer using gfx::Graphics<commit_after>extern crate gfx_gl as gl;
extern crate camera_controllers;
extern crate collada;
extern crate env_logger;
extern crate gfx;
extern crate gfx_debug_draw;
extern crate gfx_device_gl;
extern crate piston;
extern crate sdl2;
extern crate sdl2_window;
extern crate shader_version;
extern crate skeletal_animation;
extern crate vecmath;
extern crate dev_menu;

use std::path::Path;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;

use gfx::traits::*;

use gfx_debug_draw::DebugRenderer;

use piston::window::{
    WindowSettings,
    OpenGLWindow,
};

use piston::event::*;

use vecmath::{Matrix4, mat4_id};

use sdl2_window::Sdl2Window;

use camera_controllers::{
    OrbitZoomCamera,
    OrbitZoomCameraSettings,
    CameraPerspective,
    model_view_projection
};

use skeletal_animation::*;
use collada::document::ColladaDocument;

mod sdl2_window_output;

pub struct Settings {
    pub draw_skeleton: bool,
    pub draw_labels: bool,
    pub draw_mesh: bool,
    pub playback_speed: f32,

    pub params: HashMap<String, f32>,
}

fn main() {

    env_logger::init().unwrap();

    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        shader_version::OpenGL::_3_2,
        WindowSettings::new(
            "Skeletal Animation Demo".to_string(),
            piston::window::Size { width: 640, height: 480 }
        ).exit_on_esc(true)
    );

    let (mut device, mut factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let mut renderer = factory.create_renderer();

    let window = Rc::new(RefCell::new(window));

    let window_output = sdl2_window_output::WindowOutput::new(window.clone(), factory.get_main_frame_buffer());

    let clear = gfx::ClearData {
        color: [0.3, 0.3, 0.3, 1.0],
        depth: 1.0,
        stencil: 0
    };

    let mut debug_renderer = DebugRenderer::new(&device, &mut factory, [win_width as u32, win_height as u32], 64, None, None).ok().unwrap();

    // TODO - these are (usually) available in the COLLADA file, associated with a <mesh> element in a somewhat convoluted way
    let texture_paths = vec![
        "assets/young_lightskinned_male_diffuse.png",
        "assets/suit01lres_diffuse.png",
        "assets/male02_diffuse_black.png",
        "assets/brown_eye.png",
        "assets/eyebrow009.png",
        "assets/eyelashes01.png",
    ];

    let collada_document = ColladaDocument::from_path(&Path::new("assets/suit_guy.dae")).unwrap();

    // TODO better.. we keep reloading the same document over and over for different things...
    let skeleton = {
        let skeleton_set = collada_document.get_skeletons().unwrap();
        Skeleton::from_collada(&skeleton_set[0])
    };

    let skeleton = Rc::new(skeleton);

    let mut asset_manager = AssetManager::new();
    asset_manager.load_animations("assets/clips.json");

    let controller_def = AssetManager::load_def_from_path("assets/human_controller.json").unwrap();
    let mut controller = AnimationController::new(controller_def, skeleton.clone(), &asset_manager.animation_clips);

    let mut skinned_renderer = SkinnedRenderer::from_collada(&mut factory, collada_document, texture_paths).unwrap();

    let model = mat4_id();
    let mut projection = CameraPerspective {
        fov: 90.0f32,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: (win_width as f32) / (win_height as f32)
    }.projection();

    let mut orbit_zoom_camera: OrbitZoomCamera<f32> = OrbitZoomCamera::new(
        [0.0, 0.0, 0.0],
        OrbitZoomCameraSettings::default()
    );

    // Start event loop

    let mut settings = Settings {

        draw_skeleton: true,
        draw_labels: false,
        draw_mesh: true,
        playback_speed: 1.0,

        params: HashMap::new(),
    };

    let mut menu = dev_menu::Menu::<Settings>::new();

    menu.add_item(dev_menu::MenuItem::action_item(
        "Toggle Skeleton",
        Box::new( |ref mut settings| { settings.draw_skeleton = !settings.draw_skeleton; })
    ));

    menu.add_item(dev_menu::MenuItem::action_item(
        "Toggle Joint Labels",
        Box::new( |ref mut settings| { settings.draw_labels = !settings.draw_labels; })
    ));

    menu.add_item(dev_menu::MenuItem::action_item(
        "Toggle Mesh",
        Box::new( |ref mut settings| { settings.draw_mesh = !settings.draw_mesh; })
    ));

    menu.add_item(dev_menu::MenuItem::slider_item(
        "Playback Speed = ",
        [-5.0, 5.0],
        0.01,
        Box::new( |ref settings| { settings.playback_speed }),
        Box::new( |ref mut settings, value| { settings.playback_speed = value }),
    ));

    for (param, &value) in controller.get_parameters().iter() {
        settings.params.insert(param.clone(), value);

        // Apparently need to make our own string copies to move into each closure..
        let param_copy_1 = param.clone();
        let param_copy_2 = param.clone();

        menu.add_item(dev_menu::MenuItem::slider_item(
            &format!("Param[{}] = ", param)[..],
            [0.0, 1.0],
            0.01,
            Box::new( move |ref settings| {
                settings.params[&param_copy_1[..]]
            }),
            Box::new( move |ref mut settings, value| {
                settings.params.insert(param_copy_2.clone(), value);
            }),
        ));
    }

    for e in window.events() {

        orbit_zoom_camera.event(&e);
        menu.event(&e, &mut settings);

        e.resize(|width, height| {
            debug_renderer.resize(width, height);

            // Update projection matrix
            projection = CameraPerspective {
                fov: 90.0f32,
                near_clip: 0.1,
                far_clip: 1000.0,
                aspect_ratio: (width as f32) / (height as f32)
            }.projection();
        });

        e.update(|args| {

            controller.set_playback_speed(settings.playback_speed as f64);

            for (param, &value) in settings.params.iter() {
                controller.set_param_value(param, value);
            }

            controller.update(args.dt);
        });

        e.render(|args| {

            renderer.clear(clear, gfx::COLOR | gfx::DEPTH, &window_output);

            let camera_view = orbit_zoom_camera.camera(args.ext_dt).orthogonal();

            let camera_projection = model_view_projection(
                model,
                camera_view,
                projection
            );

            // Draw axes
            debug_renderer.draw_line([0.0, 0.0, 0.0], [5.0, 0.0, 0.0], [1.0, 0.0, 0.0, 1.0]);
            debug_renderer.draw_line([0.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, 1.0, 0.0, 1.0]);
            debug_renderer.draw_line([0.0, 0.0, 0.0], [0.0, 0.0, 5.0], [0.0, 0.0, 1.0, 1.0]);

            debug_renderer.draw_text_at_position(
                "X",
                [6.0, 0.0, 0.0],
                [1.0, 0.0, 0.0, 1.0],
            );

            debug_renderer.draw_text_at_position(
                "Y",
                [0.0, 6.0, 0.0],
                [0.0, 1.0, 0.0, 1.0],
            );

            debug_renderer.draw_text_at_position(
                "Z",
                [0.0, 0.0, 6.0],
                [0.0, 0.0, 1.0, 1.0],
            );

            let mut global_poses: [Matrix4<f32>; 64] = [ mat4_id(); 64 ];

            controller.get_output_pose(args.ext_dt, &mut global_poses[0 .. skeleton.joints.len()]);

            if settings.draw_mesh {
                skinned_renderer.render(&mut renderer, &mut factory, &window_output, camera_view, camera_projection, &global_poses);
            }

            if settings.draw_skeleton {
                skeleton.draw(&global_poses, &mut debug_renderer, settings.draw_labels);
            }

            menu.draw(&settings, &mut debug_renderer);

            debug_renderer.render(&mut renderer, &mut factory, &window_output, camera_projection);

            device.submit(renderer.as_buffer());

            renderer.reset();

            device.after_frame();
            factory.cleanup();

        });
    }
}
<|endoftext|>


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

#![feature(box_syntax)]
#![feature(link_args)]

#[macro_use]
extern crate objc;

#[macro_use]
extern crate log;

extern crate libc;
extern crate cocoa;
extern crate gleam;
extern crate objc_foundation;
extern crate open;

mod app;
mod window;
mod view;
mod servo;
mod platform;
mod state;

use app::{App, AppEvent, AppCommand};
use window::{Window, WindowEvent, WindowCommand};
use view::ViewEvent;
use servo::ServoEvent;
use std::rc::Rc;
use std::env::args;
use servo::{Servo, ServoUrl, WebRenderDebugOption};

fn main() {

    let logs = platform::Logger::init();

    info!("starting");

    let app = App::new().unwrap();
    let window = app.create_window().unwrap();

    app.mut_state().current_window_index = Some(0);
    app.mut_state().windows.push(Window::get_init_state());

    let view = Rc::new(window.create_view().unwrap());

    Servo::configure(App::get_resources_path().unwrap());

    let servo = {
        let geometry = view.get_geometry();
        let waker = window.create_event_loop_waker();
        Servo::new(geometry, view.clone(), waker)
    };

    // Skip first argument (executable), and find the first
    // argument that doesn't start with `-`
    let url = args().skip(1).find(|arg| {
        !arg.starts_with("-")
    }).unwrap_or("https://blog.servo.org/".to_owned());

    let browser = servo.create_browser(&url);
    servo.select_browser(browser.id);

    app.mut_state().windows[0].current_browser_index = Some(0);
    app.mut_state().windows[0].browsers.push(browser);

    info!("Servo version: {}", servo.version());

    let handle_events = || {

        // Loop until no events are available anymore.
        loop {

            let app_events = app.get_events();
            let win_events = window.get_events();
            let view_events = view.get_events();
            let servo_events = servo.get_events();

            if app_events.is_empty() &&
               win_events.is_empty() &&
               view_events.is_empty() &&
               servo_events.is_empty() {
                   break
            }

            // FIXME: it's really annoying we need this
            let mut force_sync = false;
            let mut ui_invalidated = false;

            for event in app_events {
                match event {
                    AppEvent::DidFinishLaunching => {
                        // FIXME: does this work?
                    }
                    AppEvent::WillTerminate => {
                        // FIXME: does this work?
                    }
                    AppEvent::DidChangeScreenParameters => {
                        // FIXME: does this work?
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    AppEvent::DoCommand(cmd) => {
                        match cmd {
                            AppCommand::ClearHistory => {
                                // FIXME
                            }
                            AppCommand::ToggleOptionDarkTheme => {
                                app.mut_state().dark_theme = !app.state().dark_theme;
                                ui_invalidated = true;
                            }
                        }
                    }
                }
            }

            for event in win_events {
                match event {
                    WindowEvent::EventLoopAwaken => {
                        force_sync = true;
                    }
                    WindowEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    WindowEvent::DidEnterFullScreen => {
                        // FIXME
                    }
                    WindowEvent::DidExitFullScreen => {
                        // FIXME
                    }
                    WindowEvent::WillClose => {
                        // FIXME
                    }
                    WindowEvent::DoCommand(cmd) => {
                        let idx = app.state().windows[0].current_browser_index.unwrap();
                        let ref mut state = app.mut_state().windows[0].browsers[idx];
                        match cmd {
                            WindowCommand::Stop => {
                                // FIXME
                            }
                            WindowCommand::Reload => {
                                servo.reload(state.id);
                            }
                            WindowCommand::NavigateBack => {
                                servo.go_back(state.id);
                            }
                            WindowCommand::NavigateForward => {
                                servo.go_forward(state.id);
                            }
                            WindowCommand::OpenLocation => {
                                app.mut_state().windows[0].urlbar_focused = true;
                                ui_invalidated = true;
                            }
                            WindowCommand::OpenInDefaultBrowser => {
                                if let Some(ref url) = state.url {
                                    open::that(url.clone()).ok();
                                }
                            }
                            WindowCommand::ZoomIn => {
                                ui_invalidated = true;
                                state.zoom *= 1.1;
                                servo.zoom(state.zoom);
                            }
                            WindowCommand::ZoomOut => {
                                ui_invalidated = true;
                                state.zoom /= 1.1;
                                servo.zoom(state.zoom);
                            }
                            WindowCommand::ZoomToActualSize => {
                                ui_invalidated = true;
                                state.zoom = 1.0;
                                servo.reset_zoom();
                            }

                            WindowCommand::ToggleSidebar => {
                                app.mut_state().windows[0].sidebar_is_open = !app.mut_state().windows[0].sidebar_is_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::ShowOptions => {
                                app.mut_state().windows[0].options_open = !app.mut_state().windows[0].options_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::Load(request) => {
                                state.user_input = Some(request.clone());
                                let url = ServoUrl::parse(&request).or_else(|error| {
                                    // FIXME: weak
                                    if request.ends_with(".com") || request.ends_with(".org") || request.ends_with(".net") {
                                        ServoUrl::parse(&format!("http://{}", request))
                                    } else {
                                        Err(error)
                                    }
                                }).or_else(|_| {
                                    ServoUrl::parse(&format!("https://duckduckgo.com/html/?q={}", request))
                                });
                                match url {
                                    Ok(url) => {
                                        servo.load_url(state.id, url)
                                    },
                                    Err(err) => warn!("Can't parse url: {}", err),
                                }
                            }
                            WindowCommand::ToggleOptionShowLogs => {
                                app.mut_state().windows[0].logs_visible = !app.state().windows[0].logs_visible;
                                ui_invalidated = true;
                            },
                            WindowCommand::NewTab => {
                                let browser = servo.create_browser("about:blank");
                                servo.select_browser(browser.id);
                                servo.update_geometry(view.get_geometry());
                                app.mut_state().windows[0].current_browser_index = Some(idx + 1);
                                app.mut_state().windows[0].browsers.push(browser);
                                ui_invalidated = true;
                            },
                            WindowCommand::CloseTab => {
                                if app.state().windows[0].browsers.len() > 1 {
                                    let id = app.state().windows[0].browsers[idx].id;
                                    let new_id = if idx == app.state().windows[0].browsers.len() - 1 {
                                        app.mut_state().windows[0].current_browser_index = Some(idx - 1);
                                        app.mut_state().windows[0].browsers[idx - 1].id
                                    } else {
                                        app.state().windows[0].browsers[idx + 1].id
                                    };
                                    servo.select_browser(new_id);
                                    servo.close_browser(id);
                                    app.mut_state().windows[0].browsers.remove(idx);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::PrevTab => {
                                let new_idx = if idx == 0 {
                                    app.state().windows[0].browsers.len() - 1
                                } else {
                                    idx - 1
                                };
                                app.mut_state().windows[0].current_browser_index = Some(new_idx);
                                let id = app.state().windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::NextTab => {
                                let new_idx = if idx == app.state().windows[0].browsers.len() - 1 {
                                    0
                                } else {
                                    idx + 1
                                };
                                app.mut_state().windows[0].current_browser_index = Some(new_idx);
                                let id = app.state().windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::SelectTab(idx) => {
                                if app.state().windows[0].current_browser_index != Some(idx) {
                                    app.mut_state().windows[0].current_browser_index = Some(idx);
                                    let id = app.state().windows[0].browsers[idx].id;
                                    servo.select_browser(id);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::ToggleOptionFragmentBorders => { },
                            WindowCommand::ToggleOptionParallelDisplayListBuidling => { },
                            WindowCommand::ToggleOptionShowParallelLayout => { },
                            WindowCommand::ToggleOptionConvertMouseToTouch => { },
                            WindowCommand::ToggleOptionTileBorders => { },

                            WindowCommand::ToggleOptionWRProfiler => {
                                let ref mut state = app.mut_state().windows[0];
                                state.debug_options.wr_profiler = !state.debug_options.wr_profiler;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::Profiler);
                            },

                            WindowCommand::ToggleOptionWRTextureCacheDebug => {
                                let ref mut state = app.mut_state().windows[0];
                                state.debug_options.wr_texture_cache_debug = !state.debug_options.wr_texture_cache_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::TextureCacheDebug);
                            },

                            WindowCommand::ToggleOptionWRTargetDebug => {
                                let ref mut state = app.mut_state().windows[0];
                                state.debug_options.wr_render_target_debug = !state.debug_options.wr_render_target_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::RenderTargetDebug);
                            },
                        }
                    }
                }
            }

            for event in view_events {
                let idx = app.state().windows[0].current_browser_index.unwrap();
                let ref mut state = app.mut_state().windows[0].browsers[idx];
                match event {
                    ViewEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    ViewEvent::MouseWheel(delta, phase) => {
                        let (x, y) = match delta {
                            view::MouseScrollDelta::PixelDelta(x, y) => {
                                (x, y)
                            },
                            _ => (0.0, 0.0),
                        };
                        servo.perform_scroll(0, 0, x, y, phase);
                    }
                    ViewEvent::MouseMoved(x, y) => {
                        state.last_mouse_point = (x, y);
                        servo.perform_mouse_move(x, y);
                    }
                    ViewEvent::MouseInput(element_state, button) => {
                        let (x, y) = state.last_mouse_point;
                        let (org_x, org_y) = state.last_mouse_down_point;
                        let last_mouse_down_button = state.last_mouse_down_button;
                        servo.perform_click(x, y, org_x, org_y, element_state, button, last_mouse_down_button);
                        state.last_mouse_down_point = (x, y);
                        if element_state == view::ElementState::Pressed {
                            state.last_mouse_down_button = Some(button);
                        }
                    }
                    ViewEvent::KeyEvent(c, key, keystate, modifiers) => {
                        servo.send_key(state.id, c, key, keystate, modifiers);
                    }
                }
            }

            for event in servo_events {
                match event {
                    ServoEvent::SetWindowInnerSize(..) => {
                        // ignore
                    }
                    ServoEvent::SetWindowPosition(..) => {
                        // ignore
                    }
                    ServoEvent::SetFullScreenState(fullscreen) => {
                        if fullscreen {
                            view.enter_fullscreen();
                        } else {
                            view.exit_fullscreen();
                        }
                    }
                    ServoEvent::TitleChanged(id, title) => {
                        match app.mut_state().windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.title = title;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::StatusChanged(status) => {
                        app.mut_state().windows[0].status = status;
                        ui_invalidated = true;
                    }
                    ServoEvent::LoadStart(id) => {
                        match app.mut_state().windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = true;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::LoadEnd(id) => {
                        match app.mut_state().windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = false;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::HeadParsed(..) => {
                        // FIXME
                    }
                    ServoEvent::HistoryChanged(id, entries, current) => {
                        match app.mut_state().windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                let url = entries[current].url.to_string();
                                browser.url = Some(url);
                                browser.can_go_back = current > 0;
                                browser.can_go_forward = current < entries.len() - 1;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::CursorChanged(cursor) => {
                        app.mut_state().cursor = cursor;
                        ui_invalidated = true;
                    }
                    ServoEvent::FaviconChanged(..) => {
                        // FIXME
                    }
                    ServoEvent::Key(..) => {
                        // FIXME
                    }
                }
            }

            if ui_invalidated {
                app.render();
                window.render();
            }

            servo.sync(force_sync);
        }

        // Here, only stuff that we know for sure won't trigger any
        // new events

        // FIXME: logs will grow until pulled
        if app.state().windows[0].logs_visible {
            window.append_logs(&logs.get_logs());
        }
    };

    view.set_live_resize_callback(&handle_events);

    app.run(handle_events);

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

#![feature(box_syntax)]
#![feature(link_args)]

#[macro_use]
extern crate objc;

#[macro_use]
extern crate log;

extern crate libc;
extern crate cocoa;
extern crate gleam;
extern crate objc_foundation;
extern crate open;

mod app;
mod window;
mod view;
mod servo;
mod platform;
mod state;

use app::{App, AppEvent, AppCommand};
use window::{Window, WindowEvent, WindowCommand};
use view::ViewEvent;
use servo::ServoEvent;
use std::rc::Rc;
use std::env::args;
use servo::{Servo, ServoUrl, WebRenderDebugOption};

fn main() {

    let logs = platform::Logger::init();

    info!("starting");

    let app = App::new().unwrap();
    let window = app.create_window().unwrap();

    let mut state = App::get_init_state();

    state.current_window_index = Some(0);
    state.windows.push(Window::get_init_state());

    let view = Rc::new(window.create_view().unwrap());

    Servo::configure(App::get_resources_path().unwrap());

    let servo = {
        let geometry = view.get_geometry();
        let waker = window.create_event_loop_waker();
        Servo::new(geometry, view.clone(), waker)
    };

    // Skip first argument (executable), and find the first
    // argument that doesn't start with `-`
    let url = args().skip(1).find(|arg| {
        !arg.starts_with("-")
    }).unwrap_or("https://blog.servo.org/".to_owned());

    let browser = servo.create_browser(&url);
    servo.select_browser(browser.id);

    state.windows[0].current_browser_index = Some(0);
    state.windows[0].browsers.push(browser);

    info!("Servo version: {}", servo.version());

    let handle_events = || {

        // Loop until no events are available anymore.
        loop {

            let app_events = app.get_events();
            let win_events = window.get_events();
            let view_events = view.get_events();
            let servo_events = servo.get_events();

            if app_events.is_empty() &&
               win_events.is_empty() &&
               view_events.is_empty() &&
               servo_events.is_empty() {
                   break
            }

            // FIXME: it's really annoying we need this
            let mut force_sync = false;
            let mut ui_invalidated = false;

            for event in app_events {
                match event {
                    AppEvent::DidFinishLaunching => {
                        // FIXME: does this work?
                    }
                    AppEvent::WillTerminate => {
                        // FIXME: does this work?
                    }
                    AppEvent::DidChangeScreenParameters => {
                        // FIXME: does this work?
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    AppEvent::DoCommand(cmd) => {
                        match cmd {
                            AppCommand::ClearHistory => {
                                // FIXME
                            }
                            AppCommand::ToggleOptionDarkTheme => {
                                state.dark_theme = !state.dark_theme;
                                ui_invalidated = true;
                            }
                        }
                    }
                }
            }

            for event in win_events {
                match event {
                    WindowEvent::EventLoopAwaken => {
                        force_sync = true;
                    }
                    WindowEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    WindowEvent::DidEnterFullScreen => {
                        // FIXME
                    }
                    WindowEvent::DidExitFullScreen => {
                        // FIXME
                    }
                    WindowEvent::WillClose => {
                        // FIXME
                    }
                    WindowEvent::DoCommand(cmd) => {
                        let idx = state.windows[0].current_browser_index.unwrap();
                        let bid = state.windows[0].browsers[idx].id;
                        match cmd {
                            WindowCommand::Stop => {
                                // FIXME
                            }
                            WindowCommand::Reload => {
                                servo.reload(bid);
                            }
                            WindowCommand::NavigateBack => {
                                servo.go_back(bid);
                            }
                            WindowCommand::NavigateForward => {
                                servo.go_forward(bid);
                            }
                            WindowCommand::OpenLocation => {
                                state.windows[0].urlbar_focused = true;
                                ui_invalidated = true;
                            }
                            WindowCommand::OpenInDefaultBrowser => {
                                if let Some(ref url) = state.windows[0].browsers[idx].url {
                                    open::that(url.clone()).ok();
                                }
                            }
                            WindowCommand::ZoomIn => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom *= 1.1;
                                servo.zoom(state.windows[0].browsers[idx].zoom);
                            }
                            WindowCommand::ZoomOut => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom /= 1.1;
                                servo.zoom(state.windows[0].browsers[idx].zoom);
                            }
                            WindowCommand::ZoomToActualSize => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom = 1.0;
                                servo.reset_zoom();
                            }

                            WindowCommand::ToggleSidebar => {
                                state.windows[0].sidebar_is_open = !state.windows[0].sidebar_is_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::ShowOptions => {
                                state.windows[0].options_open = !state.windows[0].options_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::Load(request) => {
                                state.windows[0].browsers[idx].user_input = Some(request.clone());
                                let url = ServoUrl::parse(&request).or_else(|error| {
                                    // FIXME: weak
                                    if request.ends_with(".com") || request.ends_with(".org") || request.ends_with(".net") {
                                        ServoUrl::parse(&format!("http://{}", request))
                                    } else {
                                        Err(error)
                                    }
                                }).or_else(|_| {
                                    ServoUrl::parse(&format!("https://duckduckgo.com/html/?q={}", request))
                                });
                                match url {
                                    Ok(url) => {
                                        servo.load_url(bid, url)
                                    },
                                    Err(err) => warn!("Can't parse url: {}", err),
                                }
                            }
                            WindowCommand::ToggleOptionShowLogs => {
                                state.windows[0].logs_visible = !state.windows[0].logs_visible;
                                ui_invalidated = true;
                            },
                            WindowCommand::NewTab => {
                                let browser = servo.create_browser("about:blank");
                                servo.select_browser(browser.id);
                                servo.update_geometry(view.get_geometry());
                                state.windows[0].current_browser_index = Some(idx + 1);
                                state.windows[0].browsers.push(browser);
                                ui_invalidated = true;
                            },
                            WindowCommand::CloseTab => {
                                if state.windows[0].browsers.len() > 1 {
                                    let id = state.windows[0].browsers[idx].id;
                                    let new_id = if idx == state.windows[0].browsers.len() - 1 {
                                        state.windows[0].current_browser_index = Some(idx - 1);
                                        state.windows[0].browsers[idx - 1].id
                                    } else {
                                        state.windows[0].browsers[idx + 1].id
                                    };
                                    servo.select_browser(new_id);
                                    servo.close_browser(id);
                                    state.windows[0].browsers.remove(idx);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::PrevTab => {
                                let new_idx = if idx == 0 {
                                    state.windows[0].browsers.len() - 1
                                } else {
                                    idx - 1
                                };
                                state.windows[0].current_browser_index = Some(new_idx);
                                let id = state.windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::NextTab => {
                                let new_idx = if idx == state.windows[0].browsers.len() - 1 {
                                    0
                                } else {
                                    idx + 1
                                };
                                state.windows[0].current_browser_index = Some(new_idx);
                                let id = state.windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::SelectTab(idx) => {
                                if state.windows[0].current_browser_index != Some(idx) {
                                    state.windows[0].current_browser_index = Some(idx);
                                    let id = state.windows[0].browsers[idx].id;
                                    servo.select_browser(id);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::ToggleOptionFragmentBorders => { },
                            WindowCommand::ToggleOptionParallelDisplayListBuidling => { },
                            WindowCommand::ToggleOptionShowParallelLayout => { },
                            WindowCommand::ToggleOptionConvertMouseToTouch => { },
                            WindowCommand::ToggleOptionTileBorders => { },

                            WindowCommand::ToggleOptionWRProfiler => {
                                state.windows[0].debug_options.wr_profiler = !state.windows[0].debug_options.wr_profiler;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::Profiler);
                            },

                            WindowCommand::ToggleOptionWRTextureCacheDebug => {
                                state.windows[0].debug_options.wr_texture_cache_debug = !state.windows[0].debug_options.wr_texture_cache_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::TextureCacheDebug);
                            },

                            WindowCommand::ToggleOptionWRTargetDebug => {
                                state.windows[0].debug_options.wr_render_target_debug = !state.windows[0].debug_options.wr_render_target_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::RenderTargetDebug);
                            },
                        }
                    }
                }
            }

            for event in view_events {
                let idx = state.windows[0].current_browser_index.unwrap();
                let state = &mut state.windows[0].browsers[idx];
                match event {
                    ViewEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    ViewEvent::MouseWheel(delta, phase) => {
                        let (x, y) = match delta {
                            view::MouseScrollDelta::PixelDelta(x, y) => (x, y),
                            _ => (0.0, 0.0),
                        };
                        servo.perform_scroll(0, 0, x, y, phase);
                    }
                    ViewEvent::MouseMoved(x, y) => {
                        state.last_mouse_point = (x, y);
                        servo.perform_mouse_move(x, y);
                    }
                    ViewEvent::MouseInput(element_state, button) => {
                        let (x, y) = state.last_mouse_point;
                        let (org_x, org_y) = state.last_mouse_down_point;
                        let last_mouse_down_button = state.last_mouse_down_button;
                        servo.perform_click(x, y, org_x, org_y, element_state, button, last_mouse_down_button);
                        state.last_mouse_down_point = (x, y);
                        if element_state == view::ElementState::Pressed {
                            state.last_mouse_down_button = Some(button);
                        }
                    }
                    ViewEvent::KeyEvent(c, key, keystate, modifiers) => {
                        servo.send_key(state.id, c, key, keystate, modifiers);
                    }
                }
            }

            for event in servo_events {
                match event {
                    ServoEvent::SetWindowInnerSize(..) => {
                        // ignore
                    }
                    ServoEvent::SetWindowPosition(..) => {
                        // ignore
                    }
                    ServoEvent::SetFullScreenState(fullscreen) => {
                        if fullscreen {
                            view.enter_fullscreen();
                        } else {
                            view.exit_fullscreen();
                        }
                    }
                    ServoEvent::TitleChanged(id, title) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.title = title;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::StatusChanged(status) => {
                        state.windows[0].status = status;
                        ui_invalidated = true;
                    }
                    ServoEvent::LoadStart(id) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = true;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::LoadEnd(id) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = false;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::HeadParsed(..) => {
                        // FIXME
                    }
                    ServoEvent::HistoryChanged(id, entries, current) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                let url = entries[current].url.to_string();
                                browser.url = Some(url);
                                browser.can_go_back = current > 0;
                                browser.can_go_forward = current < entries.len() - 1;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::CursorChanged(cursor) => {
                        state.cursor = cursor;
                        ui_invalidated = true;
                    }
                    ServoEvent::FaviconChanged(..) => {
                        // FIXME
                    }
                    ServoEvent::Key(..) => {
                        // FIXME
                    }
                }
            }

            if ui_invalidated {
                app.render(&state);
                // FIXME: no mut!
                window.render(&mut state.windows[0]);
            }

            servo.sync(force_sync);
        }

        // Here, only stuff that we know for sure won't trigger any
        // new events

        // FIXME: logs will grow until pulled
        if state.windows[0].logs_visible {
            window.append_logs(&logs.get_logs());
        }
    };

    view.set_live_resize_callback(&handle_events);

    app.run(handle_events);

}
<|endoftext|>


<commit_before>#![feature(io)]
#![feature(rand)]
#![allow(deprecated)]

use game::{Game};

use std::old_io;

mod game;

fn main() {
    println!("Guess the word game");
    let mut game = Game::new(get_words());
    game_loop(&mut game);
    println!("'{}' - You won!", game.intended_word());
}

fn game_loop(game : &mut Game) {
    loop {
        print!(" {}, {} letters left, ", game.current_progress(), game.letters_left());
        let input = old_io::stdin().read_line().ok().expect("Failed to read line");
        let input_trimed = &input[].trim();
        game.guess(input_trimed);
        if game.letters_left() == 0 {
            break;
        }
    }
}

fn get_words() -> Vec<String> {
    vec![
        "rust".to_string(),
        "is".to_string(),
        "the".to_string(),
        "best".to_string(),
        "programming".to_string(),
        "language".to_string(),
    ]
}
<commit_msg>Формирование списка строк по-симпачичнее<commit_after>#![feature(io)]
#![feature(rand)]
#![allow(deprecated)]

use game::{Game};

use std::old_io;

mod game;

fn main() {
    println!("Guess the word game");
    let mut game = Game::new(get_words());
    game_loop(&mut game);
    println!("'{}' - You won!", game.intended_word());
}

fn game_loop(game : &mut Game) {
    loop {
        print!(" {}, {} letters left, ", game.current_progress(), game.letters_left());
        let input = old_io::stdin().read_line().ok().expect("Failed to read line");
        let input_trimed = &input[].trim();
        game.guess(input_trimed);
        if game.letters_left() == 0 {
            break;
        }
    }
}

fn get_words() -> Vec<String> {
    let words = vec![
        "rust",
        "is",
        "the",
        "best",
        "programming",
        "language",
    ];
    words.iter().map(|x| x.to_string()).collect()
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

extern crate regex;
use regex::Regex;

use std::io;
use std::io::Write;

#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    Unknown(String), // Invalid test (basically non-ascii)
    Literal(String), // Numeric literal number
    Func(Function), // Pre-defined function (like cos() )
    Const(Constant), // Constant like pi or e
    Var(String), // str arbitrary single char variable name
    Op(Operator), // Any of the 4 operators (+-*/)
    Open, // Open parens '('
    Close, // Closing parens ')'
    Comma,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Function {
	Abs,
    Sqrt,
    Ln,
    Log,
    Sin,
    Csc,
    Cos,
    Sec,
    Tan,
    Cot,
    Asin,
    Acsc,
    Acos,
    Asec,
    Atan,
    Acot,
    Sinh,
    Csch,
    Cosh,
    Sech,
    Tanh,
    Coth,
    Asinh,
    Acsch,
    Acosh,
    Asech,
    Atanh,
    Acoth,
    Max,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Constant {
	Pi,
	E,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
pub enum Operator {
    Add=0,
    Sub=1,
    Div=2,
    Mul=3,
    Pow=4, // Right
}

#[derive(Debug, PartialEq, Clone)]
struct Expression {
    tokens: Vec<Token>,
}

struct ExpressionIter<'a> {
	expr: &'a Expression,
	count: usize,
}

impl<'a> Iterator for ExpressionIter<'a> {
	type Item = &'a Token;
    fn next(&mut self) -> Option<&'a Token> {
    	let token = self.expr.get_tokens().get(self.count);
    	self.count += 1;
    	token
    }
}

impl Expression {
	fn new(tokens: Vec<Token>) -> Self {
		Expression {tokens: tokens}
	}

	fn push(&mut self, token: Token) {
		self.tokens.push(token);
	}

	fn get_tokens(&self) -> &[Token] {
		self.tokens.as_slice()
	}

	fn get_mut_tokens(&mut self) -> &mut [Token] {
		self.tokens.as_mut_slice()
	}

	fn get_token(&self, index: usize) -> &Token {
		self.tokens.get(index).unwrap()
	}

	fn get_mut_token(&mut self, index: usize) -> &mut Token {
		self.tokens.get_mut(index).unwrap()
	}

	fn replace_token(&mut self, index: usize, new_token: Token) {
		self.tokens.remove(index);
		self.tokens.insert(index, new_token);
	}

	fn replace_all_tokens(&mut self, new_token: Vec<Token>) {
		self.tokens = new_token
	}

	fn find_first(&self, token: &Token) -> Option<usize> {
		for i in 0..self.tokens.len() {
			if self.tokens.get(i).unwrap() == token {
				return Some(i);
			}
		}
		None
	}

	fn find_last(&self, token: &Token) -> Option<usize> {
		for i in (0..self.tokens.len()).rev() {
			if self.tokens.get(i).unwrap() == token {
				return Some(i);
			}
		}
		None
	}

	fn split_at(&self, index: usize) -> (&[Token], &[Token]) {
		self.tokens.split_at(index)
	}

	fn len(&self) -> usize {
		self.tokens.len()
	}

	fn iter(&self) -> ExpressionIter {
		ExpressionIter {expr: &self, count: 0}
	}
}

fn main() {
	let numeric_regex: Regex = Regex::new(r"\d+\.\d+|\d+").unwrap();
	let function_regex: Regex = Regex::new(r"\w{2,}").unwrap();
    println!("Welcome to Rust-Calculus!");
    println!("To evaluate an expression, simply type one in and hit RETURN.");
    println!("To set a variable, simply type VAR_NAME=EXPRESSION and hit RETURN.");
    println!("Valid commands are: sym_int, int, sym_def, and def.");
    println!("Type 'quit' to exit.");
    let mut input = String::new();
    let stdin = io::stdin();
    let mut stdout = io::stdout();
    loop {
    	input.clear();
    	print!(">>>> ");
    	stdout.flush().ok();
        if let Err(x) = stdin.read_line(&mut input) {
        	println!("There was a problem reading stdin: {:?}", x);
        	print!("Exiting...");;
        	break;
        }
        input = strip_white_space(&input).to_lowercase();
        if input == "quit" {
        	println!("Exiting...");
        	break;
        }
        let expr = parse_input(&input, &numeric_regex, &function_regex);
        if expr.is_ok() {
        	println!("{:?}", &expr.unwrap());
        } else {
        	println!("Encountered an error while parsing: {:?}", expr.unwrap_err());
        	println!("Try Again...(type 'quit' to exit)");
        	continue;
        }
    }
}

fn strip_white_space(input: &String) -> String {
	input.split_whitespace().collect::<Vec<&str>>().join("")
}

fn parse_input(input: &String, numeric_regex: &Regex, function_regex: &Regex) -> Result<Expression, String> {
	// 1. Replace everthing except letters/numbers with their enums
	// 2. Then go through and replace things with Literals or functions
	let mut expr: Expression = Expression::new(Vec::new());
	let mut builder: String = String::new();
	for c in input.chars() {
		match c {
		    '(' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Open);
		    },
		    ')' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Close);
		    },
		    '+' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Op(Operator::Add));
		    },
		    '-' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Op(Operator::Sub));
		    },
		    '*' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Op(Operator::Mul));
		    },
		    '/' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Op(Operator::Div));
		    },
		    '^' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Op(Operator::Pow));
		    },
		    ',' => {
		    	if builder.len() > 0 {
		    		if numeric_regex.is_match(&builder[..]) {
		    			expr.push(Token::Literal(builder.clone()));
		    		} else if function_regex.is_match(&builder[..]) {
		    			expr.push(map_string_to_func(&builder));
		    		}
		    		builder = String::new();
		    	}
		    	expr.push(Token::Comma);
		    },
		    _ => {
		    	builder.push(c);
		    }
		}
	}
	if builder.len() > 0 {
		if numeric_regex.is_match(&builder[..]) {
			expr.push(Token::Literal(builder.clone()));
		} else if function_regex.is_match(&builder[..]) {
			expr.push(map_string_to_func(&builder));
		}
		builder = String::new();
	}
	let mut op_stack: Vec<Token> = Vec::with_capacity(input.len());
	let mut out_queue: Vec<Token> = Vec::with_capacity(input.len());
	for i in 0..expr.len() {
		let current_token = expr.get_token(i);
		match current_token {
		    &Token::Literal(ref x) => out_queue.push(Token::Literal(x.clone())),
		    &Token::Func(ref x) => op_stack.push(Token::Func(x.clone())),
		    &Token::Comma => {
		    	loop {
			    	let stack_token = try!{op_stack.pop().ok_or("Malformed Expression, comma but no Parenthesis")};
			    	match stack_token {
			    	    Token::Open => {op_stack.push(stack_token); break;},
			    	    _ => out_queue.push(stack_token),
			    	}
		    	}
			},
		    &Token::Op(ref o1) =>  {
		    	loop {
			    	if op_stack.len() < 1 {
						break;
					}
			    	let o2 = op_stack.pop().unwrap(); // top of stack, must exist based off of previous if
			    	match o1 {
			    	    &Operator::Pow => match o2 {
			    	    	_ => { op_stack.push(o2); break; },
			    	    },
			    	    &Operator::Mul | &Operator::Div => match o2 {
			    	    	Token::Op(Operator::Pow) | Token::Op(Operator::Mul) | Token::Op(Operator::Div) => out_queue.push(o2),
			    	    	_ => { op_stack.push(o2); break; },
			    	    },
			    	    &Operator::Add | &Operator::Sub => match o2 {
			    	    	Token::Op(Operator::Add) | Token::Op(Operator::Sub) => out_queue.push(o2),
			    	    	_ => { op_stack.push(o2); break; },
			    	    }
			    	}
		    	};
		    	op_stack.push(Token::Op(o1.clone()));
			},
			&Token::Open => op_stack.push(Token::Open),
			&Token::Close => {
				loop {
					let stack_token = try!{op_stack.pop().ok_or("Malformed Expression, found a ) without (")};
					match stack_token {
						Token::Open => break,
						_ => out_queue.push(stack_token),
					}
				};
				if op_stack.len() > 0 {
					let next_stack_token = op_stack.pop().unwrap(); // must exist based off of previous if
					match next_stack_token {
						Token::Func(ref x) => out_queue.push(Token::Func(x.clone())),
						_ => op_stack.push(next_stack_token),
					}
				}
			},
			&Token::Unknown(ref x) => {
				let mut message: String = "You either misspelled a function, or it is not yet implemented. The unknown string was: ".to_owned();
				message.push_str(x);
				return Err(message);
			},
		    _ => break,
		}
	}
	while op_stack.len() > 0 {
	    out_queue.push(op_stack.pop().unwrap()); // The item must exist
	}
	Ok(Expression::new(out_queue))
}

fn map_string_to_func(input: &String) -> Token {
	match &(input.to_lowercase())[..] {
		"abs" => Token::Func(Function::Abs),
	    "sqrt" => Token::Func(Function::Sqrt),
	    "ln" => Token::Func(Function::Ln),
	    "log" => Token::Func(Function::Log),
	    "sin" => Token::Func(Function::Sin),
	    "csc" => Token::Func(Function::Csc),
	    "cos" => Token::Func(Function::Cos),
	    "sec" => Token::Func(Function::Sec),
	    "tan" => Token::Func(Function::Tan),
	    "cot" => Token::Func(Function::Cot),
	    "asin" => Token::Func(Function::Asin),
	    "acsc" => Token::Func(Function::Acsc),
	    "acos" => Token::Func(Function::Acos),
	    "asec" => Token::Func(Function::Asec),
	    "atan" => Token::Func(Function::Atan),
	    "acot" => Token::Func(Function::Acot),
	    "sinh" => Token::Func(Function::Sinh),
	    "csch" => Token::Func(Function::Csch),
	    "cosh" => Token::Func(Function::Cosh),
	    "sech" => Token::Func(Function::Sech),
	    "tanh" => Token::Func(Function::Tanh),
	    "coth" => Token::Func(Function::Coth),
	    "asinh" => Token::Func(Function::Asinh),
	    "acsch" => Token::Func(Function::Acsch),
	    "acosh" => Token::Func(Function::Acosh),
	    "asech" => Token::Func(Function::Asech),
	    "atanh" => Token::Func(Function::Atanh),
	    "acoth" => Token::Func(Function::Acoth),
	    "max" => Token::Func(Function::Max),
	    _ => Token::Unknown(input.clone()),
	}
}
<commit_msg>Made pretty<commit_after>#![allow(dead_code)]

extern crate regex;
use regex::Regex;

use std::io;
use std::io::Write;

#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    Unknown(String), // Invalid test (basically non-ascii)
    Literal(String), // Numeric literal number
    Func(Function), // Pre-defined function (like cos() )
    Const(Constant), // Constant like pi or e
    Var(String), // str arbitrary single char variable name
    Op(Operator), // Any of the 4 operators (+-*/)
    Open, // Open parens '('
    Close, // Closing parens ')'
    Comma,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Function {
    Abs,
    Sqrt,
    Ln,
    Log,
    Sin,
    Csc,
    Cos,
    Sec,
    Tan,
    Cot,
    Asin,
    Acsc,
    Acos,
    Asec,
    Atan,
    Acot,
    Sinh,
    Csch,
    Cosh,
    Sech,
    Tanh,
    Coth,
    Asinh,
    Acsch,
    Acosh,
    Asech,
    Atanh,
    Acoth,
    Max,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Constant {
    Pi,
    E,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
pub enum Operator {
    Add = 0,
    Sub = 1,
    Div = 2,
    Mul = 3,
    Pow = 4, // Right
}

#[derive(Debug, PartialEq, Clone)]
struct Expression {
    tokens: Vec<Token>,
}

struct ExpressionIter<'a> {
    expr: &'a Expression,
    count: usize,
}

impl<'a> Iterator for ExpressionIter<'a> {
    type Item = &'a Token;
    fn next(&mut self) -> Option<&'a Token> {
        let token = self.expr.get_tokens().get(self.count);
        self.count += 1;
        token
    }
}

impl Expression {
    fn new(tokens: Vec<Token>) -> Self {
        Expression { tokens: tokens }
    }

    fn push(&mut self, token: Token) {
        self.tokens.push(token);
    }

    fn get_tokens(&self) -> &[Token] {
        self.tokens.as_slice()
    }

    fn get_mut_tokens(&mut self) -> &mut [Token] {
        self.tokens.as_mut_slice()
    }

    fn get_token(&self, index: usize) -> &Token {
        self.tokens.get(index).unwrap()
    }

    fn get_mut_token(&mut self, index: usize) -> &mut Token {
        self.tokens.get_mut(index).unwrap()
    }

    fn replace_token(&mut self, index: usize, new_token: Token) {
        self.tokens.remove(index);
        self.tokens.insert(index, new_token);
    }

    fn replace_all_tokens(&mut self, new_token: Vec<Token>) {
        self.tokens = new_token
    }

    fn find_first(&self, token: &Token) -> Option<usize> {
        for i in 0..self.tokens.len() {
            if self.tokens.get(i).unwrap() == token {
                return Some(i);
            }
        }
        None
    }

    fn find_last(&self, token: &Token) -> Option<usize> {
        for i in (0..self.tokens.len()).rev() {
            if self.tokens.get(i).unwrap() == token {
                return Some(i);
            }
        }
        None
    }

    fn split_at(&self, index: usize) -> (&[Token], &[Token]) {
        self.tokens.split_at(index)
    }

    fn len(&self) -> usize {
        self.tokens.len()
    }

    fn iter(&self) -> ExpressionIter {
        ExpressionIter {
            expr: &self,
            count: 0,
        }
    }
}

fn main() {
    let numeric_regex: Regex = Regex::new(r"\d+\.\d+|\d+").unwrap();
    let function_regex: Regex = Regex::new(r"\w{2,}").unwrap();
    println!("Welcome to Rust-Calculus!");
    println!("To evaluate an expression, simply type one in and hit RETURN.");
    println!("To set a variable, simply type VAR_NAME=EXPRESSION and hit RETURN.");
    println!("Valid commands are: sym_int, int, sym_def, and def.");
    println!("Type 'quit' to exit.");
    let mut input = String::new();
    let stdin = io::stdin();
    let mut stdout = io::stdout();
    loop {
        input.clear();
        print!(">>>> ");
        stdout.flush().ok();
        if let Err(x) = stdin.read_line(&mut input) {
            println!("There was a problem reading stdin: {:?}", x);
            print!("Exiting...");;
            break;
        }
        input = strip_white_space(&input).to_lowercase();
        if input == "quit" {
            println!("Exiting...");
            break;
        }
        let expr = parse_input(&input, &numeric_regex, &function_regex);
        if expr.is_ok() {
            println!("{:?}", &expr.unwrap());
        } else {
            println!("Encountered an error while parsing: {:?}",
                     expr.unwrap_err());
            println!("Try Again...(type 'quit' to exit)");
            continue;
        }
    }
}

fn strip_white_space(input: &String) -> String {
    input.split_whitespace().collect::<Vec<&str>>().join("")
}

fn parse_input(input: &String,
               numeric_regex: &Regex,
               function_regex: &Regex)
               -> Result<Expression, String> {
    // 1. Replace everthing except letters/numbers with their enums
    // 2. Then go through and replace things with Literals or functions
    let mut expr: Expression = Expression::new(Vec::new());
    let mut builder: String = String::new();
    for c in input.chars() {
        match c {
            '(' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Open);
            }
            ')' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Close);
            }
            '+' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Op(Operator::Add));
            }
            '-' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Op(Operator::Sub));
            }
            '*' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Op(Operator::Mul));
            }
            '/' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Op(Operator::Div));
            }
            '^' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Op(Operator::Pow));
            }
            ',' => {
                if builder.len() > 0 {
                    if numeric_regex.is_match(&builder[..]) {
                        expr.push(Token::Literal(builder.clone()));
                    } else if function_regex.is_match(&builder[..]) {
                        expr.push(map_string_to_func(&builder));
                    }
                    builder = String::new();
                }
                expr.push(Token::Comma);
            }
            _ => {
                builder.push(c);
            }
        }
    }
    if builder.len() > 0 {
        if numeric_regex.is_match(&builder[..]) {
            expr.push(Token::Literal(builder.clone()));
        } else if function_regex.is_match(&builder[..]) {
            expr.push(map_string_to_func(&builder));
        }
    }
    let mut op_stack: Vec<Token> = Vec::with_capacity(input.len());
    let mut out_queue: Vec<Token> = Vec::with_capacity(input.len());
    for i in 0..expr.len() {
        let current_token = expr.get_token(i);
        match current_token {
            &Token::Literal(ref x) => out_queue.push(Token::Literal(x.clone())),
            &Token::Func(ref x) => op_stack.push(Token::Func(x.clone())),
            &Token::Comma => {
                loop {
                    let stack_token = try!{op_stack.pop().ok_or("Malformed Expression, comma but no Parenthesis")};
                    match stack_token {
                        Token::Open => {
                            op_stack.push(stack_token);
                            break;
                        }
                        _ => out_queue.push(stack_token),
                    }
                }
            }
            &Token::Op(ref o1) => {
                loop {
                    if op_stack.len() < 1 {
                        break;
                    }
                    let o2 = op_stack.pop().unwrap(); // top of stack, must exist based off of previous if
                    match o1 {
                        &Operator::Pow => {
                            match o2 {
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                        &Operator::Mul | &Operator::Div => {
                            match o2 {
                                Token::Op(Operator::Pow) |
                                Token::Op(Operator::Mul) |
                                Token::Op(Operator::Div) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                        &Operator::Add | &Operator::Sub => {
                            match o2 {
                                Token::Op(Operator::Add) |
                                Token::Op(Operator::Sub) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                    }
                }
                op_stack.push(Token::Op(o1.clone()));
            }
            &Token::Open => op_stack.push(Token::Open),
            &Token::Close => {
                loop {
                    let stack_token =
                        try!{op_stack.pop().ok_or("Malformed Expression, found a ) without (")};
                    match stack_token {
                        Token::Open => break,
                        _ => out_queue.push(stack_token),
                    }
                }
                if op_stack.len() > 0 {
                    let next_stack_token = op_stack.pop().unwrap(); // must exist based off of previous if
                    match next_stack_token {
                        Token::Func(ref x) => out_queue.push(Token::Func(x.clone())),
                        _ => op_stack.push(next_stack_token),
                    }
                }
            }
            &Token::Unknown(ref x) => {
                let mut message: String = "You either misspelled a function, or it is not yet \
                                           implemented. The unknown string was: ".to_owned();
                message.push_str(x);
                return Err(message);
            }
            _ => break,
        }
    }
    while op_stack.len() > 0 {
        out_queue.push(op_stack.pop().unwrap()); // The item must exist
    }
    Ok(Expression::new(out_queue))
}

fn map_string_to_func(input: &String) -> Token {
    match &(input.to_lowercase())[..] {
        "abs" => Token::Func(Function::Abs),
        "sqrt" => Token::Func(Function::Sqrt),
        "ln" => Token::Func(Function::Ln),
        "log" => Token::Func(Function::Log),
        "sin" => Token::Func(Function::Sin),
        "csc" => Token::Func(Function::Csc),
        "cos" => Token::Func(Function::Cos),
        "sec" => Token::Func(Function::Sec),
        "tan" => Token::Func(Function::Tan),
        "cot" => Token::Func(Function::Cot),
        "asin" => Token::Func(Function::Asin),
        "acsc" => Token::Func(Function::Acsc),
        "acos" => Token::Func(Function::Acos),
        "asec" => Token::Func(Function::Asec),
        "atan" => Token::Func(Function::Atan),
        "acot" => Token::Func(Function::Acot),
        "sinh" => Token::Func(Function::Sinh),
        "csch" => Token::Func(Function::Csch),
        "cosh" => Token::Func(Function::Cosh),
        "sech" => Token::Func(Function::Sech),
        "tanh" => Token::Func(Function::Tanh),
        "coth" => Token::Func(Function::Coth),
        "asinh" => Token::Func(Function::Asinh),
        "acsch" => Token::Func(Function::Acsch),
        "acosh" => Token::Func(Function::Acosh),
        "asech" => Token::Func(Function::Asech),
        "atanh" => Token::Func(Function::Atanh),
        "acoth" => Token::Func(Function::Acoth),
        "max" => Token::Func(Function::Max),
        _ => Token::Unknown(input.clone()),
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate clap;
#[macro_use] extern crate log;
#[macro_use] extern crate serde;
#[macro_use] extern crate serde_json;
#[macro_use] extern crate glob;
#[macro_use] extern crate uuid;
#[macro_use] extern crate regex;
extern crate config;

use cli::CliConfig;
use configuration::Configuration;
use runtime::{ImagLogger, Runtime};
use clap::App;
use module::Module;
use module::ModuleError;
use module::bm::BMModule;
use storage::backend::StorageBackend;

mod cli;
mod configuration;
mod runtime;
mod module;
mod storage;
mod ui;

fn main() {
    let yaml = load_yaml!("../etc/cli.yml");
    let app = App::from_yaml(yaml);
    let config = CliConfig::new(app);
    let configuration = Configuration::new(&config);

    let logger = ImagLogger::init(&configuration, &config);
    debug!("Logger created!");

    debug!("CliConfig    : {:?}", &config);
    debug!("Configuration: {:?}", &configuration);

    let rt = Runtime::new(configuration, config);

    debug!("Runtime      : {:?}", &rt);

    if let Some(matches) = rt.config.cli_matches.subcommand_matches("bm") {
        let module : BMModule = Module::new(&rt);
        let commands          = module.get_commands(&rt);
        if let Some(command)  = matches.subcommand_name() {
            debug!("Subcommand: {}", command);

            let backend = StorageBackend::new(rt.get_rtp());

            match commands.get(command) {
                Some(f) => f(&rt, &backend),
                None    => debug!("No command '{}' found", command),
            }
        } else {
            debug!("No subcommand");
        }

        module.shutdown(&rt);
    } else {
        // Err(ModuleError::mk("No commandline call"))
        info!("No commandline call...")
    }

    info!("Hello, world!");
}
<commit_msg>Add CommandEnv building in command calling code in main()<commit_after>#[macro_use] extern crate clap;
#[macro_use] extern crate log;
#[macro_use] extern crate serde;
#[macro_use] extern crate serde_json;
#[macro_use] extern crate glob;
#[macro_use] extern crate uuid;
#[macro_use] extern crate regex;
extern crate config;

use cli::CliConfig;
use configuration::Configuration;
use runtime::{ImagLogger, Runtime};
use clap::App;
use module::Module;
use module::ModuleError;
use module::CommandEnv;
use module::bm::BMModule;
use storage::backend::StorageBackend;

mod cli;
mod configuration;
mod runtime;
mod module;
mod storage;
mod ui;

fn main() {
    let yaml = load_yaml!("../etc/cli.yml");
    let app = App::from_yaml(yaml);
    let config = CliConfig::new(app);
    let configuration = Configuration::new(&config);

    let logger = ImagLogger::init(&configuration, &config);
    debug!("Logger created!");

    debug!("CliConfig    : {:?}", &config);
    debug!("Configuration: {:?}", &configuration);

    let rt = Runtime::new(configuration, config);

    debug!("Runtime      : {:?}", &rt);

    if let Some(matches) = rt.config.cli_matches.subcommand_matches("bm") {
        let module : BMModule = Module::new(&rt);
        let commands          = module.get_commands(&rt);
        if let Some(command)  = matches.subcommand_name() {
            debug!("Subcommand: {}", command);

            let backend = StorageBackend::new(rt.get_rtp());

            let cmdenv = CommandEnv {
                rt: &rt,
                bk: &backend,
                matches: matches,
            };

            let result = match commands.get(command) {
                Some(f) => f(cmdenv),
                None    => Err(ModuleError::new("No subcommand found")),
            };

            debug!("Result of command: {:?}", result);
        } else {
            debug!("No subcommand");
        }

        module.shutdown(&rt);
    } else {
        // Err(ModuleError::mk("No commandline call"))
        info!("No commandline call...")
    }

    info!("Hello, world!");
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate router;
extern crate rustc_serialize;

use router::Router;
use iron::prelude::*;
use iron::status::Status;
use rustc_serialize::json;

mod memory;
mod helpers;
mod temperature;
mod load;

fn main() {
    let mut router = Router::new();
    router.get("/temperature", |_: &mut Request| -> IronResult<Response> {
        let temp = temperature::temperature();
        match temp {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "temperature");

    router.get("/memory", |_: &mut Request| -> IronResult<Response> {
        let mem = memory::read_usage();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "memory");

    router.get("/load", |_: &mut Request| -> IronResult<Response> {
        let mem = load::load();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "load");
    Iron::new(router).http("localhost:3001").unwrap();
}
<commit_msg>Rading bind addr from environment variable<commit_after>extern crate iron;
extern crate router;
extern crate rustc_serialize;

use router::Router;
use iron::prelude::*;
use iron::status::Status;
use rustc_serialize::json;
use std::env;
use std::net::SocketAddr;
use std::str::FromStr;

mod memory;
mod helpers;
mod temperature;
mod load;

fn main() {
    let mut router = Router::new();
    router.get("/temperature", |_: &mut Request| -> IronResult<Response> {
        let temp = temperature::temperature();
        match temp {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "temperature");

    router.get("/memory", |_: &mut Request| -> IronResult<Response> {
        let mem = memory::read_usage();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "memory");

    router.get("/load", |_: &mut Request| -> IronResult<Response> {
        let mem = load::load();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "load");

    let bind_str = env::var("BIND_STR");

    match bind_str {
        Err(_) => println!("Could not read bind str"),
        Ok(val) => {
            match SocketAddr::from_str(val.as_str()) {
                Err(_) => println!("Could not parse BIND_STR"),
                Ok(val) => {
                    Iron::new(router).http(val).unwrap();
                    println!("Ok!")
                }
            }
        }
    }
}
<|endoftext|>