<commit_before>#[macro_use]
extern crate clap;
extern crate ansi_term;
extern crate atty;
extern crate regex;
extern crate ignore;

pub mod lscolors;
pub mod fshelper;

use std::borrow::Cow;
use std::env;
use std::error::Error;
use std::io::Write;
use std::ops::Deref;
#[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf, Component};
use std::process;
use std::sync::Arc;
use std::sync::mpsc::channel;
use std::thread;
use std::time;

use clap::{App, AppSettings, Arg};
use atty::Stream;
use regex::{Regex, RegexBuilder};
use ignore::WalkBuilder;

use lscolors::LsColors;

/// Defines how to display search result paths.
#[derive(PartialEq)]
enum PathDisplay {
    /// As an absolute path
    Absolute,

    /// As a relative path
    Relative
}

/// Configuration options for *fd*.
struct FdOptions {
    /// Determines whether the regex search is case-sensitive or case-insensitive.
    case_sensitive: bool,

    /// Whether to search within the full file path or just the base name (filename or directory
    /// name).
    search_full_path: bool,

    /// Whether to ignore hidden files and directories (or not).
    ignore_hidden: bool,

    /// Whether to respect VCS ignore files (`.gitignore`, `.ignore`, ..) or not.
    read_ignore: bool,

    /// Whether to follow symlinks or not.
    follow_links: bool,

    /// Whether elements of output should be separated by a null character
    null_separator: bool,

    /// The maximum search depth, or `None` if no maximum search depth should be set.
    ///
    /// A depth of `1` includes all files under the current directory, a depth of `2` also includes
    /// all files under subdirectories of the current directory, etc.
    max_depth: Option<usize>,

    /// The number of threads to use.
    threads: Option<usize>,

    /// Time to buffer results internally before streaming to the console. This is useful to
    /// provide a sorted output, in case the total execution time is shorter than
    /// `max_buffer_time`.
    max_buffer_time: Option<time::Duration>,

    /// Display results as relative or absolute path.
    path_display: PathDisplay,

    /// `None` if the output should not be colorized. Otherwise, a `LsColors` instance that defines
    /// how to style different filetypes.
    ls_colors: Option<LsColors>
}

/// The receiver thread can either be buffering results or directly streaming to the console.
enum ReceiverMode {
    /// Receiver is still buffering in order to sort the results, if the search finishes fast
    /// enough.
    Buffering,

    /// Receiver is directly printing results to the output.
    Streaming
}

/// Root directory
static ROOT_DIR : &'static str = "/";

/// Parent directory
static PARENT_DIR : &'static str = "..";

/// Print a search result to the console.
fn print_entry(base: &Path, entry: &PathBuf, config: &FdOptions) {
    let path_full = base.join(entry);

    let path_str = entry.to_string_lossy();

    #[cfg(target_family = "unix")]
    let is_executable = |p: &std::path::PathBuf| {
        p.metadata()
         .ok()
         .map(|f| f.permissions().mode() & 0o111 != 0)
         .unwrap_or(false)
    };

    #[cfg(not(target_family = "unix"))]
    let is_executable =  |p: &std::path::PathBuf| {false};

    let stdout = std::io::stdout();
    let mut handle = stdout.lock();

    if let Some(ref ls_colors) = config.ls_colors {
        let default_style = ansi_term::Style::default();

        let mut component_path = base.to_path_buf();

        if config.path_display == PathDisplay::Absolute {
            print!("{}", ls_colors.directory.paint(ROOT_DIR));
        }

        // Traverse the path and colorize each component
        for component in entry.components() {
            let comp_str = match component {
                Component::Normal(p) => p.to_string_lossy(),
                Component::ParentDir => Cow::from(PARENT_DIR),
                _                    => error("Error: unexpected path component.")
            };

            component_path.push(Path::new(comp_str.deref()));

            let style =
                if component_path.symlink_metadata()
                                 .map(|md| md.file_type().is_symlink())
                                 .unwrap_or(false) {
                    &ls_colors.symlink
                } else if component_path.is_dir() {
                    &ls_colors.directory
                } else if is_executable(&component_path) {
                    &ls_colors.executable
                } else {
                    // Look up file name
                    let o_style =
                        component_path.file_name()
                                      .and_then(|n| n.to_str())
                                      .and_then(|n| ls_colors.filenames.get(n));

                    match o_style {
                        Some(s) => s,
                        None =>
                            // Look up file extension
                            component_path.extension()
                                          .and_then(|e| e.to_str())
                                          .and_then(|e| ls_colors.extensions.get(e))
                                          .unwrap_or(&default_style)
                    }
                };

            write!(handle, "{}", style.paint(comp_str)).ok();

            if component_path.is_dir() && component_path != path_full {
                let sep = std::path::MAIN_SEPARATOR.to_string();
                write!(handle, "{}", style.paint(sep)).ok();
            }
        }

        let r = if config.null_separator {
          write!(handle, "{}", '\0')
        } else {
          writeln!(handle, "")
        };
        if r.is_err() {
            // Probably a broken pipe. Exit gracefully.
            process::exit(0);
        }
    } else {
        // Uncolorized output

        let prefix = if config.path_display == PathDisplay::Absolute { ROOT_DIR } else { "" };
        let separator = if config.null_separator { "\0" } else { "\n" };

        let r = write!(&mut std::io::stdout(), "{}{}{}", prefix, path_str, separator);

        if r.is_err() {
            // Probably a broken pipe. Exit gracefully.
            process::exit(0);
        }
    }
}

/// Recursively scan the given search path and search for files / pathnames matching the pattern.
fn scan(root: &Path, pattern: Arc<Regex>, base: &Path, config: Arc<FdOptions>) {
    let (tx, rx) = channel();

    let walker = WalkBuilder::new(root)
                     .hidden(config.ignore_hidden)
                     .ignore(config.read_ignore)
                     .git_ignore(config.read_ignore)
                     .parents(config.read_ignore)
                     .git_global(config.read_ignore)
                     .git_exclude(config.read_ignore)
                     .follow_links(config.follow_links)
                     .max_depth(config.max_depth)
                     .threads(config.threads.unwrap_or(0))
                     .build_parallel();

    // Spawn the thread that receives all results through the channel.
    let rx_config = Arc::clone(&config);
    let rx_base = base.to_owned();
    let receiver_thread = thread::spawn(move || {
        let start = time::Instant::now();

        let mut buffer = vec!();

        // Start in buffering mode
        let mut mode = ReceiverMode::Buffering;

        // Maximum time to wait before we start streaming to the console.
        let max_buffer_time = rx_config.max_buffer_time
                                       .unwrap_or_else(|| time::Duration::from_millis(100));

        for value in rx {
            match mode {
                ReceiverMode::Buffering => {
                    buffer.push(value);

                    // Have we reached the maximum time?
                    if time::Instant::now() - start > max_buffer_time {
                        // Flush the buffer
                        for v in &buffer {
                            print_entry(&rx_base, v, &rx_config);
                        }
                        buffer.clear();

                        // Start streaming
                        mode = ReceiverMode::Streaming;
                    }
                },
                ReceiverMode::Streaming => {
                    print_entry(&rx_base, &value, &rx_config);
                }
            }
        }

        // If we have finished fast enough (faster than max_buffer_time), we haven't streamed
        // anything to the console, yet. In this case, sort the results and print them:
        if !buffer.is_empty() {
            buffer.sort();
            for value in buffer {
                print_entry(&rx_base, &value, &rx_config);
            }
        }
    });

    // Spawn the sender threads.
    walker.run(|| {
        let base = base.to_owned();
        let config = config.clone();
        let pattern = pattern.clone();
        let tx_thread = tx.clone();

        Box::new(move |entry_o| {
            let entry = match entry_o {
                Ok(e) => e,
                Err(_) => return ignore::WalkState::Continue
            };

            let path_rel_buf = match fshelper::path_relative_from(entry.path(), &*base) {
                Some(p) => p,
                None => error("Error: could not get relative path for directory entry.")
            };
            let path_rel = path_rel_buf.as_path();

            let search_str_o =
                if config.search_full_path {
                    Some(path_rel.to_string_lossy())
                } else {
                    path_rel.file_name()
                            .map(|f| f.to_string_lossy())
                };

            if let Some(search_str) = search_str_o {
                // TODO: take care of the unwrap call
                pattern.find(&*search_str)
                       .map(|_| tx_thread.send(path_rel_buf.to_owned()).unwrap());
            }

            ignore::WalkState::Continue
        })
    });

    // Drop the initial sender. If we don't do this, the receiver will block even
    // if all threads have finished, since there is still one sender around.
    drop(tx);

    // Wait for the receiver thread to print out all results.
    receiver_thread.join().unwrap();
}

/// Print error message to stderr and exit with status `1`.
fn error(message: &str) -> ! {
    writeln!(&mut std::io::stderr(), "{}", message)
        .expect("Failed writing to stderr");
    process::exit(1);
}

fn main() {
    let matches =
        App::new("fd")
            .version(crate_version!())
            .usage("fd [FLAGS/OPTIONS] [<pattern>] [<path>]")
            .setting(AppSettings::ColoredHelp)
            .setting(AppSettings::DeriveDisplayOrder)
            .arg(Arg::with_name("case-sensitive")
                        .long("case-sensitive")
                        .short("s")
                        .help("Case-sensitive search (default: smart case)"))
            .arg(Arg::with_name("full-path")
                        .long("full-path")
                        .short("p")
                        .help("Search full path (default: file-/dirname only)"))
            .arg(Arg::with_name("hidden")
                        .long("hidden")
                        .short("H")
                        .help("Search hidden files and directories"))
            .arg(Arg::with_name("no-ignore")
                        .long("no-ignore")
                        .short("I")
                        .help("Do not respect .(git)ignore files"))
            .arg(Arg::with_name("follow")
                        .long("follow")
                        .short("L")
                        .help("Follow symlinks"))
            .arg(Arg::with_name("null_separator")
                        .long("print0")
                        .short("0")
                        .help("Separate results by the null character"))
            .arg(Arg::with_name("absolute-path")
                        .long("absolute-path")
                        .short("a")
                        .help("Show absolute instead of relative paths"))
            .arg(Arg::with_name("no-color")
                        .long("no-color")
                        .short("n")
                        .help("Do not colorize output"))
            .arg(Arg::with_name("depth")
                        .long("max-depth")
                        .short("d")
                        .takes_value(true)
                        .help("Set maximum search depth (default: none)"))
            .arg(Arg::with_name("threads")
                        .long("threads")
                        .short("j")
                        .takes_value(true)
                        .help("The number of threads used for searching"))
            .arg(Arg::with_name("max-buffer-time")
                        .long("max-buffer-time")
                        .takes_value(true)
                        .help("the time (in ms) to buffer, before streaming to the console")
                        .hidden(true))
            .arg(Arg::with_name("pattern")
                        .help("the search pattern, a regular expression (optional)"))
            .arg(Arg::with_name("path")
                        .help("the root directory for the filesystem search (optional)"))
            .get_matches();

    // Get the search pattern
    let empty_pattern = String::new();
    let pattern = matches.value_of("pattern").unwrap_or(&empty_pattern);

    // Get the current working directory
    let current_dir_buf = match env::current_dir() {
        Ok(cd) => cd,
        Err(_) => error("Error: could not get current directory.")
    };
    let current_dir = current_dir_buf.as_path();

    // Get the root directory for the search
    let mut root_dir_is_absolute = false;
    let root_dir_buf = if let Some(rd) = matches.value_of("path") {
        let path = Path::new(rd);

        root_dir_is_absolute = path.is_absolute();

        path.canonicalize().unwrap_or_else(
            |_| error(&format!("Error: could not find directory '{}'.", rd))
        )
    } else {
        current_dir_buf.clone()
    };

    if !root_dir_buf.is_dir() {
        error(&format!("Error: '{}' is not a directory.", root_dir_buf.to_string_lossy()));
    }

    let root_dir = root_dir_buf.as_path();

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = matches.is_present("case-sensitive") ||
                         pattern.chars().any(char::is_uppercase);

    let colored_output = !matches.is_present("no-color") &&
                         atty::is(Stream::Stdout);

    let ls_colors =
        if colored_output {
            Some(
                env::var("LS_COLORS")
                    .ok()
                    .map(|val| LsColors::from_string(&val))
                    .unwrap_or_default()
            )
        } else {
            None
        };

    let config = FdOptions {
        case_sensitive:    case_sensitive,
        search_full_path:  matches.is_present("full-path"),
        ignore_hidden:     !matches.is_present("hidden"),
        read_ignore:       !matches.is_present("no-ignore"),
        follow_links:      matches.is_present("follow"),
        null_separator:    matches.is_present("null_separator"),
        max_depth:         matches.value_of("depth")
                                   .and_then(|n| usize::from_str_radix(n, 10).ok()),
        threads:           matches.value_of("threads")
                                   .and_then(|n| usize::from_str_radix(n, 10).ok()),
        max_buffer_time:   matches.value_of("max-buffer-time")
                                  .and_then(|n| u64::from_str_radix(n, 10).ok())
                                  .map(time::Duration::from_millis),
        path_display:      if matches.is_present("absolute-path") || root_dir_is_absolute {
                               PathDisplay::Absolute
                           } else {
                               PathDisplay::Relative
                           },
        ls_colors:         ls_colors
    };

    let root = Path::new(ROOT_DIR);
    let base = match config.path_display {
        PathDisplay::Relative => current_dir,
        PathDisplay::Absolute => root
    };

    match RegexBuilder::new(pattern)
              .case_insensitive(!config.case_sensitive)
              .build() {
        Ok(re)   => scan(root_dir, Arc::new(re), base, Arc::new(config)),
        Err(err) => error(err.description())
    }
}
<commit_msg>Add --dereference as an alias for --follow<commit_after>#[macro_use]
extern crate clap;
extern crate ansi_term;
extern crate atty;
extern crate regex;
extern crate ignore;

pub mod lscolors;
pub mod fshelper;

use std::borrow::Cow;
use std::env;
use std::error::Error;
use std::io::Write;
use std::ops::Deref;
#[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf, Component};
use std::process;
use std::sync::Arc;
use std::sync::mpsc::channel;
use std::thread;
use std::time;

use clap::{App, AppSettings, Arg};
use atty::Stream;
use regex::{Regex, RegexBuilder};
use ignore::WalkBuilder;

use lscolors::LsColors;

/// Defines how to display search result paths.
#[derive(PartialEq)]
enum PathDisplay {
    /// As an absolute path
    Absolute,

    /// As a relative path
    Relative
}

/// Configuration options for *fd*.
struct FdOptions {
    /// Determines whether the regex search is case-sensitive or case-insensitive.
    case_sensitive: bool,

    /// Whether to search within the full file path or just the base name (filename or directory
    /// name).
    search_full_path: bool,

    /// Whether to ignore hidden files and directories (or not).
    ignore_hidden: bool,

    /// Whether to respect VCS ignore files (`.gitignore`, `.ignore`, ..) or not.
    read_ignore: bool,

    /// Whether to follow symlinks or not.
    follow_links: bool,

    /// Whether elements of output should be separated by a null character
    null_separator: bool,

    /// The maximum search depth, or `None` if no maximum search depth should be set.
    ///
    /// A depth of `1` includes all files under the current directory, a depth of `2` also includes
    /// all files under subdirectories of the current directory, etc.
    max_depth: Option<usize>,

    /// The number of threads to use.
    threads: Option<usize>,

    /// Time to buffer results internally before streaming to the console. This is useful to
    /// provide a sorted output, in case the total execution time is shorter than
    /// `max_buffer_time`.
    max_buffer_time: Option<time::Duration>,

    /// Display results as relative or absolute path.
    path_display: PathDisplay,

    /// `None` if the output should not be colorized. Otherwise, a `LsColors` instance that defines
    /// how to style different filetypes.
    ls_colors: Option<LsColors>
}

/// The receiver thread can either be buffering results or directly streaming to the console.
enum ReceiverMode {
    /// Receiver is still buffering in order to sort the results, if the search finishes fast
    /// enough.
    Buffering,

    /// Receiver is directly printing results to the output.
    Streaming
}

/// Root directory
static ROOT_DIR : &'static str = "/";

/// Parent directory
static PARENT_DIR : &'static str = "..";

/// Print a search result to the console.
fn print_entry(base: &Path, entry: &PathBuf, config: &FdOptions) {
    let path_full = base.join(entry);

    let path_str = entry.to_string_lossy();

    #[cfg(target_family = "unix")]
    let is_executable = |p: &std::path::PathBuf| {
        p.metadata()
         .ok()
         .map(|f| f.permissions().mode() & 0o111 != 0)
         .unwrap_or(false)
    };

    #[cfg(not(target_family = "unix"))]
    let is_executable =  |p: &std::path::PathBuf| {false};

    let stdout = std::io::stdout();
    let mut handle = stdout.lock();

    if let Some(ref ls_colors) = config.ls_colors {
        let default_style = ansi_term::Style::default();

        let mut component_path = base.to_path_buf();

        if config.path_display == PathDisplay::Absolute {
            print!("{}", ls_colors.directory.paint(ROOT_DIR));
        }

        // Traverse the path and colorize each component
        for component in entry.components() {
            let comp_str = match component {
                Component::Normal(p) => p.to_string_lossy(),
                Component::ParentDir => Cow::from(PARENT_DIR),
                _                    => error("Error: unexpected path component.")
            };

            component_path.push(Path::new(comp_str.deref()));

            let style =
                if component_path.symlink_metadata()
                                 .map(|md| md.file_type().is_symlink())
                                 .unwrap_or(false) {
                    &ls_colors.symlink
                } else if component_path.is_dir() {
                    &ls_colors.directory
                } else if is_executable(&component_path) {
                    &ls_colors.executable
                } else {
                    // Look up file name
                    let o_style =
                        component_path.file_name()
                                      .and_then(|n| n.to_str())
                                      .and_then(|n| ls_colors.filenames.get(n));

                    match o_style {
                        Some(s) => s,
                        None =>
                            // Look up file extension
                            component_path.extension()
                                          .and_then(|e| e.to_str())
                                          .and_then(|e| ls_colors.extensions.get(e))
                                          .unwrap_or(&default_style)
                    }
                };

            write!(handle, "{}", style.paint(comp_str)).ok();

            if component_path.is_dir() && component_path != path_full {
                let sep = std::path::MAIN_SEPARATOR.to_string();
                write!(handle, "{}", style.paint(sep)).ok();
            }
        }

        let r = if config.null_separator {
          write!(handle, "{}", '\0')
        } else {
          writeln!(handle, "")
        };
        if r.is_err() {
            // Probably a broken pipe. Exit gracefully.
            process::exit(0);
        }
    } else {
        // Uncolorized output

        let prefix = if config.path_display == PathDisplay::Absolute { ROOT_DIR } else { "" };
        let separator = if config.null_separator { "\0" } else { "\n" };

        let r = write!(&mut std::io::stdout(), "{}{}{}", prefix, path_str, separator);

        if r.is_err() {
            // Probably a broken pipe. Exit gracefully.
            process::exit(0);
        }
    }
}

/// Recursively scan the given search path and search for files / pathnames matching the pattern.
fn scan(root: &Path, pattern: Arc<Regex>, base: &Path, config: Arc<FdOptions>) {
    let (tx, rx) = channel();

    let walker = WalkBuilder::new(root)
                     .hidden(config.ignore_hidden)
                     .ignore(config.read_ignore)
                     .git_ignore(config.read_ignore)
                     .parents(config.read_ignore)
                     .git_global(config.read_ignore)
                     .git_exclude(config.read_ignore)
                     .follow_links(config.follow_links)
                     .max_depth(config.max_depth)
                     .threads(config.threads.unwrap_or(0))
                     .build_parallel();

    // Spawn the thread that receives all results through the channel.
    let rx_config = Arc::clone(&config);
    let rx_base = base.to_owned();
    let receiver_thread = thread::spawn(move || {
        let start = time::Instant::now();

        let mut buffer = vec!();

        // Start in buffering mode
        let mut mode = ReceiverMode::Buffering;

        // Maximum time to wait before we start streaming to the console.
        let max_buffer_time = rx_config.max_buffer_time
                                       .unwrap_or_else(|| time::Duration::from_millis(100));

        for value in rx {
            match mode {
                ReceiverMode::Buffering => {
                    buffer.push(value);

                    // Have we reached the maximum time?
                    if time::Instant::now() - start > max_buffer_time {
                        // Flush the buffer
                        for v in &buffer {
                            print_entry(&rx_base, v, &rx_config);
                        }
                        buffer.clear();

                        // Start streaming
                        mode = ReceiverMode::Streaming;
                    }
                },
                ReceiverMode::Streaming => {
                    print_entry(&rx_base, &value, &rx_config);
                }
            }
        }

        // If we have finished fast enough (faster than max_buffer_time), we haven't streamed
        // anything to the console, yet. In this case, sort the results and print them:
        if !buffer.is_empty() {
            buffer.sort();
            for value in buffer {
                print_entry(&rx_base, &value, &rx_config);
            }
        }
    });

    // Spawn the sender threads.
    walker.run(|| {
        let base = base.to_owned();
        let config = config.clone();
        let pattern = pattern.clone();
        let tx_thread = tx.clone();

        Box::new(move |entry_o| {
            let entry = match entry_o {
                Ok(e) => e,
                Err(_) => return ignore::WalkState::Continue
            };

            let path_rel_buf = match fshelper::path_relative_from(entry.path(), &*base) {
                Some(p) => p,
                None => error("Error: could not get relative path for directory entry.")
            };
            let path_rel = path_rel_buf.as_path();

            let search_str_o =
                if config.search_full_path {
                    Some(path_rel.to_string_lossy())
                } else {
                    path_rel.file_name()
                            .map(|f| f.to_string_lossy())
                };

            if let Some(search_str) = search_str_o {
                // TODO: take care of the unwrap call
                pattern.find(&*search_str)
                       .map(|_| tx_thread.send(path_rel_buf.to_owned()).unwrap());
            }

            ignore::WalkState::Continue
        })
    });

    // Drop the initial sender. If we don't do this, the receiver will block even
    // if all threads have finished, since there is still one sender around.
    drop(tx);

    // Wait for the receiver thread to print out all results.
    receiver_thread.join().unwrap();
}

/// Print error message to stderr and exit with status `1`.
fn error(message: &str) -> ! {
    writeln!(&mut std::io::stderr(), "{}", message)
        .expect("Failed writing to stderr");
    process::exit(1);
}

fn main() {
    let matches =
        App::new("fd")
            .version(crate_version!())
            .usage("fd [FLAGS/OPTIONS] [<pattern>] [<path>]")
            .setting(AppSettings::ColoredHelp)
            .setting(AppSettings::DeriveDisplayOrder)
            .arg(Arg::with_name("case-sensitive")
                        .long("case-sensitive")
                        .short("s")
                        .help("Case-sensitive search (default: smart case)"))
            .arg(Arg::with_name("full-path")
                        .long("full-path")
                        .short("p")
                        .help("Search full path (default: file-/dirname only)"))
            .arg(Arg::with_name("hidden")
                        .long("hidden")
                        .short("H")
                        .help("Search hidden files and directories"))
            .arg(Arg::with_name("no-ignore")
                        .long("no-ignore")
                        .short("I")
                        .help("Do not respect .(git)ignore files"))
            .arg(Arg::with_name("follow")
                        .long("follow")
                        .short("L")
                        .help("Follow symlinks")
                        .alias("dereference"))
            .arg(Arg::with_name("null_separator")
                        .long("print0")
                        .short("0")
                        .help("Separate results by the null character"))
            .arg(Arg::with_name("absolute-path")
                        .long("absolute-path")
                        .short("a")
                        .help("Show absolute instead of relative paths"))
            .arg(Arg::with_name("no-color")
                        .long("no-color")
                        .short("n")
                        .help("Do not colorize output"))
            .arg(Arg::with_name("depth")
                        .long("max-depth")
                        .short("d")
                        .takes_value(true)
                        .help("Set maximum search depth (default: none)"))
            .arg(Arg::with_name("threads")
                        .long("threads")
                        .short("j")
                        .takes_value(true)
                        .help("The number of threads used for searching"))
            .arg(Arg::with_name("max-buffer-time")
                        .long("max-buffer-time")
                        .takes_value(true)
                        .help("the time (in ms) to buffer, before streaming to the console")
                        .hidden(true))
            .arg(Arg::with_name("pattern")
                        .help("the search pattern, a regular expression (optional)"))
            .arg(Arg::with_name("path")
                        .help("the root directory for the filesystem search (optional)"))
            .get_matches();

    // Get the search pattern
    let empty_pattern = String::new();
    let pattern = matches.value_of("pattern").unwrap_or(&empty_pattern);

    // Get the current working directory
    let current_dir_buf = match env::current_dir() {
        Ok(cd) => cd,
        Err(_) => error("Error: could not get current directory.")
    };
    let current_dir = current_dir_buf.as_path();

    // Get the root directory for the search
    let mut root_dir_is_absolute = false;
    let root_dir_buf = if let Some(rd) = matches.value_of("path") {
        let path = Path::new(rd);

        root_dir_is_absolute = path.is_absolute();

        path.canonicalize().unwrap_or_else(
            |_| error(&format!("Error: could not find directory '{}'.", rd))
        )
    } else {
        current_dir_buf.clone()
    };

    if !root_dir_buf.is_dir() {
        error(&format!("Error: '{}' is not a directory.", root_dir_buf.to_string_lossy()));
    }

    let root_dir = root_dir_buf.as_path();

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = matches.is_present("case-sensitive") ||
                         pattern.chars().any(char::is_uppercase);

    let colored_output = !matches.is_present("no-color") &&
                         atty::is(Stream::Stdout);

    let ls_colors =
        if colored_output {
            Some(
                env::var("LS_COLORS")
                    .ok()
                    .map(|val| LsColors::from_string(&val))
                    .unwrap_or_default()
            )
        } else {
            None
        };

    let config = FdOptions {
        case_sensitive:    case_sensitive,
        search_full_path:  matches.is_present("full-path"),
        ignore_hidden:     !matches.is_present("hidden"),
        read_ignore:       !matches.is_present("no-ignore"),
        follow_links:      matches.is_present("follow"),
        null_separator:    matches.is_present("null_separator"),
        max_depth:         matches.value_of("depth")
                                   .and_then(|n| usize::from_str_radix(n, 10).ok()),
        threads:           matches.value_of("threads")
                                   .and_then(|n| usize::from_str_radix(n, 10).ok()),
        max_buffer_time:   matches.value_of("max-buffer-time")
                                  .and_then(|n| u64::from_str_radix(n, 10).ok())
                                  .map(time::Duration::from_millis),
        path_display:      if matches.is_present("absolute-path") || root_dir_is_absolute {
                               PathDisplay::Absolute
                           } else {
                               PathDisplay::Relative
                           },
        ls_colors:         ls_colors
    };

    let root = Path::new(ROOT_DIR);
    let base = match config.path_display {
        PathDisplay::Relative => current_dir,
        PathDisplay::Absolute => root
    };

    match RegexBuilder::new(pattern)
              .case_insensitive(!config.case_sensitive)
              .build() {
        Ok(re)   => scan(root_dir, Arc::new(re), base, Arc::new(config)),
        Err(err) => error(err.description())
    }
}
<|endoftext|>


<commit_before>fn main() {
    let dow = ["Duinday", "Sitaday", "Wikiday", "Tuxday", "Gnuday", "Commonday"];
    let moy = ["Jabim", "Zodrak", "Trogool", "Yanar", "Shkumbe", "Habniah", "Skarl", "Mikon", "Pertunda", "Kib", "Broket"];
    let yoff: usize = 0;
    let dpm = 33;
    let dpw = dow.len();
    let mpy = moy.len();
    let mut moff = yoff;

    for mm in 0..mpy {
        let spaces = (17 - moy[mm].len()) / 2;
        for _ in 0..spaces {
            print!(" ");
        }
        println!("{}", moy[mm]);

        for dd in 0..dpw {
            let mut abbrd = String::from(dow[dd]);
            abbrd.truncate(2);
            print!("{} ", abbrd);
        }

        moff = print_days(moff, dpm, dpw);
    }
}

fn print_days(moff: usize, dpm: usize, dpw: usize) -> usize {
    if moff != 0 {
        println!("");
    }

    for _ in 0 .. moff {
        print!("   ");
    }

    for day in 1 .. dpm + 1 {
        if (day + moff) % dpw == 1 {
            println!("");
        }

        print!("{:2} ", day);
    }

    println!("");
    return if moff == 0 { 3 } else { 0 };
}

<commit_msg>Add most months<commit_after>extern crate time;

fn main() {
    let dow = ["Duinday", "Sitaday", "Wikiday", "Tuxday", "Gnuday", "Commonday"];
    let moy = ["Jabim", "Zodrak", "Trogool", "Yanar", "Shkumbe", "Habniah", "Skarl", "Mikon", "Pertunda", "Kib", "Broket"];
    let dpm = 33;
    let dpw = dow.len();
    let mpy = moy.len();
    let (year, month, day, yoff) = current_day(time::now());
    let wd = (yoff + month * 3 + day) % dpw;
    let mut moff = yoff;

    for mm in 0..mpy {
        let spaces = (17 - moy[mm].len()) / 2;
        for _ in 0..spaces {
            print!(" ");
        }
        println!("{}", moy[mm]);

        for dd in 0..dpw {
            let mut abbrd = String::from(dow[dd]);
            abbrd.truncate(2);
            print!("{} ", abbrd);
        }

        let dd = if mm == month { day } else { 1000 };
        moff = print_days(moff, dpm, dpw, dd);
    }

    println!("Today is {}, {:02} of {} {}.  [{}.{:02}.{:02}]", dow[wd], day, moy[month], year, year, month + 1, day);
}

fn print_days(moff: usize, dpm: usize, dpw: usize, highlight: usize) -> usize {
    if moff != 0 {
        println!("");
    }

    for _ in 0 .. moff {
        print!("   ");
    }

    for day in 1 .. dpm + 1 {
        if (day + moff) % dpw == 1 {
            println!("");
        }

        let ch = if day == highlight { ">" } else if day + 1 == highlight { "<" } else { " " };
        print!("{:2}{}", day, ch);
    }

    println!("");
    return if moff == 0 { 3 } else { 0 };
}

fn current_day(current_time: time::Tm) -> (usize, usize, usize, usize) {
    let epoch_days_offset = 1483889;
    let seconds_per_day = 86400;
    let now = current_time.to_timespec();
    let days_since_epoch = (epoch_days_offset + now.sec / seconds_per_day) as i32;
    let days_per_year = 365;
    let leap_year = 4;
    let not_leap_year = 33;
    let days_per_month = 33;

    let mut count = 1;
    let mut days_remaining = days_since_epoch;
    let mut year = 0;
    while days_remaining > days_per_year + 1 {
        days_remaining -= days_per_year;
        year += 1;
        if count > not_leap_year {
            count = 1;
        }
        if count % leap_year == 0 {
            days_remaining -= 1;
        }
        count += 1;
    }
    if days_remaining == days_per_year + 1 && count % leap_year == 0 {
        days_remaining = 0;
        year += 1;
    }

    let month = days_remaining / days_per_month;
    let day = days_remaining - month * days_per_month;
    return (year, month as usize, day as usize + 1, (year % 2 * 3) as usize);
}

<|endoftext|>


<commit_before>#![feature(rustc_private)]
#[macro_use] extern crate log;

extern crate ansi_term;
use ansi_term::Colour::{Black, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
use ansi_term::Style;

extern crate num;
use num::traits::Num;

use std::fs::File;
use std::io::*;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
//use std::iter::{count};
//use std::iter::range_step;

fn step_by<T: Num+Copy>(start: T, step: T, len: usize) -> Vec<T> {
    let mut result: Vec<T> = Vec::with_capacity(len);
    let mut curr = start;
    for i in 1..len+1 {
        result.push(curr);
        curr = curr + step;
    }
    result
}

fn vec_to_string(input: &Vec<char>) -> String {
    input.iter().map(|&c| { c }).collect()
}

// Index source
struct InputSource {
    haystack: Vec<char>,
    indexed_haystack: HashMap<char, Vec<usize>>,
}

fn index_chars(input: &Vec<char>) -> HashMap<char, Vec<usize>> {
    let mut indexed_haystack = HashMap::new();
    for (idx, &c) in input.iter().enumerate() {
        match indexed_haystack.entry(c) {
            Vacant(entry) => { entry.insert(vec![idx]); },
            Occupied(mut entry) => { (*entry.get_mut()).push(idx); }
        }
    }

    indexed_haystack
}

impl InputSource {
    fn new(haystack: Vec<char>) -> InputSource {
        let indexed_haystack = index_chars(&haystack);

        InputSource {
            haystack: haystack,
            indexed_haystack: indexed_haystack,
        }
    }

    fn search_for_anywhere<'a>(&'a self, needle: &'a Vec<char>) -> Option<EDS> {
        EDS::new(self, needle)
    }

    fn search_for<'a>(&'a self, needle: &'a Vec<char>, start_options: Vec<usize>, step_options: Vec<i64>) -> Option<EDS> {
        EDS::new(self, needle)
    }

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

// This is a struct for doing the searching
struct EDS<'a, 'b> {
    source: &'a InputSource,

    // String to search for
    needle: &'b Vec<char>,

    first_poses: Vec<usize>,
    second_poses: Vec<usize>,

    // keep track of state between runs
    first_poses_idx: usize,
    second_poses_idx: usize,

}

impl<'a, 'b> Iterator for EDS<'a, 'b> {
    // (start, offset)
    type Item = (usize, i64);

    // This actually does the searching
    fn next(&mut self) -> Option<(usize, i64)> {
        debug!("Start of next call");
        let len_first_poses = self.first_poses.len();
        let len_second_poses = self.second_poses.len();

        if self.first_poses_idx == len_first_poses {
            debug!("Reached end, finishing");
            // reached the end
            return None;
        }

        let len_needle = self.needle.len();
        let len_haystack = self.source.haystack.len();
        let mut have_done_one_loop = false;
        let first_run = self.first_poses_idx == 0 && self.second_poses_idx == 0;

        loop {
            debug!("Start of loop");
            // Starts off at 0/0, and we don't want to increment it the first time
            if ! (self.first_poses_idx == 0 && self.second_poses_idx == 0 && !have_done_one_loop) {
                debug!("Incrementing counters");
                if self.second_poses_idx == len_second_poses - 1 {
                    self.second_poses_idx = 0;
                    self.first_poses_idx += 1;
                } else{
                    self.second_poses_idx += 1;
                }
            }
            have_done_one_loop = true;
            if self.first_poses_idx == len_first_poses {
                debug!("Reached end, finishing");
                // reached the end
                return None;
            }

            debug!("first_poses_idx {} second_poses_idx {}", self.first_poses_idx, self.second_poses_idx);
            let first_pos = self.first_poses[self.first_poses_idx];
            let second_pos = self.second_poses[self.second_poses_idx];
            debug!("first_pos {} second_pos {}", first_pos, second_pos);

            let step: i64 = (second_pos as i64) - (first_pos as i64);
            if step == 1 {
                continue;
            }
            let positions: Vec<i64> = step_by(first_pos as i64, step, len_needle);
            //let positions: Vec<i64> = range_step(first_pos as i64, step*len_needle, step).collect();
            debug!("Start {} step {}", first_pos, step);
            if positions.iter().any(|&x| { x<0 }) {
                // TODO there's probably a better maths way to do this
                continue;
            }
            let positions: Vec<usize> = positions.iter().map(|&x| {  x as usize }).collect();
            debug!("positions {:?}", positions);
            if positions.len() == 0 {
                // WTF
                continue;
            }

            if positions[positions.len()-1] > len_haystack - 1 {
                debug!("Past end");
                continue;
            }
            if positions.iter().map(|&c| { &self.source.haystack[c] }).zip(self.needle.iter()).all(|(&a, &b)| { a == b }) {
                //println!("Found starting at {} with step of {}", first_pos, step);
                return Some((first_pos, step));
            }
        }
        None
    }
}

impl<'a, 'b> EDS<'a, 'b> {
    fn new(source: &'a InputSource, needle: &'b Vec<char>) -> Option<EDS<'a, 'b>> {
        if needle.len() < 3 {
            return None;
        }
        let first_poses;
        match source.indexed_haystack.get(&needle[0]) {
            None => { return None ; }
            Some(ref entries) => {
                first_poses = (**entries).clone();
            }
        }

        let second_poses;
        match source.indexed_haystack.get(&needle[1]) {
            None => { return None ; }
            Some(ref entries) => {
                second_poses = (**entries).clone();
            }
        }

        let result = EDS {
            needle: needle, source: source,
            first_poses: first_poses, second_poses: second_poses,
            first_poses_idx: 0, second_poses_idx: 0,
        };

        return Some(result);

    }
}

fn print_results(source: &InputSource, start: usize, step: i64, len: usize) {
    let total_rows = (len + 2) as i64;
    let width: usize = 31; // 15 + 1 + 15
    let start_i = start as i64;
    let source_len = source.source_len();

    for row_num in 0..total_rows {
        for idx in 0..(width as i64) {
            let source_idx = (row_num-1)*step + start_i - 15 + idx;
            let this_char = if (source_idx < 0) || source_idx >= source_len as i64 { ' ' } else { source.haystack[source_idx as usize] };
            if idx == 15 && row_num != 0 && row_num != total_rows -1 {
                print!("{}", Red.paint(this_char.to_string()));
            } else {
                print!("{}", Style::default().paint(this_char.to_string()));
            }
        }
        print!("\n");

    }
    print!("\n");

}

fn only_alphanumeric(input: String) -> Vec<char> {
    input.chars().filter(|c| { c.is_alphabetic() }).map(|c| { c.to_lowercase().next().unwrap() }).collect()
}

fn main() {
    let args: Vec<_> = std::env::args().collect();
    let file_to_search = &args[1];
    println!("Reading in {}", file_to_search);
    let mut file_contents: String = String::new();
    File::open(file_to_search).unwrap().read_to_string(&mut file_contents);
    let haystack: Vec<char> = only_alphanumeric(file_contents);
    let source = InputSource::new(haystack);

    let needle = (&args[2]).to_string();
    println!("Looking for {}", needle);
    let needle = only_alphanumeric(needle);
    let len_needle = needle.len();

    let has_second_arg = args.len() == 4;
    let needle2;
    let len_needle2;
    if has_second_arg {
        needle2 = only_alphanumeric((&args[3]).to_string());
        let needle2_string: String = vec_to_string(&needle2);
        println!("Looking also for {}", needle2_string);
        len_needle2 = needle2.len();
    } else {
        needle2 = vec![];
    }

    match source.search_for_anywhere(&needle) {
        None => {
            println!("Cannot look for this string");
        }
        Some(eds_searcher) => {
            for (start, step) in eds_searcher.take(10) {
                println!("Found starting at {} with step of {}", start, step);
                print_results(&source, start, step, len_needle);
                if has_second_arg {
                    // now try to find the second needle2
                    match source.search_for_anywhere(&needle2) {
                        None => {
                            println!("Cannot look for {:?}", vec_to_string(&needle2));
                        }
                        Some(needle2_searcher) => {
                            for (start2, step2) in needle2_searcher.take(1) {
                                println!("Found {:?} starting at {} with step of {}", vec_to_string(&needle2), start2, step2);

                            }
                        }
                    }
                }
            }
        }
    }

}

#[test]
fn test_step_by() {
    assert_eq!(step_by(10, 2, 3), vec![10, 12, 14]);
    assert_eq!(step_by(10, -1, 3), vec![10, 9, 8]);
}

#[test]
fn test_only_alphanumeric() {
    assert_eq!(only_alphanumeric("hello there".to_string()), "hellothere".chars().collect::<Vec<char>>());
    assert_eq!(only_alphanumeric("hello there 123".to_string()), "hellothere".chars().collect::<Vec<char>>());
    assert_eq!(only_alphanumeric("HELLO there 123".to_string()), "hellothere".chars().collect::<Vec<char>>());
}
<commit_msg>rm errors<commit_after>#![feature(rustc_private)]
#[macro_use] extern crate log;

extern crate ansi_term;
use ansi_term::Colour::Red;
use ansi_term::Style;

extern crate num;
use num::traits::Num;

use std::fs::File;
use std::io::*;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
//use std::iter::{count};
//use std::iter::range_step;

fn step_by<T: Num+Copy>(start: T, step: T, len: usize) -> Vec<T> {
    let mut result: Vec<T> = Vec::with_capacity(len);
    let mut curr = start;
    for _ in 1..len+1 {
        result.push(curr);
        curr = curr + step;
    }
    result
}

fn vec_to_string(input: &Vec<char>) -> String {
    input.iter().map(|&c| { c }).collect()
}

// Index source
struct InputSource {
    haystack: Vec<char>,
    indexed_haystack: HashMap<char, Vec<usize>>,
}

fn index_chars(input: &Vec<char>) -> HashMap<char, Vec<usize>> {
    let mut indexed_haystack = HashMap::new();
    for (idx, &c) in input.iter().enumerate() {
        match indexed_haystack.entry(c) {
            Vacant(entry) => { entry.insert(vec![idx]); },
            Occupied(mut entry) => { (*entry.get_mut()).push(idx); }
        }
    }

    indexed_haystack
}

impl InputSource {
    fn new(haystack: Vec<char>) -> InputSource {
        let indexed_haystack = index_chars(&haystack);

        InputSource {
            haystack: haystack,
            indexed_haystack: indexed_haystack,
        }
    }

    fn search_for_anywhere<'a>(&'a self, needle: &'a Vec<char>) -> Option<EDS> {
        EDS::new(self, needle)
    }

    fn search_for<'a>(&'a self, needle: &'a Vec<char>, start_options: Vec<usize>, step_options: Vec<i64>) -> Option<EDS> {
        EDS::new(self, needle)
    }

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

// This is a struct for doing the searching
struct EDS<'a, 'b> {
    source: &'a InputSource,

    // String to search for
    needle: &'b Vec<char>,

    first_poses: Vec<usize>,
    second_poses: Vec<usize>,

    // keep track of state between runs
    first_poses_idx: usize,
    second_poses_idx: usize,

}

impl<'a, 'b> Iterator for EDS<'a, 'b> {
    // (start, offset)
    type Item = (usize, i64);

    // This actually does the searching
    fn next(&mut self) -> Option<(usize, i64)> {
        debug!("Start of next call");
        let len_first_poses = self.first_poses.len();
        let len_second_poses = self.second_poses.len();

        if self.first_poses_idx == len_first_poses {
            debug!("Reached end, finishing");
            // reached the end
            return None;
        }

        let len_needle = self.needle.len();
        let len_haystack = self.source.haystack.len();
        let mut have_done_one_loop = false;
        let first_run = self.first_poses_idx == 0 && self.second_poses_idx == 0;

        loop {
            debug!("Start of loop");
            // Starts off at 0/0, and we don't want to increment it the first time
            if ! (self.first_poses_idx == 0 && self.second_poses_idx == 0 && !have_done_one_loop) {
                debug!("Incrementing counters");
                if self.second_poses_idx == len_second_poses - 1 {
                    self.second_poses_idx = 0;
                    self.first_poses_idx += 1;
                } else{
                    self.second_poses_idx += 1;
                }
            }
            have_done_one_loop = true;
            if self.first_poses_idx == len_first_poses {
                debug!("Reached end, finishing");
                // reached the end
                return None;
            }

            debug!("first_poses_idx {} second_poses_idx {}", self.first_poses_idx, self.second_poses_idx);
            let first_pos = self.first_poses[self.first_poses_idx];
            let second_pos = self.second_poses[self.second_poses_idx];
            debug!("first_pos {} second_pos {}", first_pos, second_pos);

            let step: i64 = (second_pos as i64) - (first_pos as i64);
            if step == 1 {
                continue;
            }
            let positions: Vec<i64> = step_by(first_pos as i64, step, len_needle);
            //let positions: Vec<i64> = range_step(first_pos as i64, step*len_needle, step).collect();
            debug!("Start {} step {}", first_pos, step);
            if positions.iter().any(|&x| { x<0 }) {
                // TODO there's probably a better maths way to do this
                continue;
            }
            let positions: Vec<usize> = positions.iter().map(|&x| {  x as usize }).collect();
            debug!("positions {:?}", positions);
            if positions.len() == 0 {
                // WTF
                continue;
            }

            if positions[positions.len()-1] > len_haystack - 1 {
                debug!("Past end");
                continue;
            }
            if positions.iter().map(|&c| { &self.source.haystack[c] }).zip(self.needle.iter()).all(|(&a, &b)| { a == b }) {
                //println!("Found starting at {} with step of {}", first_pos, step);
                return Some((first_pos, step));
            }
        }
        None
    }
}

impl<'a, 'b> EDS<'a, 'b> {
    fn new(source: &'a InputSource, needle: &'b Vec<char>) -> Option<EDS<'a, 'b>> {
        if needle.len() < 3 {
            return None;
        }
        let first_poses;
        match source.indexed_haystack.get(&needle[0]) {
            None => { return None ; }
            Some(ref entries) => {
                first_poses = (**entries).clone();
            }
        }

        let second_poses;
        match source.indexed_haystack.get(&needle[1]) {
            None => { return None ; }
            Some(ref entries) => {
                second_poses = (**entries).clone();
            }
        }

        let result = EDS {
            needle: needle, source: source,
            first_poses: first_poses, second_poses: second_poses,
            first_poses_idx: 0, second_poses_idx: 0,
        };

        return Some(result);

    }
}

fn print_results(source: &InputSource, start: usize, step: i64, len: usize) {
    let total_rows = (len + 2) as i64;
    let width: usize = 31; // 15 + 1 + 15
    let start_i = start as i64;
    let source_len = source.source_len();

    for row_num in 0..total_rows {
        for idx in 0..(width as i64) {
            let source_idx = (row_num-1)*step + start_i - 15 + idx;
            let this_char = if (source_idx < 0) || source_idx >= source_len as i64 { ' ' } else { source.haystack[source_idx as usize] };
            if idx == 15 && row_num != 0 && row_num != total_rows -1 {
                print!("{}", Red.paint(this_char.to_string()));
            } else {
                print!("{}", Style::default().paint(this_char.to_string()));
            }
        }
        print!("\n");

    }
    print!("\n");

}

fn only_alphanumeric(input: String) -> Vec<char> {
    input.chars().filter(|c| { c.is_alphabetic() }).map(|c| { c.to_lowercase().next().unwrap() }).collect()
}

fn main() {
    let args: Vec<_> = std::env::args().collect();
    let file_to_search = &args[1];
    println!("Reading in {}", file_to_search);
    let mut file_contents: String = String::new();
    File::open(file_to_search).unwrap().read_to_string(&mut file_contents);
    let haystack: Vec<char> = only_alphanumeric(file_contents);
    let source = InputSource::new(haystack);

    let needle = (&args[2]).to_string();
    println!("Looking for {}", needle);
    let needle = only_alphanumeric(needle);
    let len_needle = needle.len();

    let has_second_arg = args.len() == 4;
    let needle2;
    let len_needle2;
    if has_second_arg {
        needle2 = only_alphanumeric((&args[3]).to_string());
        let needle2_string: String = vec_to_string(&needle2);
        println!("Looking also for {}", needle2_string);
        len_needle2 = needle2.len();
    } else {
        needle2 = vec![];
    }

    match source.search_for_anywhere(&needle) {
        None => {
            println!("Cannot look for this string");
        }
        Some(eds_searcher) => {
            for (start, step) in eds_searcher.take(10) {
                println!("Found starting at {} with step of {}", start, step);
                print_results(&source, start, step, len_needle);
                if has_second_arg {
                    // now try to find the second needle2
                    match source.search_for_anywhere(&needle2) {
                        None => {
                            println!("Cannot look for {:?}", vec_to_string(&needle2));
                        }
                        Some(needle2_searcher) => {
                            for (start2, step2) in needle2_searcher.take(1) {
                                println!("Found {:?} starting at {} with step of {}", vec_to_string(&needle2), start2, step2);

                            }
                        }
                    }
                }
            }
        }
    }

}

#[test]
fn test_step_by() {
    assert_eq!(step_by(10, 2, 3), vec![10, 12, 14]);
    assert_eq!(step_by(10, -1, 3), vec![10, 9, 8]);
}

#[test]
fn test_only_alphanumeric() {
    assert_eq!(only_alphanumeric("hello there".to_string()), "hellothere".chars().collect::<Vec<char>>());
    assert_eq!(only_alphanumeric("hello there 123".to_string()), "hellothere".chars().collect::<Vec<char>>());
    assert_eq!(only_alphanumeric("HELLO there 123".to_string()), "hellothere".chars().collect::<Vec<char>>());
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Dirty experiment with /dev/tty<commit_after>use std::{fs, io};
use std::io::{Read, Write};

fn magic() -> Result<(), io::Error> {
    println!("The magic begins");

    let mut input = String::new();
    try!(io::stdin().read_to_string(&mut input));

    let mut tty = try!(fs::OpenOptions::new().read(true).write(true).open("/dev/tty"));

    let _ = writeln!(&mut tty, "{}", input);

    let mut buffer = String::new();
    match tty.read_to_string(&mut buffer) {
        Ok(_) => println!("Input: {}", buffer),
        Err(e) => println!("Error: {}", e),
    };

    Ok(())
}

fn main() {
    let _ = magic();
}
<|endoftext|>


<commit_before>extern crate clap;
use clap::{Arg, App, AppSettings};
use slog::{Logger, LevelFilter, Level, DrainExt};
use yaml_rust::{YamlLoader};
use std::io::prelude::*;
use std::fs::File;
use yaml_rust::Yaml;
use std::collections::BTreeMap;

#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate yaml_rust;

#[derive(Debug)]
struct DotFile {
  source: String,
  target: String
}

fn main() {
  let matches: clap::ArgMatches = create_app().get_matches();
  let stream = slog_term::streamer().full().build();
  let verbose: bool = matches.is_present("verbose");
  let log = if verbose {
    slog::Logger::root(stream.fuse(), o!())
  } else {
    slog::Logger::root(LevelFilter::new(stream, Level::Info).fuse(), o!())
  };

  let config_file = matches.value_of("config_file").unwrap();
  info!(log, "Starting engine"; "config_file" => config_file);

  let config = match load_config_file(config_file) {
    Ok(content) => content,
    Err(e) => {
      error!(log, "Failed to load config file."; "error" => format!("{:?}", e));
      panic!(1)
    }
  };

  let yaml_documents = match YamlLoader::load_from_str(&config) {
    Ok(yaml) => yaml,
    Err(e) => {
      error!(log, "Failed to parse config file."; "error" => format!("{:?}", e));
      panic!(2)
    }
  };
  let yaml_config = &yaml_documents[0];
  let dot_files: &Yaml = &yaml_config["files"];
  if dot_files.is_badvalue() {
    warn!(log, "Empty files list");
  }

  info!(log, "Parsed config file. Liftoff!");
  process_dot_files(&log, dot_files);
}

fn process_dot_files(log: &Logger, dot_files: &Yaml) {
  info!(log, "Processing dotfiles");
  if let Yaml::Hash(entries) = dot_files.clone() {
    for (key, value) in entries {
      match (key, value) {
        (Yaml::String(target), Yaml::String(source)) =>
          process_dot_file(log, DotFile{ source: source.to_string(), target: target.to_string() }),
        (Yaml::String(target), Yaml::Hash(settings)) =>
         {},
        _ => {}
      }
    }
  } else {
    warn!(log, "Found no entries to process");
  }
}

fn process_dot_file(log: &Logger, dot_file: DotFile) {
  info!(log, "Process entry"; "target" => dot_file.target, "source" => dot_file.source);
}

fn load_config_file(file: &str) -> Result<String, std::io::Error> {
  let mut file = try!(File::open(file));
  let mut content = String::new();
  try!(file.read_to_string(&mut content));
  return Ok(content)
}

fn create_app<'a>() -> App<'a, 'a> {
  App::new("dotcopter")
    .version("0.1")
    .setting(AppSettings::ColoredHelp)
    .author("Patrick Haun <bomgar85@googlemail.com>")
    .about("manages dotfiles installation")
    .arg(Arg::with_name("force").short("f").long("force").takes_value(false))
    .arg(Arg::with_name("verbose")
           .long("verbose")
           .short("v")
           .help("debug output")
           .required(false)
           .takes_value(false))
    .arg(Arg::with_name("config_file").required(true))
}
<commit_msg>start supporting of nested object<commit_after>extern crate clap;
use clap::{Arg, App, AppSettings};
use slog::{Logger, LevelFilter, Level, DrainExt};
use yaml_rust::{YamlLoader};
use std::io::prelude::*;
use std::fs::File;
use yaml_rust::Yaml;
use std::collections::BTreeMap;

#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate yaml_rust;

#[derive(Debug)]
struct DotFile {
  source: String,
  target: String
}

fn main() {
  let matches: clap::ArgMatches = create_app().get_matches();
  let stream = slog_term::streamer().full().build();
  let verbose: bool = matches.is_present("verbose");
  let log = if verbose {
    slog::Logger::root(stream.fuse(), o!())
  } else {
    slog::Logger::root(LevelFilter::new(stream, Level::Info).fuse(), o!())
  };

  let config_file = matches.value_of("config_file").unwrap();
  info!(log, "Starting engine"; "config_file" => config_file);

  let config = match load_config_file(config_file) {
    Ok(content) => content,
    Err(e) => {
      error!(log, "Failed to load config file."; "error" => format!("{:?}", e));
      panic!(1)
    }
  };

  let yaml_documents = match YamlLoader::load_from_str(&config) {
    Ok(yaml) => yaml,
    Err(e) => {
      error!(log, "Failed to parse config file."; "error" => format!("{:?}", e));
      panic!(2)
    }
  };
  let yaml_config = &yaml_documents[0];
  let dot_files: &Yaml = &yaml_config["files"];
  if dot_files.is_badvalue() {
    warn!(log, "Empty files list");
  }

  info!(log, "Parsed config file. Liftoff!");
  process_dot_files(&log, dot_files);
}

fn process_dot_files(log: &Logger, dot_files: &Yaml) {
  info!(log, "Processing dotfiles");
  if let Yaml::Hash(entries) = dot_files.clone() {
    for (key, value) in entries {
      match (key, value) {
        (Yaml::String(target), Yaml::String(source)) =>
          process_dot_file(log, DotFile{ source: source.to_string(), target: target.to_string() }),
        (Yaml::String(target), Yaml::Hash(settings)) =>
          process_dot_file(log, dot_file_from_settings(target, &settings)),
        _ => {}
      }
    }
  } else {
    warn!(log, "Found no entries to process");
  }
}

fn dot_file_from_settings(target: String, settings: &yaml_rust::yaml::Hash) -> DotFile {
  DotFile{ source: "<todo>".to_string(), target: target.to_string() }
}

fn process_dot_file(log: &Logger, dot_file: DotFile) {
  info!(log, "Process entry"; "target" => dot_file.target, "source" => dot_file.source);
}

fn load_config_file(file: &str) -> Result<String, std::io::Error> {
  let mut file = try!(File::open(file));
  let mut content = String::new();
  try!(file.read_to_string(&mut content));
  return Ok(content)
}

fn create_app<'a>() -> App<'a, 'a> {
  App::new("dotcopter")
    .version("0.1")
    .setting(AppSettings::ColoredHelp)
    .author("Patrick Haun <bomgar85@googlemail.com>")
    .about("manages dotfiles installation")
    .arg(Arg::with_name("force").short("f").long("force").takes_value(false))
    .arg(Arg::with_name("verbose")
           .long("verbose")
           .short("v")
           .help("debug output")
           .required(false)
           .takes_value(false))
    .arg(Arg::with_name("config_file").required(true))
}
<|endoftext|>


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

fn main() {
    intro();
    let l = 0;
}
<commit_msg>Starting first round of computation<commit_after>
// Allow all uppercase variable names
#![allow(non_snake_case)]
#![allow(unused_variables)]

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

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

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

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

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

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

fn f420() {
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rustdown Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(macro_rules)]
#![feature(phase)]
#![feature(globs)]
#![feature(import_shadowing)]
#![crate_id="rustdown#0.1"]

extern crate rustdoc;
extern crate getopts;

use std::os;
use std::path::posix::Path;
use getopts::OptGroup;

use html::ToHtml;

mod blocks;
mod mdfile;
mod html;
mod text;
mod types;
mod convert;

fn print_usage(program: &str, opts: &[OptGroup]) {
    let summary = getopts::short_usage(program, opts);
    let usage = getopts::usage(summary.as_slice(), opts);
    println!("{}", usage);
}

// Get the options.
// Print help if necessary, otherwise return Some(matches).
fn opts() -> Option<getopts::Matches> {
    let args: Vec<String> = os::args();

    let program = "rustdown";

    let opts = [
        getopts::opt("i",
                     "input",
                     "markdown file for input",
                     "INPUT",
                     getopts::Yes,
                     getopts::Req),
        getopts::opt("o",
                     "output",
                     "set output file name",
                     "OUTPUT",
                     getopts::Yes,
                     getopts::Optional),
        getopts::optflag("p",
                         "preview",
                         "preview the output in a web browser"),
        getopts::optflag("h", "help", "print this help menu")
    ];
    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => {
            println!("{}\n", f.to_string());
            print_usage(program.as_slice(), opts);
            return None;
        }
    };
    if matches.opt_present("h") {
        print_usage(program.as_slice(), opts);
        return None;
    }
    return Some(matches);
}

fn main() {
    match opts() {
        Some(matches) => {
            let input = matches.opt_str("i").expect("Some input argument is required!");
            let input_file = match Path::new_opt(input) {
                Some(file) => file,
                None => return,
            };
            match mdfile::open_markdown_file(&input_file) {
                Ok(file) => {
                    let blocks = blocks::blockify_file(file);
                    let markdown = convert::convert(blocks);
                    for md in markdown.iter() {
                        let html = md.to_html();
                        println!("{}", html);
                    }
                }
                Err(e) => {
                    println!("Error opening markdown file:\n{}", e);
                }
            }
        }
        _ => {
            // User asked for help
        }
    }
}
<commit_msg>factor out logic into fn<commit_after>// Copyright 2014 The Rustdown Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(macro_rules)]
#![feature(phase)]
#![feature(globs)]
#![feature(import_shadowing)]

extern crate rustdoc;
extern crate getopts;
extern crate url;

use std::os;
use std::path::posix::Path;
use std::io::fs::File;
use getopts::OptGroup;

use html::ToHtml;

mod blocks;
mod mdfile;
mod html;
mod text;
mod types;
mod convert;

fn print_usage(program: &str, opts: &[OptGroup]) {
    let summary = getopts::short_usage(program, opts);
    let usage = getopts::usage(summary.as_slice(), opts);
    println!("{}", usage);
}

// Get the options.
// Print help if necessary, otherwise return Some(matches).
fn opts() -> Option<getopts::Matches> {
    let args: Vec<String> = os::args();

    let program = "rustdown";

    let opts = [
        getopts::opt("i",
                     "input",
                     "markdown file for input",
                     "INPUT",
                     getopts::Yes,
                     getopts::Req),
        getopts::opt("o",
                     "output",
                     "set output file name",
                     "OUTPUT",
                     getopts::Yes,
                     getopts::Optional),
        getopts::optflag("p",
                         "preview",
                         "preview the output in a web browser"),
        getopts::optflag("h", "help", "print this help menu")
    ];
    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => {
            println!("{}\n", f.to_string());
            print_usage(program.as_slice(), opts);
            return None;
        }
    };
    if matches.opt_present("h") {
        print_usage(program.as_slice(), opts);
        return None;
    }
    return Some(matches);
}

fn read_markdown_file(file: File) {
    let blocks = blocks::blockify_file(file);
    let markdown = convert::convert(blocks);
    for md in markdown.iter() {
        let html = md.to_html();
        println!("{}", html);
    }
}

fn main() {
    match opts() {
        Some(matches) => {
            let input = matches.opt_str("i").expect("Some input argument is required!");
            let input_file = match Path::new_opt(input) {
                Some(file) => file,
                None => return,
            };
            match mdfile::open_markdown_file(&input_file) {
                Ok(file) => {
                    read_markdown_file(file);
                }
                Err(e) => {
                    println!("Error opening markdown file:\n{}", e);
                }
            }
        }
        _ => {
            // User asked for help
        }
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

// `error_chain!` can recurse deeply
#![recursion_limit = "1024"]

#[macro_use] extern crate error_chain;
#[macro_use] extern crate glium;
#[macro_use] extern crate serde_derive;
extern crate bytes;
extern crate futures;
extern crate rand;
extern crate serde;
extern crate serde_json;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_proto;
extern crate tokio_service;

#[cfg(test)]
#[macro_use]
mod test_utils;

mod drawer;
mod errors;
mod graph;
mod jsonproto;
mod map;
mod math;
mod mouse;
mod protocol;
mod scheduler;
mod square;
mod state;
mod visible_graph;
mod xorshift;

use drawer::Drawer;
use map::MapParameters;
use math::{apply, compose};
use mouse::Mouse;
use protocol::Participant;
use state::Player;
use visible_graph::GraphPt;

use glium::glutin::{Event, ElementState, MouseButton};
use glium::Surface;

use std::io::Write;
use std::net::SocketAddr;

// This only gives access within this module. Make this `pub use errors::*;`
// instead if the types must be accessible from other modules (e.g., within
// a `links` section).
use errors::*;

fn main() {
    if let Err(ref e) = run() {
        use ::std::io::Write;
        let stderr = &mut ::std::io::stderr();
        let errmsg = "Error writing to stderr";

        writeln!(stderr, "error: {}", e).expect(errmsg);

        for e in e.iter().skip(1) {
            writeln!(stderr, "caused by: {}", e).expect(errmsg);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
        }

        ::std::process::exit(1);
    }
}

fn usage() -> ! {
    writeln!(std::io::stderr(), "Usage: rbattle (client|server) ADDR")
        .expect("error writing to stderr");
    std::process::exit(1);
}

fn run() -> Result<()> {
    let mut args = std::env::args().skip(1);
    let mode = args.next().unwrap_or_else(|| usage());
    let socket_addr: SocketAddr = args.next()
        .unwrap_or_else(|| usage())
        .parse()
        .expect("couldn't parse address");

    let mut participant =
        if mode == "server" {
            Participant::new_server(socket_addr, MapParameters {
                size: (15, 15),
                sources: vec![32, 42, 182, 192],
                player_colors: vec![(0x9f, 0x20, 0xb1), (0xe0, 0x6f, 0x3a),
                                    (0x20, 0xb1, 0x21), (0x20, 0x67, 0xb1)]
            })
        } else if mode == "client" {
            Participant::new_client(socket_addr)?
        } else {
            usage()
        };

    let map = participant.snapshot().map.clone();

    use glium::DisplayBuild;

    let display = glium::glutin::WindowBuilder::new()
        .with_title("rbattle".to_string())
        .build_glium()
        .chain_err(|| "unable to open window")?;

    let drawer = Drawer::new(&display, &map)
        .chain_err(|| "failed to construct Drawer for map")?;

    let mut mouse = Mouse::new(participant.get_player(), map.clone());

    loop {
        // Take a snapshot of the current state and operate on that.
        let state = participant.snapshot();

        // It seems like glium always makes a frame take a full 16ms, regardless
        // of how much work we ask it to do, but I don't see anything in the
        // documentation about this. We're leaning on that for now to keep
        // timing consistent, but we'll need to add something to control timing
        // explicitly to avoid depending on this behavior.
        let mut frame = display.draw();
        frame.clear_color(1.0, 1.0, 1.0, 1.0);
        let status = drawer.draw(&mut frame, &state, &mouse);
        frame.finish()
            .chain_err(|| "drawing finish failed")?;

        let window_to_game = status?;
        let window_to_graph = compose(map.game_to_graph, window_to_game);

        for event in display.poll_events() {
            match event {
                Event::Closed => return Ok(()),
                Event::MouseMoved(x, y) => {
                    let graph_pos = apply(window_to_graph, [x as f32, y as f32]);
                    mouse.move_to(GraphPt(graph_pos));
                }
                Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                    mouse.click();
                }
                Event::MouseInput(ElementState::Released, MouseButton::Left) => {
                    if let Some(action) = mouse.release() {
                        participant.request_action(action);
                    }
                }
                _ => ()
            }
        }
    }
}
<commit_msg>Fix warnings.<commit_after>// `error_chain!` can recurse deeply
#![recursion_limit = "1024"]

#[macro_use] extern crate error_chain;
#[macro_use] extern crate glium;
#[macro_use] extern crate serde_derive;
extern crate bytes;
extern crate futures;
extern crate rand;
extern crate serde;
extern crate serde_json;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_proto;
extern crate tokio_service;

#[cfg(test)]
#[macro_use]
mod test_utils;

mod drawer;
mod errors;
mod graph;
mod jsonproto;
mod map;
mod math;
mod mouse;
mod protocol;
mod scheduler;
mod square;
mod state;
mod visible_graph;
mod xorshift;

use drawer::Drawer;
use map::MapParameters;
use math::{apply, compose};
use mouse::Mouse;
use protocol::Participant;
use visible_graph::GraphPt;

use glium::glutin::{Event, ElementState, MouseButton};
use glium::Surface;

use std::io::Write;
use std::net::SocketAddr;

// This only gives access within this module. Make this `pub use errors::*;`
// instead if the types must be accessible from other modules (e.g., within
// a `links` section).
use errors::*;

fn main() {
    if let Err(ref e) = run() {
        use ::std::io::Write;
        let stderr = &mut ::std::io::stderr();
        let errmsg = "Error writing to stderr";

        writeln!(stderr, "error: {}", e).expect(errmsg);

        for e in e.iter().skip(1) {
            writeln!(stderr, "caused by: {}", e).expect(errmsg);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
        }

        ::std::process::exit(1);
    }
}

fn usage() -> ! {
    writeln!(std::io::stderr(), "Usage: rbattle (client|server) ADDR")
        .expect("error writing to stderr");
    std::process::exit(1);
}

fn run() -> Result<()> {
    let mut args = std::env::args().skip(1);
    let mode = args.next().unwrap_or_else(|| usage());
    let socket_addr: SocketAddr = args.next()
        .unwrap_or_else(|| usage())
        .parse()
        .expect("couldn't parse address");

    let mut participant =
        if mode == "server" {
            Participant::new_server(socket_addr, MapParameters {
                size: (15, 15),
                sources: vec![32, 42, 182, 192],
                player_colors: vec![(0x9f, 0x20, 0xb1), (0xe0, 0x6f, 0x3a),
                                    (0x20, 0xb1, 0x21), (0x20, 0x67, 0xb1)]
            })
        } else if mode == "client" {
            Participant::new_client(socket_addr)?
        } else {
            usage()
        };

    let map = participant.snapshot().map.clone();

    use glium::DisplayBuild;

    let display = glium::glutin::WindowBuilder::new()
        .with_title("rbattle".to_string())
        .build_glium()
        .chain_err(|| "unable to open window")?;

    let drawer = Drawer::new(&display, &map)
        .chain_err(|| "failed to construct Drawer for map")?;

    let mut mouse = Mouse::new(participant.get_player(), map.clone());

    loop {
        // Take a snapshot of the current state and operate on that.
        let state = participant.snapshot();

        // It seems like glium always makes a frame take a full 16ms, regardless
        // of how much work we ask it to do, but I don't see anything in the
        // documentation about this. We're leaning on that for now to keep
        // timing consistent, but we'll need to add something to control timing
        // explicitly to avoid depending on this behavior.
        let mut frame = display.draw();
        frame.clear_color(1.0, 1.0, 1.0, 1.0);
        let status = drawer.draw(&mut frame, &state, &mouse);
        frame.finish()
            .chain_err(|| "drawing finish failed")?;

        let window_to_game = status?;
        let window_to_graph = compose(map.game_to_graph, window_to_game);

        for event in display.poll_events() {
            match event {
                Event::Closed => return Ok(()),
                Event::MouseMoved(x, y) => {
                    let graph_pos = apply(window_to_graph, [x as f32, y as f32]);
                    mouse.move_to(GraphPt(graph_pos));
                }
                Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                    mouse.click();
                }
                Event::MouseInput(ElementState::Released, MouseButton::Left) => {
                    if let Some(action) = mouse.release() {
                        participant.request_action(action);
                    }
                }
                _ => ()
            }
        }
    }
}
<|endoftext|>


<commit_before>mod board;

#[cfg(not(test))]
fn main() {
  let mut brd = board::Board::new(65, 248).random();
  let mut timer = std::io::Timer::new().unwrap();
  let ref mut worker_pool = board::WorkerPool::new_with_default_size();
  let periodic = timer.periodic(std::time::Duration::milliseconds(64));
  loop {
    println!("\x1b[H\x1b[2J{:?}", brd);
    periodic.recv().unwrap();
    brd = brd.parallel_next_generation(worker_pool);
  }
}
<commit_msg>Update for the old_io stopgap<commit_after>mod board;

#[cfg(not(test))]
fn main() {
  let mut brd = board::Board::new(65, 248).random();
  let mut timer = std::old_io::Timer::new().unwrap();
  let ref mut worker_pool = board::WorkerPool::new_with_default_size();
  let periodic = timer.periodic(std::time::Duration::milliseconds(64));
  loop {
    println!("\x1b[H\x1b[2J{:?}", brd);
    periodic.recv().unwrap();
    brd = brd.parallel_next_generation(worker_pool);
  }
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::{Button, Event, Events, EventLoop, Input, Motion, OpenGL, PistonWindow,
    WindowSettings};
use opengl_graphics::GlGraphics;

use game::Game;

fn main() {

    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: PistonWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    let mut events = window.events();

    while let Some(e) = events.next(&mut window) {
    // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Controller(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Controller(button))) => {
                game.button_release(button);
            }

            // Controller Axis are Move Input types
            Event::Input(Input::Move(Motion::ControllerAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }

}
<commit_msg>Fix whitespace.<commit_after>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::{Button, Event, Events, EventLoop, Input, Motion, OpenGL, PistonWindow,
    WindowSettings};
use opengl_graphics::GlGraphics;

use game::Game;

fn main() {
    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: PistonWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    let mut events = window.events();

    while let Some(e) = events.next(&mut window) {
        // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Controller(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Controller(button))) => {
                game.button_release(button);
            }

            // Controller Axis are Move Input types
            Event::Input(Input::Move(Motion::ControllerAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

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


<commit_before>extern crate docopt;
extern crate rustc_serialize;
extern crate entities;

use std::char;
use docopt::Docopt;
use entities::ENTITIES;

const USAGE: &'static str = "
how-do-i-escape: Prints escape sequences for unicode graphemes

Usage:
  how-do-i-escape <grapheme>
  how-do-i-escape (--help | --version)

Options:
  -h, --help  Show this screen.
  --version   Show version.

Example:
  $ how-do-i-escape \u{00A7}
  css  = \"\\00A7\"
  html = §
  js   = \"\\u00A7\"
";

#[derive(RustcDecodable)]
struct Args {
    arg_grapheme: String,
}

fn main() {
    let version = format!("v{}", env!("CARGO_PKG_VERSION"));

    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.help(true).version(Some(version)).decode())
        .unwrap_or_else(|e| e.exit());

    let grapheme = args.arg_grapheme;

    println!(r#"css  = "{}""#, escape_grapheme(&grapheme, as_css));
    println!(r#"html = {}"#, escape_grapheme(&grapheme, as_html));
    println!(r#"js   = "{}""#, escape_grapheme(&grapheme, as_js));
}

fn escape_grapheme<F>(grapheme: &str, int_to_escape_sequence: F) -> String
    where F: Fn(u32) -> String
{
    grapheme.chars()
        .map(|ch| ch as u32)
        .map(int_to_escape_sequence)
        .collect()
}

fn as_css(i: u32) -> String {
    format!("\\{:01$X}", i, 4)
}

fn as_js(i: u32) -> String {
    if i <= 0xFFFF {
        format!("\\u{:01$X}", i, 4)
    } else {
        format!("\\u{{{:X}}}", i)
    }
}

fn as_html(i: u32) -> String {
    // Some characters have multiple entity options
    // e.g. " and "
    let entity_options = ENTITIES.iter().filter(|e| {
        match e.codepoints {
            entities::Codepoints::Single(cp) => cp == i,
            _ => false,
        }
    }).collect::<Vec<_>>();

    if entity_options.is_empty() {
        format!("&#x{:01$X};", i, 4)
    } else {
        let nicest = choose_nice_entity(entity_options);
        nicest.entity.to_string()
    }
}

// "nice" means prefer lowercase and ends with a semicolon
fn choose_nice_entity(options: Vec<&entities::Entity>) -> &entities::Entity {
    assert!(!options.is_empty());

    let nicest_entity = options.iter().find(|entity| {
        has_semicolon(entity) && !is_all_caps(entity)
    });

    if let Some(entity) = nicest_entity {
        return entity;
    }

    let less_nice_entity = options.iter().find(|entity| {
        has_semicolon(entity)
    });

    if let Some(entity) = less_nice_entity {
        return entity;
    }

    let ok_entity = options.iter().find(|entity| {
        !is_all_caps(entity)
    });

    if let Some(entity) = ok_entity {
        return entity;
    }

    options[0]
}

fn has_semicolon(entity: &entities::Entity) -> bool {
    entity.entity.ends_with(";")
}

fn is_all_caps(entity: &entities::Entity) -> bool {
    !entity.entity.chars().any(char::is_lowercase)
}

#[cfg(test)]
mod tests {
    use super::{as_css, as_html, as_js, escape_grapheme};

    #[test]
    fn test_as_css() {
        assert_eq!(as_css(0), r"\0000");
        assert_eq!(as_css(0xFFFF), r"\FFFF");
        assert_ne!(as_css(0xBEEF), r"\beef");
        // assert_eq!(as_css(0x10000), ?);
    }

    #[test]
    fn test_as_html() {
        assert_eq!(as_html(0), r"�");
        assert_eq!(as_html(0xFFFF), r"");
        assert_ne!(as_html(0xBEEF), r"뻯");
        assert_eq!(as_html(',' as u32), r",");
        assert_eq!(as_html('>' as u32), r">");
        // assert_eq!(as_html(0x10000), ?);
    }

    #[test]
    fn test_as_js() {
        assert_eq!(as_js(0), r"\u0000");
        assert_eq!(as_js(0xFFFF), r"\uFFFF");
        assert_ne!(as_js(0xBEEF), r"\ubeef");
        assert_eq!(as_js(0x10000), r"\u{10000}");
        assert_eq!(as_js(0x10FFFF), r"\u{10FFFF}");
        assert_eq!(as_js(0xFFFFFFFF), r"\u{FFFFFFFF}");
    }

    #[test]
    fn test_escape_grapheme() {
        let always_hello = escape_grapheme("\u{FF}", |_| "hello".to_string());
        assert_eq!(always_hello, "hello");

        let simple = escape_grapheme("\u{FF}", |i| format!("{}", i));
        assert_eq!(simple, "255");
    }
}
<commit_msg>Adjust formatting<commit_after>extern crate docopt;
extern crate rustc_serialize;
extern crate entities;

use std::char;
use docopt::Docopt;
use entities::ENTITIES;

const USAGE: &'static str = "
how-do-i-escape: Prints escape sequences for unicode graphemes

Usage:
  how-do-i-escape <grapheme>
  how-do-i-escape (--help | --version)

Options:
  -h, --help  Show this screen.
  --version   Show version.

Example:
  $ how-do-i-escape \u{00A7}
  css  = \"\\00A7\"
  html = §
  js   = \"\\u00A7\"
";

#[derive(RustcDecodable)]
struct Args {
    arg_grapheme: String,
}

fn main() {
    let version = format!("v{}", env!("CARGO_PKG_VERSION"));

    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.help(true).version(Some(version)).decode())
        .unwrap_or_else(|e| e.exit());

    let grapheme = args.arg_grapheme;

    println!(r#"css  = "{}""#, escape_grapheme(&grapheme, as_css));
    println!(r#"html = {}"#, escape_grapheme(&grapheme, as_html));
    println!(r#"js   = "{}""#, escape_grapheme(&grapheme, as_js));
}

fn escape_grapheme<F>(grapheme: &str, int_to_escape_sequence: F) -> String
    where F: Fn(u32) -> String
{
    grapheme.chars()
        .map(|ch| ch as u32)
        .map(int_to_escape_sequence)
        .collect()
}

fn as_css(i: u32) -> String {
    format!("\\{:01$X}", i, 4)
}

fn as_js(i: u32) -> String {
    if i <= 0xFFFF {
        format!("\\u{:01$X}", i, 4)
    } else {
        format!("\\u{{{:X}}}", i)
    }
}

fn as_html(i: u32) -> String {
    // Some characters have multiple entity options
    // e.g. " and "
    let entity_options = ENTITIES.iter()
        .filter(|e| {
            match e.codepoints {
                entities::Codepoints::Single(cp) => cp == i,
                _ => false,
            }
        })
        .collect::<Vec<_>>();

    if entity_options.is_empty() {
        format!("&#x{:01$X};", i, 4)
    } else {
        let nicest = choose_nice_entity(entity_options);
        nicest.entity.to_string()
    }
}

// "nice" means prefer lowercase and ends with a semicolon
fn choose_nice_entity(options: Vec<&entities::Entity>) -> &entities::Entity {
    assert!(!options.is_empty());

    let nicest_entity = options.iter().find(|entity| has_semicolon(entity) && !is_all_caps(entity));

    if let Some(entity) = nicest_entity {
        return entity;
    }

    let less_nice_entity = options.iter().find(|entity| has_semicolon(entity));

    if let Some(entity) = less_nice_entity {
        return entity;
    }

    let ok_entity = options.iter().find(|entity| !is_all_caps(entity));

    if let Some(entity) = ok_entity {
        return entity;
    }

    options[0]
}

fn has_semicolon(entity: &entities::Entity) -> bool {
    entity.entity.ends_with(";")
}

fn is_all_caps(entity: &entities::Entity) -> bool {
    !entity.entity.chars().any(char::is_lowercase)
}

#[cfg(test)]
mod tests {
    use super::{as_css, as_html, as_js, escape_grapheme};

    #[test]
    fn test_as_css() {
        assert_eq!(as_css(0), r"\0000");
        assert_eq!(as_css(0xFFFF), r"\FFFF");
        assert_ne!(as_css(0xBEEF), r"\beef");
        // assert_eq!(as_css(0x10000), ?);
    }

    #[test]
    fn test_as_html() {
        assert_eq!(as_html(0), r"�");
        assert_eq!(as_html(0xFFFF), r"");
        assert_ne!(as_html(0xBEEF), r"뻯");
        assert_eq!(as_html(',' as u32), r",");
        assert_eq!(as_html('>' as u32), r">");
        // assert_eq!(as_html(0x10000), ?);
    }

    #[test]
    fn test_as_js() {
        assert_eq!(as_js(0), r"\u0000");
        assert_eq!(as_js(0xFFFF), r"\uFFFF");
        assert_ne!(as_js(0xBEEF), r"\ubeef");
        assert_eq!(as_js(0x10000), r"\u{10000}");
        assert_eq!(as_js(0x10FFFF), r"\u{10FFFF}");
        assert_eq!(as_js(0xFFFFFFFF), r"\u{FFFFFFFF}");
    }

    #[test]
    fn test_escape_grapheme() {
        let always_hello = escape_grapheme("\u{FF}", |_| "hello".to_string());
        assert_eq!(always_hello, "hello");

        let simple = escape_grapheme("\u{FF}", |i| format!("{}", i));
        assert_eq!(simple, "255");
    }
}
<|endoftext|>