<commit_before>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate glob;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;
use glob::Pattern;
use cobalt::create_new_project;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;
use std::path::PathBuf;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tbuild -- build the cobalt project at the source dir",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

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

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

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

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

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                if let Some(path) = val.path {
                                    if path.is_absolute() {
                                        // get where process was run from
                                        let cwd = std::env::current_dir().unwrap_or(PathBuf::new());
                                        // strip absolute path
                                        let rel_path = path.strip_prefix(&cwd).unwrap_or(&cwd);

                                        // check if path starts with the build folder.
                                        if !&config.ignore.iter().any(|pattern| Pattern::matches_path(
                                            pattern,
                                            rel_path)) {
                                            build(&config);
                                        }

                                    } else {
                                        // check if path starts with build folder.
                                        // TODO: may want to check if it starts `./`
                                        if !&config.ignore.iter().any(|pattern| Pattern::matches_path(pattern, &path)) {
                                            build(&config);
                                        }
                                    }
                                }
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        "new" => {
            if matches.free.len() == 2 {
                let dest = matches.free[1].clone();

                match create_new_project(&dest) {
                    Ok(_) => info!("Created new project at {}", dest),
                    Err(e) => {
                        error!("{}", e);
                        error!("Could not create a new cobalt project");
                        std::process::exit(1);
                    }
                }
            } else {
                println!("cobalt new DIRECTORY");
                print_usage(opts);
                std::process::exit(1);
            }
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<commit_msg>added new command to usage<commit_after>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate glob;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;
use glob::Pattern;
use cobalt::create_new_project;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;
use std::path::PathBuf;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tnew -- create a new cobalt project",
                        "\n\tbuild -- build the cobalt project at the source dir",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

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

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

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

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

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                if let Some(path) = val.path {
                                    if path.is_absolute() {
                                        // get where process was run from
                                        let cwd = std::env::current_dir().unwrap_or(PathBuf::new());
                                        // strip absolute path
                                        let rel_path = path.strip_prefix(&cwd).unwrap_or(&cwd);

                                        // check if path starts with the build folder.
                                        if !&config.ignore.iter().any(|pattern| Pattern::matches_path(
                                            pattern,
                                            rel_path)) {
                                            build(&config);
                                        }

                                    } else {
                                        // check if path starts with build folder.
                                        // TODO: may want to check if it starts `./`
                                        if !&config.ignore.iter().any(|pattern| Pattern::matches_path(pattern, &path)) {
                                            build(&config);
                                        }
                                    }
                                }
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        "new" => {
            if matches.free.len() == 2 {
                let dest = matches.free[1].clone();

                match create_new_project(&dest) {
                    Ok(_) => info!("Created new project at {}", dest),
                    Err(e) => {
                        error!("{}", e);
                        error!("Could not create a new cobalt project");
                        std::process::exit(1);
                    }
                }
            } else {
                println!("cobalt new DIRECTORY");
                print_usage(opts);
                std::process::exit(1);
            }
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>extern crate sdl;
extern crate rand;
extern crate time;

use rand::Rng;

use time::PreciseTime;

use sdl::video::{SurfaceFlag, VideoFlag, Surface};
use sdl::event::{Event, Key};

struct Color {
    r: u8,
    g: u8,
    b: u8
}

struct Stars_3D {
    speed: i32,
    spread: i32,
    stars_x: Vec<f32>,
    stars_y: Vec<f32>,
    stars_z: Vec<f32>
}

impl Stars_3D {
    pub fn new(num_stars: usize, _spread: i32, _speed: i32) -> Stars_3D {
        let mut obj = Stars_3D {
            spread: _spread,
            speed: _speed,
            stars_x: vec![0.0; num_stars],
            stars_y: vec![0.0; num_stars],
            stars_z: vec![0.0; num_stars] };

        for idx in 0..num_stars {
            obj.init_star(idx);
        }

        obj
    }

    fn init_star(&mut self, idx: usize) {
        let mut rng = rand::thread_rng();
        self.stars_x[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_y[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_z[idx] = (rng.next_f32() + 0.00001) * (self.spread as f32);
    }

    pub fn update_and_render(&mut self, screen: &Surface, delta: f32)
	{
        clear(screen);

        let color = Color{r:233, g:233, b:233};

		let halfWidth  = screen.get_width() as f32 / 2.0f32;
		let halfHeight = screen.get_height()as f32 / 2.0f32;
        for i in 0..self.stars_x.len() {
            self.stars_z[i] -= delta * self.speed as f32;

            if(self.stars_z[i] <= 0f32) {
                self.init_star(i);
            }

            let x = (self.stars_x[i]/self.stars_z[i] * halfWidth + halfWidth);
            let y = (self.stars_y[i]/self.stars_z[i] * halfHeight + halfHeight);

            if x < 0f32 || x >= screen.get_width() as f32 || y < 0f32 || y >= screen.get_height() as f32 {
                self.init_star(i);
            } else {
                set_pixel(x as i32, y as i32, &color, &screen);
            }
        }
	}
}

fn clear(screen: &Surface) {
    screen.fill_rect(Some(sdl::Rect {
                x: 0,
                y: 0,
                w: screen.get_width(),
                h: screen.get_height()
            }), sdl::video::Color::RGB(0,0,0));
}

fn set_pixel(_x: i32, _y:i32, color: &Color, screen: &Surface) {

    // println!("{}",screen.get_width());
    let x: usize = _x as usize * 4;
    let y: usize = _y as usize * 4;
    let idx_blue: usize = x + y * screen.get_width() as usize;
    let idx_green: usize = (x + y * screen.get_width() as usize) + 1;
    let idx_red: usize = (x + y * screen.get_width() as usize) + 2;
    let idx_alpha: usize = (x + y * screen.get_width() as usize) + 3;

    screen.with_lock(|pixels| {
        pixels[idx_blue] = color.b;
        pixels[idx_green] = color.g;
        pixels[idx_red] = color.r;
        pixels[idx_alpha] = 0;

        true
    });
}

fn draw_line(x0: i32, y0: i32, x1: i32, y1: i32, color: &Color, screen: &Surface) {
    for x in x0..x1 {
        // println!("{}", x);
        let t: f32 = (x-x0) as f32 /(x1-x0) as f32;
        let y: i32 = (y0 as f32 *(1.0-t) + y1 as f32 *t) as i32;
        // image.set(x, y, color);
        set_pixel(x, y, color, screen);
    }
}

fn main() {
    sdl::init(&[sdl::InitFlag::Video]);
    sdl::wm::set_caption("rust-sdl demo - video", "rust-sdl");

    let mut rng = rand::thread_rng();
    let screen = match sdl::video::set_video_mode(1024, 768, 32,
                                                  &[SurfaceFlag::HWSurface],
                                                  &[VideoFlag::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => panic!("failed to set video mode: {}", err)
    };

    // let color = Color{r:233, g:233, b:233};

    // set_pixel(400, 300, &color, &screen);

    // draw_line(10, 10, 100, 100, &color, &screen);

    // draw_line(13, 20, 80, 40,  &color, &screen);
    // draw_line(20, 13, 40, 80,  &color, &screen);
    // draw_line(80, 40, 13, 20,  &color, &screen);

    let mut stars = Stars_3D::new(4000, 64, 20);

    let mut start = PreciseTime::now();

    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                Event::Quit => break 'main,
                Event::None => break 'event,
                Event::Key(k, _, _, _)
                    if k == Key::Escape
                        => break 'main,
                _ => { }
            }
        }

        let end = PreciseTime::now();
        let delta = start.to(end);
        start = PreciseTime::now();

        println!("{} ms", delta.num_milliseconds());

        stars.update_and_render(&screen, delta.num_milliseconds() as f32 / 1000f32);
        screen.flip();

    }

    sdl::quit();
}
<commit_msg>format<commit_after>extern crate sdl;
extern crate rand;
extern crate time;

use rand::Rng;

use time::PreciseTime;

use sdl::video::{SurfaceFlag, VideoFlag, Surface};
use sdl::event::{Event, Key};

struct Color {
    r: u8,
    g: u8,
    b: u8
}

struct Stars_3D {
    speed: i32,
    spread: i32,
    stars_x: Vec<f32>,
    stars_y: Vec<f32>,
    stars_z: Vec<f32>
}

impl Stars_3D {
    pub fn new(num_stars: usize, _spread: i32, _speed: i32) -> Stars_3D {
        let mut obj = Stars_3D {
            spread: _spread,
            speed: _speed,
            stars_x: vec![0.0; num_stars],
            stars_y: vec![0.0; num_stars],
            stars_z: vec![0.0; num_stars] };

        for idx in 0..num_stars {
            obj.init_star(idx);
        }

        obj
    }

    fn init_star(&mut self, idx: usize) {
        let mut rng = rand::thread_rng();
        self.stars_x[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_y[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_z[idx] = (rng.next_f32() + 0.00001) * (self.spread as f32);
    }

    pub fn update_and_render(&mut self, screen: &Surface, delta: f32) {
        clear(screen);

        let color = Color{r:233, g:233, b:233};

		let halfWidth  = screen.get_width() as f32 / 2.0f32;
		let halfHeight = screen.get_height()as f32 / 2.0f32;
        for i in 0..self.stars_x.len() {
            self.stars_z[i] -= delta * self.speed as f32;

            if(self.stars_z[i] <= 0f32) {
                self.init_star(i);
            }

            let x = (self.stars_x[i]/self.stars_z[i] * halfWidth + halfWidth);
            let y = (self.stars_y[i]/self.stars_z[i] * halfHeight + halfHeight);

            if x < 0f32 || x >= screen.get_width() as f32 || y < 0f32 || y >= screen.get_height() as f32 {
                self.init_star(i);
            } else {
                set_pixel(x as i32, y as i32, &color, &screen);
            }
        }
	}
}

fn clear(screen: &Surface) {
    screen.fill_rect(Some(sdl::Rect {
                x: 0,
                y: 0,
                w: screen.get_width(),
                h: screen.get_height()
            }), sdl::video::Color::RGB(0,0,0));
}

fn set_pixel(_x: i32, _y:i32, color: &Color, screen: &Surface) {

    // println!("{}",screen.get_width());
    let x: usize = _x as usize * 4;
    let y: usize = _y as usize * 4;
    let idx_blue: usize = x + y * screen.get_width() as usize;
    let idx_green: usize = (x + y * screen.get_width() as usize) + 1;
    let idx_red: usize = (x + y * screen.get_width() as usize) + 2;
    let idx_alpha: usize = (x + y * screen.get_width() as usize) + 3;

    screen.with_lock(|pixels| {
        pixels[idx_blue] = color.b;
        pixels[idx_green] = color.g;
        pixels[idx_red] = color.r;
        pixels[idx_alpha] = 0;

        true
    });
}

fn draw_line(x0: i32, y0: i32, x1: i32, y1: i32, color: &Color, screen: &Surface) {
    for x in x0..x1 {
        // println!("{}", x);
        let t: f32 = (x-x0) as f32 /(x1-x0) as f32;
        let y: i32 = (y0 as f32 *(1.0-t) + y1 as f32 *t) as i32;
        // image.set(x, y, color);
        set_pixel(x, y, color, screen);
    }
}

fn main() {
    sdl::init(&[sdl::InitFlag::Video]);
    sdl::wm::set_caption("rust-sdl demo - video", "rust-sdl");

    let mut rng = rand::thread_rng();
    let screen = match sdl::video::set_video_mode(1024, 768, 32,
                                                  &[SurfaceFlag::HWSurface],
                                                  &[VideoFlag::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => panic!("failed to set video mode: {}", err)
    };

    // let color = Color{r:233, g:233, b:233};

    // set_pixel(400, 300, &color, &screen);

    // draw_line(10, 10, 100, 100, &color, &screen);

    // draw_line(13, 20, 80, 40,  &color, &screen);
    // draw_line(20, 13, 40, 80,  &color, &screen);
    // draw_line(80, 40, 13, 20,  &color, &screen);

    let mut stars = Stars_3D::new(4000, 64, 20);

    let mut start = PreciseTime::now();

    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                Event::Quit => break 'main,
                Event::None => break 'event,
                Event::Key(k, _, _, _)
                    if k == Key::Escape
                        => break 'main,
                _ => { }
            }
        }

        let end = PreciseTime::now();
        let delta = start.to(end);
        start = PreciseTime::now();

        println!("{} ms", delta.num_milliseconds());

        stars.update_and_render(&screen, delta.num_milliseconds() as f32 / 1000f32);
        screen.flip();

    }

    sdl::quit();
}
<|endoftext|>


<commit_before>
// Allow all uppercase variable names
#![allow(non_snake_case)]
#![allow(unused_variables)]

use std::io::{self,BufRead};

fn intro() {
    println!("{:^60}", "LUNAR");
    println!("{:^60}", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
    println!("\n\n");
    println!("THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR");
    println!("LANDING CAPSULE.");
    println!("\n");
    println!("THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY");
    println!("XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY.");
    println!("");
    println!("SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN");
    println!("0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND.");
    println!("SET NEW BURN RATE EVERY 10 SECONDS.");
    println!("");
    println!("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS.");
    println!("\n\n");
    println!("GOOD LUCK");
}

fn main() {
    intro();
    let L = 0;
    println!("{:>10} {:>10} {:>10} {:>10} {:>10}", "SEC", "MI + FT", "MPH", "LB FUEL", "BURN RATE\n");

    let A = 120.0;
    let V = 1;
    let M = 33000.0;
    let N = 16500.0;
    let G = 1E-03;
    let Z = 1.8;

    println!("{:>10} {:>10} {:>10} {:>10} {:>10}", L, A, (5280 * ( A - ((A as i64) as f64)) as i64), 3600 * V, M - N);

    //let K = io::stdin().read_line().ok().expect("Failed to read line");
    let sin = io::stdin();
    let s = sin.lock().lines().next().unwrap().unwrap();
    let input: Option<f64> = s.trim().parse::<f64>().ok();
    let K = match input {
        Some(f) => f,
        None    => {
            println!("please input a number");
            return;
        }
    };
    let T = 10.0;
    if M - N < 1E-03 {
        // 240
    } else {
        if T < 1E-03 {
            // 150
        } else {
            let mut S = T; // 180
            if M >= N + S * K {
                // 200
            } else {
                S = (M - N) / K; // 190
            }
            // 200
            f420();
        }
    }
}

fn f420() {
}
<commit_msg>Triggering Travis<commit_after>
// Allow all uppercase variable names
#![allow(non_snake_case)]
#![allow(unused_variables)]

use std::io::{self,BufRead};

fn intro() {
    println!("{:^60}", "LUNAR");
    println!("{:^60}", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
    println!("\n\n");
    println!("THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR");
    println!("LANDING CAPSULE.");
    println!("\n");
    println!("THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY");
    println!("XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY.");
    println!("");
    println!("SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN");
    println!("0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND.");
    println!("SET NEW BURN RATE EVERY 10 SECONDS.");
    println!("");
    println!("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS.");
    println!("\n\n");
    println!("GOOD LUCK");
}

fn main() {
    intro();
    let L = 0;
    println!("{:>10} {:>10} {:>10} {:>10} {:>10}", "SEC", "MI + FT", "MPH", "LB FUEL", "BURN RATE\n");

    let A = 120.0;
    let V = 1;
    let M = 33000.0;
    let N = 16500.0;
    let G = 1E-03;
    let Z = 1.8;

    println!("{:>10} {:>10} {:>10} {:>10} {:>10}", L, A, (5280 * ( A - ((A as i64) as f64)) as i64), 3600 * V, M - N);

    //let K = io::stdin().read_line().ok().expect("Failed to read line");
    let sin = io::stdin();
    let s = sin.lock().lines().next().unwrap().unwrap();
    let input: Option<f64> = s.trim().parse::<f64>().ok();
    let K = match input {
        Some(f) => f,
        None    => {
            println!("please input a number");
            return;
        }
    };
    let T = 10.0;
    if M - N < 1E-03 {
        // 240
    } else {
        if T < 1E-03 {
            // 150
        } else {
            let mut S = T; // 180
            if M >= N + S * K {
                // 200
            } else {
                S = (M - N) / K; // 190
            }
            // 200
            f420();
        }
    }
}

fn f420() {
}

// EOF
<|endoftext|>


<commit_before>extern crate loc;

extern crate clap;
extern crate deque;
extern crate itertools;
extern crate num_cpus;
extern crate walkdir;
extern crate regex;

use clap::{Arg, App, AppSettings};
use walkdir::WalkDir;

use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::thread;

use deque::{Stealer, Stolen};
use regex::Regex;

use loc::*;

enum Work {
    File(String),
    Quit,
}

struct Worker {
    chan: Stealer<Work>,
}

#[derive(Clone)]
struct FileCount {
    path: String,
    lang: Lang,
    count: Count,
}

// This concurrency pattern ripped directly from ripgrep
impl Worker {
    fn run(self) -> Vec<FileCount> {
        let mut v: Vec<FileCount> = vec![];
        loop {
            match self.chan.steal() {
                // What causes these?
                Stolen::Empty | Stolen::Abort => continue,
                Stolen::Data(Work::Quit) => break,
                Stolen::Data(Work::File(path)) => {
                    let lang = lang_from_ext(&path);
                    if lang != Lang::Unrecognized {
                        let count = count(&path);
                        v.push(FileCount {
                            lang: lang,
                            path: String::from(path),
                            count: count,
                        });
                    }
                }
            };
        }
        v
    }
}

fn main() {

    let matches = App::new("count")
        .global_settings(&[AppSettings::ColoredHelp])
        .version("0.1")
        .author("Curtis Gagliardi <curtis@curtis.io>")
        .about("counts things quickly hopefully")
        // TODO(cgag): actually implement filtering
        .arg(Arg::with_name("exclude")
            .required(false)
            .long("exclude")
            .value_name("REGEX")
            .takes_value(true)
            .help("comma separated list of files/directories to ignore"))
        .arg(Arg::with_name("files")
             .required(false)
             .long("files")
             .takes_value(false)
             .help("Show stats for individual files"))
        .arg(Arg::with_name("sort")
            .required(false)
            .long("sort")
            .value_name("COLUMN")
            .takes_value(true)
            .help("Column to sort by"))
        .arg(Arg::with_name("target")
            .required(true)
            .multiple(true)
            .help("File or directory to count"))
        .get_matches();

    let filepaths = matches.values_of("target").unwrap();
    let sort = matches.value_of("sort").unwrap_or("code");
    let by_file = matches.is_present("files");
    let exclude_regex = match matches.value_of("exclude") {
        Some(rx_str) => {
            match Regex::new(rx_str) {
                Ok(r) => Some(r),
                Err(e) => {
                    println!("Error processing regex: {}", e);
                    std::process::exit(1);
                }
            }
        }
        None => None,
    };

    let threads = num_cpus::get();
    let mut workers = vec![];
    let (workq, stealer) = deque::new();
    for _ in 0..threads {
        let worker = Worker { chan: stealer.clone() };
        workers.push(thread::spawn(|| worker.run()));
    }

    for filepath in filepaths {
        // TODO(cgag): cleanup?
        if exclude_regex.is_some() {
            let r = &&exclude_regex.clone().unwrap();
            for entry in WalkDir::new(filepath).into_iter().filter_map(|e| e.ok()) {
                if entry.file_type().is_file() {
                    let path = entry.path().to_str().unwrap();
                    if !r.is_match(path) {
                        workq.push(Work::File(String::from(path)));
                    }
                }
            }
        } else {
            for entry in WalkDir::new(filepath).into_iter().filter_map(|e| e.ok()) {
                if entry.file_type().is_file() {
                    let path = entry.path().to_str().unwrap();
                    workq.push(Work::File(String::from(path)));
                }
            }
        }
    }

    for _ in 0..workers.len() {
        workq.push(Work::Quit);
    }

    let mut filecounts: Vec<FileCount> = Vec::new();
    for worker in workers {
        filecounts.extend(worker.join().unwrap().iter().cloned())
    }

    let mut by_lang: HashMap<Lang, Vec<FileCount>> = HashMap::new();
    for fc in filecounts {
        match by_lang.entry(fc.lang) {
            Entry::Occupied(mut by_lang) => by_lang.get_mut().push(fc),
            Entry::Vacant(by_lang) => {
                by_lang.insert(vec![fc]);
            }
        };
    }

    let linesep = str_repeat("-", 80);

    if by_file {
        // TODO(cgag): Need sorting for by_file as well.
        println!("{}", linesep);
        println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                 "Language",
                 "Files",
                 "Lines",
                 "Blank",
                 "Comment",
                 "Code");
        println!("{}", linesep);

        // TODO(cgag): do the summing first, so we can do additional sorting
        // by totals.
        for (lang, mut filecounts) in by_lang {
            let mut total = Count::default();
            for fc in &filecounts {
                total.merge(&fc.count);
            }

            println!("{}", linesep);
            println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                     lang,
                     filecounts.len(),
                     total.lines,
                     total.blank,
                     total.comment,
                     total.code);

            match sort {
                "code" => filecounts.sort_by(|fc1, fc2| fc2.count.code.cmp(&fc1.count.code)),
                "comment" => {
                    filecounts.sort_by(|fc1, fc2| fc2.count.comment.cmp(&fc1.count.comment))
                }
                "blank" => filecounts.sort_by(|fc1, fc2| fc2.count.blank.cmp(&fc1.count.blank)),
                "lines" => filecounts.sort_by(|fc1, fc2| fc2.count.lines.cmp(&fc1.count.lines)),
                // No sorting by language or files here. Need to do it at a higher level.
                _ => (),
            }
            println!("{}", linesep);
            for fc in filecounts {
                println!("|{0: <25} {1: >12} {2: >12} {3: >12} {4: >12}",
                         last_n_chars(&fc.path, 25),
                         fc.count.lines,
                         fc.count.blank,
                         fc.count.comment,
                         fc.count.code);
            }
        }
    } else {
        let mut lang_totals: HashMap<&Lang, LangTotal> = HashMap::new();
        for (lang, filecounts) in &by_lang {
            let mut lang_total = Count::default();
            for fc in filecounts {
                lang_total.merge(&fc.count);
            }
            lang_totals.insert(lang,
                               LangTotal {
                                   files: filecounts.len() as u32,
                                   count: lang_total,
                               });
        }

        let mut totals_by_lang = lang_totals.iter().collect::<Vec<(&&Lang, &LangTotal)>>();
        match sort {
            "language" => totals_by_lang.sort_by(|&(l1, _), &(l2, _)| l1.to_s().cmp(l2.to_s())),
            "files" => totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.files.cmp(&c1.files)),
            "code" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.code.cmp(&c1.count.code))
            }
            "comment" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.comment.cmp(&c1.count.comment))
            }
            "blank" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.blank.cmp(&c1.count.blank))
            }
            "lines" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.lines.cmp(&c1.count.lines))
            }
            _ => {
                println!("invalid sort option {}, sorting by code", sort);
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.code.cmp(&c1.count.code))
            }
        }

        println!("{}", linesep);
        println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                 "Language",
                 "Files",
                 "Lines",
                 "Blank",
                 "Comment",
                 "Code");
        println!("{}", linesep);

        for &(lang, total) in &totals_by_lang {
            println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                     lang,
                     total.files,
                     total.count.lines,
                     total.count.blank,
                     total.count.comment,
                     total.count.code);
        }

        let mut totals = LangTotal {
            files: 0,
            count: Count::default(),
        };
        for &(_, total) in &totals_by_lang {
            totals.files += total.files;
            totals.count.code += total.count.code;
            totals.count.blank += total.count.blank;
            totals.count.comment += total.count.comment;
            totals.count.lines += total.count.lines;
        }

        println!("{}", linesep);
        println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                 "Total",
                 totals.files,
                 totals.count.lines,
                 totals.count.blank,
                 totals.count.comment,
                 totals.count.code);
        println!("{}", linesep);
    }
}

fn last_n_chars(s: &str, n: usize) -> String {
    if s.len() <= n {
        return String::from(s);
    }
    s.chars().skip(s.len() - n).collect::<String>()
}

fn str_repeat(s: &str, n: usize) -> String {
    std::iter::repeat(s).take(n).collect::<Vec<_>>().join("")
}
<commit_msg>ability to only include matching files, filter clean up<commit_after>extern crate loc;

extern crate clap;
extern crate deque;
extern crate itertools;
extern crate num_cpus;
extern crate walkdir;
extern crate regex;

use clap::{Arg, App, AppSettings};
use walkdir::WalkDir;

use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::thread;

use deque::{Stealer, Stolen};
use regex::Regex;

use loc::*;

enum Work {
    File(String),
    Quit,
}

struct Worker {
    chan: Stealer<Work>,
}

#[derive(Clone)]
struct FileCount {
    path: String,
    lang: Lang,
    count: Count,
}

// This concurrency pattern ripped directly from ripgrep
impl Worker {
    fn run(self) -> Vec<FileCount> {
        let mut v: Vec<FileCount> = vec![];
        loop {
            match self.chan.steal() {
                // What causes these?
                Stolen::Empty | Stolen::Abort => continue,
                Stolen::Data(Work::Quit) => break,
                Stolen::Data(Work::File(path)) => {
                    let lang = lang_from_ext(&path);
                    if lang != Lang::Unrecognized {
                        let count = count(&path);
                        v.push(FileCount {
                            lang: lang,
                            path: String::from(path),
                            count: count,
                        });
                    }
                }
            };
        }
        v
    }
}

fn main() {

    let matches = App::new("count")
        .global_settings(&[AppSettings::ColoredHelp])
        .version("0.1")
        .author("Curtis Gagliardi <curtis@curtis.io>")
        .about("counts things quickly hopefully")
        // TODO(cgag): actually implement filtering
        .arg(Arg::with_name("exclude")
            .required(false)
            .long("exclude")
            .value_name("REGEX")
            .takes_value(true)
            .help("Rust regex of files to exclude"))
        .arg(Arg::with_name("include")
            .required(false)
            .long("include")
            .value_name("REGEX")
            .takes_value(true)
            .help("Rust regex matching files to include. Anything not matched will be excluded"))
        .arg(Arg::with_name("files")
             .required(false)
             .long("files")
             .takes_value(false)
             .help("Show stats for individual files"))
        .arg(Arg::with_name("sort")
            .required(false)
            .long("sort")
            .value_name("COLUMN")
            .takes_value(true)
            .help("Column to sort by"))
        .arg(Arg::with_name("target")
            .required(true)
            .multiple(true)
            .help("File or directory to count"))
        .get_matches();

    let targets = matches.values_of("target").unwrap();
    let sort = matches.value_of("sort").unwrap_or("code");
    let by_file = matches.is_present("files");
    let exclude_regex = match matches.value_of("exclude") {
        Some(rx_str) => {
            match Regex::new(rx_str) {
                Ok(r) => Some(r),
                Err(e) => {
                    println!("Error processing exclude regex: {}", e);
                    std::process::exit(1);
                }
            }
        }
        None => None,
    };
    let include_regex = match matches.value_of("include") {
        Some(rx_str) => {
            match Regex::new(rx_str) {
                Ok(r) => Some(r),
                Err(e) => {
                    println!("Error processing include regex: {}", e);
                    std::process::exit(1);
                }
            }
        }
        None => None,
    };

    let threads = num_cpus::get();
    let mut workers = vec![];
    let (workq, stealer) = deque::new();
    for _ in 0..threads {
        let worker = Worker { chan: stealer.clone() };
        workers.push(thread::spawn(|| worker.run()));
    }

    for target in targets {
        let files = WalkDir::new(target)
            .into_iter()
            .filter_map(|entry| entry.ok())
            .filter(|entry| entry.file_type().is_file())
            .map(|entry| String::from(entry.path().to_str().unwrap()))
            .filter(|path| match include_regex {
                None => true,
                Some(ref include) => include.is_match(path),
            })
            .filter(|path| match exclude_regex {
                None => true,
                Some(ref exclude) => !exclude.is_match(path),
            });

        for path in files {
            workq.push(Work::File(path));
        }
    }

    for _ in 0..workers.len() {
        workq.push(Work::Quit);
    }

    let mut filecounts: Vec<FileCount> = Vec::new();
    for worker in workers {
        filecounts.extend(worker.join().unwrap().iter().cloned())
    }

    let mut by_lang: HashMap<Lang, Vec<FileCount>> = HashMap::new();
    for fc in filecounts {
        match by_lang.entry(fc.lang) {
            Entry::Occupied(mut by_lang) => by_lang.get_mut().push(fc),
            Entry::Vacant(by_lang) => {
                by_lang.insert(vec![fc]);
            }
        };
    }

    let linesep = str_repeat("-", 80);

    if by_file {
        // TODO(cgag): Need sorting for by_file as well.
        println!("{}", linesep);
        println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                 "Language",
                 "Files",
                 "Lines",
                 "Blank",
                 "Comment",
                 "Code");
        println!("{}", linesep);

        // TODO(cgag): do the summing first, so we can do additional sorting
        // by totals.
        for (lang, mut filecounts) in by_lang {
            let mut total = Count::default();
            for fc in &filecounts {
                total.merge(&fc.count);
            }

            println!("{}", linesep);
            println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                     lang,
                     filecounts.len(),
                     total.lines,
                     total.blank,
                     total.comment,
                     total.code);

            match sort {
                "code" => filecounts.sort_by(|fc1, fc2| fc2.count.code.cmp(&fc1.count.code)),
                "comment" => {
                    filecounts.sort_by(|fc1, fc2| fc2.count.comment.cmp(&fc1.count.comment))
                }
                "blank" => filecounts.sort_by(|fc1, fc2| fc2.count.blank.cmp(&fc1.count.blank)),
                "lines" => filecounts.sort_by(|fc1, fc2| fc2.count.lines.cmp(&fc1.count.lines)),
                // No sorting by language or files here. Need to do it at a higher level.
                _ => (),
            }
            println!("{}", linesep);
            for fc in filecounts {
                println!("|{0: <25} {1: >12} {2: >12} {3: >12} {4: >12}",
                         last_n_chars(&fc.path, 25),
                         fc.count.lines,
                         fc.count.blank,
                         fc.count.comment,
                         fc.count.code);
            }
        }
    } else {
        let mut lang_totals: HashMap<&Lang, LangTotal> = HashMap::new();
        for (lang, filecounts) in &by_lang {
            let mut lang_total = Count::default();
            for fc in filecounts {
                lang_total.merge(&fc.count);
            }
            lang_totals.insert(lang,
                               LangTotal {
                                   files: filecounts.len() as u32,
                                   count: lang_total,
                               });
        }

        let mut totals_by_lang = lang_totals.iter().collect::<Vec<(&&Lang, &LangTotal)>>();
        match sort {
            "language" => totals_by_lang.sort_by(|&(l1, _), &(l2, _)| l1.to_s().cmp(l2.to_s())),
            "files" => totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.files.cmp(&c1.files)),
            "code" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.code.cmp(&c1.count.code))
            }
            "comment" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.comment.cmp(&c1.count.comment))
            }
            "blank" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.blank.cmp(&c1.count.blank))
            }
            "lines" => {
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.lines.cmp(&c1.count.lines))
            }
            _ => {
                println!("invalid sort option {}, sorting by code", sort);
                totals_by_lang.sort_by(|&(_, c1), &(_, c2)| c2.count.code.cmp(&c1.count.code))
            }
        }

        println!("{}", linesep);
        println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                 "Language",
                 "Files",
                 "Lines",
                 "Blank",
                 "Comment",
                 "Code");
        println!("{}", linesep);

        for &(lang, total) in &totals_by_lang {
            println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                     lang,
                     total.files,
                     total.count.lines,
                     total.count.blank,
                     total.count.comment,
                     total.count.code);
        }

        let mut totals = LangTotal {
            files: 0,
            count: Count::default(),
        };
        for &(_, total) in &totals_by_lang {
            totals.files += total.files;
            totals.count.code += total.count.code;
            totals.count.blank += total.count.blank;
            totals.count.comment += total.count.comment;
            totals.count.lines += total.count.lines;
        }

        println!("{}", linesep);
        println!(" {0: <17} {1: >8} {2: >12} {3: >12} {4: >12} {5: >12}",
                 "Total",
                 totals.files,
                 totals.count.lines,
                 totals.count.blank,
                 totals.count.comment,
                 totals.count.code);
        println!("{}", linesep);
    }
}

fn last_n_chars(s: &str, n: usize) -> String {
    if s.len() <= n {
        return String::from(s);
    }
    s.chars().skip(s.len() - n).collect::<String>()
}

fn str_repeat(s: &str, n: usize) -> String {
    std::iter::repeat(s).take(n).collect::<Vec<_>>().join("")
}
<|endoftext|>


<commit_before>
use std::fs::File;
use std::path::Path;
use std::process::exit;

extern crate clap;
use clap::{Arg, App};

extern crate rustc_serialize;

mod appveyor;
mod config;
mod travis_ci;
mod trello;

fn get_config_path(is_using_custom_config: &mut bool, path_str: &str) -> Result<config::TrelloBSTConfigPath, &'static str> {
    if *is_using_custom_config {
        println!("Looking for the configuration file: {}", path_str);
        let path = Path::new(path_str);
        match config::TrelloBSTConfigPath::try_custom_config_path(path) {
            Ok(_config) => {
                return Ok(_config)
            },
            Err(c) => {
                return Err(c)
            },
        };
    } else {
        println!("Looking for the configuration file in default location...");
        match config::TrelloBSTConfigPath::try_default_config_path() {
            Ok(_config) => {
                return Ok(_config)
            },
            Err(c) => {
                return Err(c)
            },
        };
    }
}

fn parse_config(config_path: config::TrelloBSTConfigPath) -> Result<config::TrelloBSTAPIConfig, &'static str>{
    match File::open(config_path.config_path.as_path()) {
        Ok(file) => {
            let mut config_file = file;
            match config::TrelloBSTAPIConfig::parse_from_file(&mut config_file) {
                Ok(_config) => {
                    return Ok(_config)
                }
                Err(err)   => {
                    return Err(err)
                }
            }
        }
        Err(_)   =>{
            return Err("Cannot open config file for parsing, configuration file won't be used...");
        }
    }
}

fn main() {

    let trellobst_version = "0.0.1";

    println!("|----------------------------------------------------------|");
    println!("|-------- Welcome to the Trello Build Status Tool. --------|");
    println!("|----------------------------------------------------------|");

    ////////////////////////////////////////////////////////////
    //               Parse command line options               //
    ////////////////////////////////////////////////////////////

    let mut is_using_config_file   = true;
    let mut is_using_custom_config = false;

    let matches = App::new("TrelloBST")
        .version(trellobst_version)
        .arg(Arg::with_name("CONFIG")
            .short("c")
            .long("config")
            .help("Sets a custom config file.")
            .takes_value(true))
        .arg(Arg::with_name("NO-CONFIG")
            .short("n")
            .long("no-config")
            .help("Won't use a config file.")
            .takes_value(false))
        .get_matches();

    if matches.is_present("CONFIG") && matches.is_present("NO-CONFIG") {
        println!("Error: --config (-c) and --no-config (-n) cannot be used at the same time.");
        exit(-1);
    }

    if matches.is_present("NO-CONFIG") {
        is_using_config_file   = false;
    }

    if matches.is_present("CONFIG") {
        is_using_config_file   = true;
        is_using_custom_config = true;
    }

    ////////////////////////////////////////////////////////////
    //                   Get config path                      //
    ////////////////////////////////////////////////////////////

    let mut config_path = config::TrelloBSTConfigPath::new();

    if is_using_config_file {
        match get_config_path(&mut is_using_custom_config, matches.value_of("CONFIG").unwrap()) {
            Ok(config) => {
                config_path = config;
                println!("Found.")
            }
            Err(err)=>{
                println!("An error occurred: {}", err);
                println!("Configuration file won't be used...");
                is_using_config_file = false;
            }
        }
    }

    ////////////////////////////////////////////////////////////
    //                     Parse config                       //
    ////////////////////////////////////////////////////////////

    let mut config = config::TrelloBSTAPIConfig::new();

    if is_using_config_file {
        println!("Parsing...");
        match parse_config(config_path) {
            Ok(_config) => {
                config = _config;
                println!("Done.");
            }
            Err(err)   => {
                println!("{}", err);
                is_using_config_file = false;
            }
        }
    }

}<commit_msg>Fixed panic! when getting value for CONFIG.<commit_after>
use std::fs::File;
use std::path::Path;
use std::process::exit;

extern crate clap;
use clap::{Arg, App};

extern crate rustc_serialize;

mod appveyor;
mod config;
mod travis_ci;
mod trello;

fn get_config_path(is_using_custom_config: &mut bool, path_str: &str) -> Result<config::TrelloBSTConfigPath, &'static str> {

    if *is_using_custom_config {
        println!("Looking for the configuration file: {}", path_str);
        let path = Path::new(path_str);
        match config::TrelloBSTConfigPath::try_custom_config_path(path) {
            Ok(_config) => {
                return Ok(_config)
            },
            Err(c) => {
                return Err(c)
            },
        };
    } else {
        println!("Looking for the configuration file in default location...");
        match config::TrelloBSTConfigPath::try_default_config_path() {
            Ok(_config) => {
                return Ok(_config)
            },
            Err(c) => {
                return Err(c)
            },
        };
    }
}

fn parse_config(config_path: config::TrelloBSTConfigPath) -> Result<config::TrelloBSTAPIConfig, &'static str>{
    match File::open(config_path.config_path.as_path()) {
        Ok(file) => {
            let mut config_file = file;
            match config::TrelloBSTAPIConfig::parse_from_file(&mut config_file) {
                Ok(_config) => {
                    return Ok(_config)
                }
                Err(err)   => {
                    return Err(err)
                }
            }
        }
        Err(_)   =>{
            return Err("Cannot open config file for parsing, configuration file won't be used...");
        }
    }
}

fn main() {

    let trellobst_version = "0.0.1";

    println!("|----------------------------------------------------------|");
    println!("|-------- Welcome to the Trello Build Status Tool. --------|");
    println!("|----------------------------------------------------------|");

    ////////////////////////////////////////////////////////////
    //               Parse command line options               //
    ////////////////////////////////////////////////////////////

    let mut is_using_config_file   = true;
    let mut is_using_custom_config = false;

    let matches = App::new("TrelloBST")
        .version(trellobst_version)
        .arg(Arg::with_name("CONFIG")
            .short("c")
            .long("config")
            .help("Sets a custom config file.")
            .takes_value(true))
        .arg(Arg::with_name("NO-CONFIG")
            .short("n")
            .long("no-config")
            .help("Won't use a config file.")
            .takes_value(false))
        .get_matches();

    if matches.is_present("CONFIG") && matches.is_present("NO-CONFIG") {
        println!("Error: --config (-c) and --no-config (-n) cannot be used at the same time.");
        exit(-1);
    }

    if matches.is_present("NO-CONFIG") {
        is_using_config_file   = false;
    }

    if matches.is_present("CONFIG") {
        is_using_config_file   = true;
        is_using_custom_config = true;
    }

    ////////////////////////////////////////////////////////////
    //                   Get config path                      //
    ////////////////////////////////////////////////////////////

    let mut config_path = config::TrelloBSTConfigPath::new();

    if is_using_config_file {
        match get_config_path(&mut is_using_custom_config, matches.value_of("CONFIG").unwrap_or("")) {
            Ok(config) => {
                config_path = config;
                println!("Found.")
            }
            Err(err)=>{
                println!("An error occurred: {}", err);
                println!("Configuration file won't be used...");
                is_using_config_file = false;
            }
        }
    }

    ////////////////////////////////////////////////////////////
    //                     Parse config                       //
    ////////////////////////////////////////////////////////////

    let mut config = config::TrelloBSTAPIConfig::new();

    if is_using_config_file {

        println!("Parsing...");

        match parse_config(config_path) {
            Ok(_config) => {
                config = _config;
                println!("Done.");
            }
            Err(err)   => {
                println!("{}", err);
                is_using_config_file = false;
            }
        }
    }
}<|endoftext|>


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

use std::io::Read;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

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

#[derive(Debug)]
struct Mapping;

impl Mapping {
    fn new() -> Mapping {
        Mapping
    }
}

#[derive(Debug)]
struct Index {
    pub mappings: HashMap<&'static str, Mapping>,
}

impl Index {
    fn new() -> Index {
        Index{
            mappings: HashMap::new(),
        }
    }
}

fn index_not_found_response() -> Response {
    let mut response = Response::with((status::NotFound, "{\"message\": \"Index not found\"}"));
    response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
    return response;
}

fn main() {
    let mut indices = Arc::new(Mutex::new(HashMap::new()));
    let mut wagtail_index = Index::new();
    wagtail_index.mappings.insert("wagtaildocs_document", Mapping::new());
    indices.lock().unwrap().insert("wagtail", wagtail_index);

    let mut router = Router::new();

    router.get("/", |_: &mut Request| -> IronResult<Response> {
        Ok(Response::with((status::Ok, "Hello World!")))
    });

    {
        let indices = indices.clone();

        router.get("/:index/_count", move |req: &mut Request| -> IronResult<Response> {
            let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");
            if !indices.lock().unwrap().contains_key(index) {
                return Ok(index_not_found_response());
            }

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

            // TODO

            let mut response = Response::with((status::Ok, "{\"count\": 0}"));
            response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
            Ok(response)
        });
    }

    {
        let indices = indices.clone();

        router.get("/:index/_search", move |req: &mut Request| -> IronResult<Response> {
            let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");
            if !indices.lock().unwrap().contains_key(index) {
                return Ok(index_not_found_response());
            }

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

            // TODO

            let mut response = Response::with((status::Ok, "{\"hits\": {\"total\": 0, \"hits\": []}}"));
            response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
            Ok(response)
        });
    }

    {
        let indices = indices.clone();

        router.put("/:index/:mapping/:doc", move |req: &mut Request| -> IronResult<Response> {
            let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");
            if !indices.lock().unwrap().contains_key(index) {
                return Ok(index_not_found_response());
            }

            let ref mapping = req.extensions.get::<Router>().unwrap().find("mapping").unwrap_or("");
            if !indices.lock().unwrap().get(index).unwrap().mappings.contains_key(mapping) {
                let mut response = Response::with((status::NotFound, "{\"message\": \"Mapping not found\"}"));
                response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
                return Ok(response);
            }

            let ref doc = req.extensions.get::<Router>().unwrap().find("doc").unwrap_or("");

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

            let data = Json::from_str(&payload).unwrap();

            // TODO

            let mut response = Response::with((status::Ok, "{}"));
            response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
            Ok(response)
        });
    }

    Iron::new(router).http("localhost:9200").unwrap();
}
<commit_msg>Handle JSON parse error<commit_after>extern crate iron;
extern crate router;
extern crate rustc_serialize;

use std::io::Read;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

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

#[derive(Debug)]
struct Mapping;

impl Mapping {
    fn new() -> Mapping {
        Mapping
    }
}

#[derive(Debug)]
struct Index {
    pub mappings: HashMap<&'static str, Mapping>,
}

impl Index {
    fn new() -> Index {
        Index{
            mappings: HashMap::new(),
        }
    }
}

fn index_not_found_response() -> Response {
    let mut response = Response::with((status::NotFound, "{\"message\": \"Index not found\"}"));
    response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
    return response;
}

fn main() {
    let mut indices = Arc::new(Mutex::new(HashMap::new()));
    let mut wagtail_index = Index::new();
    wagtail_index.mappings.insert("wagtaildocs_document", Mapping::new());
    indices.lock().unwrap().insert("wagtail", wagtail_index);

    let mut router = Router::new();

    router.get("/", |_: &mut Request| -> IronResult<Response> {
        Ok(Response::with((status::Ok, "Hello World!")))
    });

    {
        let indices = indices.clone();

        router.get("/:index/_count", move |req: &mut Request| -> IronResult<Response> {
            let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");
            if !indices.lock().unwrap().contains_key(index) {
                return Ok(index_not_found_response());
            }

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

            // TODO

            let mut response = Response::with((status::Ok, "{\"count\": 0}"));
            response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
            Ok(response)
        });
    }

    {
        let indices = indices.clone();

        router.get("/:index/_search", move |req: &mut Request| -> IronResult<Response> {
            let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");
            if !indices.lock().unwrap().contains_key(index) {
                return Ok(index_not_found_response());
            }

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

            // TODO

            let mut response = Response::with((status::Ok, "{\"hits\": {\"total\": 0, \"hits\": []}}"));
            response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
            Ok(response)
        });
    }

    {
        let indices = indices.clone();

        router.put("/:index/:mapping/:doc", move |req: &mut Request| -> IronResult<Response> {
            let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");
            if !indices.lock().unwrap().contains_key(index) {
                return Ok(index_not_found_response());
            }

            let ref mapping = req.extensions.get::<Router>().unwrap().find("mapping").unwrap_or("");
            if !indices.lock().unwrap().get(index).unwrap().mappings.contains_key(mapping) {
                let mut response = Response::with((status::NotFound, "{\"message\": \"Mapping not found\"}"));
                response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
                return Ok(response);
            }

            let ref doc = req.extensions.get::<Router>().unwrap().find("doc").unwrap_or("");

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

            let data = match Json::from_str(&payload) {
                Ok(data) => data,
                Err(error) => {
                    // TODO: What specifically is bad about the JSON?
                    let mut response = Response::with((status::BadRequest, "{\"message\": \"Couldn't parse JSON\"}"));
                    response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
                    return Ok(response);
                }
            };

            // TODO

            let mut response = Response::with((status::Ok, "{}"));
            response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
            Ok(response)
        });
    }

    Iron::new(router).http("localhost:9200").unwrap();
}
<|endoftext|>