<commit_before>#![feature(collections)]

extern crate image;
extern crate num;

use image::ImageBuffer;
use image::imageops::flip_vertical;
use painting::Painting;
use geometry::*;

mod painting;
mod geometry;

fn main() {
    // image processing
    let m = match load_model_obj("obj/phone.obj") {
        Ok(m) => m,
        Err(..) => panic!("couldn't read input file"),
    };

    let width = 1920 as i32;
    let pad = 10 as i32;

    // TODO: check m.verts size
    let mut min_x = m.verts[0].x;
    let mut max_x = m.verts[0].x;
    let mut min_y = m.verts[0].y;
    let mut max_y = m.verts[0].y;

    for v in m.verts.iter() {
        if v.x < min_x { min_x = v.x; }
        if v.x > max_x { max_x = v.x; }

        if v.y < min_y { min_y = v.y; }
        if v.y > max_y { max_y = v.y; }
    }

    let ratio = (width - 2 * pad) as f64 / (max_x - min_x);
    let height = ((max_y - min_y) * ratio + 2.0 * pad as f64) as i32;

    let mut img = ImageBuffer::new(width as u32, height as u32);
    let light = (Vec3Df { x: -10.0, y: 5.5, z: -115.0 }).normalized();

    let mut zbuffer = vec![vec![std::i32::MIN; height as usize]; width as usize];

    for f in m.faces.iter() {
        let npoly = f.len();

        if npoly >= 3 {
            let v0 = m.verts[f[0]];
            let l = light * ((m.verts[f[2]] - v0).cross((m.verts[f[1]] - v0))).normalized();

            if l > 0.0f64 {
                let dens = (0xff as f64 * l) as u8;
                let col = image::Rgb([dens, dens, dens]);

                for i in 1..(npoly - 1) {
                    let v1 = m.verts[f[i]];
                    let v2 = m.verts[f[i + 1]];

                    img.triangle(
                        Vec3Di {
                            x: pad + ((v0.x - min_x) * ratio) as i32,
                            y: pad + ((v0.y - min_y) * ratio) as i32,
                            z: (v0.z * ratio) as i32
                        },
                        Vec3Di {
                            x: pad + ((v1.x - min_x) * ratio) as i32,
                            y: pad + ((v1.y - min_y) * ratio) as i32,
                            z: (v1.z * ratio) as i32
                        },
                        Vec3Di {
                            x: pad + ((v2.x - min_x) * ratio) as i32,
                            y: pad + ((v2.y - min_y) * ratio) as i32,
                            z: (v2.z * ratio) as i32
                        },
                        col,
                        &mut zbuffer
                    );
                }
            }
        }
    }

    img = flip_vertical(&img);

    // save image
    let _ = img.save("output/triangles.png");
}
<commit_msg>try to get a proper light<commit_after>#![feature(collections)]

extern crate image;
extern crate num;

use image::ImageBuffer;
use image::imageops::flip_vertical;
use painting::Painting;
use geometry::*;

mod painting;
mod geometry;

fn main() {
    // image processing
    let m = match load_model_obj("obj/african_head.obj") {
        Ok(m) => m,
        Err(..) => panic!("couldn't read input file"),
    };

    let width = 1024 as i32;
    let pad = 10 as i32;

    // TODO: check m.verts size
    let mut min_x = m.verts[0].x;
    let mut max_x = m.verts[0].x;
    let mut min_y = m.verts[0].y;
    let mut max_y = m.verts[0].y;
    let mut min_z = m.verts[0].z;
    let mut max_z = m.verts[0].z;

    for v in m.verts.iter() {
        if v.x < min_x { min_x = v.x; }
        if v.x > max_x { max_x = v.x; }

        if v.y < min_y { min_y = v.y; }
        if v.y > max_y { max_y = v.y; }

        if v.z < min_z { min_z = v.z; }
        if v.z > max_z { max_z = v.z; }
    }

    let ratio = (width - 2 * pad) as f64 / (max_x - min_x);
    let height = ((max_y - min_y) * ratio + 2.0 * pad as f64) as i32;

    let mut img = ImageBuffer::new(width as u32, height as u32);
    let light = (Vec3Df { x: 0.0, y: 0.0, z: -1.0 }).normalized();

    let mut zbuffer = vec![vec![std::i32::MIN; height as usize]; width as usize];

    for f in m.faces.iter() {
        let npoly = f.len();

        if npoly >= 3 {
            let v0 = m.verts[f[0]];
            let l = light * ((m.verts[f[2]] - v0).cross((m.verts[f[1]] - v0))).normalized();

            if l > 0.0f64 {
                let dens = (255.0 * l) as u8;
                let col = image::Rgb([dens, dens, dens]);

                for i in 1..(npoly - 1) {
                    let v1 = m.verts[f[i]];
                    let v2 = m.verts[f[i + 1]];

                    img.triangle(
                        Vec3Di {
                            x: pad + ((v0.x - min_x) * ratio) as i32,
                            y: pad + ((v0.y - min_y) * ratio) as i32,
                            z: pad + ((v0.z - min_z) * ratio) as i32
                        },
                        Vec3Di {
                            x: pad + ((v1.x - min_x) * ratio) as i32,
                            y: pad + ((v1.y - min_y) * ratio) as i32,
                            z: pad + ((v1.z - min_z) * ratio) as i32
                        },
                        Vec3Di {
                            x: pad + ((v2.x - min_x) * ratio) as i32,
                            y: pad + ((v2.y - min_y) * ratio) as i32,
                            z: pad + ((v2.z - min_z) * ratio) as i32
                        },
                        col,
                        &mut zbuffer
                    );
                }
            }
        }
    }

    img = flip_vertical(&img);

    // save image
    let _ = img.save("output/triangles.png");
}
<|endoftext|>


<commit_before>#![feature(phase)]

extern crate serialize;
extern crate git2;
extern crate docopt;
#[phase(plugin)] extern crate docopt_macros;
#[phase(plugin, link)] extern crate log;
extern crate term;

use git2::Repository;
use std::os;
use std::error;
use std::error::FromError;

docopt!(Args deriving Show, "
Usage: delivery review [--for=<pipeline>]
       delivery checkout <change> [--patchset=<number>]
       delivery rebase [--for=<pipeline>]
       delivery --help

Options:
  -h, --help               Show this message.
  -f, --for=<pipeline>     A pipeline to target [default: master]
  -p, --patchset=<number>  A patchset number [default: latest]
")

fn main() {
    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    debug!("{}", args);
    let cmd_result = match args {
        Args {
            cmd_review: true, flag_for: ref for_pipeline, ..
        } => review(for_pipeline),
        _ => no_matching_command(),
    };
    match cmd_result {
        Ok(_) => {},
        Err(e) => exit_with(e, 1)
    }
}

enum ErrorKind {
    NoMatchingCommand,
    NotOnABranch,
    GitError(git2::Error),
}

struct DeliveryError {
    pub kind: ErrorKind,
    pub detail: Option<String>,
}

impl error::Error for DeliveryError {
    fn description(&self) -> &str {
        match self.kind {
            NoMatchingCommand => "No command matches your arguments - likely unimplemented feature",
            NotOnABranch => "You must be on a branch",
            GitError(_) => "A git error occured",
        }
    }

    fn detail(&self) -> Option<String> {
        self.detail.clone()
    }

    fn cause(&self) -> Option<&error::Error> {
        self.cause()
    }
}

impl FromError<git2::Error> for DeliveryError {
    fn from_error(err: git2::Error) -> DeliveryError {
        let message = err.message().clone();
        DeliveryError {
            kind: GitError(err),
            detail: Some(message),
        }
    }
}

fn no_matching_command() -> Result<bool, DeliveryError> {
    Err(DeliveryError { kind: NoMatchingCommand, detail: None })
}

fn say_greenln(to_say: &str) {
    say_green(to_say);
    let mut t = term::stdout().unwrap();
    (write!(t, "\n")).unwrap();
}

fn say_green(to_say: &str) {
    let mut t = term::stdout().unwrap();
    t.fg(term::color::GREEN).unwrap();
    (write!(t, "{}", to_say)).unwrap();
    t.reset().unwrap()
}

fn say_redln(to_say: &str) {
    say_red(to_say);
    let mut t = term::stdout().unwrap();
    (write!(t, "\n")).unwrap();
}

fn say_red(to_say: &str) {
    let mut t = term::stdout().unwrap();
    t.fg(term::color::RED).unwrap();
    (write!(t, "{}", to_say)).unwrap();
    t.reset().unwrap()
}

fn get_repository() -> Result<Repository, DeliveryError> {
    let repo = try!(Repository::discover(&os::getcwd()));
    Ok(repo)
}

fn get_head(repo: Repository) -> Result<String, DeliveryError> {
    let head = try!(repo.head());
    let shorthand = head.shorthand();
    let result = match shorthand {
        Some(result) => Ok(String::from_str(result)),
        None => Err(DeliveryError{ kind: NotOnABranch, detail: None })
    };
    result
}

fn exit_with<T: error::Error>(e: T, i: int) {
    say_redln(e.description());
    match e.detail() {
        Some(deets) => say_redln(deets.as_slice()),
        None => {}
    }
    os::set_exit_status(i)
}

fn review(for_pipeline: &String) -> Result<bool, DeliveryError> {
    debug!("Starting review for pipeline {}", for_pipeline);
    let repo = try!(get_repository());
    let head = try!(get_head(repo));
    println!("Head is {}", head);
    say_greenln(format!("Delivery Review, current branch {}", head.as_slice()).as_slice());
    // say_greenln(head);
    Ok(true)
}

<commit_msg>Stuff<commit_after>#![feature(phase)]

extern crate serialize;
extern crate git2;
extern crate docopt;
#[phase(plugin)] extern crate docopt_macros;
#[phase(plugin, link)] extern crate log;
extern crate term;

use git2::Repository;
use std::os;
use std::error;
use std::error::FromError;

docopt!(Args deriving Show, "
Usage: delivery review [--for=<pipeline>]
       delivery checkout <change> [--patchset=<number>]
       delivery rebase [--for=<pipeline>]
       delivery --help

Options:
  -h, --help               Show this message.
  -f, --for=<pipeline>     A pipeline to target [default: master]
  -p, --patchset=<number>  A patchset number [default: latest]
")

#[cfg(not(test))]
fn main() {
    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    debug!("{}", args);
    let cmd_result = match args {
        Args {
            cmd_review: true, flag_for: ref for_pipeline, ..
        } => review(for_pipeline.as_slice()),
        _ => no_matching_command(),
    };
    match cmd_result {
        Ok(_) => {},
        Err(e) => exit_with(e, 1)
    }
}

enum ErrorKind {
    NoMatchingCommand,
    NotOnABranch,
    GitError(git2::Error),
}

struct DeliveryError {
    pub kind: ErrorKind,
    pub detail: Option<String>,
}

impl error::Error for DeliveryError {
    fn description(&self) -> &str {
        match self.kind {
            NoMatchingCommand => "No command matches your arguments - likely unimplemented feature",
            NotOnABranch => "You must be on a branch",
            GitError(_) => "A git error occured",
        }
    }

    fn detail(&self) -> Option<String> {
        self.detail.clone()
    }

    fn cause(&self) -> Option<&error::Error> {
        self.cause()
    }
}

impl FromError<git2::Error> for DeliveryError {
    fn from_error(err: git2::Error) -> DeliveryError {
        let message = err.message().clone();
        DeliveryError {
            kind: GitError(err),
            detail: Some(message),
        }
    }
}

fn no_matching_command() -> Result<bool, DeliveryError> {
    Err(DeliveryError { kind: NoMatchingCommand, detail: None })
}

fn say_greenln(to_say: &str) {
    say_green(to_say);
    let mut t = term::stdout().unwrap();
    (write!(t, "\n")).unwrap();
}

fn say_green(to_say: &str) {
    let mut t = term::stdout().unwrap();
    t.fg(term::color::GREEN).unwrap();
    (write!(t, "{}", to_say)).unwrap();
    t.reset().unwrap()
}

fn say_redln(to_say: &str) {
    say_red(to_say);
    let mut t = term::stdout().unwrap();
    (write!(t, "\n")).unwrap();
}

fn say_red(to_say: &str) {
    let mut t = term::stdout().unwrap();
    t.fg(term::color::RED).unwrap();
    (write!(t, "{}", to_say)).unwrap();
    t.reset().unwrap()
}

fn get_repository() -> Result<Repository, DeliveryError> {
    let repo = try!(Repository::discover(&os::getcwd()));
    Ok(repo)
}

fn get_head(repo: Repository) -> Result<String, DeliveryError> {
    let head = try!(repo.head());
    let shorthand = head.shorthand();
    let result = match shorthand {
        Some(result) => Ok(String::from_str(result)),
        None => Err(DeliveryError{ kind: NotOnABranch, detail: None })
    };
    result
}

fn exit_with<T: error::Error>(e: T, i: int) {
    say_redln(e.description());
    match e.detail() {
        Some(deets) => say_redln(deets.as_slice()),
        None => {}
    }
    os::set_exit_status(i)
}

fn git_push(branch: &str, target: &str) -> Result<String, DeliveryError> {
    let mut command = Command::new("git");
    command.arg("push");
    command.arg("--porcelain");
    command.arg("origin");
    command.arg(format!("{}:_for/{}/{}", branch, target, branch));
    debug!("Running: {}", command);
    let output = match command.output() {
        Ok(o) => o,
        Err(e) => { return Err(DeliveryError{ kind: FailedToExecute, detail: Some(format!("failed to execute git: {}", e.desc))}) },
    };
    if !output.status.success() {
        return Err(DeliveryError{ kind: PushFailed, detail: Some(format!("STDOUT: {}\nSTDERR: {}\n", String::from_utf8_lossy(output.output.as_slice()), String::from_utf8_lossy(output.error.as_slice())))});
    }
    let stdout = String::from_utf8_lossy(output.output.as_slice()).into_string();
    parse_git_push_output(stdout.as_slice());
    debug!("Git push: {}", stdout);
    debug!("Git exited: {}", output.status);
    Ok(stdout.into_string())
}

fn parse_git_push_output(push_output: &str) {
    for line in push_output.lines_any() {
        println!("piece: {}", line)
    }
}

#[test]
fn test_parse_git_push_output() {
    let input = String::from_str("To ssh://adam@127.0.0.1/Users/adam/src/opscode/delivery/opscode/delivery-cli2
=	refs/heads/foo:refs/heads/_for/master/foo	[up to date]
Done");
    let results: Vec<String> = parse_git_push_output(input);
    let mut valid_result: Vec<String> = Vec::new();
    valid_result.push(String::from_str("Review branch _for/master/foo is up to date"));
    assert_eq!(valid_result, results);
}

fn review(for_pipeline: &str) -> Result<bool, DeliveryError> {
    let repo = try!(get_repository());
    let head = try!(get_head(repo));
    if for_pipeline == head.as_slice() {
        return Err(DeliveryError{ kind: CannotReviewSameBranch, detail: None })
    }
    say("green", "Delivery");
    say("white", " review for change ");
    say("yellow", head.as_slice());
    say("white", " targeted for pipeline ");
    sayln("magenta", for_pipeline.as_slice());
    let output = try!(git_push(head.as_slice(), for_pipeline));
    sayln("white", output.as_slice());
    Ok(true)
}

<|endoftext|>


<commit_before>#![feature(rand)]

extern crate clap;
#[macro_use]
extern crate glium;
extern crate rand;

use std::collections::{HashSet, VecDeque};

use glium::Surface;
use glium::glutin;

/// Maximum frames per second.
const FPS: u32 = 30;

#[derive(Clone, Copy, Debug, PartialEq)]
enum Color {
    Red,
    Yellow,
    Green,
    LightBrown,
    Purple,
    Cyan,
    Blue,
    Fuchsia,
}

const COLORS: &[Color] = &[
    Color::Red,
    Color::Yellow,
    Color::Green,
    Color::LightBrown,
    Color::Purple,
    Color::Cyan,
    Color::Blue,
    Color::Fuchsia,
];

impl rand::Rand for Color {
    fn rand<R: rand::Rng>(rng: &mut R) -> Self {
        *rng.choose(COLORS).unwrap()
    }
}

struct Grid {
    width: u8,
    height: u8,

    cells: Vec<Color>,
    population: Vec<u16>,

    max_clicks: u16,
    num_clicks: u16,
}

impl Grid {
    pub fn new(num_colors: u8, size: u8) -> Self {
        use rand::distributions::{IndependentSample, Range};
        let between = Range::new(0, num_colors as usize);
        let mut rng = rand::thread_rng();

        let cells: Vec<Color> = (0..size as u64 * size as u64)
            .map(|_| COLORS[between.ind_sample(&mut rng)])
            .collect();
        let max_clicks = 25 * 2 * size as u16 * num_colors as u16 / (2 * 14 * 6);
        let mut population = vec![0; COLORS.len()];
        for &c in &cells {
            population[c as usize] += 1;
        }

        Self {
            width: size,
            height: size,

            cells,
            population,

            max_clicks,
            num_clicks: 0,
        }
    }

    fn index(&self, row: u8, column: u8) -> usize {
        self.width as usize * row as usize + column as usize
    }

    fn current_color(&self) -> Color {
        self.cells[0]
    }

    fn solved(&self) -> bool {
        let mut colors_present = 0;
        for &x in &self.population {
            if x > 0 {
                colors_present += 1;
            }
        }
        colors_present == 1
    }

    pub fn click(&mut self, row: u8, column: u8) -> bool {
        let i = self.index(row, column);
        let new_color = self.cells[i];
        if self.current_color() == new_color {
            return false;
        }

        self.num_clicks += 1;
        self.flood(new_color);
        self.solved()
    }

    /// Flood the grid from the top left cell and return the number of cell which are connected to
    /// the top left cell by cells of indentical color.
    fn flood(&mut self, new_color: Color) {
        let current_color = self.current_color();

        let rows = self.height as usize;
        let columns = self.width as usize;

        let mut visited = HashSet::new();
        let mut queue = VecDeque::new();
        queue.push_back(0);

        while let Some(i) = queue.pop_front() {
            if self.cells[i] == new_color {
                continue;
            }
            let c = self.cells[i];
            self.population[c as usize] -= 1;
            self.cells[i] = new_color;
            self.population[new_color as usize] += 1;
            visited.insert(i);

            if i % columns > 0 && self.cells[i - 1] == current_color &&
                !visited.contains(&(i - 1))
            {
                queue.push_back(i - 1);
            }
            if i % columns < columns - 1 && self.cells[i + 1] == current_color &&
                !visited.contains(&(i + 1))
            {
                queue.push_back(i + 1);
            }
            if i >= columns && self.cells[i - columns] == current_color &&
                !visited.contains(&(i - columns))
            {
                queue.push_back(i - columns);
            }
            if i < (rows - 1) * columns && self.cells[i + columns] == current_color &&
                !visited.contains(&(i + columns))
            {
                queue.push_back(i + columns);
            }
        }
    }

    pub fn aspect_ratio(&self) -> f32 {
        self.height as f32 / self.width as f32
    }
}

#[derive(Copy, Clone)]
struct Vertex {
    color: f32,
    position: [f32; 2],
}

implement_vertex!(Vertex, color, position);

const TITLE: &'static str = "Flood-It";

const VERTEX_SHADER: &str = r#"
    #version 140
    in vec2 position;
    in float color;
    uniform mat4 matrix;
    out float c;
    void main() {
        c = color;
        gl_Position = matrix * vec4(position, 0.0, 1.0);
    }
"#;

/// Map Color::* to RGB values.
const FRAGMENT_SHADER: &str = r#"
    #version 140
    in float c;
    out vec4 color;
    void main() {
        if (c <= 0.0)
            color = vec4(1.0, 0.0, 0.0, 1.0);
        else if (c <= 1.0)
            color = vec4(1.0, 1.0, 0.0, 1.0);
        else if (c <= 2.0)
            color = vec4(0.0, 0.69, 0.0, 1.0);
        else if (c <= 3.0)
            color = vec4(1.0, 0.8, 0.4, 1.0);
        else if (c <= 4.0)
            color = vec4(0.5, 0.0, 0.5, 1.0);
        else if (c <= 5.0)
            color = vec4(0.0, 1.0, 1.0, 1.0);
        else if (c <= 6.0)
            color = vec4(0.0, 0.0, 1.0, 1.0);
        else if (c <= 7.0)
            color = vec4(1.0, 0.0, 1.0, 1.0);
        else
            // Should never happen
            color = vec4(1.0, 1.0, 1.0, 1.0);
    }
"#;

fn main() {
    use clap::{App, Arg};
    use glium::glutin::{ContextBuilder, EventsLoop, WindowBuilder};
    use glutin::{Event, WindowEvent};

    let matches = App::new(TITLE)
        .author(env!("CARGO_PKG_AUTHORS"))
        .version(env!("CARGO_PKG_VERSION"))
        .arg(
            Arg::with_name("colors")
                .takes_value(true)
                .help("The number of different colors")
                .default_value("6"),
        )
        .arg(
            Arg::with_name("size")
                .takes_value(true)
                .help("The height and width of the grid")
                .default_value("14"),
        )
        .get_matches();

    let colors = {
        let tmp: u8 = matches
            .value_of("colors")
            .and_then(|x| x.parse().ok())
            .unwrap_or(6);
        if tmp < 3 || tmp > 8 {
            panic!("Flood-It only supports 3 through 8 (inclusive) colors.");
        } else {
            tmp
        }
    };
    let size: u8 = {
        let tmp: u8 = matches
            .value_of("size")
            .and_then(|x| x.parse().ok())
            .unwrap_or(14);
        if tmp < 2 {
            panic!("Flood-It needs a grid of at least 2x2 cells.");
        } else {
            tmp
        }
    };

    let mut events_loop = EventsLoop::new();
    let window = WindowBuilder::new().with_title(TITLE);
    let context = ContextBuilder::new();
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    let program = glium::Program::from_source(&display, VERTEX_SHADER, FRAGMENT_SHADER, None)
        .unwrap();

    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let params = glium::DrawParameters {
        backface_culling: glium::draw_parameters::BackfaceCullingMode::CullCounterClockwise,
        ..Default::default()
    };

    let mut grid = Grid::new(colors, size);
    let grid_aspect_ratio = grid.aspect_ratio();

    let mut cursor_position = (0.0, 0.0);

    main_loop(|| {
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 1.0);
        let (width, height) = target.get_dimensions();
        let screen_aspect_ratio = height as f32 / width as f32;

        let (ratio_x, ratio_y) = if screen_aspect_ratio < grid_aspect_ratio {
            (screen_aspect_ratio, 1.0)
        } else {
            (1.0, screen_aspect_ratio.recip())
        };

        let uniforms =
            uniform! {
            matrix: [
                [ratio_x, 0.0, 0.0, 0.0],
                [0.0, -ratio_y, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0_f32],
            ]
        };

        let mut triangles = vec![];

        for i in 0..grid.cells.len() {
            let x = (i % grid.width as usize) as f32;
            let y = (i / grid.width as usize) as f32;

            let cell_size = 2.0 / grid.height.max(grid.width) as f32;

            let mut quad = generate_rectangle_vertices(
                x * cell_size - 1.0,
                y * cell_size - 1.0,
                (x + 1.0) * cell_size - 1.0,
                (y + 1.0) * cell_size - 1.0,
                grid.cells[i],
            );
            triangles.append(&mut quad);
        }

        let vertex_buffer = glium::VertexBuffer::new(&display, &triangles).unwrap();
        target
            .draw(&vertex_buffer, &indices, &program, &uniforms, &params)
            .unwrap();

        target.finish().unwrap();

        let mut closed = false;
        events_loop.poll_events(|event| match event {
            Event::WindowEvent { event, .. } => {
                match event {
                    WindowEvent::Closed => closed = true,
                    WindowEvent::MouseMoved { position, .. } =>
                        cursor_position = position,
                    WindowEvent::MouseInput {
                        state: glium::glutin::ElementState::Released,
                        button: glium::glutin::MouseButton::Left,
                        ..
                    } => {
                        let offsets = {
                            let offset = (width as f64 - height as f64).abs() / 2.0;
                            if screen_aspect_ratio < grid_aspect_ratio {
                                (offset, 0.0)
                            } else {
                                (0.0, offset)
                            }
                        };
                        if cursor_position.0 - offsets.0 >= 0.0 &&
                            cursor_position.1 - offsets.1 >= 0.0
                        {
                            let column = ((cursor_position.0 - offsets.0) * grid.width as f64 /
                                              (width as f64 - 2.0 * offsets.0))
                                .floor() as u8;
                            let row = ((cursor_position.1 - offsets.1) * grid.height as f64 /
                                           (height as f64 - 2.0 * offsets.1))
                                .floor() as u8;
                            if grid.click(row, column) {
                                    if grid.num_clicks <= grid.max_clicks {
                                        println!("You win! You used {} out of {} available moves.", grid.num_clicks, grid.max_clicks);
                                    } else {
                                        println!("You lose. You took {} moves but should have finished in {}.", grid.num_clicks, grid.max_clicks);
                                }
                            }
                        }
                    }
                    _ => (),
                }
            }
            _ => (),
        });
        !closed
    });
}

fn generate_rectangle_vertices(
    left: f32,
    bottom: f32,
    right: f32,
    top: f32,
    color: Color,
) -> Vec<Vertex> {
    let color = color as u32 as f32;
    vec![
        Vertex {
            color,
            position: [left, bottom],
        },
        Vertex {
            color,
            position: [right, bottom],
        },
        Vertex {
            color,
            position: [left, top],
        },
        Vertex {
            color,
            position: [right, bottom],
        },
        Vertex {
            color,
            position: [right, top],
        },
        Vertex {
            color,
            position: [left, top],
        },
    ]
}

fn main_loop<F: FnMut() -> bool>(mut callback: F) {
    use std::time::{Duration, Instant};
    use std::thread;

    let one_frame = Duration::new(0, 10 ^ 9 / FPS + 1);
    let mut last_frame = Instant::now();

    while callback() {
        let now = Instant::now();
        let remaining = one_frame.checked_sub(now - last_frame).unwrap_or_default();
        last_frame = now;
        thread::sleep(remaining);
    }
}
<commit_msg>Remove superfluous #![feature(rand)]<commit_after>extern crate clap;
#[macro_use]
extern crate glium;
extern crate rand;

use std::collections::{HashSet, VecDeque};

use glium::Surface;
use glium::glutin;

/// Maximum frames per second.
const FPS: u32 = 30;

#[derive(Clone, Copy, Debug, PartialEq)]
enum Color {
    Red,
    Yellow,
    Green,
    LightBrown,
    Purple,
    Cyan,
    Blue,
    Fuchsia,
}

const COLORS: &[Color] = &[
    Color::Red,
    Color::Yellow,
    Color::Green,
    Color::LightBrown,
    Color::Purple,
    Color::Cyan,
    Color::Blue,
    Color::Fuchsia,
];

impl rand::Rand for Color {
    fn rand<R: rand::Rng>(rng: &mut R) -> Self {
        *rng.choose(COLORS).unwrap()
    }
}

struct Grid {
    width: u8,
    height: u8,

    cells: Vec<Color>,
    population: Vec<u16>,

    max_clicks: u16,
    num_clicks: u16,
}

impl Grid {
    pub fn new(num_colors: u8, size: u8) -> Self {
        use rand::distributions::{IndependentSample, Range};
        let between = Range::new(0, num_colors as usize);
        let mut rng = rand::thread_rng();

        let cells: Vec<Color> = (0..size as u64 * size as u64)
            .map(|_| COLORS[between.ind_sample(&mut rng)])
            .collect();
        let max_clicks = 25 * 2 * size as u16 * num_colors as u16 / (2 * 14 * 6);
        let mut population = vec![0; COLORS.len()];
        for &c in &cells {
            population[c as usize] += 1;
        }

        Self {
            width: size,
            height: size,

            cells,
            population,

            max_clicks,
            num_clicks: 0,
        }
    }

    fn index(&self, row: u8, column: u8) -> usize {
        self.width as usize * row as usize + column as usize
    }

    fn current_color(&self) -> Color {
        self.cells[0]
    }

    fn solved(&self) -> bool {
        let mut colors_present = 0;
        for &x in &self.population {
            if x > 0 {
                colors_present += 1;
            }
        }
        colors_present == 1
    }

    pub fn click(&mut self, row: u8, column: u8) -> bool {
        let i = self.index(row, column);
        let new_color = self.cells[i];
        if self.current_color() == new_color {
            return false;
        }

        self.num_clicks += 1;
        self.flood(new_color);
        self.solved()
    }

    /// Flood the grid from the top left cell and return the number of cell which are connected to
    /// the top left cell by cells of indentical color.
    fn flood(&mut self, new_color: Color) {
        let current_color = self.current_color();

        let rows = self.height as usize;
        let columns = self.width as usize;

        let mut visited = HashSet::new();
        let mut queue = VecDeque::new();
        queue.push_back(0);

        while let Some(i) = queue.pop_front() {
            if self.cells[i] == new_color {
                continue;
            }
            let c = self.cells[i];
            self.population[c as usize] -= 1;
            self.cells[i] = new_color;
            self.population[new_color as usize] += 1;
            visited.insert(i);

            if i % columns > 0 && self.cells[i - 1] == current_color &&
                !visited.contains(&(i - 1))
            {
                queue.push_back(i - 1);
            }
            if i % columns < columns - 1 && self.cells[i + 1] == current_color &&
                !visited.contains(&(i + 1))
            {
                queue.push_back(i + 1);
            }
            if i >= columns && self.cells[i - columns] == current_color &&
                !visited.contains(&(i - columns))
            {
                queue.push_back(i - columns);
            }
            if i < (rows - 1) * columns && self.cells[i + columns] == current_color &&
                !visited.contains(&(i + columns))
            {
                queue.push_back(i + columns);
            }
        }
    }

    pub fn aspect_ratio(&self) -> f32 {
        self.height as f32 / self.width as f32
    }
}

#[derive(Copy, Clone)]
struct Vertex {
    color: f32,
    position: [f32; 2],
}

implement_vertex!(Vertex, color, position);

const TITLE: &'static str = "Flood-It";

const VERTEX_SHADER: &str = r#"
    #version 140
    in vec2 position;
    in float color;
    uniform mat4 matrix;
    out float c;
    void main() {
        c = color;
        gl_Position = matrix * vec4(position, 0.0, 1.0);
    }
"#;

/// Map Color::* to RGB values.
const FRAGMENT_SHADER: &str = r#"
    #version 140
    in float c;
    out vec4 color;
    void main() {
        if (c <= 0.0)
            color = vec4(1.0, 0.0, 0.0, 1.0);
        else if (c <= 1.0)
            color = vec4(1.0, 1.0, 0.0, 1.0);
        else if (c <= 2.0)
            color = vec4(0.0, 0.69, 0.0, 1.0);
        else if (c <= 3.0)
            color = vec4(1.0, 0.8, 0.4, 1.0);
        else if (c <= 4.0)
            color = vec4(0.5, 0.0, 0.5, 1.0);
        else if (c <= 5.0)
            color = vec4(0.0, 1.0, 1.0, 1.0);
        else if (c <= 6.0)
            color = vec4(0.0, 0.0, 1.0, 1.0);
        else if (c <= 7.0)
            color = vec4(1.0, 0.0, 1.0, 1.0);
        else
            // Should never happen
            color = vec4(1.0, 1.0, 1.0, 1.0);
    }
"#;

fn main() {
    use clap::{App, Arg};
    use glium::glutin::{ContextBuilder, EventsLoop, WindowBuilder};
    use glutin::{Event, WindowEvent};

    let matches = App::new(TITLE)
        .author(env!("CARGO_PKG_AUTHORS"))
        .version(env!("CARGO_PKG_VERSION"))
        .arg(
            Arg::with_name("colors")
                .takes_value(true)
                .help("The number of different colors")
                .default_value("6"),
        )
        .arg(
            Arg::with_name("size")
                .takes_value(true)
                .help("The height and width of the grid")
                .default_value("14"),
        )
        .get_matches();

    let colors = {
        let tmp: u8 = matches
            .value_of("colors")
            .and_then(|x| x.parse().ok())
            .unwrap_or(6);
        if tmp < 3 || tmp > 8 {
            panic!("Flood-It only supports 3 through 8 (inclusive) colors.");
        } else {
            tmp
        }
    };
    let size: u8 = {
        let tmp: u8 = matches
            .value_of("size")
            .and_then(|x| x.parse().ok())
            .unwrap_or(14);
        if tmp < 2 {
            panic!("Flood-It needs a grid of at least 2x2 cells.");
        } else {
            tmp
        }
    };

    let mut events_loop = EventsLoop::new();
    let window = WindowBuilder::new().with_title(TITLE);
    let context = ContextBuilder::new();
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    let program = glium::Program::from_source(&display, VERTEX_SHADER, FRAGMENT_SHADER, None)
        .unwrap();

    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let params = glium::DrawParameters {
        backface_culling: glium::draw_parameters::BackfaceCullingMode::CullCounterClockwise,
        ..Default::default()
    };

    let mut grid = Grid::new(colors, size);
    let grid_aspect_ratio = grid.aspect_ratio();

    let mut cursor_position = (0.0, 0.0);

    main_loop(|| {
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 1.0);
        let (width, height) = target.get_dimensions();
        let screen_aspect_ratio = height as f32 / width as f32;

        let (ratio_x, ratio_y) = if screen_aspect_ratio < grid_aspect_ratio {
            (screen_aspect_ratio, 1.0)
        } else {
            (1.0, screen_aspect_ratio.recip())
        };

        let uniforms =
            uniform! {
            matrix: [
                [ratio_x, 0.0, 0.0, 0.0],
                [0.0, -ratio_y, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0_f32],
            ]
        };

        let mut triangles = vec![];

        for i in 0..grid.cells.len() {
            let x = (i % grid.width as usize) as f32;
            let y = (i / grid.width as usize) as f32;

            let cell_size = 2.0 / grid.height.max(grid.width) as f32;

            let mut quad = generate_rectangle_vertices(
                x * cell_size - 1.0,
                y * cell_size - 1.0,
                (x + 1.0) * cell_size - 1.0,
                (y + 1.0) * cell_size - 1.0,
                grid.cells[i],
            );
            triangles.append(&mut quad);
        }

        let vertex_buffer = glium::VertexBuffer::new(&display, &triangles).unwrap();
        target
            .draw(&vertex_buffer, &indices, &program, &uniforms, &params)
            .unwrap();

        target.finish().unwrap();

        let mut closed = false;
        events_loop.poll_events(|event| match event {
            Event::WindowEvent { event, .. } => {
                match event {
                    WindowEvent::Closed => closed = true,
                    WindowEvent::MouseMoved { position, .. } =>
                        cursor_position = position,
                    WindowEvent::MouseInput {
                        state: glium::glutin::ElementState::Released,
                        button: glium::glutin::MouseButton::Left,
                        ..
                    } => {
                        let offsets = {
                            let offset = (width as f64 - height as f64).abs() / 2.0;
                            if screen_aspect_ratio < grid_aspect_ratio {
                                (offset, 0.0)
                            } else {
                                (0.0, offset)
                            }
                        };
                        if cursor_position.0 - offsets.0 >= 0.0 &&
                            cursor_position.1 - offsets.1 >= 0.0
                        {
                            let column = ((cursor_position.0 - offsets.0) * grid.width as f64 /
                                              (width as f64 - 2.0 * offsets.0))
                                .floor() as u8;
                            let row = ((cursor_position.1 - offsets.1) * grid.height as f64 /
                                           (height as f64 - 2.0 * offsets.1))
                                .floor() as u8;
                            if grid.click(row, column) {
                                    if grid.num_clicks <= grid.max_clicks {
                                        println!("You win! You used {} out of {} available moves.", grid.num_clicks, grid.max_clicks);
                                    } else {
                                        println!("You lose. You took {} moves but should have finished in {}.", grid.num_clicks, grid.max_clicks);
                                }
                            }
                        }
                    }
                    _ => (),
                }
            }
            _ => (),
        });
        !closed
    });
}

fn generate_rectangle_vertices(
    left: f32,
    bottom: f32,
    right: f32,
    top: f32,
    color: Color,
) -> Vec<Vertex> {
    let color = color as u32 as f32;
    vec![
        Vertex {
            color,
            position: [left, bottom],
        },
        Vertex {
            color,
            position: [right, bottom],
        },
        Vertex {
            color,
            position: [left, top],
        },
        Vertex {
            color,
            position: [right, bottom],
        },
        Vertex {
            color,
            position: [right, top],
        },
        Vertex {
            color,
            position: [left, top],
        },
    ]
}

fn main_loop<F: FnMut() -> bool>(mut callback: F) {
    use std::time::{Duration, Instant};
    use std::thread;

    let one_frame = Duration::new(0, 10 ^ 9 / FPS + 1);
    let mut last_frame = Instant::now();

    while callback() {
        let now = Instant::now();
        let remaining = one_frame.checked_sub(now - last_frame).unwrap_or_default();
        last_frame = now;
        thread::sleep(remaining);
    }
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	//route for get balance, accepts a public key, and a property identifier

	fn get_balance(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getfee(req: &mut Request) -> IronResult<Response> {

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("6").output().expect("failed");

		 let mut s = String::from_utf8(fee.stdout).unwrap();
    		s.pop();
		let mut response = Response::with((status::Ok, s));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

	Iron::new(router).http("localhost:3001").unwrap();
}
<commit_msg>form payload over api<commit_after>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

#[derive(Debug, Deserialize, Serialize)]
struct Payload {
	amount: String,
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.post("/getpayload", move |r: &mut Request| getfee(r), "getpayload");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	//route for get balance, accepts a public key, and a property identifier

	fn get_balance(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getpayload(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let payload: Payload = serde_json::from_str(&payload).unwrap();
		let payload = Command::new("omnicore-cli").arg("omni_createpayload_simplesend").arg("56").arg(payload.amount).output().expect("failed");

		let output = payload.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getfee(req: &mut Request) -> IronResult<Response> {

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("6").output().expect("failed");

		 let mut s = String::from_utf8(fee.stdout).unwrap();
    		s.pop();
		let mut response = Response::with((status::Ok, s));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

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


<commit_before>extern crate rust_guessing_game;

use std::old_io as io;
use std::rand;
use std::cmp::Ordering;

use rust_guessing_game::my_funcs;

#[cfg(not(test))]
fn main() {
    println!("Guess the magic number!");
    let magic_number = ( rand::random::<uint>() % 100u ) + 1u;
    loop {
        let input = io::stdin().read_line().ok().expect("That was bad input");
        let input_optoin_uint: Option<uint> = input.parse();
        let input_uint = match input_optoin_uint {
            Some(num) => num,
            None      => {
                println!("Please input a number");
                continue;
            }
        };
        match my_funcs::compare(input_uint, magic_number) {
            Ordering::Less    => println!("Guess higher."),
            Ordering::Greater => println!("Guess lower."),
            Ordering::Equal   => {
                println!("You win!");
                return
            },
        }
    }
}
<commit_msg>uint -> usize<commit_after>extern crate rust_guessing_game;

use std::old_io as io;
use std::rand;
use std::cmp::Ordering;

use rust_guessing_game::my_funcs;

#[cfg(not(test))]
fn main() {
    println!("Guess the magic number!");
    let magic_number = ( rand::random::<usize>() % 100u ) + 1u;
    loop {
        let input = io::stdin().read_line().ok().expect("That was bad input");
        let input_optoin_usize: Option<usize> = input.parse();
        let input_usize = match input_optoin_usize {
            Some(num) => num,
            None      => {
                println!("Please input a number");
                continue;
            }
        };
        match my_funcs::compare(input_usize, magic_number) {
            Ordering::Less    => println!("Guess higher."),
            Ordering::Greater => println!("Guess lower."),
            Ordering::Equal   => {
                println!("You win!");
                return
            },
        }
    }
}
<|endoftext|>


<commit_before>use clap::Clap;
use std::cmp::Ordering;
use std::fs::File;

fn normalize_col(col: &str) -> String {
    lazy_static::lazy_static! {
        static ref RE: regex::Regex = regex::Regex::new(r"\(.*?\)$").unwrap();
    }
    let mut col = RE
        .replace_all(col, "")
        .to_lowercase()
        .trim()
        .replace("(", "")
        .replace(")", "")
        .replace(" ", "_")
        .replace(".", "_")
        .replace("-", "_")
        .replace("/", "_")
        .replace("?", "")
        .replace(",", "_")
        .replace("&", "_")
        .replace("#", "");
    if !col.chars().next().map(char::is_alphabetic).unwrap_or(true) {
        col = format!("c_{}", col)
    }
    col
}

fn _create_table(db: &mut rusqlite::Connection, table_name: &str, cols: &[String]) {
    let create_columns = cols
        .iter()
        .map(|c| format!("{} varchar", c))
        .collect::<Vec<String>>()
        .join(", ");
    db.execute(
        &format!("CREATE TABLE {} ({})", table_name, create_columns),
        &[] as &[&dyn rusqlite::types::ToSql],
    )
    .unwrap();
}

fn _load_table_from_path(
    db: &mut rusqlite::Connection,
    table_name: &str,
    path: &str,
    delimiter: u8,
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
    let mut num_rows = 0;
    let f = File::open(path)?;
    let file_size = f.metadata().unwrap().len();
    let mut reader = csv::ReaderBuilder::new()
        .flexible(true)
        .delimiter(delimiter)
        .from_reader(f);

    let normalized_cols =
        reader
            .headers()?
            .iter()
            .map(normalize_col)
            .fold(vec![], |mut v, orig_col| {
                let mut col = orig_col.clone();
                let mut i = 1;
                while v.contains(&col) {
                    col = format!("{}_{}", orig_col, i);
                    i += 1
                }
                v.push(col);
                v
            });
    _create_table(db, table_name, &normalized_cols);

    let insert_query = format!(
        "INSERT INTO {} VALUES ({})",
        table_name,
        normalized_cols
            .iter()
            .map(|_| "?")
            .collect::<Vec<_>>()
            .join(", ")
    );
    let pb = indicatif::ProgressBar::new(file_size);
    pb.set_style(
        indicatif::ProgressStyle::default_bar()
            .template("[{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")
            .progress_chars("#>-"),
    );
    let mut records = reader.byte_records();
    let tx = db.transaction().unwrap();
    {
        let mut stmt = tx.prepare(&insert_query).expect("tx.prepare() failed");
        while let Some(row) = records.next() {
            let mut row = row?;
            match row.len().cmp(&normalized_cols.len()) {
                Ordering::Less => {
                    for _ in 0..normalized_cols.len() - row.len() {
                        row.push_field(b"");
                    }
                }
                Ordering::Greater => {
                    panic!("Too many fields on row {}, fields: {:?}", num_rows + 1, row);
                }
                Ordering::Equal => {}
            }
            stmt.execute(rusqlite::params_from_iter(
                row.iter().map(String::from_utf8_lossy),
            ))
            .unwrap();

            num_rows += 1;
            if num_rows % 10000 == 0 {
                pb.set_position(records.reader().position().byte())
            }
        }
    }
    tx.commit().unwrap();
    pb.finish();

    println!(
        "Loaded {} rows into {}({}) from {:?}",
        num_rows,
        table_name,
        normalized_cols.join(", "),
        path,
    );
    Ok(normalized_cols)
}

struct FromAnySqlType {
    value: String,
}

impl rusqlite::types::FromSql for FromAnySqlType {
    fn column_result(
        value: rusqlite::types::ValueRef<'_>,
    ) -> Result<FromAnySqlType, rusqlite::types::FromSqlError> {
        let result = match value {
            rusqlite::types::ValueRef::Null => "null".to_string(),
            rusqlite::types::ValueRef::Integer(v) => v.to_string(),
            rusqlite::types::ValueRef::Real(v) => v.to_string(),
            rusqlite::types::ValueRef::Blob(v) | rusqlite::types::ValueRef::Text(v) => {
                String::from_utf8(v.to_vec()).unwrap()
            }
        };
        Ok(FromAnySqlType { value: result })
    }
}

fn _prepare_query<'a>(
    conn: &'a mut rusqlite::Connection,
    query: &str,
) -> Result<rusqlite::Statement<'a>, String> {
    conn.prepare(query).map_err(|e| e.to_string())
}

fn _handle_query(conn: &mut rusqlite::Connection, line: &str) -> Result<(), String> {
    let mut stmt = _prepare_query(conn, line)?;

    let mut table = comfy_table::Table::new();
    table.load_preset("││──╞═╪╡┆    ┬┴┌┐└┘");
    table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
    let mut title_row = comfy_table::Row::new();
    for col in stmt.column_names() {
        title_row.add_cell(comfy_table::Cell::new(col));
    }
    table.set_header(title_row);

    let mut results = stmt.query(&[] as &[&dyn rusqlite::types::ToSql]).unwrap();
    while let Ok(Some(r)) = results.next() {
        let mut row = comfy_table::Row::new();
        for i in 0..r.column_count() {
            let cell: FromAnySqlType = r.get(i).unwrap();
            row.add_cell(comfy_table::Cell::new(&cell.value));
        }
        table.add_row(row);
    }
    println!("{}", table);
    Ok(())
}

fn _handle_export(conn: &mut rusqlite::Connection, line: &str) -> Result<(), String> {
    lazy_static::lazy_static! {
        static ref RE: regex::Regex = regex::Regex::new(r"^\.export\(([\w_\-\./]+)\) (.*)").unwrap();
    }
    let caps = RE
        .captures(line)
        .ok_or_else(|| "Must match `.export(file-name) SQL`".to_owned())?;
    let destination_path = &caps[1];
    let query = &caps[2];

    let mut stmt = _prepare_query(conn, query)?;

    let mut writer = csv::Writer::from_path(destination_path).map_err(|e| format!("{:?}", e))?;
    writer.write_record(stmt.column_names()).unwrap();

    let mut results = stmt.query(&[] as &[&dyn rusqlite::types::ToSql]).unwrap();
    while let Ok(Some(r)) = results.next() {
        writer
            .write_record((0..r.column_count()).map(|i| {
                let cell: FromAnySqlType = r.get(i).unwrap();
                cell.value
            }))
            .unwrap();
    }

    Ok(())
}

fn _process_query(conn: &mut rusqlite::Connection, line: &str) {
    let result = if line.starts_with(".export") {
        _handle_export(conn, line)
    } else if line.starts_with(".schema") {
        _handle_query(
            conn,
            "SELECT sql AS schema FROM sqlite_master WHERE name like 't%'",
        )
    } else {
        _handle_query(conn, line)
    };
    if let Err(e) = result {
        println!("{}", e);
    }
}

fn install_udfs(c: &mut rusqlite::Connection) -> Result<(), Box<dyn std::error::Error>> {
    c.create_scalar_function(
        "regexp_extract",
        3,
        rusqlite::functions::FunctionFlags::SQLITE_UTF8
            | rusqlite::functions::FunctionFlags::SQLITE_DETERMINISTIC,
        |ctx| {
            let re = ctx.get_or_create_aux(
                0,
                |vr| -> Result<_, Box<dyn std::error::Error + Send + Sync + 'static>> {
                    Ok(regex::Regex::new(vr.as_str()?)?)
                },
            )?;
            let value = ctx.get::<Box<str>>(1)?;
            let replacement = ctx.get::<Box<str>>(2)?;

            let caps = match re.captures(&value) {
                Some(caps) => caps,
                None => return Ok("".to_string()),
            };
            let mut dest = String::new();
            caps.expand(&replacement, &mut dest);
            Ok(dest)
        },
    )?;

    Ok(())
}

struct SimpleWordCompleter {
    words: Vec<String>,
}

static BREAK_CHARS: [u8; 5] = [b' ', b'(', b')', b',', b'.'];
impl SimpleWordCompleter {
    fn new(words: Vec<String>) -> SimpleWordCompleter {
        SimpleWordCompleter { words }
    }
}

impl rustyline::Helper for SimpleWordCompleter {}

impl rustyline::hint::Hinter for SimpleWordCompleter {
    type Hint = String;

    fn hint(&self, _line: &str, _pos: usize, _ctx: &rustyline::Context<'_>) -> Option<String> {
        None
    }
}

impl rustyline::highlight::Highlighter for SimpleWordCompleter {}

impl rustyline::validate::Validator for SimpleWordCompleter {}

impl rustyline::completion::Completer for SimpleWordCompleter {
    type Candidate = String;

    fn complete(
        &self,
        line: &str,
        pos: usize,
        _ctx: &rustyline::Context<'_>,
    ) -> rustyline::Result<(usize, Vec<String>)> {
        let (start, word) = rustyline::completion::extract_word(line, pos, None, &BREAK_CHARS);

        let matches = self
            .words
            .iter()
            .filter(|w| w.starts_with(word))
            .cloned()
            .collect();
        Ok((start, matches))
    }
}

#[derive(Clap)]
struct Opts {
    #[clap(long, about = "Use ',' as the delimiter for the CSV")]
    comma: bool,
    #[clap(long, about = "Use '|' as the delimiter for the CSV")]
    pipe: bool,
    #[clap(long, about = "Use '\\t' as the delimiter for the CSV")]
    tab: bool,
    #[clap(long, about = "Use ';' as the delimiter for the CSV")]
    semicolon: bool,

    #[clap()]
    paths: Vec<String>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let opts = Opts::parse();

    let delim = match (opts.comma, opts.pipe, opts.tab, opts.semicolon) {
        (true, false, false, false) | (false, false, false, false) => b',',
        (false, true, false, false) => b'|',
        (false, false, true, false) => b'\t',
        (false, false, false, true) => b';',
        _ => {
            eprintln!("Can't pass more than one of --comma, --pipe, and --tab");
            std::process::exit(1);
        }
    };

    let mut conn = rusqlite::Connection::open_in_memory().unwrap();

    let mut base_words = [
        // keywords
        "distinct",
        "select",
        "from",
        "group",
        "by",
        "order",
        "where",
        "count",
        "limit",
        "offset",
        // functions
        "length",
        "coalesce",
        "regexp_extract",
        // csv-sql commands
        "export",
        "schema",
    ]
    .iter()
    .map(|&s| s.to_string())
    .collect::<Vec<String>>();

    if opts.paths.len() == 1 {
        let mut col_names = _load_table_from_path(&mut conn, "t", &opts.paths[0], delim)?;
        base_words.append(&mut col_names);
    } else {
        for (idx, path) in opts.paths.iter().enumerate() {
            let mut col_names =
                _load_table_from_path(&mut conn, &format!("t{}", idx + 1), path, delim)?;
            base_words.append(&mut col_names);
        }
    }

    install_udfs(&mut conn)?;

    let completer = SimpleWordCompleter::new(base_words);
    let mut rl = rustyline::Editor::new();
    rl.set_helper(Some(completer));
    let history_path = dirs::home_dir().unwrap().join(".csv-sql-history");
    let _ = rl.load_history(&history_path);
    loop {
        match rl.readline("> ") {
            Ok(line) => {
                if line.trim().is_empty() {
                    continue;
                }
                _process_query(&mut conn, &line);
                rl.add_history_entry(line);
            }
            Err(rustyline::error::ReadlineError::Interrupted) => {
                println!("Interrupted");
                continue;
            }
            Err(rustyline::error::ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                println!("Error: {}", err);
                break;
            }
        }
    }
    rl.save_history(&history_path).unwrap();

    Ok(())
}

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

    #[test]
    fn test_normalize_col() {
        for (value, expected) in &[
            ("", ""),
            ("abc", "abc"),
            ("(S)AO", "sao"),
            ("abc (123)", "abc"),
            ("2/6/2000", "c_2_6_2000"),
            ("COMBO#", "combo"),
        ] {
            assert_eq!(&&normalize_col(value), expected);
        }
    }
}
<commit_msg>Handle colons in column names (#604)<commit_after>use clap::Clap;
use std::cmp::Ordering;
use std::fs::File;

fn normalize_col(col: &str) -> String {
    lazy_static::lazy_static! {
        static ref RE: regex::Regex = regex::Regex::new(r"\(.*?\)$").unwrap();
    }
    let mut col = RE
        .replace_all(col, "")
        .to_lowercase()
        .trim()
        .replace("(", "")
        .replace(")", "")
        .replace(" ", "_")
        .replace(".", "_")
        .replace("-", "_")
        .replace("/", "_")
        .replace("?", "")
        .replace(",", "_")
        .replace("&", "_")
        .replace(":", "")
        .replace("#", "");
    if !col.chars().next().map(char::is_alphabetic).unwrap_or(true) {
        col = format!("c_{}", col)
    }
    col
}

fn _create_table(db: &mut rusqlite::Connection, table_name: &str, cols: &[String]) {
    let create_columns = cols
        .iter()
        .map(|c| format!("{} varchar", c))
        .collect::<Vec<String>>()
        .join(", ");
    db.execute(
        &format!("CREATE TABLE {} ({})", table_name, create_columns),
        &[] as &[&dyn rusqlite::types::ToSql],
    )
    .unwrap();
}

fn _load_table_from_path(
    db: &mut rusqlite::Connection,
    table_name: &str,
    path: &str,
    delimiter: u8,
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
    let mut num_rows = 0;
    let f = File::open(path)?;
    let file_size = f.metadata().unwrap().len();
    let mut reader = csv::ReaderBuilder::new()
        .flexible(true)
        .delimiter(delimiter)
        .from_reader(f);

    let normalized_cols =
        reader
            .headers()?
            .iter()
            .map(normalize_col)
            .fold(vec![], |mut v, orig_col| {
                let mut col = orig_col.clone();
                let mut i = 1;
                while v.contains(&col) {
                    col = format!("{}_{}", orig_col, i);
                    i += 1
                }
                v.push(col);
                v
            });
    _create_table(db, table_name, &normalized_cols);

    let insert_query = format!(
        "INSERT INTO {} VALUES ({})",
        table_name,
        normalized_cols
            .iter()
            .map(|_| "?")
            .collect::<Vec<_>>()
            .join(", ")
    );
    let pb = indicatif::ProgressBar::new(file_size);
    pb.set_style(
        indicatif::ProgressStyle::default_bar()
            .template("[{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")
            .progress_chars("#>-"),
    );
    let mut records = reader.byte_records();
    let tx = db.transaction().unwrap();
    {
        let mut stmt = tx.prepare(&insert_query).expect("tx.prepare() failed");
        while let Some(row) = records.next() {
            let mut row = row?;
            match row.len().cmp(&normalized_cols.len()) {
                Ordering::Less => {
                    for _ in 0..normalized_cols.len() - row.len() {
                        row.push_field(b"");
                    }
                }
                Ordering::Greater => {
                    panic!("Too many fields on row {}, fields: {:?}", num_rows + 1, row);
                }
                Ordering::Equal => {}
            }
            stmt.execute(rusqlite::params_from_iter(
                row.iter().map(String::from_utf8_lossy),
            ))
            .unwrap();

            num_rows += 1;
            if num_rows % 10000 == 0 {
                pb.set_position(records.reader().position().byte())
            }
        }
    }
    tx.commit().unwrap();
    pb.finish();

    println!(
        "Loaded {} rows into {}({}) from {:?}",
        num_rows,
        table_name,
        normalized_cols.join(", "),
        path,
    );
    Ok(normalized_cols)
}

struct FromAnySqlType {
    value: String,
}

impl rusqlite::types::FromSql for FromAnySqlType {
    fn column_result(
        value: rusqlite::types::ValueRef<'_>,
    ) -> Result<FromAnySqlType, rusqlite::types::FromSqlError> {
        let result = match value {
            rusqlite::types::ValueRef::Null => "null".to_string(),
            rusqlite::types::ValueRef::Integer(v) => v.to_string(),
            rusqlite::types::ValueRef::Real(v) => v.to_string(),
            rusqlite::types::ValueRef::Blob(v) | rusqlite::types::ValueRef::Text(v) => {
                String::from_utf8(v.to_vec()).unwrap()
            }
        };
        Ok(FromAnySqlType { value: result })
    }
}

fn _prepare_query<'a>(
    conn: &'a mut rusqlite::Connection,
    query: &str,
) -> Result<rusqlite::Statement<'a>, String> {
    conn.prepare(query).map_err(|e| e.to_string())
}

fn _handle_query(conn: &mut rusqlite::Connection, line: &str) -> Result<(), String> {
    let mut stmt = _prepare_query(conn, line)?;

    let mut table = comfy_table::Table::new();
    table.load_preset("││──╞═╪╡┆    ┬┴┌┐└┘");
    table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
    let mut title_row = comfy_table::Row::new();
    for col in stmt.column_names() {
        title_row.add_cell(comfy_table::Cell::new(col));
    }
    table.set_header(title_row);

    let mut results = stmt.query(&[] as &[&dyn rusqlite::types::ToSql]).unwrap();
    while let Ok(Some(r)) = results.next() {
        let mut row = comfy_table::Row::new();
        for i in 0..r.column_count() {
            let cell: FromAnySqlType = r.get(i).unwrap();
            row.add_cell(comfy_table::Cell::new(&cell.value));
        }
        table.add_row(row);
    }
    println!("{}", table);
    Ok(())
}

fn _handle_export(conn: &mut rusqlite::Connection, line: &str) -> Result<(), String> {
    lazy_static::lazy_static! {
        static ref RE: regex::Regex = regex::Regex::new(r"^\.export\(([\w_\-\./]+)\) (.*)").unwrap();
    }
    let caps = RE
        .captures(line)
        .ok_or_else(|| "Must match `.export(file-name) SQL`".to_owned())?;
    let destination_path = &caps[1];
    let query = &caps[2];

    let mut stmt = _prepare_query(conn, query)?;

    let mut writer = csv::Writer::from_path(destination_path).map_err(|e| format!("{:?}", e))?;
    writer.write_record(stmt.column_names()).unwrap();

    let mut results = stmt.query(&[] as &[&dyn rusqlite::types::ToSql]).unwrap();
    while let Ok(Some(r)) = results.next() {
        writer
            .write_record((0..r.column_count()).map(|i| {
                let cell: FromAnySqlType = r.get(i).unwrap();
                cell.value
            }))
            .unwrap();
    }

    Ok(())
}

fn _process_query(conn: &mut rusqlite::Connection, line: &str) {
    let result = if line.starts_with(".export") {
        _handle_export(conn, line)
    } else if line.starts_with(".schema") {
        _handle_query(
            conn,
            "SELECT sql AS schema FROM sqlite_master WHERE name like 't%'",
        )
    } else {
        _handle_query(conn, line)
    };
    if let Err(e) = result {
        println!("{}", e);
    }
}

fn install_udfs(c: &mut rusqlite::Connection) -> Result<(), Box<dyn std::error::Error>> {
    c.create_scalar_function(
        "regexp_extract",
        3,
        rusqlite::functions::FunctionFlags::SQLITE_UTF8
            | rusqlite::functions::FunctionFlags::SQLITE_DETERMINISTIC,
        |ctx| {
            let re = ctx.get_or_create_aux(
                0,
                |vr| -> Result<_, Box<dyn std::error::Error + Send + Sync + 'static>> {
                    Ok(regex::Regex::new(vr.as_str()?)?)
                },
            )?;
            let value = ctx.get::<Box<str>>(1)?;
            let replacement = ctx.get::<Box<str>>(2)?;

            let caps = match re.captures(&value) {
                Some(caps) => caps,
                None => return Ok("".to_string()),
            };
            let mut dest = String::new();
            caps.expand(&replacement, &mut dest);
            Ok(dest)
        },
    )?;

    Ok(())
}

struct SimpleWordCompleter {
    words: Vec<String>,
}

static BREAK_CHARS: [u8; 5] = [b' ', b'(', b')', b',', b'.'];
impl SimpleWordCompleter {
    fn new(words: Vec<String>) -> SimpleWordCompleter {
        SimpleWordCompleter { words }
    }
}

impl rustyline::Helper for SimpleWordCompleter {}

impl rustyline::hint::Hinter for SimpleWordCompleter {
    type Hint = String;

    fn hint(&self, _line: &str, _pos: usize, _ctx: &rustyline::Context<'_>) -> Option<String> {
        None
    }
}

impl rustyline::highlight::Highlighter for SimpleWordCompleter {}

impl rustyline::validate::Validator for SimpleWordCompleter {}

impl rustyline::completion::Completer for SimpleWordCompleter {
    type Candidate = String;

    fn complete(
        &self,
        line: &str,
        pos: usize,
        _ctx: &rustyline::Context<'_>,
    ) -> rustyline::Result<(usize, Vec<String>)> {
        let (start, word) = rustyline::completion::extract_word(line, pos, None, &BREAK_CHARS);

        let matches = self
            .words
            .iter()
            .filter(|w| w.starts_with(word))
            .cloned()
            .collect();
        Ok((start, matches))
    }
}

#[derive(Clap)]
struct Opts {
    #[clap(long, about = "Use ',' as the delimiter for the CSV")]
    comma: bool,
    #[clap(long, about = "Use '|' as the delimiter for the CSV")]
    pipe: bool,
    #[clap(long, about = "Use '\\t' as the delimiter for the CSV")]
    tab: bool,
    #[clap(long, about = "Use ';' as the delimiter for the CSV")]
    semicolon: bool,

    #[clap()]
    paths: Vec<String>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let opts = Opts::parse();

    let delim = match (opts.comma, opts.pipe, opts.tab, opts.semicolon) {
        (true, false, false, false) | (false, false, false, false) => b',',
        (false, true, false, false) => b'|',
        (false, false, true, false) => b'\t',
        (false, false, false, true) => b';',
        _ => {
            eprintln!("Can't pass more than one of --comma, --pipe, and --tab");
            std::process::exit(1);
        }
    };

    let mut conn = rusqlite::Connection::open_in_memory().unwrap();

    let mut base_words = [
        // keywords
        "distinct",
        "select",
        "from",
        "group",
        "by",
        "order",
        "where",
        "count",
        "limit",
        "offset",
        // functions
        "length",
        "coalesce",
        "regexp_extract",
        // csv-sql commands
        "export",
        "schema",
    ]
    .iter()
    .map(|&s| s.to_string())
    .collect::<Vec<String>>();

    if opts.paths.len() == 1 {
        let mut col_names = _load_table_from_path(&mut conn, "t", &opts.paths[0], delim)?;
        base_words.append(&mut col_names);
    } else {
        for (idx, path) in opts.paths.iter().enumerate() {
            let mut col_names =
                _load_table_from_path(&mut conn, &format!("t{}", idx + 1), path, delim)?;
            base_words.append(&mut col_names);
        }
    }

    install_udfs(&mut conn)?;

    let completer = SimpleWordCompleter::new(base_words);
    let mut rl = rustyline::Editor::new();
    rl.set_helper(Some(completer));
    let history_path = dirs::home_dir().unwrap().join(".csv-sql-history");
    let _ = rl.load_history(&history_path);
    loop {
        match rl.readline("> ") {
            Ok(line) => {
                if line.trim().is_empty() {
                    continue;
                }
                _process_query(&mut conn, &line);
                rl.add_history_entry(line);
            }
            Err(rustyline::error::ReadlineError::Interrupted) => {
                println!("Interrupted");
                continue;
            }
            Err(rustyline::error::ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                println!("Error: {}", err);
                break;
            }
        }
    }
    rl.save_history(&history_path).unwrap();

    Ok(())
}

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

    #[test]
    fn test_normalize_col() {
        for (value, expected) in &[
            ("", ""),
            ("abc", "abc"),
            ("(S)AO", "sao"),
            ("abc (123)", "abc"),
            ("2/6/2000", "c_2_6_2000"),
            ("COMBO#", "combo"),
        ] {
            assert_eq!(&&normalize_col(value), expected);
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate osciemu;

use std::io;
use osciemu::utils::{load_file};
use osciemu::memory::{Memory, SliceMemory};
use osciemu::emulator::Emulator;
use osciemu::loader::{hexloader, rawloader};

fn main() {
    let matches = clap_app!(myapp =>
            (version: "0.1.0")
            (author: "Surma <surma@surma.link>")
            (about: "Emulates an osci CPU")
            (@arg IMAGE: -i --image +takes_value "Image to load into memory")
            (@arg BIOS: -b --bios +required +takes_value "BIOS to load")
            (@arg STEP: --step "Walk through in stepping mode")
            (@arg MAX_STEP: --maxstep +takes_value "Maximum number of CPU cycles (0 means infinite)")
        )
        .get_matches();

    let max_steps = matches.value_of("MAX_STEP")
                        .map(|s| {
                            s.parse::<usize>()
                                .expect("--max-step needs to be a number")
                        })
                        .unwrap_or(0);

    let image_mem = matches.value_of("IMAGE")
                            .ok_or(io::Error::new(io::ErrorKind::Other, "Parameter not specified"))
                            .and_then(load_file)
                            .unwrap_or_else(|_err| Box::new(SliceMemory::new(0)));

    let bios_mem = matches.value_of("BIOS")
                            .ok_or(io::Error::new(io::ErrorKind::Other, "Parameter not specified"))
                            .and_then(load_file)
                            .expect("Could not load bios");

    let step_mode = matches.is_present("STEP");

    let mut emulator = Emulator::new(image_mem, bios_mem);

    println!("FLAGS_START_ADDRESS = 0x{:08X}", osciemu::memory::address::FLAGS_START_ADDRESS);
    println!("IVT_START_ADDRESS = 0x{:08X}", osciemu::memory::address::IVT_START_ADDRESS);
    println!("REGISTERS_START_ADDRESS = 0x{:08X}", osciemu::memory::address::REGISTERS_START_ADDRESS);
    println!("STACK_POINTER_ADDRESS = 0x{:08X}", osciemu::memory::address::STACK_POINTER_ADDRESS);

    for _count in RangeIterator::new(0, max_steps) {
        if emulator.is_halted() {
            break;
        }
        println!("ip: 0x{:08X}, r0: 0x{:08X}, r1: 0x{:08X}, r2: 0x{:08X}, r3: \
                  0x{:08X}",
                 emulator.ip,
                 emulator.get_register(0),
                 emulator.get_register(1),
                 emulator.get_register(2),
                 emulator.get_register(3));
        emulator.step();
        if step_mode {
            let mut buffer = String::new();
            let _ = io::stdin().read_line(&mut buffer);
        }
    }
    if !emulator.is_halted() {
        std::process::exit(1);
    }
}

struct RangeIterator {
    count: usize,
    max: usize
}

impl RangeIterator {
    fn new(start: usize, max: usize) -> RangeIterator {
        RangeIterator {
            count: start,
            max,
        }
    }
}

impl Iterator for RangeIterator {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        if self.count == self.max && self.max != 0 {
            return None;
        }
        let result = Some(self.count);
        if self.count != std::usize::MAX {
            self.count = self.count + 1;
        }
        result
    }
}
<commit_msg>Revert "feat(osci-cli): Don’t show instruction counter"<commit_after>#[macro_use]
extern crate clap;
extern crate osciemu;

use std::io;
use osciemu::utils::{load_file};
use osciemu::memory::{Memory, SliceMemory};
use osciemu::emulator::Emulator;
use osciemu::loader::{hexloader, rawloader};

fn main() {
    let matches = clap_app!(myapp =>
            (version: "0.1.0")
            (author: "Surma <surma@surma.link>")
            (about: "Emulates an osci CPU")
            (@arg IMAGE: -i --image +takes_value "Image to load into memory")
            (@arg BIOS: -b --bios +required +takes_value "BIOS to load")
            (@arg STEP: --step "Walk through in stepping mode")
            (@arg MAX_STEP: --maxstep +takes_value "Maximum number of CPU cycles (0 means infinite)")
        )
        .get_matches();

    let max_steps = matches.value_of("MAX_STEP")
                        .map(|s| {
                            s.parse::<usize>()
                                .expect("--max-step needs to be a number")
                        })
                        .unwrap_or(0);

    let image_mem = matches.value_of("IMAGE")
                            .ok_or(io::Error::new(io::ErrorKind::Other, "Parameter not specified"))
                            .and_then(load_file)
                            .unwrap_or_else(|_err| Box::new(SliceMemory::new(0)));

    let bios_mem = matches.value_of("BIOS")
                            .ok_or(io::Error::new(io::ErrorKind::Other, "Parameter not specified"))
                            .and_then(load_file)
                            .expect("Could not load bios");

    let step_mode = matches.is_present("STEP");

    let mut emulator = Emulator::new(image_mem, bios_mem);

    println!("FLAGS_START_ADDRESS = 0x{:08X}", osciemu::memory::address::FLAGS_START_ADDRESS);
    println!("IVT_START_ADDRESS = 0x{:08X}", osciemu::memory::address::IVT_START_ADDRESS);
    println!("REGISTERS_START_ADDRESS = 0x{:08X}", osciemu::memory::address::REGISTERS_START_ADDRESS);
    println!("STACK_POINTER_ADDRESS = 0x{:08X}", osciemu::memory::address::STACK_POINTER_ADDRESS);

    for count in RangeIterator::new(0, max_steps) {
        if emulator.is_halted() {
            break;
        }
        println!("count: {:4}, ip: 0x{:08X}, r0: 0x{:08X}, r1: 0x{:08X}, r2: 0x{:08X}, r3: \
                  0x{:08X}",
                 count,
                 emulator.ip,
                 emulator.get_register(0),
                 emulator.get_register(1),
                 emulator.get_register(2),
                 emulator.get_register(3));
        emulator.step();
        if step_mode {
            let mut buffer = String::new();
            let _ = io::stdin().read_line(&mut buffer);
        }
    }
    if !emulator.is_halted() {
        std::process::exit(1);
    }
}

struct RangeIterator {
    count: usize,
    max: usize
}

impl RangeIterator {
    fn new(start: usize, max: usize) -> RangeIterator {
        RangeIterator {
            count: start,
            max,
        }
    }
}

impl Iterator for RangeIterator {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        if self.count == self.max && self.max != 0 {
            return None;
        }
        let result = Some(self.count);
        if self.count != std::usize::MAX {
            self.count = self.count + 1;
        }
        result
    }
}
<|endoftext|>


<commit_before>use core::iter::Repeat;
use std::io::BufferedReader;
use std::io::stdio::StdReader;

pub struct Tape {
    content: Vec<u8>,
    pointer: uint
}

impl Tape {
    pub fn new() -> Tape {
        Tape {
            content: Repeat::new(0u8).take(30_000u).collect(),
            pointer: 0,
        }
    }

    pub fn inc(&mut self) {
        *self.content.get_mut(self.pointer) += 1u8;
    }

    pub fn dec(&mut self) {
        *self.content.get_mut(self.pointer) -= 1u8;
    }

    pub fn next(&mut self) {
        self.pointer += 1;
    }

    pub fn prev(&mut self) {
        self.pointer -= 1;
    }

    pub fn char_value(&mut self) -> char {
        self.content[self.pointer] as char
    }

    pub fn value(&mut self) -> u8 {
        self.content[self.pointer]
    }

    pub fn read_value(&mut self, reader: &mut BufferedReader<StdReader>) {
        let value = reader.read_char().ok().unwrap() as u8;
        self.set_value(value)
    }

    fn set_value(&mut self, value: u8) {
        *self.content.get_mut(self.pointer) = value;
    }
}
<commit_msg>Remove extra space<commit_after>use core::iter::Repeat;
use std::io::BufferedReader;
use std::io::stdio::StdReader;

pub struct Tape {
    content: Vec<u8>,
    pointer: uint
}

impl Tape {
    pub fn new() -> Tape {
        Tape {
            content: Repeat::new(0u8).take(30_000u).collect(),
            pointer: 0,
        }
    }

    pub fn inc(&mut self) {
        *self.content.get_mut(self.pointer) += 1u8;
    }

    pub fn dec(&mut self) {
        *self.content.get_mut(self.pointer) -= 1u8;
    }

    pub fn next(&mut self) {
        self.pointer += 1;
    }

    pub fn prev(&mut self) {
        self.pointer -= 1;
    }

    pub fn char_value(&mut self) -> char {
        self.content[self.pointer] as char
    }

    pub fn value(&mut self) -> u8 {
        self.content[self.pointer]
    }

    pub fn read_value(&mut self, reader: &mut BufferedReader<StdReader>) {
        let value = reader.read_char().ok().unwrap() as u8;
        self.set_value(value)
    }

    fn set_value(&mut self, value: u8) {
        *self.content.get_mut(self.pointer) = value;
    }
}
<|endoftext|>


<commit_before>//! Math related constants

// taken from https://en.wikipedia.org/wiki/Mathematical_constants_and_functions

// also nice: http://www.ebyte.it/library/educards/constants/MathConstants.html

pub const golden_ratio: f64 = 1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475;
pub const euler_mascheroni: f64 = 0.577215664901532860606512090082402431042159335939923598805767234884867726777664670936947063291746749;
pub const meissel_mertens: f64 = 0.261497212847642783755426838608695859051566648261199206192064213924924510897368209714142631434246651051617;
pub const bernstein: f64 =  0.28016949902386913303643649123067200004248213981236;
pub const inverse_pi: f64 = 0.318309886183790671537767526745028724068919291480912897495334688117793595268453070180227605532506171;
pub const chebyshev: f64 = 0.5901702995080481130226689702792442936168583174407236497579321997021520903603578974892293080979039771;
pub const fibonaci: f64 = 1.22674201072035324441763023045536165587140969044025041964329730121402213831531216845262156249479774125913;
pub const hermite: f64 = 0.1547005383792515290182975610039149112952035025402537520372046529679553446058666913874307911714990504504;
<commit_msg>Add more math constants<commit_after>//! Math related constants

// taken from https://en.wikipedia.org/wiki/Mathematical_constants_and_functions

// also nice: http://www.ebyte.it/library/educards/constants/MathConstants.html

pub const golden_ratio: f64 = 1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475;
pub const euler_mascheroni: f64 = 0.577215664901532860606512090082402431042159335939923598805767234884867726777664670936947063291746749;
pub const meissel_mertens: f64 = 0.261497212847642783755426838608695859051566648261199206192064213924924510897368209714142631434246651051617;
pub const bernstein: f64 =  0.28016949902386913303643649123067200004248213981236;
pub const inverse_pi: f64 = 0.318309886183790671537767526745028724068919291480912897495334688117793595268453070180227605532506171;
pub const chebyshev: f64 = 0.5901702995080481130226689702792442936168583174407236497579321997021520903603578974892293080979039771;
pub const fibonaci: f64 = 1.22674201072035324441763023045536165587140969044025041964329730121402213831531216845262156249479774125913;
pub const hermite: f64 = 0.1547005383792515290182975610039149112952035025402537520372046529679553446058666913874307911714990504504;

// Named real math constants
pub const alladi_grinstead: f64 = 0.809394020540639130717931;
pub const apery: f64 = 1.202056903159594285399738;
pub const artin: f64 = 0.373955813619202288054728;
pub const backhouse: f64 = 1.456074948582689671399595;
pub const barban: f64 = 2.596536290450542073632740;
pub const besicovitch: f64 = 0.149162536496481100121144;
pub const blazy: f64 = 2.566543832171388844467529;
pub const boling: f64 = 1.805917418986691013997505;
pub const bruns_twin_primes: f64 = 1.902160583104;
pub const buffon: f64 = 0.636619772367581343075535;
pub const cahen: f64 = 0.643410546288338026182254;
pub const catalan: f64 = 0.915965594177219015054603;
pub const champernowne: f64 = 0.123456789101112131415161;
pub const copeland_erdos: f64 = 0.235711131719232931374143;
pub const conway: f64 = 1.303577269034296391257099;
pub const delian: f64 = 1.259921049894873164767210;
pub const dottie: f64 = 0.739085133215160641655312;
pub const efimov: f64 = 22.694382595366695192860217;
pub const embree_trefethen: f64 = 0.70258;
pub const erdos_borwein: f64 = 1.606695152415291763783301;
pub const feigenbaum_reduction_parameter: f64 = -2.502907875095892822283902;
pub const feller_tornier: f64 = 0.661317049469622335289765;
pub const feigenbaum_bifurcation_velocity: f64 = 0.661317049469622335289765;
pub const flajolet_odlyzko: f64 = 0.757823011268492837742175;
pub const foias: f64 = 1.187452351126501054595480;
pub const foias_ewing: f64 = 2.293166287411861031508028;
pub const fransen_robinson: f64 = 2.807770242028519365221501;
pub const gauss_kuzmin_wirsing: f64 = 0.303663002898732658597448;
pub const gelfond: f64 = 23.140692632779269005729086;
pub const gelfond_schneider: f64 = 2.665144142690225188650297;
pub const gibbs: f64 = 1.851937051982466170361053;
pub const wilbraham_gibbs: f64 = 1.178979744472167270232028;
pub const gieseking: f64 = 1.014941606409653625021202;
pub const glaisher_kinkelin: f64 = 1.282427129100622636875342;
pub const kinkelin: f64 = -0.165421143700450929213919;
pub const golomb_dickman: f64 = 0.624329988543550870992936;
pub const gompertz: f64 = 0.596347362323194074341078;
pub const graham: f64 = 0.783591464262726575401950;
pub const grossmann: f64 = 0.73733830336929;
pub const heat_brown_morotz: f64 = 0.001317641154853178109817;
pub const kempner_mahler_number: f64 = 0.816421509021893143708079;
pub const khinchin: f64 = 2.685452001065306445309714;
pub const khinchin_levy: f64 = 1.186569110415625452821722;
pub const levy: f64 = 3.275822918721811159787681;
pub const knuths_random_generators: f64 = 0.211324865405187117745425;
pub const kolakoski: f64 = 0.794507192779479276240362;
pub const komornik_loreti: f64 = 1.787231650182965933013274;
pub const landau_ramanujan: f64 = 0.764223653589220662990698;
pub const lagrange_numbers: f64 = 2.973213749463701104522401;
pub const laplace_limit: f64 = 0.662743419349181580974742;
pub const liebs_sqaure_ice: f64 = 1.539600717839002038691063;
pub const liouville: f64 = 0.110001000000000000000001;
pub const loch: f64 = 0.970270114392033925740256;
pub const madelung: f64 = -1.747564594633182190636212;
pub const meissel_merten: f64 = 0.261497212847642783755426;
pub const mills: f64 = 1.306377883863080690468614;
pub const minkowski_bower: f64 = 0.420372339423223075640993;
pub const mrb: f64 = 0.187859642462067120248517;
pub const murata: f64 = 2.826419997067591575546391;
pub const niven: f64 = 1.705211140105367764288551;
pub const norton: f64 = 0.065351425923037321378782;
pub const odlyzko_wilf: f64 = 1.622270502884767315956950;
pub const omega: f64 = 0.567143290409783872999968;
pub const otter: f64 = 2.955765285651994974714817;
pub const plouffe: f64 = 0.147583617650433274175401;
pub const pogson: f64 = 2.511886431509580111085032;
pub const polyas_random_walk: f64 = 0.340537329550999142826273;
pub const porter: f64 = 1.467078079433975472897798;
pub const prevost: f64 = 3.359885666243177553172011;
pub const prince_ruperts_cube: f64 = 1.060660171779821286601266;
pub const renyis_parking: f64 = 0.747597920253411435178730;
pub const salem_number: f64 = 1.176280818259917506544070;
pub const sarnak: f64 = 0.723648402298200009408849;
pub const schwarzschild: f64 = 7.389056098930650227230427;
pub const shall_wilson: f64 = 0.660161815846869573927812;
pub const sierpinski: f64 = 0.822825249678847032995328;
pub const soldner: f64 = 1.451369234883381050283968;
pub const somos_quadratic_reference: f64 = 1.661687949633594121295818;
pub const taniguchie: f64 = 0.678234491917391978035538;
pub const theodorus: f64 = 1.732050807568877293527446;
pub const thue_morse: f64 = 0.412454033640107597783361;
pub const viswanath: f64 = 1.1319882487943;
pub const walli: f64 = 2.094551481542326591482386;
pub const weierstrass: f64 = 0.474949379987920650332504;
pub const wyler: f64 = 0.007297348130031832128956;
pub const zagier: f64 = 0.180717104711806478057792;
pub const zolotarev: f64 = 0.311078866704819209027546;
<|endoftext|>