<commit_before>// Copyright 2016 Alex Crawford
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate clap;
extern crate hyper;
extern crate hyper_rustls;
extern crate pulldown_cmark;
extern crate rayon;
extern crate url;
extern crate walkdir;

mod document;
mod error;

use clap::{Arg, App};
use document::{Document, Error, Event};
use error::{DocumentError, DocumentLocation, LinkError, LocatedDocumentError};
use hyper::client::Client;
use hyper::header::UserAgent;
use hyper::net::HttpsConnector;
use hyper::status::StatusCode;
use hyper_rustls::TlsClient;
use rayon::prelude::*;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::File;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::exit;
use std::sync::Arc;
use url::{ParseError, Url};
use walkdir::WalkDir;

macro_rules! fail {
    ($($print:expr),+) => {
        {
            let _ = writeln!(&mut std::io::stderr(), $($print),+);
            exit(1);
        }
    };
}

macro_rules! printerror {
    ($error:expr, $flag:expr) => {
        {
            println!("{}", $error);
            $flag = true;
        }
    };
}

struct LinkContext {
    target: String,
    text: String,
    line: usize,
    file: PathBuf,
}

impl LinkContext {
    fn new_error(self, error: LinkError) -> LocatedDocumentError {
        LocatedDocumentError {
            location: DocumentLocation {
                path: self.file,
                line: self.line,
            },
            error: DocumentError::Link {
                text: self.text,
                target: self.target,
                error: error,
            },
        }
    }
}

fn main() {
    let matches = App::new("Marker")
        .version(crate_version!())
        .arg(Arg::with_name("root")
            .short("r")
            .long("root")
            .help("The path to the root of the documentation to be checked")
            .takes_value(true))
        .arg(Arg::with_name("skip-http")
            .long("skip-http")
            .help("Skip validation of HTTP[S] URLs"))
        .get_matches();

    let skip_http = matches.is_present("skip-http");
    let root = Path::new(matches.value_of("root").unwrap_or("."));
    let mut links = Vec::new();
    let mut found_error = false;

    for entry in WalkDir::new(root).into_iter().filter_map(|entry| {
        let entry = entry.unwrap_or_else(|error| {
            fail!("Failed to walk directory: {}", error);
        });
        if entry.file_type().is_file() && entry.path().extension() == Some(OsStr::new("md")) {
            Some(entry)
        } else {
            None
        }
    }) {
        let contents = {
            let mut file = File::open(entry.path()).unwrap_or_else(|error| {
                fail!("Failed to open file ({}): {}",
                      entry.path().display(),
                      error);
            });
            let mut text = String::new();
            if let Err(error) = file.read_to_string(&mut text) {
                fail!("Failed to read file ({}): {}",
                      entry.path().display(),
                      error);
            };
            text
        };

        for event in Document::new(&contents) {
            match event.event {
                Event::Link { target, text } => {
                    links.push(LinkContext {
                        target: target,
                        text: text,
                        line: event.line,
                        file: entry.path().to_path_buf(),
                    })
                }
                Event::Error(Error::ReferenceBroken { target, text }) => {
                    printerror!(LinkContext {
                                        target: target,
                                        text: text,
                                        line: event.line,
                                        file: entry.path().to_path_buf(),
                                    }
                                    .new_error(LinkError::ReferenceBroken),
                                found_error)
                }
            }
        }
    }

    let mut urls = HashMap::new();
    for link in links {
        match Url::parse(&link.target) {
            Ok(_) if skip_http => {}
            Ok(mut url) => {
                url.set_fragment(None);
                urls.entry(url).or_insert(Vec::new()).push(link)
            }
            Err(ParseError::RelativeUrlWithoutBase) => {
                if let Err(error) = check_path(&link.target, &link.file) {
                    printerror!(link.new_error(error), found_error)
                }
            }
            Err(error) => printerror!(link.new_error(LinkError::UrlMalformed(error)), found_error),
        }
    }

    for (result, links) in urls.into_par_iter()
        .map(|(url, links)| (check_url(url), links))
        .collect::<Vec<_>>() {
        if let Err(error) = result {
            for link in links {
                printerror!(link.new_error(error.clone()), found_error)
            }
        }
    }

    if found_error {
        exit(1)
    }
}

fn check_url(url: Url) -> Result<(), LinkError> {
    if url.scheme() != "http" && url.scheme() != "https" {
        return Ok(());
    }

    let client = Client::with_connector(HttpsConnector::new(TlsClient::new()));
    let agent = UserAgent(format!("marker/{}", crate_version!()));

    let res = client.head(url.clone()).header(agent.clone()).send().and_then(|resp| {
        if resp.status == StatusCode::MethodNotAllowed {
            client.get(url.clone()).header(agent.clone()).send()
        } else {
            Ok(resp)
        }
    });
    match res {
        Ok(resp) => {
            match resp.status {
                StatusCode::Ok => Ok(()),
                status => Err(LinkError::HttpStatus(status)),
            }
        }
        Err(error) => return Err(LinkError::HttpError(Arc::new(error))),
    }
}

fn check_path(target: &str, file: &Path) -> Result<(), LinkError> {
    let path = Path::new(OsStr::new(target.split('#').next().expect("string")));
    if path.is_absolute() {
        Err(LinkError::PathAbsolute)
    } else if !file.parent().expect("non-root file path").join(path).exists() {
        Err(LinkError::PathNonExistant)
    } else {
        Ok(())
    }
}
<commit_msg>main: apply new rustfmt rules<commit_after>// Copyright 2016 Alex Crawford
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate clap;
extern crate hyper;
extern crate hyper_rustls;
extern crate pulldown_cmark;
extern crate rayon;
extern crate url;
extern crate walkdir;

mod document;
mod error;

use clap::{Arg, App};
use document::{Document, Error, Event};
use error::{DocumentError, DocumentLocation, LinkError, LocatedDocumentError};
use hyper::client::Client;
use hyper::header::UserAgent;
use hyper::net::HttpsConnector;
use hyper::status::StatusCode;
use hyper_rustls::TlsClient;
use rayon::prelude::*;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::File;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::exit;
use std::sync::Arc;
use url::{ParseError, Url};
use walkdir::WalkDir;

macro_rules! fail {
    ($($print:expr),+) => {
        {
            let _ = writeln!(&mut std::io::stderr(), $($print),+);
            exit(1);
        }
    };
}

macro_rules! printerror {
    ($error:expr, $flag:expr) => {
        {
            println!("{}", $error);
            $flag = true;
        }
    };
}

struct LinkContext {
    target: String,
    text: String,
    line: usize,
    file: PathBuf,
}

impl LinkContext {
    fn new_error(self, error: LinkError) -> LocatedDocumentError {
        LocatedDocumentError {
            location: DocumentLocation {
                path: self.file,
                line: self.line,
            },
            error: DocumentError::Link {
                text: self.text,
                target: self.target,
                error: error,
            },
        }
    }
}

fn main() {
    let matches = App::new("Marker")
        .version(crate_version!())
        .arg(Arg::with_name("root")
            .short("r")
            .long("root")
            .help("The path to the root of the documentation to be checked")
            .takes_value(true))
        .arg(Arg::with_name("skip-http")
            .long("skip-http")
            .help("Skip validation of HTTP[S] URLs"))
        .get_matches();

    let skip_http = matches.is_present("skip-http");
    let root = Path::new(matches.value_of("root").unwrap_or("."));
    let mut links = Vec::new();
    let mut found_error = false;

    for entry in WalkDir::new(root).into_iter().filter_map(|entry| {
        let entry = entry.unwrap_or_else(|error| {
            fail!("Failed to walk directory: {}", error);
        });
        if entry.file_type().is_file() && entry.path().extension() == Some(OsStr::new("md")) {
            Some(entry)
        } else {
            None
        }
    }) {
        let contents = {
            let mut file = File::open(entry.path()).unwrap_or_else(|error| {
                fail!("Failed to open file ({}): {}",
                      entry.path().display(),
                      error);
            });
            let mut text = String::new();
            if let Err(error) = file.read_to_string(&mut text) {
                fail!("Failed to read file ({}): {}",
                      entry.path().display(),
                      error);
            };
            text
        };

        for event in Document::new(&contents) {
            match event.event {
                Event::Link { target, text } => {
                    links.push(LinkContext {
                        target: target,
                        text: text,
                        line: event.line,
                        file: entry.path().to_path_buf(),
                    })
                }
                Event::Error(Error::ReferenceBroken { target, text }) => {
                    printerror!(LinkContext {
                                        target: target,
                                        text: text,
                                        line: event.line,
                                        file: entry.path().to_path_buf(),
                                    }
                                    .new_error(LinkError::ReferenceBroken),
                                found_error)
                }
            }
        }
    }

    let mut urls = HashMap::new();
    for link in links {
        match Url::parse(&link.target) {
            Ok(_) if skip_http => {}
            Ok(mut url) => {
                url.set_fragment(None);
                urls.entry(url).or_insert(Vec::new()).push(link)
            }
            Err(ParseError::RelativeUrlWithoutBase) => {
                if let Err(error) = check_path(&link.target, &link.file) {
                    printerror!(link.new_error(error), found_error)
                }
            }
            Err(error) => printerror!(link.new_error(LinkError::UrlMalformed(error)), found_error),
        }
    }

    for (result, links) in urls.into_par_iter()
        .map(|(url, links)| (check_url(url), links))
        .collect::<Vec<_>>() {
        if let Err(error) = result {
            for link in links {
                printerror!(link.new_error(error.clone()), found_error)
            }
        }
    }

    if found_error {
        exit(1)
    }
}

fn check_url(url: Url) -> Result<(), LinkError> {
    if url.scheme() != "http" && url.scheme() != "https" {
        return Ok(());
    }

    let client = Client::with_connector(HttpsConnector::new(TlsClient::new()));
    let agent = UserAgent(format!("marker/{}", crate_version!()));

    let res = client.head(url.clone())
        .header(agent.clone())
        .send()
        .and_then(|resp| if resp.status == StatusCode::MethodNotAllowed {
            client.get(url.clone()).header(agent.clone()).send()
        } else {
            Ok(resp)
        });
    match res {
        Ok(resp) => {
            match resp.status {
                StatusCode::Ok => Ok(()),
                status => Err(LinkError::HttpStatus(status)),
            }
        }
        Err(error) => return Err(LinkError::HttpError(Arc::new(error))),
    }
}

fn check_path(target: &str, file: &Path) -> Result<(), LinkError> {
    let path = Path::new(OsStr::new(target.split('#').next().expect("string")));
    if path.is_absolute() {
        Err(LinkError::PathAbsolute)
    } else if !file.parent().expect("non-root file path").join(path).exists() {
        Err(LinkError::PathNonExistant)
    } else {
        Ok(())
    }
}
<|endoftext|>


<commit_before>// Christopher Chen
// Alex Cohen
// Thornton Uhl
// Kevin Wilde

use std::collections::HashMap;
use std::io::{BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
    let usernames = Arc::new(Mutex::new(HashMap::new()));
    let (sender_to_router, receiver_from_clients) = channel();

    //Router thread
    thread::spawn(move|| {
        loop {
            let message = receiver_from_clients.recv().unwrap();
            println!("Router received {}", message);
        }
    });

    // accept connections and process them, spawning a new thread for each one
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let usernames = usernames.clone();
                let sender_to_router = sender_to_router.clone();
                thread::spawn(move|| {
                    // connection succeeded
                    create_client(stream, &usernames, sender_to_router);
                });
            }
            Err(e) => {
                println!("{}", e);
            }
        }
    }

    // close the socket server
    drop(listener);
}

fn create_client(stream: TcpStream, usernames: &Arc<Mutex<HashMap<String, Sender<String>>>>, sender_to_router: Sender<String>) {
    println!("New client");
    let mut stream = stream;
    stream.write(&"Welcome to Smazy\n".to_string().into_bytes()).unwrap();
    stream.write(&"Please enter a username:\n".to_string().into_bytes()).unwrap();
    stream.flush().unwrap();
    let mut reader = BufReader::new(stream);
    let mut username = "".to_string();
    match reader.read_line(&mut username) {
        Ok(n) => {
            let (sender_to_client, receiver_from_router) = channel();
            let mut guard = usernames.lock().unwrap();
            if n > 0 && !guard.contains_key(&username) {
                guard.insert(username.to_string(), sender_to_client);
                println!("Username is {}", username.to_string());
            }

            loop {
                sender_to_router.send("Hi".to_string()).unwrap();
                let message = receiver_from_router.recv().unwrap();
                println!("User received {}", message);
                println!("end of loop");
            }
        },
        Err(e) => println!("{}", e)
    }
}
<commit_msg>Don't block on recv. Use try_recv<commit_after>// Christopher Chen
// Alex Cohen
// Thornton Uhl
// Kevin Wilde

use std::collections::HashMap;
use std::io::{BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender, TryRecvError};
use std::thread;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
    let usernames = Arc::new(Mutex::new(HashMap::new()));
    let (sender_to_router, receiver_from_clients) = channel();

    //Router thread
    thread::spawn(move|| {
        loop {
            let message = receiver_from_clients.recv().unwrap();
            println!("Router received {}", message);
        }
    });

    // accept connections and process them, spawning a new thread for each one
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let usernames = usernames.clone();
                let sender_to_router = sender_to_router.clone();
                thread::spawn(move|| {
                    // connection succeeded
                    handle_client(stream, &usernames, sender_to_router);
                });
            }
            Err(e) => {
                println!("{}", e);
            }
        }
    }

    // close the socket server
    drop(listener);
}

fn handle_client(stream: TcpStream, usernames: &Arc<Mutex<HashMap<String, Sender<String>>>>, sender_to_router: Sender<String>) {
    println!("New client");
    let mut stream = stream;
    stream.write(&"Welcome to Smazy\n".to_string().into_bytes()).unwrap();
    stream.write(&"Please enter a username:\n".to_string().into_bytes()).unwrap();
    stream.flush().unwrap();
    let mut reader = BufReader::new(stream);
    let mut username = "".to_string();
    match reader.read_line(&mut username) {
        Ok(n) => {
            let (sender_to_client, receiver_from_router) = channel();
            let mut guard = usernames.lock().unwrap();
            if n > 0 && !guard.contains_key(&username) {
                guard.insert(username.to_string(), sender_to_client);
                println!("Username is {}", username.to_string());
            }

            loop {
                sender_to_router.send("Hi".to_string()).unwrap();
                match receiver_from_router.try_recv() {
                    Ok(msg) => println!("User {} received message: {}", &username, msg),
                    Err(TryRecvError::Empty) => continue,
                    Err(TryRecvError::Disconnected) => panic!("User {} disconnected from router", &username)
                }
                println!("end of loop");
            }
        },
        Err(e) => println!("{}", e)
    }
}
<|endoftext|>


<commit_before>use std::env;

const HELP_MESSAGE: &str = r#"
Usage:
  table -h | --help
  table -v | --version

Options:
  -h --help     Print help message
  -v --version  Print version
"#;

const VERSION: &str = "0.3.0";

fn main() {
    for (i, arg) in env::args().enumerate() {
        if i == 0 {
            continue;
        }

        match &*arg {
            "-h" | "--help" => println!("{}", HELP_MESSAGE.trim()),
            "-v" | "--version" => println!("{}", VERSION),
            _ => println!("TODO: implement other flags"),
        }
    }
}
<commit_msg>Exit immediately when -h or -v flag is passed<commit_after>use std::env;
use std::process;

const HELP_MESSAGE: &str = r#"
Usage:
  table -h | --help
  table -v | --version

Options:
  -h --help     Print help message
  -v --version  Print version
"#;

const VERSION: &str = "0.3.0";

fn main() {
    for (i, arg) in env::args().enumerate() {
        if i == 0 {
            continue;
        }

        match &*arg {
            "-h" | "--help" => {
                println!("{}", HELP_MESSAGE.trim());
                process::exit(0);
            }
            "-v" | "--version" => {
                println!("{}", VERSION);
                process::exit(0);
            }
            _ => println!("TODO: implement other flags"),
        }
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;
extern crate fps_clock;

use sdl2::video::Window;
use sdl2::render::Canvas;
use sdl2::EventPump;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::image::{LoadTexture, INIT_PNG};
use sdl2::rect::Rect;

use fps_clock::FpsClock;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Direction {
    Up,
    Down,
    Left,
    Right
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Tile {
    Wall,
    Player,
    PlayerOnGoal,
    Star,
    StarOnGoal,
    Goal,
    Floor,
}
impl Tile {
    /// Character to tile mapping taken from http://sokobano.de/wiki/index.php?title=Level_format
    /// I renamed Box to Star to not conflict with the Box type.
    fn from_char(c: char) -> Result<Tile, String> {
        match c {
            '#' => Ok(Tile::Wall),
            '@' => Ok(Tile::Player),
            '+' => Ok(Tile::PlayerOnGoal),
            '$' => Ok(Tile::Star),
            '*' => Ok(Tile::StarOnGoal),
            '.' => Ok(Tile::Goal),
            ' ' => Ok(Tile::Floor),
            _ => Err(format!("'{}' is an invalid tile", c)),
        }
    }
    fn to_char(&self) -> char {
        use Tile::*;
        match *self {
            Wall => '#',
            Player => '@',
            PlayerOnGoal => '+',
            Star => '$',
            StarOnGoal => '*',
            Goal => '.',
            Floor => ' ',
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Position {
    x: usize,
    y: usize,
}
impl Position {
    fn new(x: usize, y: usize) -> Position {
        Position {x, y}
    }
    fn move_in_direction(&self, dir: Direction) -> Position {
        match dir {
            Direction::Down => Position {y: self.y+1, ..*self},
            Direction::Up => Position {y: self.y-1, ..*self},
            Direction::Left => Position {x: self.x-1, ..*self},
            Direction::Right => Position {x: self.x-1, ..*self},
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Player {
    position: Position,
    direction: Direction,
}
impl Player {
    fn new(position: Position, direction: Direction) -> Player {
        Player {
            position,
            direction,
        }
    }
    fn move_in_direction(&self, direction: Direction) -> Player {
        Player::new(self.position.move_in_direction(direction), direction)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Star {
    position: Position
}
impl Star {
    fn new(position: Position) -> Star {
        Star { position }
    }
    fn move_in_direction(&self, direction: Direction) -> Star {
        Star::new(self.position.move_in_direction(direction))
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct GameState {
    player: Player,
    stars: Vec<Star>,
    steps: usize,
}
impl GameState {
    fn new(player: Player, stars: Vec<Star>, steps: usize) -> GameState {
        GameState { player, stars, steps }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct Level {
    width: usize,
    height: usize,
    map: Vec<Vec<Tile>>,
    start_state: GameState,
}
impl Level {
    fn from_lines(lines: Vec<&str>) -> Result<Level, String> {
        let longest_line_len = lines.iter()
                                .map(|l| l.len())
                                .max()
                                .ok_or_else(|| "Invalid level: Level is empty")?;
        let mut map = Vec::with_capacity(lines.len());
        let mut stars = Vec::new();
        let mut player_pos = None;
        for (y, line) in lines.iter().enumerate() {
            let mut row = Vec::with_capacity(line.len());
            for (x, tile) in line.chars().enumerate() {
                let tile = Tile::from_char(tile)?;
                row.push(tile);
                if tile == Tile::Player || tile == Tile::PlayerOnGoal {
                    // This tile is the starting position
                    player_pos = Some(Position::new(x, y));
                } else if tile == Tile::Star || tile == Tile::StarOnGoal {
                    stars.push(Star::new(Position::new(x, y)));
                }
            }
            if line.len() < longest_line_len {
                for _ in 0..(longest_line_len - line.len()) {
                    row.push(Tile::Floor);
                }
            }
            map.push(row);
        }
        let start_state = GameState::new(Player::new(player_pos.ok_or_else(|| "Invalid level: Level has no starting position")?, Direction::Left),
                                         stars,
                                         0);
        let height = map.len();
        Ok(Level { map, width: longest_line_len, height, start_state})
    }
    fn as_string(&self) -> String {
        let mut map = String::new();
        for line in &self.map {
            for tile in line {
                map.push(tile.to_char());
            }
            map.push('\n');
        }
        map
    }
}

fn load_levels(levels: &str) -> Result<Vec<Level>, String> {
    let mut parsed_levels = Vec::new();
    let mut map_lines = Vec::new();
    for line in levels.lines() {
        let line = line.trim_right();
        let line = if let Some(i) = line.find(';') {
            &line[0..i]
        } else {
            line
        };
        if !line.is_empty() {
            map_lines.push(line);
        } else if line.is_empty() && !map_lines.is_empty() {
            parsed_levels.push(Level::from_lines(map_lines)?);
            map_lines = Vec::new();
        }
    }
    Ok(parsed_levels)
}

fn init_sdl(app_name: &str, width: u32, height: u32) -> Result<(Canvas<Window>, EventPump), String> {
    let sdl_context = sdl2::init()?;
    let _image_context = sdl2::image::init(INIT_PNG)?;
    let video_subsystem = sdl_context.video()?;

    let window = video_subsystem.window(app_name, width, height)
        .position_centered()
        .opengl()
        .build()
        .map_err(|e| format!("{}", e))?;

    let canvas = window.into_canvas().build().map_err(|e| format!("{}", e))?;
    let event_pump = sdl_context.event_pump()?;
    Ok((canvas, event_pump))
}

macro_rules! rect {
    ($x:expr, $y:expr, $w:expr, $h:expr) => (Rect::new($x as i32, $y as i32, $w as u32, $h as u32))
}

fn rect_at_center_of(pos: Position, w: u32, h: u32) -> Rect {
    let topleft_x = pos.x as u32 - w/2;
    let topleft_y = pos.y as u32 - h/2;
    rect!(topleft_x, topleft_y, w, h)
}

const LEVELS: &'static str = include_str!("../levels.txt");
const SPRITE_PATH: &'static str = "resources/images/sokoban_spritesheet.png";

fn main() {
    let (width, height) = (800, 600);
    let parsed_levels = load_levels(LEVELS).unwrap();
    let (mut canvas, mut event_pump) = init_sdl("Sokoban", width, height).unwrap();
    let texture_creator = canvas.texture_creator();
    let texture = texture_creator.load_texture(SPRITE_PATH).unwrap();
    let center_rect = rect_at_center_of(Position::new((width/2) as usize, (height/2) as usize), width/2, height/2);
    let mut clock = FpsClock::new(60);
    'main: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'main
                },
                _ => {}
            }
        }
        canvas.set_draw_color(Color::RGB(29, 167, 226));
        canvas.clear();
        canvas.copy(&texture, None, Some(center_rect)).expect("Render failed");
        canvas.present();
        clock.tick();
    }
}
<commit_msg>Add level rendering code<commit_after>extern crate sdl2;
extern crate fps_clock;
#[macro_use]
extern crate lazy_static;

use std::cmp::PartialEq;

use sdl2::video::Window;
use sdl2::render::Canvas;
use sdl2::render::Texture;
use sdl2::EventPump;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::image::{LoadTexture, INIT_PNG};
use sdl2::rect::{Rect, Point};
use sdl2::ttf::Sdl2TtfContext;
use sdl2::surface::Surface;
use sdl2::pixels::PixelFormatEnum;

use fps_clock::FpsClock;

macro_rules! rect {
    ($x:expr, $y:expr, $w:expr, $h:expr) => (Rect::new($x as i32, $y as i32, $w as u32, $h as u32))
}

const LEVELS: &'static str = include_str!("../levels.txt");
const SPRITESHEET_PATH: &'static str = "resources/images/sokoban_spritesheet.png";
const FONT_PATH: &'static str = "resources/font/swansea.ttf";

lazy_static! {
    static ref FLOOR_GRAY: Color = Color::RGB(128, 128, 128);
    static ref BACKGROUND_COLOR: Color = Color::RGB(45, 168, 18);
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Direction {
    Up,
    Down,
    Left,
    Right
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Tile {
    Wall,
    Player,
    PlayerOnGoal,
    Star,
    StarOnGoal,
    Goal,
    OutsideFloor,
    InsideFloor
}
impl Tile {
    /// Character to tile mapping taken from http://sokobano.de/wiki/index.php?title=Level_format
    /// I renamed Box to Star to not conflict with the Box type.
    fn from_char(c: char) -> Result<Tile, String> {
        match c {
            '#' => Ok(Tile::Wall),
            '@' => Ok(Tile::Player),
            '+' => Ok(Tile::PlayerOnGoal),
            '$' => Ok(Tile::Star),
            '*' => Ok(Tile::StarOnGoal),
            '.' => Ok(Tile::Goal),
            ' ' => Ok(Tile::OutsideFloor),
            _ => Err(format!("'{}' is an invalid tile", c)),
        }
    }
    fn to_char(&self) -> char {
        match *self {
            Tile::Wall => '#',
            Tile::Player => '@',
            Tile::PlayerOnGoal => '+',
            Tile::Star => '$',
            Tile::StarOnGoal => '*',
            Tile::Goal => '.',
            Tile::OutsideFloor => '~',
            Tile::InsideFloor => ' ',
        }
    }
    fn spritesheet_rect(&self) -> Rect {
        match *self {
            Tile::Wall => rect!(448, 64, 64, 64),
            Tile::PlayerOnGoal | Tile::Goal | Tile::StarOnGoal => rect!(60, 576, 20, 20),
            Tile::Star => rect!(384, 0, 64, 64),
            Tile::InsideFloor => rect!(192, 528, 64, 64),
            _ => panic!()
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Position {
    x: usize,
    y: usize,
}
impl Position {
    fn new(x: usize, y: usize) -> Position {
        Position {x, y}
    }
    fn move_in_direction(&self, dir: Direction) -> Position {
        match dir {
            Direction::Down => Position {y: self.y+1, ..*self},
            Direction::Up => Position {y: self.y-1, ..*self},
            Direction::Left => Position {x: self.x-1, ..*self},
            Direction::Right => Position {x: self.x-1, ..*self},
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Player {
    position: Position,
    direction: Direction,
}
impl Player {
    fn new(position: Position, direction: Direction) -> Player {
        Player {
            position,
            direction,
        }
    }
    fn move_in_direction(&self, direction: Direction) -> Player {
        Player::new(self.position.move_in_direction(direction), direction)
    }
    fn spritesheet_rect(&self) -> Rect {
        match self.direction {
            Direction::Down => rect!(554, 208, 42, 50),
            Direction::Left => rect!(543, 440, 45, 50),
            Direction::Right => rect!(512, 108, 45, 50),
            Direction::Up => rect!(554, 158, 42, 50),
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Star {
    position: Position
}
impl Star {
    fn new(position: Position) -> Star {
        Star { position }
    }
    fn move_in_direction(&self, direction: Direction) -> Star {
        Star::new(self.position.move_in_direction(direction))
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Goal {
    position: Position
}
impl Goal {
    fn new(position: Position) -> Goal {
        Goal { position }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct GameState {
    player: Player,
    stars: Vec<Star>,
    goals: Vec<Goal>,
    steps: usize,
}
impl GameState {
    fn new(player: Player, stars: Vec<Star>, goals: Vec<Goal>,  steps: usize) -> GameState {
        GameState { player, stars, goals, steps }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct Level {
    width: usize,
    height: usize,
    map: Vec<Vec<Tile>>,
    start_state: GameState,
}
impl Level {
    fn from_lines(lines: Vec<&str>) -> Result<Level, String> {
        let longest_line_len = lines.iter()
                                .map(|l| l.len())
                                .max()
                                .ok_or_else(|| "Invalid level: Level is empty")?;
        let mut map = Vec::with_capacity(lines.len());
        let mut stars = Vec::new();
        let mut goals = Vec::new();
        let mut player_pos = None;
        for (y, line) in lines.iter().enumerate() {
            let mut row = Vec::with_capacity(line.len());
            for (x, tile) in line.chars().enumerate() {
                let tile = Tile::from_char(tile)?;
                if tile == Tile::Player || tile == Tile::PlayerOnGoal {
                    // This tile is the starting position
                    player_pos = Some(Position::new(x, y));
                    row.push(Tile::OutsideFloor);
                } else if tile == Tile::Star || tile == Tile::StarOnGoal {
                    stars.push(Star::new(Position::new(x, y)));
                    row.push(Tile::OutsideFloor);
                } else if tile == Tile::PlayerOnGoal
                          || tile == Tile::StarOnGoal
                          || tile == Tile::Goal {
                    goals.push(Goal::new(Position::new(x, y)));
                    row.push(Tile::OutsideFloor);
                } else {
                    row.push(tile);
                }
            }
            if line.len() < longest_line_len {
                for _ in 0..(longest_line_len - line.len()) {
                    row.push(Tile::OutsideFloor);
                }
            }
            map.push(row);
        }
        let pos = player_pos.ok_or_else(|| "Invalid level: Level has no starting position")?;
        let start_state = GameState::new(Player::new(pos, Direction::Right),
                                         stars,
                                         goals,
                                         0);
        let height = map.len();
        floodfill(&mut map, Tile::OutsideFloor, Tile::InsideFloor, pos.x, pos.y);
        Ok(Level { map, width: longest_line_len, height, start_state})
    }
    fn as_string(&self) -> String {
        let mut map = String::new();
        for line in &self.map {
            for tile in line {
                map.push(tile.to_char());
            }
            map.push('\n');
        }
        map
    }
}

fn load_levels(levels: &str) -> Result<Vec<Level>, String> {
    let mut parsed_levels = Vec::new();
    let mut map_lines = Vec::new();
    for line in levels.lines() {
        let line = line.trim_right();
        let line = if let Some(i) = line.find(';') {
            &line[0..i]
        } else {
            line
        };
        if !line.is_empty() {
            map_lines.push(line);
        } else if line.is_empty() && !map_lines.is_empty() {
            parsed_levels.push(Level::from_lines(map_lines)?);
            map_lines = Vec::new();
        }
    }
    Ok(parsed_levels)
}

fn floodfill<T: PartialEq + Copy>(map: &mut Vec<Vec<T>>, old: T, new: T, x: usize, y: usize) {
    if map[y][x] == old {
        map[y][x] = new;
    }
    if x > 0 && map[y][x-1] == old {
        floodfill(map, old, new, x-1, y);
    }
    if x + 1 < map[y].len() && map[y][x+1] == old {
        floodfill(map, old, new, x+1, y);
    }
    if y > 0 && map[y-1][x] == old {
        floodfill(map, old, new, x, y-1)
    }
    if y + 1 < map.len() && map[y+1][x] == old {
        floodfill(map, old, new, x, y+1)
    }
}

fn render_level_to_surface(level: &Level, game_state: &GameState, spritesheet_path: &str) -> Surface<'static> {
    let map = &level.map;
    let surf = Surface::new((level.width * 64) as u32,
                                (level.height * 64) as u32,
                                PixelFormatEnum::ABGR1555 /* <- I have no clue if this is right or not */).unwrap();
    let mut canvas = surf.into_canvas().unwrap();
    let texture_creator = canvas.texture_creator();
    let spritesheet = texture_creator.load_texture(spritesheet_path).unwrap();
    canvas.set_draw_color(*BACKGROUND_COLOR);
    canvas.clear();
    for (y, row) in map.iter().enumerate() {
        for (x, tile) in row.iter().enumerate() {
            match *tile {
                Tile::OutsideFloor => (),
                Tile::InsideFloor | Tile::Wall => {
                    canvas.copy(&spritesheet, tile.spritesheet_rect(), rect!(x*64, y*64, 64, 64)).unwrap();
                },
                _ => ()
            }
        }
    }
    for goal in &game_state.goals {
        let (x, y) = (&goal.position.x, &goal.position.y);
        canvas.copy(&spritesheet, Tile::Goal.spritesheet_rect(), rect!(x*64+22, y*64+22, 20, 20)).unwrap();
    }
    for star in &game_state.stars {
        let (x, y) = (&star.position.x, &star.position.y);
        canvas.copy(&spritesheet, Tile::Star.spritesheet_rect(), rect!(x*64, y*64, 64, 64)).unwrap();
    }
    let player = game_state.player;
    let (player_x, player_y) = (player.position.x, player.position.y);
    let player_rect = player.spritesheet_rect();
    let w = player_rect.width();
    let h = player_rect.height();
    let r = Rect::from_center(Point::new((player_x*64+32) as i32, (player_y*64+32) as i32), w, h);
    canvas.copy(&spritesheet, player_rect, r).unwrap();
    canvas.into_surface()
}

fn init_sdl(app_name: &str, width: u32, height: u32) -> Result<(Canvas<Window>, EventPump, Sdl2TtfContext), String> {
    let sdl_context = sdl2::init()?;
    let _image_context = sdl2::image::init(INIT_PNG)?;
    let video_subsystem = sdl_context.video()?;

    let window = video_subsystem.window(app_name, width, height)
        .position_centered()
        .opengl()
        .build()
        .map_err(|e| format!("{}", e))?;

    let canvas = window.into_canvas().build().map_err(|e| format!("{}", e))?;
    let event_pump = sdl_context.event_pump()?;
    let ttf_context = sdl2::ttf::init().map_err(|e| format!("{}", e))?;
    Ok((canvas, event_pump, ttf_context))
}

fn rect_at_center_of(pos: Position, w: u32, h: u32) -> Rect {
    let topleft_x = pos.x as u32 - w/2;
    let topleft_y = pos.y as u32 - h/2;
    rect!(topleft_x, topleft_y, w, h)
}

fn main() {
    let mut parsed_levels = load_levels(LEVELS).unwrap();
    let level = &mut parsed_levels[2];
    let game_state = &level.start_state;
    let (width, height) = (800, 600);
    let (mut canvas, mut event_pump, ttf_context) = init_sdl("Sokoban", width, height).unwrap();
    let texture_creator = canvas.texture_creator();
    let mut clock = FpsClock::new(60);
    'main: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'main
                },
                _ => {}
            }
        }
        let level_surf = render_level_to_surface(level, game_state, SPRITESHEET_PATH);
        let center_rect = rect_at_center_of(Position::new((width/2) as usize, (height/2) as usize), level_surf.width(), level_surf.height());
        let level_texture = texture_creator.create_texture_from_surface(level_surf).unwrap();
        canvas.set_draw_color(*BACKGROUND_COLOR);
        canvas.clear();
        canvas.copy(&level_texture, None, Some(center_rect)).expect("Render failed");
        canvas.present();
        clock.tick();
    }
}
<|endoftext|>


<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![feature(slice_patterns)]

extern crate rustc_driver;
extern crate getopts;
extern crate rustc;
extern crate syntax;
extern crate rustc_plugin;
extern crate clippy_lints;
extern crate rustc_serialize;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use syntax::diagnostics;
use std::path::PathBuf;
use std::process::Command;

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls(RustcDefaultCalls);

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

impl ClippyCompilerCalls {
    fn new() -> Self {
        ClippyCompilerCalls(RustcDefaultCalls)
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      descriptions: &diagnostics::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.0.early_callback(matches, sopts, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &diagnostics::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.0.no_input(matches, sopts, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.0.late_callback(matches, sess, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.0.build_controller(sess, matches);

        let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
        control.after_parse.callback = Box::new(move |state| {
            {
                let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed"));
                registry.args_hidden = Some(Vec::new());
                clippy_lints::register_plugins(&mut registry);

                let rustc_plugin::registry::Registry { early_lint_passes, late_lint_passes, lint_groups, llvm_passes, attributes, mir_passes, .. } = registry;
                let sess = &state.session;
                let mut ls = sess.lint_store.borrow_mut();
                for pass in early_lint_passes {
                    ls.register_early_pass(Some(sess), true, pass);
                }
                for pass in late_lint_passes {
                    ls.register_late_pass(Some(sess), true, pass);
                }

                for (name, to) in lint_groups {
                    ls.register_group(Some(sess), true, name, to);
                }

                sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                sess.mir_passes.borrow_mut().extend(mir_passes);
                sess.plugin_attributes.borrow_mut().extend(attributes);
            }
            old(state);
        });

        control
    }
}

use std::path::Path;

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    let sys_root = match (home, toolchain) {
        (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
        _ => option_env!("SYSROOT").map(|s| s.to_owned())
                                   .or(Command::new("rustc").arg("--print")
                                                            .arg("sysroot")
                                                            .output().ok()
                                                            .and_then(|out| String::from_utf8(out.stdout).ok())
                                                            .map(|s| s.trim().to_owned())
                                                            )
                .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust"),
    };

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        let mut metadata = cargo::metadata().expect("could not obtain cargo metadata");
        assert_eq!(metadata.version, 1);
        for target in metadata.packages.remove(0).targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                } else if first == "bin" {
                    if let Err(code) = process(vec!["--bin".to_owned(), target.name].into_iter().chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        let args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };
        let (result, _) = rustc_driver::run_compiler(&args, &mut ClippyCompilerCalls::new());

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P, sysroot: &str) -> Result<(), i32>
    where P: AsRef<Path>, I: Iterator<Item=String> {

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push(String::from("--sysroot"));
    args.push(sysroot.to_owned());
    args.push("-Zno-trans".to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        use std::os::unix::process::ExitStatusExt;
        Err(exit_status.code().or(exit_status.signal()).unwrap_or(-1))
    }
}
<commit_msg>clippy should work on all systems<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![feature(slice_patterns)]

extern crate rustc_driver;
extern crate getopts;
extern crate rustc;
extern crate syntax;
extern crate rustc_plugin;
extern crate clippy_lints;
extern crate rustc_serialize;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use syntax::diagnostics;
use std::path::PathBuf;
use std::process::Command;

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls(RustcDefaultCalls);

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

impl ClippyCompilerCalls {
    fn new() -> Self {
        ClippyCompilerCalls(RustcDefaultCalls)
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      descriptions: &diagnostics::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.0.early_callback(matches, sopts, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &diagnostics::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.0.no_input(matches, sopts, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.0.late_callback(matches, sess, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.0.build_controller(sess, matches);

        let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
        control.after_parse.callback = Box::new(move |state| {
            {
                let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed"));
                registry.args_hidden = Some(Vec::new());
                clippy_lints::register_plugins(&mut registry);

                let rustc_plugin::registry::Registry { early_lint_passes, late_lint_passes, lint_groups, llvm_passes, attributes, mir_passes, .. } = registry;
                let sess = &state.session;
                let mut ls = sess.lint_store.borrow_mut();
                for pass in early_lint_passes {
                    ls.register_early_pass(Some(sess), true, pass);
                }
                for pass in late_lint_passes {
                    ls.register_late_pass(Some(sess), true, pass);
                }

                for (name, to) in lint_groups {
                    ls.register_group(Some(sess), true, name, to);
                }

                sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                sess.mir_passes.borrow_mut().extend(mir_passes);
                sess.plugin_attributes.borrow_mut().extend(attributes);
            }
            old(state);
        });

        control
    }
}

use std::path::Path;

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    let sys_root = match (home, toolchain) {
        (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
        _ => option_env!("SYSROOT").map(|s| s.to_owned())
                                   .or(Command::new("rustc").arg("--print")
                                                            .arg("sysroot")
                                                            .output().ok()
                                                            .and_then(|out| String::from_utf8(out.stdout).ok())
                                                            .map(|s| s.trim().to_owned())
                                                            )
                .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust"),
    };

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        let mut metadata = cargo::metadata().expect("could not obtain cargo metadata");
        assert_eq!(metadata.version, 1);
        for target in metadata.packages.remove(0).targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                } else if first == "bin" {
                    if let Err(code) = process(vec!["--bin".to_owned(), target.name].into_iter().chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        let args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };
        let (result, _) = rustc_driver::run_compiler(&args, &mut ClippyCompilerCalls::new());

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P, sysroot: &str) -> Result<(), i32>
    where P: AsRef<Path>, I: Iterator<Item=String> {

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push(String::from("--sysroot"));
    args.push(sysroot.to_owned());
    args.push("-Zno-trans".to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>


<commit_before>//Hello Rusty!
fn main() {
    println!("Hello, world!");
}
<commit_msg>just some more play code<commit_after>//Hello Rusty!

struct Point{
	x: i32, //int 32
	y: i32
}

fn main() {
	let xx = 42; //int obviously
	let name = "rusty";

    println!("Hello, world!");
    println!("xx = {}, name = {}", xx, name);

    //this is kind of cool, hmm
    let isRusty = if name == "rusty"{
    	true
    } else{
    	false
    };

    if isRusty {
    	println!("Hi Rusty!");
    }

    let x = 5;
    let number = match x {
    	1 => "one",
    	2 => "two",
    	3 => "three",
    	4 => "four",
    	5 => "five",
    	_ => "something else",
    };
    println!("number = {}", number);

    for x in 0..10 {
    	println!("x = {}", x);
    	match x{
    		1 => println!("one for the money"),
    		2 => println!("two for the show"),
    		3 => println!("three to get ready"),
    		4 => println!("four to go!"),
    		5 => println!("Johnny Five is alive!"),
    		_ => println!("just a number..."),
    	}

    	let pt = Point{x: x, y: x*2};
    	println!("pt.x = {}, pt.y = {}", pt.x, pt.y);
    }
}<|endoftext|>


<commit_before>extern crate docopt;
extern crate nalgebra;
extern crate riscan_pro;
extern crate rustc_serialize;

use docopt::Docopt;
use nalgebra::{Iterable, Transpose};
use riscan_pro::{Matrix, Project};
use rustc_serialize::json::{Json, ToJson};
use std::collections::HashMap;

const USAGE: &'static str = "
RiSCAN PRO utilities.

Usage:
    riscan-pro export-filters <project> <scan-position>
    riscan-pro socs-to-glcs <project> <scan-position> [<x> <y> <z>]
    riscan-pro scan-positions <project>
    riscan-pro (-h | --help)

Options:
    -h --help                       Show this screen.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_export_filters: bool,
    cmd_socs_to_glcs: bool,
    cmd_scan_positions: bool,
    arg_project: String,
    arg_scan_position: String,
    arg_x: Option<f64>,
    arg_y: Option<f64>,
    arg_z: Option<f64>,
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());
    let project = Project::from_path(args.arg_project).unwrap();
    if args.cmd_socs_to_glcs {
        let scan_position = project.scan_position(&args.arg_scan_position).unwrap();
        let glcs = scan_position.socs_to_glcs((args.arg_x.unwrap_or(0.),
                                               args.arg_y.unwrap_or(0.),
                                               args.arg_z.unwrap_or(0.)));
        println!("{:.2}, {:.2}, {:.2}", glcs.0, glcs.1, glcs.2);
    } else if args.cmd_scan_positions {
        for scan_position in project.scan_positions() {
            println!("{}", scan_position.name());
        }
    } else if args.cmd_export_filters {
        let scan_position = project.scan_position(&args.arg_scan_position).unwrap();
        let mut filters = Vec::new();
        filters.push(filters_transformation(scan_position.sop()));
        filters.push(filters_transformation(scan_position.pop()));
        println!("{}", filters.to_json());
    }
}

fn filters_transformation(matrix: Matrix) -> Json {
    let mut filter = HashMap::new();
    filter.insert("type".to_string(), "filters.transformation".to_json());
    filter.insert("matrix".to_string(),
                  matrix.transpose()
                      .iter()
                      .map(|n| format!("{}", n))
                      .collect::<Vec<_>>()
                      .join(" ")
                      .to_json());
    filter.to_json()
}
<commit_msg>Main executable can go straight to SP<commit_after>extern crate docopt;
extern crate nalgebra;
extern crate riscan_pro;
extern crate rustc_serialize;

use docopt::Docopt;
use nalgebra::{Iterable, Transpose};
use riscan_pro::{Matrix, Project, ScanPosition};
use rustc_serialize::json::{Json, ToJson};
use std::collections::HashMap;

const USAGE: &'static str = "
RiSCAN PRO utilities.

Usage:
    riscan-pro export-filters <project> [<scan-position>]
    riscan-pro socs-to-glcs <project> [<scan-position>] [<x> <y> <z>]
    riscan-pro scan-positions <project>
    riscan-pro (-h | --help)

Options:
    -h --help                       Show this screen.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_export_filters: bool,
    cmd_socs_to_glcs: bool,
    cmd_scan_positions: bool,
    arg_project: String,
    arg_scan_position: Option<String>,
    arg_x: Option<f64>,
    arg_y: Option<f64>,
    arg_z: Option<f64>,
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());
    if args.cmd_socs_to_glcs {
        let scan_position = if let Some(scan_position) = args.arg_scan_position {
            let project = Project::from_path(args.arg_project).unwrap();
            project.scan_position(&scan_position).unwrap().clone()
        } else {
            ScanPosition::from_path(args.arg_project).unwrap()
        };
        let glcs = scan_position.socs_to_glcs((args.arg_x.unwrap_or(0.),
                                               args.arg_y.unwrap_or(0.),
                                               args.arg_z.unwrap_or(0.)));
        println!("{:.2}, {:.2}, {:.2}", glcs.0, glcs.1, glcs.2);
    } else if args.cmd_scan_positions {
        let project = Project::from_path(args.arg_project).unwrap();
        for scan_position in project.scan_positions() {
            println!("{}", scan_position.name());
        }
    } else if args.cmd_export_filters {
        let scan_position = if let Some(scan_position) = args.arg_scan_position {
            let project = Project::from_path(args.arg_project).unwrap();
            project.scan_position(&scan_position).unwrap().clone()
        } else {
            ScanPosition::from_path(args.arg_project).unwrap()
        };
        let mut filters = Vec::new();
        filters.push(filters_transformation(scan_position.sop()));
        filters.push(filters_transformation(scan_position.pop()));
        println!("{}", filters.to_json());
    }
}

fn filters_transformation(matrix: Matrix) -> Json {
    let mut filter = HashMap::new();
    filter.insert("type".to_string(), "filters.transformation".to_json());
    filter.insert("matrix".to_string(),
                  matrix.transpose()
                      .iter()
                      .map(|n| format!("{}", n))
                      .collect::<Vec<_>>()
                      .join(" ")
                      .to_json());
    filter.to_json()
}
<|endoftext|>


<commit_before>use std::env;
use std::error::Error;
use std::fs::File;
use std::path::Path;
use std::io::Read;
use std::process;

fn input() -> u8 {
    let c = match std::io::stdin().bytes().next()
                .and_then(|result| result.ok()).map(|byte| byte as u8) {
        None => process::exit(0),
        Some(c) => c,
    };
    c
}

fn output(c: u8) {
    print!("{}", c as char);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let path = Path::new(&args[1]);
    let display = path.display();

    let mut file = match File::open(&path) {
        Err(why) => panic!("Could not open {}: {}",
                           display, Error::description(&why)),
        Ok(file) => file,
    };

    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("Could not read {}: {}",
                           display, Error::description(&why)),
        Ok(_) => {},
    }

    let mut code_ptr: usize = 0;
    let mut data_ptr: usize = 0;
    let code = s.into_bytes();
    let mut data = [0 as u8; 30000];

    while code_ptr < code.len() {
        let c = code[code_ptr];
        match c as char {
            '>' => data_ptr += 1,
            '<' => data_ptr -= 1,
            '+' => data[data_ptr] += 1,
            '-' => data[data_ptr] -= 1,
            '.' => output(data[data_ptr]),
            ',' => data[data_ptr] = input(),
            '[' => {
                if data[data_ptr] == 0 {
                    let mut count = 1;
                    while count != 0 {
                        code_ptr += 1;
                        if code[code_ptr] == '[' as u8 { count += 1; }
                        if code[code_ptr] == ']' as u8 { count -= 1; }
                    }
                }
            },
            ']' => {
                if data[data_ptr] != 0 {
                    let mut count = 1;
                    while count != 0 {
                        code_ptr -= 1;
                        if code[code_ptr] == ']' as u8 { count += 1; }
                        if code[code_ptr] == '[' as u8 { count -= 1; }
                    }
                }
            },
            _ => {},
        }
        code_ptr += 1;
    }
}
<commit_msg>Add jumptable<commit_after>use std::env;
use std::error::Error;
use std::fs::File;
use std::path::Path;
use std::io::Read;
use std::process;

fn compute_jumptable(code: &Vec<u8>) -> Vec<u64> {
    let mut ptr = 0;
    let mut jumptable = vec![0 as u64; code.len()];
    let mut bracket_nesting =  0;
    let mut seek = ptr;

    while ptr < code.len() {
        if code[ptr] == '[' as u8 {
            bracket_nesting = 1;
            seek = ptr;

            while bracket_nesting != 0 && (seek+1 < code.len()) {
                seek += 1;
                if code[seek] == ']' as u8 {
                    bracket_nesting -= 1;
                } else if code[seek] == '[' as u8 {
                    bracket_nesting += 1;
                }
            }

            if bracket_nesting == 0 {
                jumptable[ptr] = seek as u64;
                jumptable[seek] = ptr as u64;
            } else {
                panic!("Unmatched '[': ptr={}", ptr);
            }
        }
        ptr += 1;
    }

    jumptable
}

fn input() -> u8 {
    let c = match std::io::stdin().bytes().next()
                .and_then(|result| result.ok()).map(|byte| byte as u8) {
        None => process::exit(0),
        Some(c) => c,
    };
    c
}

fn output(c: u8) {
    print!("{}", c as char);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let path = Path::new(&args[1]);
    let display = path.display();

    let mut file = match File::open(&path) {
        Err(why) => panic!("Could not open {}: {}",
                           display, Error::description(&why)),
        Ok(file) => file,
    };

    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("Could not read {}: {}",
                           display, Error::description(&why)),
        Ok(_) => {},
    }

    let mut code_ptr: usize = 0;
    let mut data_ptr: usize = 0;
    let code = s.into_bytes();
    let mut data = [0 as u8; 30000];
    let jumptable = compute_jumptable(&code);

    while code_ptr < code.len() {
        let c = code[code_ptr];
        match c as char {
            '>' => data_ptr += 1,
            '<' => data_ptr -= 1,
            '+' => data[data_ptr] += 1,
            '-' => data[data_ptr] -= 1,
            '.' => output(data[data_ptr]),
            ',' => data[data_ptr] = input(),
            '[' => {
                if data[data_ptr] == 0 {
                    code_ptr = jumptable[code_ptr] as usize;
                }
            },
            ']' => {
                if data[data_ptr] != 0 {
                    code_ptr = jumptable[code_ptr] as usize;
                }
            },
            _ => {},
        }
        code_ptr += 1;
    }
}
<|endoftext|>


<commit_before>extern crate hiredis;

fn main() {
    let redis  = hiredis::Redis::new("127.0.0.1", 6379);
    let result = redis.command("SUBSCRIBE IRC");

    let mut reply = hiredis::Reply::empty();

    loop {
        redis.receive(&mut reply);
        println!("Num: {}", reply.typename() as uint);
    }
}
<commit_msg>Use Arrays<commit_after>extern crate hiredis;

fn main() {
    let redis  = hiredis::Redis::new("127.0.0.1", 6379);
    let result = redis.command("SUBSCRIBE IRC");

    let mut reply = hiredis::Reply::empty();

    loop {
        redis.receive(&mut reply);
        println!("Num: {}", reply.typename() as uint);

        for v in reply.array().iter() {
            match v.typename() {
                hiredis::String => {
                    println!("Value: {}", v.string());
                }

                _ => {
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// main.rs
#![feature(plugin)]
#![plugin(docopt_macros)]

extern crate rustc_serialize;
extern crate docopt;
extern crate regex;

use std::fmt::{ Display, Formatter };
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
//use std::io::{BufReader,BufRead};
use std::io::BufReader;
use std::fs::OpenOptions;
use std::io::BufWriter;
use std::path::Path;
// https://github.com/docopt/docopt.rs
use docopt::Docopt;

// https://doc.rust-lang.org/regex/regex/index.html
use regex::Regex;

docopt!(Args derive Debug, "
Alexey Mekhanoshin

Usage:
	rus_fritz -e <engfile>  -r <rusfile> ( -o <outfile> | --stdout )
	rus_fritz (-h | --help)
	rus_fritz --version
Options:
  -h --help		Show this screen.
  --version		Show version.
");

struct EnglishName {
	name: String,
	opis: String,
}

struct RussianName {
	name: String,
	opis: String,
	using: bool,
}

impl EnglishName {
	fn new<S: Into<String>>(name: S, opis: S) -> EnglishName {
		EnglishName {
			name: name.into(),
			opis: opis.into(),
		}
	}
}

impl RussianName {
	fn new<S: Into<String>>(name: S, opis: S) -> RussianName {
		RussianName {
			name: name.into(),
			opis: opis.into(),
			using: false,
		}
	}
}

impl std::fmt::Display for EnglishName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        //Ok(())
        write!(f, "Display Eng: {},\t\t\t{}", self.name, self.opis)
    }
}

impl std::fmt::Display for RussianName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        	write!(f, "Display Rus: {},\t\t\t{}", self.name, self.opis)
    }
}

fn open_eng_file(engvec: &mut Vec<EnglishName>, file_name: &String) {

	let file = match File::open(file_name) {
		Ok(f) => f,
		Err(..) => panic!("Not open file: {}",file_name),
	};
	let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
	for line in BufReader::new(file).lines() {
		let s = line.unwrap();
		//println!("{}", s)
		for cap in re.captures_iter(&s) {
			let ubs = EnglishName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
			engvec.push(ubs);
		}
	}
}

fn open_rus_file(engvec: &mut Vec<RussianName>, file_name: &String) {
	let path = Path::new(file_name);
	//let display = path.display();
	let file = match File::open(path) {
		Ok(f) => f,
		Err(..) => panic!("Not open file: {}",file_name),
	};
	let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
	for line in BufReader::new(file).lines() {
		let s = line.unwrap();
		//println!("{}", s)
		for cap in re.captures_iter(&s) {
			let ubs = RussianName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
			engvec.push(ubs);
		}
	}
}

fn create_out_file(file_name: &String) -> BufWriter<File> {
	let mut options = OpenOptions::new();
	let file = match options.create(true).write(true).open(file_name) {
		Ok(file) => file,
		Err(..) => panic!("Not create/open file: {}", file_name),
	};
	let writer = BufWriter::new(file);
	return writer;
	// return true;
}

fn main() {

	let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
	if args.flag_stdout {
		println!("{:?}", args);
		if args.flag_h { println!("Print Help coming soon ..." ); return; }
		if args.flag_version { println!("Print Version coming soon ..." ); return; }
	}

	let mut engvec: Vec<EnglishName> = Vec::new();
	let mut rusvec: Vec<RussianName> = Vec::new();
	//let wr: BufWriter<File>;

	open_eng_file(&mut engvec, &args.arg_engfile.to_string());
	assert!( !engvec.is_empty() );
	open_rus_file(&mut rusvec, &args.arg_rusfile.to_string());
	assert!( !rusvec.is_empty() );

	//  Подготовка закончилась, начинаем работу.

	if args.flag_stdout {
		println!("/*\n\tRecreated by RusFritz project\n*/");
	} else {
		// Write to file
	}

	let mut i=0;
	let mut found = false;
	let mut outstr = String::new();

    for e in &mut engvec {
    	i = i+1;
    	for r in &mut rusvec {
    		if e.name == r.name {
    			e.opis = r.opis.clone();
    			found = true;
    			r.using = true;
    			if args.flag_stdout {
    				println!("{},\t\t{};", r.name, r.opis);
    			} else {
    				let s = String::from( format!("{},\t\t{};\n", r.name, r.opis) );
    				outstr.push_str(&s);
    			}
    		}
    	}
    	if !found {
    		//println!("ERR: {} - не найдено соответствие", e.name );
    		if args.flag_stdout {
    			println!("{},\t\t{};",e.name, e.opis);
    		} else {
    			// Wite output to file
    		}

    	}
    	found = false;
    }
    // Print if not using from Russian Names
    println!("------ Not using Found from Russian File --------");
    for r in rusvec {
    	if r.using == false {
    		println!("{},\t\t{}",r.name,r.opis);

    	}
    }

    // File write, if needed
    if args.flag_stdout == false {
		let mut wr = create_out_file(&args.arg_outfile.to_string());
		if outstr.len() > 0 {
			match wr.write_all(&outstr.as_bytes()) {
				Err(why) => {
					panic!("couldn't write to{}: {}",
						&args.arg_outfile.to_string(),
						Error::description(&why))
				},
				Ok(_) => println!("Good write file"),
			};
			wr.flush();
		}
	}

    //println!("Обработано {} строк из {}",i, engvec.len());
    //let writer = std::io::file_writer(&Path(std::os::args()[2]), [io::Append, io::Create]).unwrap();

}
<commit_msg>More debug messages for file i/o<commit_after>// main.rs
#![feature(plugin)]
#![plugin(docopt_macros)]

extern crate rustc_serialize;
extern crate docopt;
extern crate regex;

use std::fmt::{ Display, Formatter };
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
//use std::io::{BufReader,BufRead};
use std::io::BufReader;
use std::fs::OpenOptions;
use std::io::BufWriter;
use std::path::Path;
// https://github.com/docopt/docopt.rs
use docopt::Docopt;

// https://doc.rust-lang.org/regex/regex/index.html
use regex::Regex;

docopt!(Args derive Debug, "
Alexey Mekhanoshin

Usage:
	rus_fritz -e <engfile>  -r <rusfile> ( -o <outfile> | --stdout )
	rus_fritz (-h | --help)
	rus_fritz --version
Options:
  -h --help		Show this screen.
  --version		Show version.
");

struct EnglishName {
	name: String,
	opis: String,
}

struct RussianName {
	name: String,
	opis: String,
	using: bool,
}

impl EnglishName {
	fn new<S: Into<String>>(name: S, opis: S) -> EnglishName {
		EnglishName {
			name: name.into(),
			opis: opis.into(),
		}
	}
}

impl RussianName {
	fn new<S: Into<String>>(name: S, opis: S) -> RussianName {
		RussianName {
			name: name.into(),
			opis: opis.into(),
			using: false,
		}
	}
}

impl std::fmt::Display for EnglishName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        //Ok(())
        write!(f, "Display Eng: {},\t\t\t{}", self.name, self.opis)
    }
}

impl std::fmt::Display for RussianName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        	write!(f, "Display Rus: {},\t\t\t{}", self.name, self.opis)
    }
}

fn open_eng_file(engvec: &mut Vec<EnglishName>, file_name: &String) {
	let path = Path::new(file_name);
	let display = path.display();
	let file = match File::open(path) {
		Ok(f) => f,
		Err(why) => panic!("Not open file {}: {}", display, Error::description(&why) ),
	};
	let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
	for line in BufReader::new(file).lines() {
		let s = line.unwrap();
		//println!("{}", s)
		for cap in re.captures_iter(&s) {
			let ubs = EnglishName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
			engvec.push(ubs);
		}
	}
}

fn open_rus_file(engvec: &mut Vec<RussianName>, file_name: &String) {
	let path = Path::new(file_name);
	let display = path.display();
	let file = match File::open(path) {
		Ok(f) => f,
		Err(why) => panic!("Not open file: {}: {}", display, Error::description(&why) ),
	};
	let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
	for line in BufReader::new(file).lines() {
		let s = line.unwrap();
		//println!("{}", s)
		for cap in re.captures_iter(&s) {
			let ubs = RussianName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
			engvec.push(ubs);
		}
	}
}

fn create_out_file(file_name: &String) -> BufWriter<File> {
	let path = Path::new(file_name);
	let display = path.display();
	let mut options = OpenOptions::new();
	let file = match options.create(true).write(true).open(path) {
		Ok(file) => file,
		Err(why) => panic!("Not create/open file {}: {}", display, Error::description(&why)),
	};
	let writer = BufWriter::new(file);
	return writer;
	// return true;
}

fn main() {

	let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
	if args.flag_stdout {
		println!("{:?}", args);
		if args.flag_h { println!("Print Help coming soon ..." ); return; }
		if args.flag_version { println!("Print Version coming soon ..." ); return; }
	}

	let mut engvec: Vec<EnglishName> = Vec::new();
	let mut rusvec: Vec<RussianName> = Vec::new();
	//let wr: BufWriter<File>;

	open_eng_file(&mut engvec, &args.arg_engfile.to_string());
	assert!( !engvec.is_empty() );
	open_rus_file(&mut rusvec, &args.arg_rusfile.to_string());
	assert!( !rusvec.is_empty() );

	//  Подготовка закончилась, начинаем работу.

	if args.flag_stdout {
		println!("/*\n\tRecreated by RusFritz project\n*/");
	} else {
		// Write to file
	}

	let mut i=0;
	let mut found = false;
	let mut outstr = String::new();

    for e in &mut engvec {
    	i = i+1;
    	for r in &mut rusvec {
    		if e.name == r.name {
    			e.opis = r.opis.clone();
    			found = true;
    			r.using = true;
    			if args.flag_stdout {
    				println!("{},\t\t{};", r.name, r.opis);
    			} else {
    				let s = String::from( format!("{},\t\t{};\n", r.name, r.opis) );
    				outstr.push_str(&s);
    			}
    		}
    	}
    	if !found {
    		//println!("ERR: {} - не найдено соответствие", e.name );
    		if args.flag_stdout {
    			println!("{},\t\t{};",e.name, e.opis);
    		} else {
    			// Wite output to file
    		}

    	}
    	found = false;
    }
    // Print if not using from Russian Names
    println!("------ Not using Found from Russian File --------");
    for r in rusvec {
    	if r.using == false {
    		println!("{},\t\t{}",r.name,r.opis);

    	}
    }

    // File write, if needed
    if args.flag_stdout == false {
		let mut wr = create_out_file(&args.arg_outfile.to_string());
		if outstr.len() > 0 {
			match wr.write_all(&outstr.as_bytes()) {
				Err(why) => {
					panic!("couldn't write to{}: {}",
						&args.arg_outfile.to_string(),
						Error::description(&why))
				},
				Ok(_) => println!("Good write file"),
			};
			wr.flush();
		}
	}

    //println!("Обработано {} строк из {}",i, engvec.len());
    //let writer = std::io::file_writer(&Path(std::os::args()[2]), [io::Append, io::Create]).unwrap();

}
<|endoftext|>


<commit_before>mod google;
mod stackexchange;

extern crate regex;
extern crate hyper;
extern crate rustc_serialize;
extern crate select;
extern crate flate2;
extern crate getopts;

use std::env;
use std::process::exit;

use getopts::Options;

use google::Google;
use stackexchange::StackExchangeApi;
use stackexchange::StackExchangeAnswer;

#[derive(Debug)]
struct How2RSSettings {
    max_answers_count: usize,
    query: String
}

impl Default for How2RSSettings {
    fn default() -> Self {
        How2RSSettings {
            max_answers_count: 5,
            query: String::new()
        }
    }
}

fn print_usage(opts: Options) {
    let brief = "Usage: how2-rs [options] query";
    print!("{}", opts.usage(&brief));
}

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

    let mut opts = Options::new();
    opts.optopt("m",
                "max-answers",
                "Maximum answers to retrieve (defaults to 5).",
                "COUNT");
    opts.optflag("h", "help", "Show usage.");

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

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

    let mut settings = How2RSSettings::default();

    if matches.opt_present("m") {
        let count_cli = matches.opt_str("m");
        match count_cli {
            Some(count_str) => {
                match count_str.parse::<usize>() {
                    Ok(count) => {
                        settings.max_answers_count = count;
                    }
                    Err(_) => {
                        println!("'m' option should be an integer.");
                        exit(1);
                    }
                }
            }
            None => {
                println!("Argument to option 'm' missing.");
                exit(1);
            }
        }
    }

    settings.query = matches.free.join(" ");

    settings
}

fn search(settings: How2RSSettings) -> Vec<StackExchangeAnswer> {
    let google = Google::default();
    let links = google.google(&settings.query);
    let links_urls = links.iter()
                          .map(|l| l.link.as_str())
                          .collect();

    let api = StackExchangeApi::new();

    let mut answers = api.answers(links_urls);

    answers.sort_by_key(|a| -a.score);
    let left_answers: Vec<_> = answers.drain(..)
                                      .take(settings.max_answers_count)
                                      .collect();

    left_answers
}

fn main() {
    let settings = get_settings();
    let answers = search(settings);

    for answer in answers.iter() {
        println!("{}", answer);
        println!("===-----===");
    }
}

#[test]
fn stackexchange_works() {
    let mut settings = How2RSSettings::default();
    settings.query = String::from("rust lang linked list");

    let answers = search(settings);

    assert_eq!(answers.len(), 3);
    assert!(answers.iter().any(|a| a.answer_id == 22269167));
}
<commit_msg>More tests.<commit_after>mod google;
mod stackexchange;

extern crate regex;
extern crate hyper;
extern crate rustc_serialize;
extern crate select;
extern crate flate2;
extern crate getopts;

use std::env;
use std::process::exit;

use getopts::Options;

use google::Google;
use stackexchange::StackExchangeApi;
use stackexchange::StackExchangeAnswer;

#[derive(Debug)]
struct How2RSSettings {
    max_answers_count: usize,
    query: String
}

impl Default for How2RSSettings {
    fn default() -> Self {
        How2RSSettings {
            max_answers_count: 5,
            query: String::new()
        }
    }
}

fn print_usage(opts: Options) {
    let brief = "Usage: how2-rs [options] query";
    print!("{}", opts.usage(&brief));
}

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

    let mut opts = Options::new();
    opts.optopt("m",
                "max-answers",
                "Maximum answers to retrieve (defaults to 5).",
                "COUNT");
    opts.optflag("h", "help", "Show usage.");

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

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

    let mut settings = How2RSSettings::default();

    if matches.opt_present("m") {
        let count_cli = matches.opt_str("m");
        match count_cli {
            Some(count_str) => {
                match count_str.parse::<usize>() {
                    Ok(count) => {
                        settings.max_answers_count = count;
                    }
                    Err(_) => {
                        println!("'m' option should be an integer.");
                        exit(1);
                    }
                }
            }
            None => {
                println!("Argument to option 'm' missing.");
                exit(1);
            }
        }
    }

    settings.query = matches.free.join(" ");

    settings
}

fn search(settings: How2RSSettings) -> Vec<StackExchangeAnswer> {
    let google = Google::default();
    let links = google.google(&settings.query);
    let links_urls = links.iter()
                          .map(|l| l.link.as_str())
                          .collect();

    let api = StackExchangeApi::new();

    let mut answers = api.answers(links_urls);

    answers.sort_by_key(|a| -a.score);
    let left_answers: Vec<_> = answers.drain(..)
                                      .take(settings.max_answers_count)
                                      .collect();

    left_answers
}

fn main() {
    let settings = get_settings();
    let answers = search(settings);

    for answer in answers.iter() {
        println!("{}", answer);
        println!("===-----===");
    }
}

#[test]
fn stackexchange_works() {
    let mut settings = How2RSSettings::default();
    settings.query = String::from("rust lang linked list");

    let answers = search(settings);

    assert_eq!(answers.len(), 3);
    assert!(answers.iter().any(|a| a.answer_id == 22269167));
}

#[test]
fn no_bad_results() {
    let mut settings = How2RSSettings::default();
    settings.query = String::from("rust lang is not awesome");

    let answers = search(settings);

    assert_eq!(answers.len(), 0);
}
<|endoftext|>


<commit_before>extern crate iron;
#[macro_use]
extern crate router;
extern crate staticfile;
extern crate mount;
extern crate urlencoded;
extern crate rustc_serialize;
extern crate html5ever;
extern crate regex;
extern crate uuid;

use std::net::SocketAddrV4;
use std::net::Ipv4Addr;
use std::path::Path;
use iron::prelude::*;
use iron::status;
use iron::mime::Mime;
use staticfile::Static;
use mount::Mount;
use router::{Router};
use urlencoded::UrlEncodedQuery;
use urlencoded::UrlEncodedBody;
use std::str::FromStr;

#[macro_use]
extern crate string_cache;
extern crate pink_spider;

use pink_spider::error::Error;
use pink_spider::scraper::extract;
use pink_spider::model::{Track, Entry, Provider};
use rustc_serialize::json::{ToJson, Json};

pub fn index_entries(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let entries          = Entry::find(page, per_page);
    let json_obj: Json   = entries.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn index_tracks(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let tracks  = Track::find(page, per_page);
    let json_obj: Json   = tracks.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn playlistify(req: &mut Request) -> IronResult<Response> {
    pub fn playlistify2(req: &mut Request) -> Result<Response, Error> {
        let ref params  = try!(req.get_ref::<UrlEncodedQuery>());
        let url         = try!(params.get("url").ok_or(Error::BadRequest));
        let defaults    = &vec!("false".to_string());
        let force_param = params.get("force").unwrap_or(defaults);
        let force       = force_param.len() > 0 && &force_param[0] == "true";
        let entry       = try!(find_or_playlistify_entry(&url[0], force));
        let json_obj    = entry.to_json() as Json;
        let json_str    = json_obj.to_string() as String;
        Ok(Response::with((status::Ok, application_json(), json_str)))
    }
    playlistify2(req).map_err(|err| IronError::from(err))
}

pub fn find_or_playlistify_entry(url: &str, force: bool) -> Result<Entry, Error> {
    match Entry::find_by_url(url) {
        Ok(entry) => {
            println!("Get entry from database cache: {}", url);
            if force {
                println!("Update entry: {}", url);
                let entry = try!(playlistify_entry(entry));
                Ok(entry)
            } else {
                Ok(entry)
            }
        },
        Err(_) => {
            let entry = try!(Entry::create_by_url(url.to_string()));
            let entry = try!(playlistify_entry(entry));
            println!("Create new entry to database cache: {}", url);
            Ok(entry)
        },
    }
}

pub fn playlistify_entry(entry: Entry) -> Result<Entry, Error> {
    let mut e = entry.clone();
    let product = try!(extract(&entry.url));
    match product.og_obj {
        Some(og_obj) => {
            e.title       = Some(og_obj.title);
            e.description = og_obj.description;
            e.locale      = og_obj.locale;
            e.visual_url  = og_obj.images.first().map(|i| i.url.clone());
        },
        None => (),
    }
    for t in product.tracks {
        let track = try!(Track::find_or_create(t.provider,
                                               t.title,
                                               t.url,
                                               t.identifier));
        match entry.tracks.iter().find(|&t| t.id == track.id) {
            Some(_) => (),
            None    => e.add_track(track.clone())
        }
    }
    try!(e.save());
    Ok(e)
}

pub fn show_track_by_id(req: &mut Request) -> IronResult<Response> {
    let ref track_id = req.extensions.get::<Router>().unwrap()
                          .find("track_id").unwrap();
    match Track::find_by_id(track_id) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn show_track(req: &mut Request) -> IronResult<Response> {
    let provider   = req.extensions.get::<Router>().unwrap().find("provider").unwrap();
    let identifier = req.extensions.get::<Router>().unwrap().find("id").unwrap();
    let p = &Provider::new(provider.to_string());
    match Track::find_by(p, identifier) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn update_track(req: &mut Request) -> IronResult<Response> {
    let mut track = try!(Track::find_by_id(&query_as_string(req, "track_id")));
    match param_as_string(req, "title") {
        Some(title) => track.title = title,
        None        => println!("no title")
    }
    match param_as_string(req, "url") {
        Some(url) => track.url = url,
        None      => println!("no url")
    }
    try!(track.save());
    let res = track.to_json().to_string();
    Ok(Response::with((status::Ok, application_json(), res)))
}

fn param_as_string(req: &mut Request, key: &str) -> Option<String> {
    match req.get_ref::<UrlEncodedBody>() {
        Ok(ref params) => match params.get(key) {
            Some(val) => Some(val[0].clone()),
            None      => None
        },
        Err(_) => None
    }
}

fn query_as_string(req: &mut Request, key: &str) -> String {
    return req.extensions.get::<Router>().unwrap()
        .find(key).unwrap().to_string();
}

fn pagination_params(req: &mut Request) -> (i64, i64) {
    match req.get_ref::<UrlEncodedQuery>() {
        Ok(ref params) =>
            (params.get("page").unwrap()[0].to_string().parse::<i64>().unwrap(),
             params.get("per_page").unwrap()[0].to_string().parse::<i64>().unwrap()),
        Err(_) =>
            (0, 10)
    }
}

fn application_json() -> Mime {
    Mime::from_str("application/json").ok().unwrap()
}

pub fn main() {
    let path = Path::new("public");
    let mut mount = Mount::new();
    mount.mount("/web/", Static::new(Path::new(path)));
    let router = router!(
        playlistify:      get  "/playlistify"          => playlistify,
        show_track_by_id: get  "/tracks/:track_id"     => show_track_by_id,
        update_track:     post "/tracks/:track_id"     => update_track,
        show_track:       get  "/tracks/:provider/:id" => show_track,
        index_entries:    get  "/entries"              => index_entries,
        index_tracks:     get  "/tracks"               => index_tracks,
        web:              get  "/*"                    => mount,
    );
    let port_str = match std::env::var("PORT") {
        Ok(n)    => n,
        Err(_) => "8080".to_string()
    };
    let port: u16 = match port_str.trim().parse() {
        Ok(n) => n,
        Err(_) => {
            println!("Faild to parse port");
            return;
        }
    };
    println!("PORT {}", port_str);
    let ip = Ipv4Addr::new(0, 0, 0, 0);
    Iron::new(router).http(SocketAddrV4::new(ip, port)).unwrap();
}
<commit_msg>Add entries/:entry_id/tracks api<commit_after>extern crate iron;
#[macro_use]
extern crate router;
extern crate staticfile;
extern crate mount;
extern crate urlencoded;
extern crate rustc_serialize;
extern crate html5ever;
extern crate regex;
extern crate uuid;

use std::net::SocketAddrV4;
use std::net::Ipv4Addr;
use std::path::Path;
use iron::prelude::*;
use iron::status;
use iron::mime::Mime;
use staticfile::Static;
use mount::Mount;
use router::{Router};
use urlencoded::UrlEncodedQuery;
use urlencoded::UrlEncodedBody;
use std::str::FromStr;
use uuid::Uuid;

#[macro_use]
extern crate string_cache;
extern crate pink_spider;

use pink_spider::error::Error;
use pink_spider::scraper::extract;
use pink_spider::model::{Track, Entry, Provider, PaginatedCollection};
use rustc_serialize::json::{ToJson, Json};

pub fn index_entries(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let entries          = Entry::find(page, per_page);
    let json_obj: Json   = entries.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn index_tracks(req: &mut Request) -> IronResult<Response> {
    let (page, per_page) = pagination_params(req);
    let tracks  = Track::find(page, per_page);
    let json_obj: Json   = tracks.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn index_tracks_by_entry(req: &mut Request) -> IronResult<Response> {
    let ref entry_id = req.extensions.get::<Router>().unwrap().find("entry_id").unwrap();
    let uuid = try!(Uuid::parse_str(entry_id).map_err(|_| Error::Unprocessable));
    let items = Track::find_by_entry_id(uuid);
    let col = PaginatedCollection {
        page:     0,
        per_page: items.len() as i64,
        total:    items.len() as i64,
        items:    items,
    };
    let json_obj: Json   = col.to_json();
    let json_str: String = json_obj.to_string();
    Ok(Response::with((status::Ok, application_json(), json_str)))
}

pub fn playlistify(req: &mut Request) -> IronResult<Response> {
    pub fn playlistify2(req: &mut Request) -> Result<Response, Error> {
        let ref params  = try!(req.get_ref::<UrlEncodedQuery>());
        let url         = try!(params.get("url").ok_or(Error::BadRequest));
        let defaults    = &vec!("false".to_string());
        let force_param = params.get("force").unwrap_or(defaults);
        let force       = force_param.len() > 0 && &force_param[0] == "true";
        let entry       = try!(find_or_playlistify_entry(&url[0], force));
        let json_obj    = entry.to_json() as Json;
        let json_str    = json_obj.to_string() as String;
        Ok(Response::with((status::Ok, application_json(), json_str)))
    }
    playlistify2(req).map_err(|err| IronError::from(err))
}

pub fn find_or_playlistify_entry(url: &str, force: bool) -> Result<Entry, Error> {
    match Entry::find_by_url(url) {
        Ok(entry) => {
            println!("Get entry from database cache: {}", url);
            if force {
                println!("Update entry: {}", url);
                let entry = try!(playlistify_entry(entry));
                Ok(entry)
            } else {
                Ok(entry)
            }
        },
        Err(_) => {
            let entry = try!(Entry::create_by_url(url.to_string()));
            let entry = try!(playlistify_entry(entry));
            println!("Create new entry to database cache: {}", url);
            Ok(entry)
        },
    }
}

pub fn playlistify_entry(entry: Entry) -> Result<Entry, Error> {
    let mut e = entry.clone();
    let product = try!(extract(&entry.url));
    match product.og_obj {
        Some(og_obj) => {
            e.title       = Some(og_obj.title);
            e.description = og_obj.description;
            e.locale      = og_obj.locale;
            e.visual_url  = og_obj.images.first().map(|i| i.url.clone());
        },
        None => (),
    }
    for t in product.tracks {
        let track = try!(Track::find_or_create(t.provider,
                                               t.title,
                                               t.url,
                                               t.identifier));
        match entry.tracks.iter().find(|&t| t.id == track.id) {
            Some(_) => (),
            None    => e.add_track(track.clone())
        }
    }
    try!(e.save());
    Ok(e)
}

pub fn show_track_by_id(req: &mut Request) -> IronResult<Response> {
    let ref track_id = req.extensions.get::<Router>().unwrap()
                          .find("track_id").unwrap();
    match Track::find_by_id(track_id) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn show_track(req: &mut Request) -> IronResult<Response> {
    let provider   = req.extensions.get::<Router>().unwrap().find("provider").unwrap();
    let identifier = req.extensions.get::<Router>().unwrap().find("id").unwrap();
    let p = &Provider::new(provider.to_string());
    match Track::find_by(p, identifier) {
        Ok(track) => {
            Ok(Response::with((status::Ok,
                               application_json(),
                               track.to_json().to_string())))
        },
        Err(e) => Ok(e.as_response())
    }
}

pub fn update_track(req: &mut Request) -> IronResult<Response> {
    let mut track = try!(Track::find_by_id(&query_as_string(req, "track_id")));
    match param_as_string(req, "title") {
        Some(title) => track.title = title,
        None        => println!("no title")
    }
    match param_as_string(req, "url") {
        Some(url) => track.url = url,
        None      => println!("no url")
    }
    try!(track.save());
    let res = track.to_json().to_string();
    Ok(Response::with((status::Ok, application_json(), res)))
}

fn param_as_string(req: &mut Request, key: &str) -> Option<String> {
    match req.get_ref::<UrlEncodedBody>() {
        Ok(ref params) => match params.get(key) {
            Some(val) => Some(val[0].clone()),
            None      => None
        },
        Err(_) => None
    }
}

fn query_as_string(req: &mut Request, key: &str) -> String {
    return req.extensions.get::<Router>().unwrap()
        .find(key).unwrap().to_string();
}

fn pagination_params(req: &mut Request) -> (i64, i64) {
    match req.get_ref::<UrlEncodedQuery>() {
        Ok(ref params) =>
            (params.get("page").unwrap()[0].to_string().parse::<i64>().unwrap(),
             params.get("per_page").unwrap()[0].to_string().parse::<i64>().unwrap()),
        Err(_) =>
            (0, 10)
    }
}

fn application_json() -> Mime {
    Mime::from_str("application/json").ok().unwrap()
}

pub fn main() {
    let path = Path::new("public");
    let mut mount = Mount::new();
    mount.mount("/web/", Static::new(Path::new(path)));
    let router = router!(
        playlistify:           get  "/playlistify"              => playlistify,
        show_track_by_id:      get  "/tracks/:track_id"         => show_track_by_id,
        update_track:          post "/tracks/:track_id"         => update_track,
        show_track:            get  "/tracks/:provider/:id"     => show_track,
        index_entries:         get  "/entries"                  => index_entries,
        index_tracks:          get  "/tracks"                   => index_tracks,
        index_tracks_by_entry: get  "/entries/:entry_id/tracks" => index_tracks_by_entry,
        web:                   get  "/*"                        => mount,
    );
    let port_str = match std::env::var("PORT") {
        Ok(n)    => n,
        Err(_) => "8080".to_string()
    };
    let port: u16 = match port_str.trim().parse() {
        Ok(n) => n,
        Err(_) => {
            println!("Faild to parse port");
            return;
        }
    };
    println!("PORT {}", port_str);
    let ip = Ipv4Addr::new(0, 0, 0, 0);
    Iron::new(router).http(SocketAddrV4::new(ip, port)).unwrap();
}
<|endoftext|>