<commit_before>use pyembed::{default_python_config, ExtensionModule, MainPythonInterpreter};
use std::path::PathBuf;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
enum IOSCommands {
    Init,
    Ids,
}

#[derive(Debug, StructOpt)]
enum BuildCommands {
    Svg {
        #[structopt(flatten)]
        in_out: InOutPaths,
    },
    Android {
        #[structopt(long = "kbd-repo", default_value = "divvun/giellakbd-android")]
        kbd_repo: String,

        #[structopt(long = "kbd-branch", default_value = "develop")]
        kbd_branch: String,

        #[structopt(long = "divvunspell-repo", default_value = "divvun/divvunspell")]
        divvunspell_repo: String,

        #[structopt(long = "divvunspell-branch", default_value = "develop")]
        divvunspell_branch: String,

        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    IOS {
        #[structopt(subcommand)]
        command: Option<IOSCommands>,

        #[structopt(long = "kbd-repo", default_value = "divvun/giellakbd-ios")]
        kbd_repo: String,

        #[structopt(long = "kbd-branch", default_value = "develop")]
        kbd_branch: String,

        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Win {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Mac {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    X11 {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    M17n {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Chrome {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Qr {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short, long = "layout")]
        layout: String,
    },
    ErrorModel {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short, long = "layout")]
        layout: String,
    },
}

#[derive(Debug, StructOpt)]
struct InOutPaths {
    #[structopt(short, long = "output", default_value = ".", parse(from_os_str))]
    output_path: PathBuf,

    #[structopt(parse(from_os_str))]
    project_path: PathBuf,
}

#[derive(Debug, StructOpt)]
struct BuildMode {
    /// Compile in 'release' mode (where necessary).
    #[structopt(short = "R", long = "release")]
    release: bool,

    /// Continuous integration build
    #[structopt(long = "ci")]
    ci: bool,
}

#[derive(Debug, StructOpt)]
enum NewCommands {
    Layout {
        #[structopt(short, long = "output", default_value = ".", parse(from_os_str))]
        output_path: PathBuf,

        #[structopt(parse(from_os_str))]
        project_path: PathBuf,
    },
    Bundle {
        #[structopt(short, long = "output", default_value = ".", parse(from_os_str))]
        output_path: PathBuf,

        bundle_name: String,
    },
}

#[derive(Debug, StructOpt)]
enum Commands {
    Build {
        #[structopt(long = "github-username")]
        github_username: Option<String>,

        #[structopt(long = "github-token")]
        github_token: Option<String>,

        #[structopt(subcommand)]
        command: BuildCommands,
    },
    New {
        #[structopt(subcommand)]
        command: NewCommands,
    },
}

#[derive(Debug, StructOpt)]
#[structopt(name = "kbdgen")]
struct Opts {
    #[structopt(long = "logging", default_value = "info")]
    logging: String,

    #[structopt(subcommand)]
    command: Commands,
}

impl BuildCommands {
    fn to_py_args<'a>(
        &'a self,
        github_username: Option<&'a str>,
        github_token: Option<&'a str>,
        logging: &'a str,
    ) -> Result<Vec<&'a str>, Box<dyn std::error::Error>> {
        use BuildCommands::*;

        let mut args = match self {
            Svg {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
            } => vec![
                "-t",
                "svg",
                "-o",
                &*output_path.to_str().unwrap(),
                &*project_path.to_str().unwrap(),
            ],
            Android {
                kbd_repo,
                kbd_branch,
                divvunspell_repo,
                divvunspell_branch,
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec![
                    "-t",
                    "android",
                    "--kbd-repo",
                    kbd_repo,
                    "--kbd-branch",
                    kbd_branch,
                    "--divvunspell-repo",
                    divvunspell_repo,
                    "--divvunspell-branch",
                    divvunspell_branch,
                    "-o",
                    &*output_path.to_str().unwrap(),
                ];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());

                args
            }
            IOS {
                command,
                kbd_repo,
                kbd_branch,
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec![
                    "-t",
                    "ios",
                    "--kbd-repo",
                    kbd_repo,
                    "--kbd-branch",
                    kbd_branch,
                    "-o",
                    &*output_path.to_str().unwrap(),
                ];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                match command {
                    Some(IOSCommands::Init) => {
                        args.push("--command");
                        args.push("init");
                    }
                    Some(IOSCommands::Ids) => {
                        args.push("--command");
                        args.push("ids");
                    }
                    _ => {}
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            Chrome {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec!["-t", "chrome", "-o", &*output_path.to_str().unwrap()];

                if *release {
                    args.push("-R");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            Win {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec!["-t", "win", "-o", &*output_path.to_str().unwrap()];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            Mac {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec!["-t", "mac", "-o", &*output_path.to_str().unwrap()];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            M17n {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                build_mode: BuildMode { release, ci },
            } => return Err(From::from("M17n isn't supported in Python".to_string())),
            X11 {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                build_mode: BuildMode { release, ci },
            } => return Err(From::from("X11 isn't supported in Python".to_string())),
            Qr {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                layout,
            } => vec![
                "-t",
                "qr",
                "-o",
                &*output_path.to_str().unwrap(),
                "--command",
                layout,
                &*project_path.to_str().unwrap(),
            ],
            ErrorModel {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                layout,
            } => vec![
                "-t",
                "errormodel",
                "-o",
                &*output_path.to_str().unwrap(),
                "--command",
                layout,
                &*project_path.to_str().unwrap(),
            ],
            X11RS { .. } => unreachable!("covered in previous match"),
        };

        if let Some(gh_username) = github_username {
            args.push("--github-username");
            args.push(&*gh_username);
        }

        if let Some(gh_token) = github_token {
            args.push("--github-token");
            args.push(&*gh_token);
        }

        args.push("--logging");
        args.push(logging);

        Ok(args)
    }
}

fn launch_py_kbdgen(args: &[&str]) -> i32 {
    // Load the default Python configuration as derived by the PyOxidizer config
    // file used at build time.
    let mut config = default_python_config();

    let mod_language_tags = ExtensionModule {
        name: std::ffi::CString::new("language_tags").unwrap(),
        init_func: py_language_tags::PyInit_language_tags,
    };

    let mod_logger = ExtensionModule {
        name: std::ffi::CString::new("rust_logger").unwrap(),
        init_func: py_logger::PyInit_rust_logger,
    };

    config.extra_extension_modules = vec![mod_language_tags, mod_logger];

    // Construct a new Python interpreter using that config, handling any errors
    // from construction.
    match MainPythonInterpreter::new(config) {
        Ok(mut interp) => {
            // And run it using the default run configuration as specified by the
            // configuration. If an uncaught Python exception is raised, handle it.
            // This includes the special SystemExit, which is a request to terminate the
            // process.
            let args = format!(
                "[{}]",
                args.iter()
                    .map(|x| format!("{:?}", x))
                    .collect::<Vec<_>>()
                    .join(", ")
            );
            match interp.run_code(&format!("import kbdgen.cli; kbdgen.cli.run_cli({})", args)) {
                Ok(_) => 0,
                Err(msg) => {
                    let py = interp.acquire_gil();
                    msg.print(py);
                    1
                }
            }
        }
        Err(msg) => {
            eprintln!("{}", msg);
            1
        }
    }
}

fn main() {
    env_logger::init();

    let opt = Opts::from_args();

    match opt.command {
        Commands::Build { github_username, github_token, command } => {
            match command.to_py_args(github_username.as_ref().map(|x| &**x), github_token.as_ref().map(|x| &**x), &opt.logging) {
                Ok(args) => std::process::exit(launch_py_kbdgen(&args)),
                Err(e) => {
                    eprintln!("{:?}", e);
                    std::process::exit(1);
                }
            }
        },

        Commands::New { command } => match command {
            NewCommands::Bundle {
                bundle_name,
                output_path,
            } => match kbdgen::cli::from_cldr::cldr_to_kbdgen(&*output_path, &*bundle_name) {
                Ok(_) => std::process::exit(0),
                Err(e) => {
                    eprintln!("{:?}", e);
                    std::process::exit(1);
                }
            },
            NewCommands::Layout {
                project_path,
                output_path,
            } => {
                eprintln!("Not yet supported.");
                std::process::exit(1)
            }
        },
    }
}
<commit_msg>Enable info logging by default<commit_after>use pyembed::{default_python_config, ExtensionModule, MainPythonInterpreter};
use std::path::PathBuf;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
enum IOSCommands {
    Init,
    Ids,
}

#[derive(Debug, StructOpt)]
enum BuildCommands {
    Svg {
        #[structopt(flatten)]
        in_out: InOutPaths,
    },
    Android {
        #[structopt(long = "kbd-repo", default_value = "divvun/giellakbd-android")]
        kbd_repo: String,

        #[structopt(long = "kbd-branch", default_value = "develop")]
        kbd_branch: String,

        #[structopt(long = "divvunspell-repo", default_value = "divvun/divvunspell")]
        divvunspell_repo: String,

        #[structopt(long = "divvunspell-branch", default_value = "develop")]
        divvunspell_branch: String,

        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    IOS {
        #[structopt(subcommand)]
        command: Option<IOSCommands>,

        #[structopt(long = "kbd-repo", default_value = "divvun/giellakbd-ios")]
        kbd_repo: String,

        #[structopt(long = "kbd-branch", default_value = "develop")]
        kbd_branch: String,

        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Win {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Mac {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short = "D", long = "dry-run")]
        dry_run: bool,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    X11 {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    M17n {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Chrome {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(flatten)]
        build_mode: BuildMode,
    },
    Qr {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short, long = "layout")]
        layout: String,
    },
    ErrorModel {
        #[structopt(flatten)]
        in_out: InOutPaths,

        #[structopt(short, long = "layout")]
        layout: String,
    },
}

#[derive(Debug, StructOpt)]
struct InOutPaths {
    #[structopt(short, long = "output", default_value = ".", parse(from_os_str))]
    output_path: PathBuf,

    #[structopt(parse(from_os_str))]
    project_path: PathBuf,
}

#[derive(Debug, StructOpt)]
struct BuildMode {
    /// Compile in 'release' mode (where necessary).
    #[structopt(short = "R", long = "release")]
    release: bool,

    /// Continuous integration build
    #[structopt(long = "ci")]
    ci: bool,
}

#[derive(Debug, StructOpt)]
enum NewCommands {
    Layout {
        #[structopt(short, long = "output", default_value = ".", parse(from_os_str))]
        output_path: PathBuf,

        #[structopt(parse(from_os_str))]
        project_path: PathBuf,
    },
    Bundle {
        #[structopt(short, long = "output", default_value = ".", parse(from_os_str))]
        output_path: PathBuf,

        bundle_name: String,
    },
}

#[derive(Debug, StructOpt)]
enum Commands {
    Build {
        #[structopt(long = "github-username")]
        github_username: Option<String>,

        #[structopt(long = "github-token")]
        github_token: Option<String>,

        #[structopt(subcommand)]
        command: BuildCommands,
    },
    New {
        #[structopt(subcommand)]
        command: NewCommands,
    },
}

#[derive(Debug, StructOpt)]
#[structopt(name = "kbdgen")]
struct Opts {
    #[structopt(long = "logging", default_value = "info")]
    logging: String,

    #[structopt(subcommand)]
    command: Commands,
}

impl BuildCommands {
    fn to_py_args<'a>(
        &'a self,
        github_username: Option<&'a str>,
        github_token: Option<&'a str>,
        logging: &'a str,
    ) -> Result<Vec<&'a str>, Box<dyn std::error::Error>> {
        use BuildCommands::*;

        let mut args = match self {
            Svg {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
            } => vec![
                "-t",
                "svg",
                "-o",
                &*output_path.to_str().unwrap(),
                &*project_path.to_str().unwrap(),
            ],
            Android {
                kbd_repo,
                kbd_branch,
                divvunspell_repo,
                divvunspell_branch,
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec![
                    "-t",
                    "android",
                    "--kbd-repo",
                    kbd_repo,
                    "--kbd-branch",
                    kbd_branch,
                    "--divvunspell-repo",
                    divvunspell_repo,
                    "--divvunspell-branch",
                    divvunspell_branch,
                    "-o",
                    &*output_path.to_str().unwrap(),
                ];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());

                args
            }
            IOS {
                command,
                kbd_repo,
                kbd_branch,
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec![
                    "-t",
                    "ios",
                    "--kbd-repo",
                    kbd_repo,
                    "--kbd-branch",
                    kbd_branch,
                    "-o",
                    &*output_path.to_str().unwrap(),
                ];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                match command {
                    Some(IOSCommands::Init) => {
                        args.push("--command");
                        args.push("init");
                    }
                    Some(IOSCommands::Ids) => {
                        args.push("--command");
                        args.push("ids");
                    }
                    _ => {}
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            Chrome {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec!["-t", "chrome", "-o", &*output_path.to_str().unwrap()];

                if *release {
                    args.push("-R");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            Win {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec!["-t", "win", "-o", &*output_path.to_str().unwrap()];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            Mac {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                dry_run,
                build_mode: BuildMode { release, ci },
            } => {
                let mut args = vec!["-t", "mac", "-o", &*output_path.to_str().unwrap()];

                if *release {
                    args.push("-R");
                }

                if *dry_run {
                    args.push("-D");
                }

                if *ci {
                    args.push("--ci");
                }

                args.push(&*project_path.to_str().unwrap());
                args
            }
            M17n {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                build_mode: BuildMode { release, ci },
            } => return Err(From::from("M17n isn't supported in Python".to_string())),
            X11 {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                build_mode: BuildMode { release, ci },
            } => return Err(From::from("X11 isn't supported in Python".to_string())),
            Qr {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                layout,
            } => vec![
                "-t",
                "qr",
                "-o",
                &*output_path.to_str().unwrap(),
                "--command",
                layout,
                &*project_path.to_str().unwrap(),
            ],
            ErrorModel {
                in_out:
                    InOutPaths {
                        output_path,
                        project_path,
                    },
                layout,
            } => vec![
                "-t",
                "errormodel",
                "-o",
                &*output_path.to_str().unwrap(),
                "--command",
                layout,
                &*project_path.to_str().unwrap(),
            ],
            X11RS { .. } => unreachable!("covered in previous match"),
        };

        if let Some(gh_username) = github_username {
            args.push("--github-username");
            args.push(&*gh_username);
        }

        if let Some(gh_token) = github_token {
            args.push("--github-token");
            args.push(&*gh_token);
        }

        args.push("--logging");
        args.push(logging);

        Ok(args)
    }
}

fn launch_py_kbdgen(args: &[&str]) -> i32 {
    // Load the default Python configuration as derived by the PyOxidizer config
    // file used at build time.
    let mut config = default_python_config();

    let mod_language_tags = ExtensionModule {
        name: std::ffi::CString::new("language_tags").unwrap(),
        init_func: py_language_tags::PyInit_language_tags,
    };

    let mod_logger = ExtensionModule {
        name: std::ffi::CString::new("rust_logger").unwrap(),
        init_func: py_logger::PyInit_rust_logger,
    };

    config.extra_extension_modules = vec![mod_language_tags, mod_logger];

    // Construct a new Python interpreter using that config, handling any errors
    // from construction.
    match MainPythonInterpreter::new(config) {
        Ok(mut interp) => {
            // And run it using the default run configuration as specified by the
            // configuration. If an uncaught Python exception is raised, handle it.
            // This includes the special SystemExit, which is a request to terminate the
            // process.
            let args = format!(
                "[{}]",
                args.iter()
                    .map(|x| format!("{:?}", x))
                    .collect::<Vec<_>>()
                    .join(", ")
            );
            match interp.run_code(&format!("import kbdgen.cli; kbdgen.cli.run_cli({})", args)) {
                Ok(_) => 0,
                Err(msg) => {
                    let py = interp.acquire_gil();
                    msg.print(py);
                    1
                }
            }
        }
        Err(msg) => {
            eprintln!("{}", msg);
            1
        }
    }
}

fn main() {
    env_logger::Builder::from_default_env()
        .filter(Some("kbdgen"), log::LevelFilter::Info)
        .target(env_logger::Target::Stderr)
        .init();

    let opt = Opts::from_args();

    match opt.command {
        Commands::Build { github_username, github_token, command } => {
            match command.to_py_args(github_username.as_ref().map(|x| &**x), github_token.as_ref().map(|x| &**x), &opt.logging) {
                Ok(args) => std::process::exit(launch_py_kbdgen(&args)),
                Err(e) => {
                    eprintln!("{:?}", e);
                    std::process::exit(1);
                }
            }
        },

        Commands::New { command } => match command {
            NewCommands::Bundle {
                bundle_name,
                output_path,
            } => match kbdgen::cli::from_cldr::cldr_to_kbdgen(&*output_path, &*bundle_name) {
                Ok(_) => std::process::exit(0),
                Err(e) => {
                    eprintln!("{:?}", e);
                    std::process::exit(1);
                }
            },
            NewCommands::Layout {
                project_path,
                output_path,
            } => {
                eprintln!("Not yet supported.");
                std::process::exit(1)
            }
        },
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;

use rustc_serialize::json::{Json, ToJson, ParserError, ErrorCode };
use std::str::FromStr;
use std::io::prelude::*;
use std::fs::{File, OpenOptions};

#[derive(Debug)]
struct ToDoList {
    list: Vec<String>
}

impl ToDoList {

    fn new() -> ToDoList {
        ToDoList { list: Vec::new() }
    }

    fn add(&mut self, s: String) {
        self.list.push(s);
    }

    fn remove(&mut self, id: usize) {
        if id < self.list.len() {
            let task = self.list.remove(id);
            println!("Задача #{} ({}) успешно удалена!", id, task);
        }

        else {
            panic!("Неверный номер элемента TODO-листа -- {}!", id);
        }
    }

    fn print(&self) {
        if self.list.len() == 0 {
            println!("Нет задач в листе!");
        }

        else {
            println!("Задачи:");
            for (i,task) in self.list.iter().enumerate() {
                println!("Задача {}: {}", i, task);
            }
        }
    }

    fn write_to_file(&self, f: &mut File) {
            f.seek(std::io::SeekFrom::Start(0)).unwrap();
            f.set_len(0).unwrap();
            f.write_all(&(self.to_json().to_string().into_bytes())).unwrap();
    }

}

impl ToJson for ToDoList {

    fn to_json(&self) -> Json {
        self.list.to_json()
    }

}

impl FromStr for ToDoList {

    type Err = ParserError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let error = ParserError::SyntaxError(ErrorCode::NotUtf8,0,0);
        if let Ok(object) = s.parse::<Json>() {
            if object.is_array() {
                let mut array: Vec<String> = Vec::new();
                for e in object.as_array().unwrap().iter() {
                    array.push(e.as_string().unwrap().into());
                }
                Ok(ToDoList { list: array })
            }
            else {
                Err(error)
            }
        }
        else {
            Err(error)
        }
    }
}

fn main() {
    use std::env;
    let mut vars = env::vars();
    let args = env::args();
    let mut storage: ToDoList;
    let mut storage_file: File;
    if let Some((_,home)) = vars.find(|&(ref name, _)| name == "HOME") {
        let path = home.clone() + "/.todo";
        if let Ok(mut file) = OpenOptions::new().read(true).write(true).open(path.clone()) {
            let mut string = String::new();
            if let Ok(_) = file.read_to_string(&mut string) {
                if let Ok(s) = string.parse::<ToDoList>() {
                    storage = s;
                }
                else {
                    panic!("Parse storage file error!");
                }
            }
            else {
                panic!("Cannot read from file to string!");
            }
            storage_file = file;
        }
        else if let Ok(mut file) = OpenOptions::new().write(true).create(true).open(path.clone()) {
            storage = ToDoList::new();
            file.write_all(storage.to_json().to_string().as_bytes()).unwrap();
            storage_file = file;
        }
        else {
            panic!("Cannot open or create storage by {}", path);
        }
    }
    else {
        panic!("Cannot find $HOME in your environment!");
    }
    if let Some(_) = env::args().position(|w| w == "list") {
        storage.print();
    }
    else if let Some(add) = env::args().position(|w| w == "add") {
        if add < (args.len() - 1) {
            storage.add(args.skip(add + 1).fold(String::new(), |s,e| s + " " + &e ));
            storage.write_to_file(&mut storage_file);
        }
        else {
            panic!("Нет описания после ключевого слова 'add'!");
        }
    }
    else if let Some(remove) = env::args().position(|w| w == "remove") {
        if remove < (args.len() - 1) {
            args.skip(remove + 1).fold((),|_, e| {
                if let Ok(id) = e.parse::<usize>() {
                    storage.remove(id);
                }
                else {
                    panic!("Невозможно удалить элемент {} -- неверный ID", e);
                }
            });
            storage.write_to_file(&mut storage_file);
        }
    }
    else {
        panic!("Нет аргументов!");
    }
}
<commit_msg>Little change of interface<commit_after>extern crate rustc_serialize;

use rustc_serialize::json::{Json, ToJson, ParserError, ErrorCode };
use std::str::FromStr;
use std::io::prelude::*;
use std::fs::{File, OpenOptions};

#[derive(Debug)]
struct ToDoList {
    list: Vec<String>
}

impl ToDoList {

    fn new() -> ToDoList {
        ToDoList { list: Vec::new() }
    }

    fn add(&mut self, s: String) {
        self.list.push(s);
    }

    fn remove(&mut self, id: usize) {
        if id < self.list.len() {
            let task = self.list.remove(id);
            println!("Задача #{} ({}) успешно удалена!", id, task);
        }

        else {
            panic!("Неверный номер элемента TODO-листа -- {}!", id);
        }
    }

    fn print(&self) {
        if self.list.len() == 0 {
            println!("Нет задач в листе!");
        }

        else {
            println!("Задачи:");
            for (i,task) in self.list.iter().enumerate() {
                println!("Задача {}: {}", i, task);
            }
        }
    }

    fn write_to_file(&self, f: &mut File) {
            f.seek(std::io::SeekFrom::Start(0)).unwrap();
            f.set_len(0).unwrap();
            f.write_all(&(self.to_json().to_string().into_bytes())).unwrap();
    }

}

impl ToJson for ToDoList {

    fn to_json(&self) -> Json {
        self.list.to_json()
    }

}

impl FromStr for ToDoList {

    type Err = ParserError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let error = ParserError::SyntaxError(ErrorCode::NotUtf8,0,0);
        if let Ok(object) = s.parse::<Json>() {
            if object.is_array() {
                let mut array: Vec<String> = Vec::new();
                for e in object.as_array().unwrap().iter() {
                    array.push(e.as_string().unwrap().into());
                }
                Ok(ToDoList { list: array })
            }
            else {
                Err(error)
            }
        }
        else {
            Err(error)
        }
    }
}

fn main() {
    use std::env;
    let mut vars = env::vars();
    let args = env::args();
    let mut storage: ToDoList;
    let mut storage_file: File;
    if let Some((_,home)) = vars.find(|&(ref name, _)| name == "HOME") {
        let path = home.clone() + "/.todo";
        if let Ok(mut file) = OpenOptions::new().read(true).write(true).open(path.clone()) {
            let mut string = String::new();
            if let Ok(_) = file.read_to_string(&mut string) {
                if let Ok(s) = string.parse::<ToDoList>() {
                    storage = s;
                }
                else {
                    panic!("Parse storage file error!");
                }
            }
            else {
                panic!("Cannot read from file to string!");
            }
            storage_file = file;
        }
        else if let Ok(mut file) = OpenOptions::new().write(true).create(true).open(path.clone()) {
            storage = ToDoList::new();
            file.write_all(storage.to_json().to_string().as_bytes()).unwrap();
            storage_file = file;
        }
        else {
            panic!("Cannot open or create storage by {}", path);
        }
    }
    else {
        panic!("Cannot find $HOME in your environment!");
    }
    if let Some(_) = env::args().position(|w| w == "list") {
        storage.print();
    }
    else if let Some(add) = env::args().position(|w| w == "add") {
        if add < (args.len() - 1) {
            storage.add(args.skip(add + 1).fold(String::new(), |s,e| s + " " + &e ));
            storage.write_to_file(&mut storage_file);
            println!("Задача успешно добавлена!");
        }
        else {
            panic!("Нет описания после ключевого слова 'add'!");
        }
    }
    else if let Some(remove) = env::args().position(|w| w == "remove") {
        if remove < (args.len() - 1) {
            args.skip(remove + 1).fold((),|_, e| {
                if let Ok(id) = e.parse::<usize>() {
                    storage.remove(id);
                }
                else {
                    panic!("Невозможно удалить элемент {} -- неверный ID", e);
                }
            });
            storage.write_to_file(&mut storage_file);
        }
    }
    else {
        panic!("Нет аргументов!");
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::ffi::OsString;
use std::fs;
use std::fs::{DirEntry, File};
use std::path::{Path,PathBuf};
use std::io::prelude::*;
extern crate rustc_serialize;
extern crate mustache;
extern crate time;

#[derive(RustcEncodable)]
struct Photo {
    caption: String,
    alt_text: String,
    full_image_path: String,
    image_path: String,
}

impl Photo {
    fn new(path: &PathBuf, file_name: &OsString) -> Photo {
        let path = path.to_str().unwrap();
        let image_name = file_name.to_str().unwrap();

        Photo {
            caption: String::new(),
            alt_text: String::new(),
            full_image_path: String::new(),
            image_path: String::new(),
        }
    }
}

#[derive(RustcEncodable)]
struct Post {
    categories: String,
    content: String,
    created: String,
    title: String,
    photos: Vec<Photo>,
}

impl Post {
    fn new() -> Post {
        Post {
            categories: "".to_owned(),
            content: String::new(),
            created: time::strftime("%Y-%m-%d %H:%M:%S +0100", &time::now()).unwrap(),
            title: "".to_owned(),
            photos: Vec::new(),
        }
    }

    fn get_file_name(&self) -> String {
        let lo_title = self.title.to_lowercase().replace(" ", "-");
        let today_date_str = time::strftime("%Y-%m-%d-", &time::now()).unwrap();

        format!("./_posts/{}{}.markdown", today_date_str, lo_title)
    }
}

fn look_for_photos(dir: &Path) -> Vec<Photo> {
    let mut images: Vec<Photo> = Vec::new();
    let mut img_filenames: Vec<String> = Vec::new();

    let is_dir: bool = fs::metadata(dir).unwrap().is_dir();

    if is_dir {
        println!("Is directory: {}", dir.to_str().unwrap());

        let dir_iter = fs::read_dir(dir).unwrap();

        for entry in dir_iter {
            let entry: DirEntry = entry.unwrap();
            let file_name = entry.file_name().into_string().unwrap();

            img_filenames.push(file_name);
            let mut photo = Photo::new(&entry.path(), &entry.file_name());
            images.push(photo);
        }
    }

    let imgs: String = &img_filenames.into_iter().collect();

    println!("Found images: {}", imgs);
    //println!("Found images: {}", String::from_iter(img_filenames));

    images
}

fn print_hint(placeholder: &str) {
    print!("\nPlease input your new post {}: ", placeholder);

    // Force print out, because stdout often gets buffered by line.
    io::stdout().flush().unwrap();
}

fn init_post() -> Post {
    let mut cnt = 1;
    let stdin = io::stdin();
    let mut post = Post::new();
    post.photos = look_for_photos(Path::new("./img/"));

    print_hint("title");

    for line in stdin.lock().lines() {
        //print_hint("HINT!");
        let input: String = line.unwrap().trim().to_owned();

        if input != "" {
            match cnt {
                1 => {
                    post.title = input;
                    print_hint("categories");
                }
                2 => {
                    post.categories = input;
                    //print_hint("... just HIT ENTER to exit.");
                    break
                }
                3 => {
                    break
                }
                _ => panic!("I'm so holy. Gnarf."),
            }
            cnt += 1;
        } else {
            println!("Idiot!");
        }
    }

    post
}

fn handle_template(post: &Post) {
    let mut template_content: String = String::new();
    let template: mustache::Template;
    let mut post_template: File = match File::open("./template.mustache") {
        Err(y) => panic!("{:?}", y),
        Ok(f) => f,
    };

    println!("Found template.");

    if let Err(err) = post_template.read_to_string(&mut template_content) {
        panic!("{:?}", err);
    }

    let mut new_file: File = match File::create(post.get_file_name()) {
        Err(y) => panic!("{:?}", y),
        Ok(f) => f,
    };

    template = mustache::compile_str(&template_content);

    template.render(&mut new_file, post).unwrap();

    println!("Successfully created new blog post: {}", post.get_file_name());
}

fn main() {
    let post: Post = init_post();
    handle_template(&post);
}
<commit_msg>Updated<commit_after>use std::io;
use std::ffi::OsString;
use std::fs;
use std::fs::{DirEntry, File};
use std::path::{Path,PathBuf};
use std::io::prelude::*;
extern crate rustc_serialize;
extern crate mustache;
extern crate time;

#[derive(RustcEncodable)]
struct Photo {
    caption: String,
    alt_text: String,
    full_image_path: String,
    image_path: String,
}

impl Photo {
    fn new(path: &PathBuf, file_name: &OsString) -> Photo {
        let path = path.to_str().unwrap().to_owned();
        let image_name = file_name.to_str().unwrap().to_owned();

        Photo {
            caption: String::new(),
            alt_text: String::new(),
            full_image_path: path,
            image_path: image_name,
        }
    }
}

#[derive(RustcEncodable)]
struct Post {
    categories: String,
    content: String,
    created: String,
    title: String,
    photos: Vec<Photo>,
}

impl Post {
    fn new() -> Post {
        Post {
            categories: "".to_owned(),
            content: String::new(),
            created: time::strftime("%Y-%m-%d %H:%M:%S +0100", &time::now()).unwrap(),
            title: "".to_owned(),
            photos: Vec::new(),
        }
    }

    fn get_file_name(&self) -> String {
        let lo_title = self.title.to_lowercase().replace(" ", "-");
        let today_date_str = time::strftime("%Y-%m-%d-", &time::now()).unwrap();

        format!("./_posts/{}{}.markdown", today_date_str, lo_title)
    }
}

fn look_for_photos(dir: &Path) -> Vec<Photo> {
    let mut images: Vec<Photo> = Vec::new();
    let mut img_filenames: Vec<String> = Vec::new();

    let is_dir: bool = fs::metadata(dir).unwrap().is_dir();

    if is_dir {
        println!("Is directory: {}", dir.to_str().unwrap());

        let dir_iter = fs::read_dir(dir).unwrap();

        for entry in dir_iter {
            let entry: DirEntry = entry.unwrap();
            let file_name = entry.file_name().into_string().unwrap();

            img_filenames.push(file_name);
            let photo = Photo::new(&entry.path(), &entry.file_name());
            images.push(photo);
        }
    }

    let imgs: String = img_filenames.into_iter().collect();

    println!("Found images: {}", imgs);
    //println!("Found images: {}", String::from_iter(img_filenames));

    images
}

fn print_hint(placeholder: &str) {
    print!("\nPlease input your new post {}: ", placeholder);

    // Force print out, because stdout often gets buffered by line.
    io::stdout().flush().unwrap();
}

fn init_post() -> Post {
    let mut cnt = 1;
    let stdin = io::stdin();
    let mut post = Post::new();
    post.photos = look_for_photos(Path::new("./img/"));

    print_hint("title");

    for line in stdin.lock().lines() {
        //print_hint("HINT!");
        let input: String = line.unwrap().trim().to_owned();

        if input != "" {
            match cnt {
                1 => {
                    post.title = input;
                    print_hint("categories");
                }
                2 => {
                    post.categories = input;
                    //print_hint("... just HIT ENTER to exit.");
                    break
                }
                3 => {
                    break
                }
                _ => panic!("I'm so holy. Gnarf."),
            }
            cnt += 1;
        } else {
            println!("Idiot!");
        }
    }

    post
}

fn handle_template(post: &Post) {
    let mut template_content: String = String::new();
    let template: mustache::Template;
    let mut post_template: File = match File::open("./template.mustache") {
        Err(y) => panic!("{:?}", y),
        Ok(f) => f,
    };

    println!("Found template.");

    if let Err(err) = post_template.read_to_string(&mut template_content) {
        panic!("{:?}", err);
    }

    let mut new_file: File = match File::create(post.get_file_name()) {
        Err(y) => panic!("{:?}", y),
        Ok(f) => f,
    };

    template = mustache::compile_str(&template_content).expect("Could not render template content");

    template.render(&mut new_file, post).unwrap();

    println!("Successfully created new blog post: {}", post.get_file_name());
}

fn main() {
    let post: Post = init_post();
    handle_template(&post);
}
<|endoftext|>


<commit_before>#![feature(core)]
#![feature(path)]

extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType, DiffLine,
    Commit, Diff, DiffFormat, DiffDelta, DiffHunk, Error, Oid};
use docopt::Docopt;
use std::old_io as io;
use std::old_io::BufferedReader;
use std::old_io::File;
use std::str;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit <repo> [<old> <new>]

If no commits are given, transit will revwalk from latest to oldest.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_repo: String,
    arg_old: Option<String>,
    arg_new: Option<String>,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    // Pull up the revwalk.
    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Unable to find repo.");
    // If we can destructures the two optional args into real things.
    if let (Some(old_string), Some(new_string)) = (args.arg_old, args.arg_new) {
        // Compare a specific commit pair.
        // Fist, get the commits. (Error checked)
        let old = Oid::from_str(&old_string[]).and_then(|oid| repo.find_commit(oid));
        let new = Oid::from_str(&new_string[]).and_then(|oid| repo.find_commit(oid));
        if old.is_ok() && new.is_ok() {
            let output = find_moves(&repo, &old.unwrap(), &new.unwrap()).unwrap();
            make_output(output);
        } else {
            panic!("Commit ids were not valid.");
        }
    } else {
        // Revwalk.
        let mut revwalk = repo.revwalk()
            .ok().expect("Unable to get revwalk.");
        // Setup some options.
        revwalk.simplify_first_parent(); // TODO: Maybe remove?
        let mut flags = git2::Sort::empty();
        flags.insert(git2::SORT_TIME);
        flags.insert(git2::SORT_TOPOLOGICAL);
        revwalk.set_sorting(flags);
        // Push HEAD to the revwalk.
        revwalk.push_head()
            .ok().expect("Unable to push HEAD.");
        // We sadly must collect here to use `.windows()`
        let history = revwalk.filter_map(|id| repo.find_commit(id).ok())
            .collect::<Vec<Commit>>();
        // Walk through each pair of commits.
        for pair in history.windows(2) {let (old, new) = (&pair[1], &pair[0]);
			let output = find_moves(&repo, old.clone(), new.clone()).unwrap();
			// mangle the vectors here to make pretty output
			make_output(output);
		}
	}
}

fn make_output(output: Vec<Output>) {
	println!("make_output:");
    println!("\toutput.len()={}", output.len());
    for i in range(0, output.len()) {
            println!("\told_commit={}",         output[i].old_commit);
            println!("\tnew_commit={}",         output[i].new_commit);
            println!("\torigin_line={}",        output[i].origin_line);
            println!("\tdestintation_line={}",  output[i].destination_line);
            println!("\tnum_lines={}",          output[i].num_lines);
    }
}

fn print_or_none<T: std::fmt::Display> (s: &str, opt: Option<T>) {
    print!("{}=", s);
    match opt {
        Some(value) => println!("{}", value),
        None => println!("NONE"),
    }
}

fn find_moves(repo: &Repository, old: &Commit, new: &Commit) -> Result<Vec<Output>, Error> {

    println!("\nFIND MOVES---------------------");

	let old_tree = try!(old.tree());
	let new_tree = try!(new.tree());
	// Build up a diff of the two trees.
	let diff = try!(Diff::tree_to_tree(repo, Some(&old_tree), Some(&new_tree), None));
	// State. TODO: Don't just use a u64.
	//let moved = 0;

    //let mut results: Vec<Output> = Vec::new();

    let mut has_addition = false;
    let mut has_deletion = false;

	//let mut current_hunk: Vec<String> = Vec::new();
	// Read about this function in http://alexcrichton.com/git2-rs/git2/struct.Diff.html#method.print
	// It's a bit weird, but I think it will provide the necessary information.
	diff.print(DiffFormat::Patch, |delta, maybe_hunk, line| -> bool {
		// Thinking:
		//  * If is not a hunk, keep going.
		//  * If it's a hunk, do regex magic.
		//  * Stick regex output into a hashmap as a hash.
		//  * Later, we will iterate through and output pased on the values.
		// Filter out all the boring context lines.
		// If we're not interested in this line just return since it will iterate to the next.
		if maybe_hunk.is_none() { return true }; // Return early.

        println!("");
        print_or_none("line.old_lineno()", line.old_lineno());
        print_or_none("line.new_lineno()", line.new_lineno());
        println!("line.num_lines()={}",  line.num_lines());
        println!("line.content_offset={}", line.content_offset());
        println!("|line.origin()|=|{}|", line.origin());  // Wrap in |'s to detect space characters.
        print!("line.content()={}", str::from_utf8(line.content()).unwrap());

        println!("delta.nfiles()={}", delta.nfiles());
        println!("delta.status()={:?}", delta.status());    // :? is for debug trait.
        println!("delta.old_file():\n\tid={}\n\tpath_bytes=TODO\n\tpath=TODO\n\tsize={}", delta.old_file().id(), delta.old_file().size());
        println!("delta.new_file():\n\tid={}\n\tpath_bytes=TODO\n\tpath=TODO\n\tsize={}", delta.new_file().id(), delta.new_file().size());

		match line.origin() {
			// Context
			' ' | '=' => {
                print!("= {}", str::from_utf8(line.content()).unwrap());
                true
            },
			// Headers
			'F' | 'H' => {
                print!("F {}", str::from_utf8(line.content()).unwrap());
                true
            },
			// Additions
			'+' | '>' => {
				print!("+ {}", str::from_utf8(line.content()).unwrap());
                has_addition = true;
				true
			},
			// Deletions
			'-' | '<' => {
				print!("- {}", str::from_utf8(line.content()).unwrap());
                has_deletion = true;
				true
			},
			// Other (We don't care about these.)
			_         => {
                print!("_ {}", str::from_utf8(line.content()).unwrap());
                true
            }
		}
			// Look at that match statement, what a hunk. So hunky.
			// match maybe_hunk {
			//     Some(hunk) => unimplemented!(),
			//     None => unimplemented!(),
			// }
	});

    println!("\nhas_addition={}, has_deletion={}", has_addition, has_deletion);

   // if has_addition && has_deletion {
/*
        results.push(Output {
		    old_commit: old.id(),
		    new_commit: new.id(),
		    origin_line: 0,
		    destination_line: 0,
		    num_lines: 0
        });
*/
    //}

    if !has_addition || !has_deletion {
        println!("Does not have addition or deletion.");
        Ok(vec![])  // Return empty vector.
    } else {

	    Ok(vec![Output {
		    old_commit: old.id(),
		    new_commit: new.id(),
		    origin_line: 0,
		    destination_line: 0,
		    num_lines: 0
	    }])
    }

   // Ok(results)
}

#[derive(Show)]
struct Output {
    old_commit: Oid,
    new_commit: Oid,
    origin_line: u32,
    destination_line: u32,
    num_lines: u32,
}
<commit_msg>Print Option with {:?}.<commit_after>#![feature(core)]
#![feature(path)]

extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType, DiffLine,
    Commit, Diff, DiffFormat, DiffDelta, DiffHunk, Error, Oid};
use docopt::Docopt;
use std::old_io as io;
use std::old_io::BufferedReader;
use std::old_io::File;
use std::str;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit <repo> [<old> <new>]

If no commits are given, transit will revwalk from latest to oldest.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_repo: String,
    arg_old: Option<String>,
    arg_new: Option<String>,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    // Pull up the revwalk.
    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Unable to find repo.");
    // If we can destructures the two optional args into real things.
    if let (Some(old_string), Some(new_string)) = (args.arg_old, args.arg_new) {
        // Compare a specific commit pair.
        // Fist, get the commits. (Error checked)
        let old = Oid::from_str(&old_string[]).and_then(|oid| repo.find_commit(oid));
        let new = Oid::from_str(&new_string[]).and_then(|oid| repo.find_commit(oid));
        if old.is_ok() && new.is_ok() {
            let output = find_moves(&repo, &old.unwrap(), &new.unwrap()).unwrap();
            make_output(output);
        } else {
            panic!("Commit ids were not valid.");
        }
    } else {
        // Revwalk.
        let mut revwalk = repo.revwalk()
            .ok().expect("Unable to get revwalk.");
        // Setup some options.
        revwalk.simplify_first_parent(); // TODO: Maybe remove?
        let mut flags = git2::Sort::empty();
        flags.insert(git2::SORT_TIME);
        flags.insert(git2::SORT_TOPOLOGICAL);
        revwalk.set_sorting(flags);
        // Push HEAD to the revwalk.
        revwalk.push_head()
            .ok().expect("Unable to push HEAD.");
        // We sadly must collect here to use `.windows()`
        let history = revwalk.filter_map(|id| repo.find_commit(id).ok())
            .collect::<Vec<Commit>>();
        // Walk through each pair of commits.
        for pair in history.windows(2) {let (old, new) = (&pair[1], &pair[0]);
			let output = find_moves(&repo, old.clone(), new.clone()).unwrap();
			// mangle the vectors here to make pretty output
			make_output(output);
		}
	}
}

fn make_output(output: Vec<Output>) {
	println!("make_output:");
    println!("\toutput.len()={}", output.len());
    for i in range(0, output.len()) {
            println!("\told_commit={}",         output[i].old_commit);
            println!("\tnew_commit={}",         output[i].new_commit);
            println!("\torigin_line={}",        output[i].origin_line);
            println!("\tdestintation_line={}",  output[i].destination_line);
            println!("\tnum_lines={}",          output[i].num_lines);
    }
}

fn find_moves(repo: &Repository, old: &Commit, new: &Commit) -> Result<Vec<Output>, Error> {

    println!("\nFIND MOVES---------------------");

	let old_tree = try!(old.tree());
	let new_tree = try!(new.tree());
	// Build up a diff of the two trees.
	let diff = try!(Diff::tree_to_tree(repo, Some(&old_tree), Some(&new_tree), None));
	// State. TODO: Don't just use a u64.
	//let moved = 0;

    //let mut results: Vec<Output> = Vec::new();

    let mut has_addition = false;
    let mut has_deletion = false;

	//let mut current_hunk: Vec<String> = Vec::new();
	// Read about this function in http://alexcrichton.com/git2-rs/git2/struct.Diff.html#method.print
	// It's a bit weird, but I think it will provide the necessary information.
	diff.print(DiffFormat::Patch, |delta, maybe_hunk, line| -> bool {
		// Thinking:
		//  * If is not a hunk, keep going.
		//  * If it's a hunk, do regex magic.
		//  * Stick regex output into a hashmap as a hash.
		//  * Later, we will iterate through and output pased on the values.
		// Filter out all the boring context lines.
		// If we're not interested in this line just return since it will iterate to the next.
		if maybe_hunk.is_none() { return true }; // Return early.

        println!("");
        println!("line.old_lineno()={:?}", line.old_lineno());
        println!("line.new_lineno()={:?}", line.new_lineno());
        println!("line.num_lines()={}",  line.num_lines());
        println!("line.content_offset={}", line.content_offset());
        println!("|line.origin()|=|{}|", line.origin());  // Wrap in |'s to detect space characters.
        print!("line.content()={}", str::from_utf8(line.content()).unwrap());

        println!("delta.nfiles()={}", delta.nfiles());
        println!("delta.status()={:?}", delta.status());    // :? is for debug trait.
        println!("delta.old_file():\n\tid={}\n\tpath_bytes=TODO\n\tpath=TODO\n\tsize={}", delta.old_file().id(), delta.old_file().size());
        println!("delta.new_file():\n\tid={}\n\tpath_bytes=TODO\n\tpath=TODO\n\tsize={}", delta.new_file().id(), delta.new_file().size());

		match line.origin() {
			// Context
			' ' | '=' => {
                print!("= {}", str::from_utf8(line.content()).unwrap());
                true
            },
			// Headers
			'F' | 'H' => {
                print!("F {}", str::from_utf8(line.content()).unwrap());
                true
            },
			// Additions
			'+' | '>' => {
				print!("+ {}", str::from_utf8(line.content()).unwrap());
                has_addition = true;
				true
			},
			// Deletions
			'-' | '<' => {
				print!("- {}", str::from_utf8(line.content()).unwrap());
                has_deletion = true;
				true
			},
			// Other (We don't care about these.)
			_         => {
                print!("_ {}", str::from_utf8(line.content()).unwrap());
                true
            }
		}
			// Look at that match statement, what a hunk. So hunky.
			// match maybe_hunk {
			//     Some(hunk) => unimplemented!(),
			//     None => unimplemented!(),
			// }
	});

    println!("\nhas_addition={}, has_deletion={}", has_addition, has_deletion);

   // if has_addition && has_deletion {
/*
        results.push(Output {
		    old_commit: old.id(),
		    new_commit: new.id(),
		    origin_line: 0,
		    destination_line: 0,
		    num_lines: 0
        });
*/
    //}

    if !has_addition || !has_deletion {
        println!("Does not have addition or deletion.");
        Ok(vec![])  // Return empty vector.
    } else {

	    Ok(vec![Output {
		    old_commit: old.id(),
		    new_commit: new.id(),
		    origin_line: 0,
		    destination_line: 0,
		    num_lines: 0
	    }])
    }

   // Ok(results)
}

#[derive(Show)]
struct Output {
    old_commit: Oid,
    new_commit: Oid,
    origin_line: u32,
    destination_line: u32,
    num_lines: u32,
}
<|endoftext|>


<commit_before>#![feature(phase)]
#[phase(plugin)]
extern crate regex_macros;
extern crate regex;

use std::io;
pub mod parser;

fn evaluate(input: &str) -> String {
    parser::parse(input).eval().to_string()
}

pub fn main() {
    loop {
        io::print(">> ");
        match io::stdin().read_line() {
            Ok(line) => {
                io::print("=> ");
                io::println(evaluate(line.as_slice().trim_right()).as_slice());
            }
            Err(_) => {
                io::print("\n");
                break;
            }
        }
    }
}
<commit_msg>jk no regex for now<commit_after>
use std::io;
pub mod parser;

fn evaluate(input: &str) -> String {
    parser::parse(input).eval().to_string()
}

pub fn main() {
    loop {
        io::print(">> ");
        match io::stdin().read_line() {
            Ok(line) => {
                io::print("=> ");
                io::println(evaluate(line.as_slice().trim_right()).as_slice());
            }
            Err(_) => {
                io::print("\n");
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate image;
extern crate pcg;

use pcg::PcgRng;
use rand::{Rng, SeedableRng};
use std::fs::File;
use std::path::Path;

#[derive(Copy, Clone)]
struct Aggregate {
    /// Age (iteration number)
    age: u32,

    /// Points to the position of the parent particle
    parent: (u32, u32),
}

struct Particle {
    x: u32,
    y: u32,
}

struct Space2d {
    width: u32,
    height: u32,

    /// For every point in the space, store information about a resting particle.

    aggregates: Vec<Option<Aggregate>>,

    /// The attraction neighborhood
    neighborhood: Vec<u8>,
}

impl Space2d {
    fn new(w: u32, h: u32) -> Space2d {
        assert!(w > 0 && h > 0);
        let nelems = (w + 2) as usize * (h + 2) as usize;
        Space2d {
            width: w,
            height: h,
            aggregates: (0..nelems).map(|_| None).collect(),
            neighborhood: (0..nelems).map(|_| 0).collect(),
        }
    }

    fn in_free_space(&self, p: &Particle) -> bool {
        let idx = self.xy_to_index(p.x, p.y);
        self.aggregates[idx].is_none()
    }

    fn attaches(&self, p: &Particle) -> bool {
        self.neighborhood[self.xy_to_index(p.x, p.y)] != 0
    }

    fn random_walk<R: Rng>(&mut self, iter: u32, rng: &mut R) {
        let mut p;

        // find free space
        loop {
            p = Particle {
                x: rng.gen_range(0, self.width),
                y: rng.gen_range(0, self.height),
            };

            if self.in_free_space(&p) {
                break;
            }
        }

        // now simulate until it hits another particle.
        loop {
            if self.attaches(&p) {
                self.set_seed(p.x, p.y, iter);
                break;
            }
            let mut x: i32 = p.x as i32;
            let mut y: i32 = p.y as i32;

            let off_x: i32 = rng.gen_range(0i32, 3) - 1;
            let off_y: i32 = rng.gen_range(0i32, 3) - 1;

            x += off_x;
            y += off_y;

            if x >= 0 && x < self.width as i32 {
                p.x = x as u32;
            }

            if y >= 0 && y < self.height as i32 {
                p.y = y as u32;
            }
        }
    }

    fn set_seed(&mut self, x: u32, y: u32, age: u32) {
        let idx = self.xy_to_index(x, y);
        self.aggregates[idx] = Some(Aggregate{
            age: age,
            parent: (x, y), // we are a root, so we are ourselves' parent
        });

        let rw = self.width as usize + 2;
        self.neighborhood[idx - 1 - rw] = 1;
        self.neighborhood[idx - rw] = 1;
        self.neighborhood[idx + 1 - rw] = 1;
        self.neighborhood[idx - 1] = 1;
        self.neighborhood[idx] = 1;
        self.neighborhood[idx + 1] = 1;
        self.neighborhood[idx - 1 + rw] = 1;
        self.neighborhood[idx + rw] = 1;
        self.neighborhood[idx + 1 + rw] = 1;
    }

    fn get_pixel(&self, x: u32, y: u32) -> Option<u32> {
        let idx = self.xy_to_index(x, y);
        self.aggregates[idx].map(|p| p.age)
    }

    #[inline]
    fn xy_to_index(&self, x: u32, y: u32) -> usize {
        debug_assert!(x < self.width && y < self.height);
        let rw = self.width as usize + 2;
        (y as usize + 1) * rw + x as usize + 1
    }

    fn save_png(&self, filename: &str, colors: &[(u8, u8, u8)], colors_step: u32) {
        let mut imgbuf = image::RgbaImage::new(self.width, self.height);

        for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
            let (r, g, b) = match self.get_pixel(x, y) {
                None => {
                    // white
                    (255, 255, 255)
                }
                Some(age) => {
                    let age = ((age as u32) / colors_step) as usize;
                    colors[age % colors.len()]
                }
            };
            *pixel = image::Rgba([r, g, b, 255]);
        }

        let ref mut fout = File::create(&Path::new(filename)).unwrap();
        let _ = image::DynamicImage::ImageRgba8(imgbuf).save(fout, image::PNG).unwrap();
    }
}

fn simulate_dla<R>(rng: &mut R,
                   width: u32,
                   height: u32,
                   iterations: u32,
                   seeds: &[(u32, u32)],
                   colors: &[(u8, u8, u8)],
                   colors_step: u32,
                   save_every: u32,
                   basename: &str)
    where R: Rng
{
    let mut space = Space2d::new(width, height);

    for &(x, y) in seeds {
        space.set_seed(x, y, 0);
    }

    space.save_png(&format!("{}_init.png", basename), colors, colors_step);

    for i in 1..iterations + 1 {
        if i % save_every == 0 {
            space.save_png(&format!("{}_{:05}.png", basename, i), colors, colors_step);
        }
        space.random_walk(i, rng);
    }
    space.save_png(&format!("{}_final.png", basename), colors, colors_step);
}

fn conf_middle() {
    let mut rng: PcgRng = SeedableRng::from_seed([0, 0]);
    const W: u32 = 400;
    const H: u32 = 300;
    const N: u32 = 20_000;

    let seeds = vec![(W / 2, H / 2)];
    simulate_dla(&mut rng,
                 W,
                 H,
                 N,
                 &seeds,
                 &[(0, 0, 0)],
                 1,
                 500,
                 "dla_middle");
}

fn conf_23() {
    let mut rng: PcgRng = SeedableRng::from_seed([0, 0]);
    const W: u32 = 400;
    const H: u32 = 180;
    const N: u32 = 20_000;

    const N_IN: u32 = 2;
    const N_OUT: u32 = 3;
    const SEED_HALF_WIDTH: u32 = 2;
    const SEED_HEIGHT: u32 = 2;

    let mut seeds = Vec::new();

    for i in 0..N_IN {
        for y in 0..SEED_HEIGHT {
            for x in 0..SEED_HALF_WIDTH {
                seeds.push(((i + 1) * W / (N_IN + 1) + x, y));
                seeds.push(((i + 1) * W / (N_IN + 1) - x, y));
            }
        }
    }

    for i in 0..N_OUT {
        for y in 0..SEED_HEIGHT {
            for x in 0..SEED_HALF_WIDTH {
                seeds.push(((i + 1) * W / (N_OUT + 1) + x, H - 1 - y));
                seeds.push(((i + 1) * W / (N_OUT + 1) - x, H - 1 - y));
            }
        }
    }

    let colors = [(0, 0, 0), (255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255)];
    simulate_dla(&mut rng, W, H, N, &seeds, &colors, 2000, 500, "dla_23");
}

fn main() {
    conf_middle();
    conf_23();
}
<commit_msg>Refactor<commit_after>extern crate rand;
extern crate image;
extern crate pcg;

use pcg::PcgRng;
use rand::{Rng, SeedableRng};
use std::fs::File;
use std::path::Path;

#[derive(Copy, Clone)]
struct Aggregate {
    /// Age (iteration number)
    age: u32,

    /// Points to the position of the parent particle
    parent: (u32, u32),
}

struct Particle {
    x: u32,
    y: u32,
}

pub struct Space2d {
    width: u32,
    height: u32,

    /// For every point in the space, store information about a resting particle.

    aggregates: Vec<Option<Aggregate>>,

    /// The attraction neighborhood
    neighborhood: Vec<u8>,
}

impl Space2d {
    pub fn new(w: u32, h: u32) -> Space2d {
        assert!(w > 0 && h > 0);
        let nelems = (w + 2) as usize * (h + 2) as usize;
        Space2d {
            width: w,
            height: h,
            aggregates: (0..nelems).map(|_| None).collect(),
            neighborhood: (0..nelems).map(|_| 0).collect(),
        }
    }

    fn in_free_space(&self, p: &Particle) -> bool {
        let idx = self.xy_to_index(p.x, p.y);
        self.aggregates[idx].is_none()
    }

    fn attaches(&self, p: &Particle) -> bool {
        self.neighborhood[self.xy_to_index(p.x, p.y)] != 0
    }

    pub fn random_walk<R: Rng>(&mut self, iter: u32, rng: &mut R) {
        let mut p;

        // find free space
        loop {
            p = Particle {
                x: rng.gen_range(0, self.width),
                y: rng.gen_range(0, self.height),
            };

            if self.in_free_space(&p) {
                break;
            }
        }

        // now simulate until it hits another particle.
        loop {
            if self.attaches(&p) {
                self.set_seed(p.x, p.y, iter);
                break;
            }
            let mut x: i32 = p.x as i32;
            let mut y: i32 = p.y as i32;

            let off_x: i32 = rng.gen_range(0i32, 3) - 1;
            let off_y: i32 = rng.gen_range(0i32, 3) - 1;

            x += off_x;
            y += off_y;

            if x >= 0 && x < self.width as i32 {
                p.x = x as u32;
            }

            if y >= 0 && y < self.height as i32 {
                p.y = y as u32;
            }
        }
    }

    pub fn set_seed(&mut self, x: u32, y: u32, age: u32) {
        let idx = self.xy_to_index(x, y);
        self.aggregates[idx] = Some(Aggregate{
            age: age,
            parent: (x, y), // we are a root, so we are ourselves' parent
        });

        self.set_neighborhood(idx);
    }

    fn set_neighborhood(&mut self, idx: usize) {
        let rw = self.width as usize + 2;
        self.neighborhood[idx - 1 - rw] = 1;
        self.neighborhood[idx - rw] = 1;
        self.neighborhood[idx + 1 - rw] = 1;
        self.neighborhood[idx - 1] = 1;
        self.neighborhood[idx] = 1;
        self.neighborhood[idx + 1] = 1;
        self.neighborhood[idx - 1 + rw] = 1;
        self.neighborhood[idx + rw] = 1;
        self.neighborhood[idx + 1 + rw] = 1;
    }

    fn get_pixel(&self, x: u32, y: u32) -> Option<u32> {
        let idx = self.xy_to_index(x, y);
        self.aggregates[idx].map(|p| p.age)
    }

    #[inline]
    fn xy_to_index(&self, x: u32, y: u32) -> usize {
        debug_assert!(x < self.width && y < self.height);
        let rw = self.width as usize + 2;
        (y as usize + 1) * rw + x as usize + 1
    }

    pub fn save_png(&self, filename: &str, colors: &[(u8, u8, u8)], colors_step: u32) {
        let mut imgbuf = image::RgbaImage::new(self.width, self.height);

        for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
            let (r, g, b) = match self.get_pixel(x, y) {
                None => {
                    // white
                    (255, 255, 255)
                }
                Some(age) => {
                    let age = ((age as u32) / colors_step) as usize;
                    colors[age % colors.len()]
                }
            };
            *pixel = image::Rgba([r, g, b, 255]);
        }

        let ref mut fout = File::create(&Path::new(filename)).unwrap();
        let _ = image::DynamicImage::ImageRgba8(imgbuf).save(fout, image::PNG).unwrap();
    }
}

fn simulate_dla<R>(rng: &mut R,
                   width: u32,
                   height: u32,
                   iterations: u32,
                   seeds: &[(u32, u32)],
                   colors: &[(u8, u8, u8)],
                   colors_step: u32,
                   save_every: u32,
                   basename: &str)
    where R: Rng
{
    let mut space = Space2d::new(width, height);

    for &(x, y) in seeds {
        space.set_seed(x, y, 0);
    }

    space.save_png(&format!("{}_init.png", basename), colors, colors_step);

    for i in 1..iterations + 1 {
        if i % save_every == 0 {
            space.save_png(&format!("{}_{:05}.png", basename, i), colors, colors_step);
        }
        space.random_walk(i, rng);
    }
    space.save_png(&format!("{}_final.png", basename), colors, colors_step);
}

fn conf_middle() {
    let mut rng: PcgRng = SeedableRng::from_seed([0, 0]);
    const W: u32 = 400;
    const H: u32 = 300;
    const N: u32 = 20_000;

    let seeds = vec![(W / 2, H / 2)];
    simulate_dla(&mut rng,
                 W,
                 H,
                 N,
                 &seeds,
                 &[(0, 0, 0)],
                 1,
                 500,
                 "dla_middle");
}

fn conf_23() {
    let mut rng: PcgRng = SeedableRng::from_seed([0, 0]);
    const W: u32 = 400;
    const H: u32 = 180;
    const N: u32 = 20_000;

    const N_IN: u32 = 2;
    const N_OUT: u32 = 3;
    const SEED_HALF_WIDTH: u32 = 2;
    const SEED_HEIGHT: u32 = 2;

    let mut seeds = Vec::new();

    for i in 0..N_IN {
        for y in 0..SEED_HEIGHT {
            for x in 0..SEED_HALF_WIDTH {
                seeds.push(((i + 1) * W / (N_IN + 1) + x, y));
                seeds.push(((i + 1) * W / (N_IN + 1) - x, y));
            }
        }
    }

    for i in 0..N_OUT {
        for y in 0..SEED_HEIGHT {
            for x in 0..SEED_HALF_WIDTH {
                seeds.push(((i + 1) * W / (N_OUT + 1) + x, H - 1 - y));
                seeds.push(((i + 1) * W / (N_OUT + 1) - x, H - 1 - y));
            }
        }
    }

    let colors = [(0, 0, 0), (255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255)];
    simulate_dla(&mut rng, W, H, N, &seeds, &colors, 2000, 500, "dla_23");
}

fn main() {
    conf_middle();
    conf_23();
}
<|endoftext|>


<commit_before>extern crate xcb;
extern crate cairo;
extern crate cairo_sys;
extern crate pango;
extern crate pangocairo;

use std::rc::Rc;

use cairo::{Context, Surface, XCBConnection, XCBDrawable, XCBSurface, XCBVisualType};
use pango::LayoutExt;
use pangocairo::CairoContextExt;
use xcb::ffi::*;

fn get_root_visual_type(conn: &xcb::Connection, screen: &xcb::Screen) -> xcb::Visualtype {
    for root in conn.get_setup().roots() {
        for allowed_depth in root.allowed_depths() {
            for visual in allowed_depth.visuals() {
                if visual.visual_id() == screen.root_visual() {
                    return visual;
                }
            }
        }
    }
    panic!("No visual type found");
}

// TODO: impl Drop?
struct Window {
    conn: Rc<xcb::Connection>,
    screen_idx: usize,
    id: u32,
    surface: Surface,
}

impl Window {
    fn new(conn: Rc<xcb::Connection>, screen_idx: usize) -> Window {
        let id = conn.generate_id();

        let surface = {
            let screen = conn.get_setup()
                .roots()
                .nth(screen_idx)
                .expect("invalid screen");
            let values = [(xcb::CW_BACK_PIXEL, screen.black_pixel()),
                          (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE)];

            let (width, height) = (screen.width_in_pixels(), 100);

            xcb::create_window(&conn,
                               xcb::COPY_FROM_PARENT as u8,
                               id,
                               screen.root(),
                               0,
                               0,
                               width,
                               height,
                               10,
                               xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
                               screen.root_visual(),
                               &values);

            let surface = unsafe {
                let cairo_conn = XCBConnection::from_raw_none(conn.get_raw_conn() as
                                                              *mut cairo_sys::xcb_connection_t);
                let visual = XCBVisualType::from_raw_none(&mut get_root_visual_type(&conn, &screen).base as
                                                          *mut xcb::ffi::xcb_visualtype_t as
                                                          *mut cairo_sys::xcb_visualtype_t);
                let drawable = XCBDrawable(id);
                Surface::create(&cairo_conn, &drawable, &visual, width as i32, height as i32)
                // TODO: Update surface width/height when window size changes.
            };

            surface
        };

        xcb::map_window(&conn, id);
        conn.flush();

        Window {
            conn,
            screen_idx,
            id,
            surface,
        }
    }

    fn screen<'a>(&'a self) -> xcb::Screen<'a> {
        self.conn
            .get_setup()
            .roots()
            .nth(self.screen_idx)
            .expect("Invalid screen")
    }

    fn expose(&self) {
        let font = pango::FontDescription::from_string("Envy Code R 27");

        let cr = Context::new(&self.surface);
        cr.set_source_rgb(1.0, 0.0, 0.0);

        let layout = cr.create_pango_layout();
        layout.set_text("Hello, world!", 13);
        layout.set_font_description(Some(&font));

        cr.show_pango_layout(&layout);

        self.conn.flush();
    }
}

fn main() {
    let (conn, screen_idx) = xcb::Connection::connect_with_xlib_display().unwrap();
    let conn = Rc::new(conn);

    let w = Window::new(conn.clone(), screen_idx as usize);

    loop {
        let event = conn.wait_for_event();
        match event {
            None => {
                break;
            }
            Some(event) => {
                let r = event.response_type() & !0x80;
                match r {
                    xcb::EXPOSE => w.expose(),
                    _ => {}
                }
            }
        }
    }
}
<commit_msg>cargo fmt<commit_after>extern crate xcb;
extern crate cairo;
extern crate cairo_sys;
extern crate pango;
extern crate pangocairo;

use std::rc::Rc;

use cairo::{Context, Surface, XCBConnection, XCBDrawable, XCBSurface, XCBVisualType};
use pango::LayoutExt;
use pangocairo::CairoContextExt;
use xcb::ffi::*;

fn get_root_visual_type(conn: &xcb::Connection, screen: &xcb::Screen) -> xcb::Visualtype {
    for root in conn.get_setup().roots() {
        for allowed_depth in root.allowed_depths() {
            for visual in allowed_depth.visuals() {
                if visual.visual_id() == screen.root_visual() {
                    return visual;
                }
            }
        }
    }
    panic!("No visual type found");
}

// TODO: impl Drop?
struct Window {
    conn: Rc<xcb::Connection>,
    screen_idx: usize,
    id: u32,
    surface: Surface,
}

impl Window {
    fn new(conn: Rc<xcb::Connection>, screen_idx: usize) -> Window {
        let id = conn.generate_id();

        let surface = {
            let screen = conn.get_setup()
                .roots()
                .nth(screen_idx)
                .expect("invalid screen");
            let values = [(xcb::CW_BACK_PIXEL, screen.black_pixel()),
                          (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE)];

            let (width, height) = (screen.width_in_pixels(), 100);

            xcb::create_window(&conn,
                               xcb::COPY_FROM_PARENT as u8,
                               id,
                               screen.root(),
                               0,
                               0,
                               width,
                               height,
                               10,
                               xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
                               screen.root_visual(),
                               &values);

            let surface = unsafe {
                let cairo_conn = XCBConnection::from_raw_none(conn.get_raw_conn() as
                                                              *mut cairo_sys::xcb_connection_t);
                let visual =
                    XCBVisualType::from_raw_none(&mut get_root_visual_type(&conn, &screen).base as
                                                 *mut xcb::ffi::xcb_visualtype_t as
                                                 *mut cairo_sys::xcb_visualtype_t);
                let drawable = XCBDrawable(id);
                Surface::create(&cairo_conn, &drawable, &visual, width as i32, height as i32)
                // TODO: Update surface width/height when window size changes.
            };

            surface
        };

        xcb::map_window(&conn, id);
        conn.flush();

        Window {
            conn,
            screen_idx,
            id,
            surface,
        }
    }

    fn screen<'a>(&'a self) -> xcb::Screen<'a> {
        self.conn
            .get_setup()
            .roots()
            .nth(self.screen_idx)
            .expect("Invalid screen")
    }

    fn expose(&self) {
        let font = pango::FontDescription::from_string("Envy Code R 27");

        let cr = Context::new(&self.surface);
        cr.set_source_rgb(1.0, 0.0, 0.0);

        let layout = cr.create_pango_layout();
        layout.set_text("Hello, world!", 13);
        layout.set_font_description(Some(&font));

        cr.show_pango_layout(&layout);

        self.conn.flush();
    }
}

fn main() {
    let (conn, screen_idx) = xcb::Connection::connect_with_xlib_display().unwrap();
    let conn = Rc::new(conn);

    let w = Window::new(conn.clone(), screen_idx as usize);

    loop {
        let event = conn.wait_for_event();
        match event {
            None => {
                break;
            }
            Some(event) => {
                let r = event.response_type() & !0x80;
                match r {
                    xcb::EXPOSE => w.expose(),
                    _ => {}
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate serde_json;

use std::string::String;
use std::io::Read;
use serde_json::Value;

fn get_title(user: &str, repo: &str, issue: &str) -> String {
    let url = format!("https://api.github.com/repos/{}/{}/issues/{}",
                      user, repo, issue);
    let client = hyper::client::Client::new();
    let mut resp = client
        .get(&url)
        .header(hyper::header::UserAgent("ids1024".to_owned()))
        .send()
        .unwrap();

    let mut body = String::new();
    resp.read_to_string(&mut body).unwrap();
    let data: Value = serde_json::from_str(&body).unwrap();
    let obj = data.as_object().unwrap();

    let title = obj.get("title").unwrap().as_string().unwrap();
    let state = obj.get("state").unwrap().as_string().unwrap();
    let url = obj.get("html_url").unwrap().as_string().unwrap();
    let issuetype =
        if obj.get("pull_request") != None {
            "pull request"
        } else {
            "issue"
        };

    return format!("[{}] [{}] {}\n{}", issuetype, state, title, url);
}

fn main() {
    println!("{}", get_title("mps-youtube", "mps-youtube", "1"));
}
<commit_msg>Do not use unwrap(); allowing error handling<commit_after>extern crate hyper;
extern crate serde_json;

use std::string::String;
use std::io::Read;
use serde_json::Value;

#[derive(Debug)]
struct GithubError;

impl From<hyper::error::Error> for GithubError {
    fn from(_: hyper::error::Error) -> Self {
        GithubError
    }
}

impl From<serde_json::error::Error> for GithubError {
    fn from(_: serde_json::error::Error) -> Self {
        GithubError
    }
}

impl From<std::io::Error> for GithubError {
    fn from(_: std::io::Error) -> Self {
        GithubError
    }
}

fn get_title(user: &str, repo: &str, issue: &str) -> Result<String, GithubError> {
    let url = format!("https://api.github.com/repos/{}/{}/issues/{}",
                      user, repo, issue);
    let client = hyper::client::Client::new();
    let mut resp = try!(client
        .get(&url)
        .header(hyper::header::UserAgent("ids1024".to_owned()))
        .send());

    let mut body = String::new();
    try!(resp.read_to_string(&mut body));
    let data: Value = try!(serde_json::from_str(&body));
    let obj = try!(data.as_object().ok_or(GithubError));

    let title = try!(try!(obj.get("title").ok_or(GithubError))
                     .as_string().ok_or(GithubError));
    let state = try!(try!(obj.get("state").ok_or(GithubError))
                     .as_string().ok_or(GithubError));
    let url = try!(try!(obj.get("html_url").ok_or(GithubError))
                        .as_string().ok_or(GithubError));
    let issuetype =
        if obj.get("pull_request") != None {
            "pull request"
        } else {
            "issue"
        };

    return Ok(format!("[{}] [{}] {}\n{}", issuetype, state, title, url));
}

fn main() {
    println!("{:?}", get_title("mps-youtube", "mps-youtube", "1"));
}
<|endoftext|>


<commit_before>use gl;
use std;
use std::mem;
use sdl2;
use sdl2::event;
use sdl2::event::Event;
use sdl2::video;
use stopwatch::TimerSet;
use yaglw::gl_context::GLContext;
use yaglw::shader::Shader;
use yaglw::texture::BufferTexture;
use yaglw::vertex_buffer::{ArrayHandle};

pub const WINDOW_WIDTH: u32 = 800;
pub const WINDOW_HEIGHT: u32 = 800;

pub fn main() {
  let timers = TimerSet::new();

  let mut sdl = sdl2::init().everything().unwrap();
  let window = make_window(&sdl);

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(video::gl_get_proc_address(s))
  });

  let mut gl = unsafe {
    GLContext::new()
  };
  let gl = &mut gl;

  match gl.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  let shader = make_shader(gl);
  shader.use_shader(gl);

  let mut heightmap =
    BufferTexture::new(gl, gl::R32F, WINDOW_WIDTH as usize);
  heightmap.buffer.push(gl, &[0.0; WINDOW_WIDTH as usize]);

  let empty_vao = ArrayHandle::new(gl);

  unsafe {
    gl::BindVertexArray(empty_vao.gl_id);
  }

  let mut event_pump = sdl.event_pump();

  while process_events(&mut event_pump) {
    timers.time("draw", || {
      gl.clear_buffer();
      unsafe {
        gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
      }
      // swap buffers
      window.gl_swap_window();
    });

    std::thread::sleep_ms(10);
  }

  timers.print();
}

fn make_shader<'a, 'b:'a>(
  gl: &'a GLContext,
) -> Shader<'b> {
  let vertex_shader: String = format!("
    #version 330 core

    void main() {{
      if (gl_VertexID == 0) {{
        gl_Position = vec4(-1, 1, 0, 1);
      }} else if (gl_VertexID == 1) {{
        gl_Position = vec4(-1, -1, 0, 1);
      }} else if (gl_VertexID == 2) {{
        gl_Position = vec4(1, 1, 0, 1);
      }} else {{
        gl_Position = vec4(1, -1, 0, 1);
      }}
    }}
  ");

  let fragment_shader: String = format!("
    #version 330 core

    layout(location=0) out vec4 frag_color;

    void main() {{
      frag_color = vec4(1, 0, 0, 1);
    }}
  ");

  let components = vec!(
    (gl::VERTEX_SHADER, vertex_shader),
    (gl::FRAGMENT_SHADER, fragment_shader),
  );

  Shader::new(gl, components.into_iter())
}

fn make_window(sdl: &sdl2::Sdl) -> video::Window {
  video::gl_attr::set_context_profile(video::GLProfile::Core);
  video::gl_attr::set_context_version(3, 3);

  // Open the window as fullscreen at the current resolution.
  let mut window =
    video::WindowBuilder::new(
      &sdl,
      "Hello, Mandelbrot",
      WINDOW_WIDTH, WINDOW_HEIGHT,
    );

  let window = window.position_centered();
  window.opengl();

  window.build().unwrap()
}

fn process_events<'a>(
  event_pump: &mut event::EventPump,
) -> bool {
  for event in event_pump.poll_iter() {
    match event {
      Event::Quit {..} => {
        return false;
      },
      Event::AppTerminating {..} => {
        return false;
      },
      _ => {},
    }
  }

  true
}
<commit_msg>Bind heightmap to a shader uniform<commit_after>use gl;
use gl::types::GLint;
use std;
use std::mem;
use sdl2;
use sdl2::event;
use sdl2::event::Event;
use sdl2::video;
use stopwatch::TimerSet;
use yaglw::gl_context::GLContext;
use yaglw::shader::Shader;
use yaglw::texture::{BufferTexture, TextureUnit};
use yaglw::vertex_buffer::{ArrayHandle};

pub const WINDOW_WIDTH: u32 = 800;
pub const WINDOW_HEIGHT: u32 = 800;

pub fn main() {
  let timers = TimerSet::new();

  let mut sdl = sdl2::init().everything().unwrap();
  let window = make_window(&sdl);

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(video::gl_get_proc_address(s))
  });

  let mut gl = unsafe {
    GLContext::new()
  };
  let gl = &mut gl;

  match gl.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  let mut shader = make_shader(gl);
  shader.use_shader(gl);

  let mut heightmap =
    BufferTexture::new(gl, gl::R32F, WINDOW_WIDTH as usize);
  heightmap.buffer.push(gl, &[0.0; WINDOW_WIDTH as usize]);

  {
    let mut bind = |name, id| {
      let unit: TextureUnit = Default::default();
      unsafe {
        gl::ActiveTexture(unit.gl_id());
        gl::BindTexture(gl::TEXTURE_BUFFER, id);
      }
      let loc = shader.get_uniform_location(name);
      unsafe {
        gl::Uniform1i(loc, unit.glsl_id as GLint);
      }
    };

    bind("heightmap", heightmap.buffer.byte_buffer.handle.gl_id);
  }

  let empty_vao = ArrayHandle::new(gl);

  unsafe {
    gl::BindVertexArray(empty_vao.gl_id);
  }

  let mut event_pump = sdl.event_pump();

  while process_events(&mut event_pump) {
    timers.time("draw", || {
      gl.clear_buffer();
      unsafe {
        gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
      }
      // swap buffers
      window.gl_swap_window();
    });

    std::thread::sleep_ms(10);
  }

  timers.print();
}

fn make_shader<'a, 'b:'a>(
  gl: &'a GLContext,
) -> Shader<'b> {
  let vertex_shader: String = format!("
    #version 330 core

    void main() {{
      if (gl_VertexID == 0) {{
        gl_Position = vec4(-1, 1, 0, 1);
      }} else if (gl_VertexID == 1) {{
        gl_Position = vec4(-1, -1, 0, 1);
      }} else if (gl_VertexID == 2) {{
        gl_Position = vec4(1, 1, 0, 1);
      }} else {{
        gl_Position = vec4(1, -1, 0, 1);
      }}
    }}
  ");

  let fragment_shader: String = format!("
    #version 330 core

    uniform samplerBuffer heightmap;

    layout(location=0) out vec4 frag_color;

    void main() {{
      float y = texelFetch(heightmap, 0).r;
      frag_color = vec4(1, y-y, 0, 1);
    }}
  ");

  let components = vec!(
    (gl::VERTEX_SHADER, vertex_shader),
    (gl::FRAGMENT_SHADER, fragment_shader),
  );

  Shader::new(gl, components.into_iter())
}

fn make_window(sdl: &sdl2::Sdl) -> video::Window {
  video::gl_attr::set_context_profile(video::GLProfile::Core);
  video::gl_attr::set_context_version(3, 3);

  // Open the window as fullscreen at the current resolution.
  let mut window =
    video::WindowBuilder::new(
      &sdl,
      "Hello, Mandelbrot",
      WINDOW_WIDTH, WINDOW_HEIGHT,
    );

  let window = window.position_centered();
  window.opengl();

  window.build().unwrap()
}

fn process_events<'a>(
  event_pump: &mut event::EventPump,
) -> bool {
  for event in event_pump.poll_iter() {
    match event {
      Event::Quit {..} => {
        return false;
      },
      Event::AppTerminating {..} => {
        return false;
      },
      _ => {},
    }
  }

  true
}
<|endoftext|>