<commit_before>use std::char;

fn prime_family(p: &str, mask: &[u8]) -> u32 {
    let mut count = 0;
    let isprime = |n: &u64| (2..(*n as f32).sqrt() as u64 + 1).all(|i| n % i != 0);
    for i in 0..10 {
        let c = p.chars()
                 .zip(mask.iter())
                 .map(|(pi, &m)| if m == 1 {
                     char::from_digit(i, 10).unwrap()
                 } else {
                     pi
                 })
                 .collect::<String>();
        if isprime(&c.parse::<u64>().unwrap()) {
            if c.chars().nth(0).unwrap() != '0' {
                count += 1;
            }
        }
    }
    count
}

pub fn main() {
    let primes = || (2..).filter(|&n| (2..(n as f32).sqrt() as u64 + 1).all(|i| n % i != 0));
    let penta_patterns = vec![
        [0,1,1,1,0],
        [1,0,1,1,0],
        [1,1,0,1,0],
        [1,1,1,0,0],
    ];
    let hexa_patterns = vec![
        [1,1,1,0,0,0],
        [0,1,1,1,0,0],
        [0,0,1,1,1,0],
        [1,0,0,1,1,0],
        [0,1,0,1,1,0],
        [1,1,0,0,1,0],
        [0,1,1,0,1,0],
        [1,0,1,1,0,0],
        [1,0,1,0,1,0],
    ];

    let same = |n: &Vec<char>| n[0] == n[1] && n[1] == n[2];
    let get_masked = |n: &str, mask: &[u8]| {
        n.chars().zip(mask.iter()).filter(|&(_, &m)| m == 1).map(|(n, _)| n).collect::<Vec<_>>()
    };

    let ten_thousands = primes()
                            .skip_while(|&x| x < 10_000)
                            .take_while(|&x| x < 100_000)
                            .collect::<Vec<u64>>();
    for p in ten_thousands {
        let p = p.to_string();
        for m in &penta_patterns {
            if same(&get_masked(&p, m)) {
                if prime_family(&p, m) > 7 {
                    println!("{}", p);
                    return;
                }
            }
        }
    }

    let hundred_thousands = primes()
                                .skip_while(|&x| x < 100_000)
                                .take_while(|&x| x < 1_000_000)
                                .collect::<Vec<u64>>();
    for &p in &hundred_thousands {
        let p = p.to_string();
        for m in &hexa_patterns {
            if same(&get_masked(&p, m)) {
                if prime_family(&p, m) > 7 {
                    println!("{}", p);
                    return;
                }
            }
        }
    }
}
<commit_msg>clean up problem 51 somewhat, and make it faster.<commit_after>use std::char;

fn prime_family_size(p: &str, mask: &[u8]) -> u32 {
    let mut count = 0;
    let isprime = |n: &u64| (2..(*n as f32).sqrt() as u64 + 1).all(|i| n % i != 0);
    for i in 0..10 {
        let c = p.chars().zip(mask.iter()) // zip number with mask
                 .map(|(p_i, &m)| if m == 1 {
                     char::from_digit(i, 10).unwrap()
                 } else {
                     p_i
                 })
                 .collect::<String>();
        if isprime(&c.parse::<u64>().unwrap()) {
            if c.chars().nth(0).unwrap() != '0' {
                count += 1;
            }
        }
    }
    count
}

pub fn main() {
    let primes = (2..).filter(|&n| (2..(n as f32).sqrt() as u64 + 1).all(|i| n % i != 0));
    let penta_patterns = vec![
        [0,1,1,1,0],
        [1,0,1,1,0],
        [1,1,0,1,0],
        [1,1,1,0,0],
    ];
    let hexa_patterns = vec![
        [1,1,1,0,0,0],
        [0,1,1,1,0,0],
        [0,0,1,1,1,0],
        [1,0,0,1,1,0],
        [0,1,0,1,1,0],
        [1,1,0,0,1,0],
        [0,1,1,0,1,0],
        [1,0,1,1,0,0],
        [1,0,1,0,1,0],
    ];

    // is the first 3 elements of a vector the same
    let same = |n: &Vec<char>| n[0] == n[1] && n[1] == n[2];

    let get_masked = |n: &str, mask: &[u8]| {
        n.chars().zip(mask.iter()).filter(|&(_, &m)| m == 1).map(|(n, _)| n).collect::<Vec<_>>()
    };

    let long_primes = primes.skip_while(|&x| x < 10_000)
                            .take_while(|&x| x < 1_000_000);
    for p in long_primes {
        let p = p.to_string();
        if p.len() == 5 {
            for m in &penta_patterns {
                if same(&get_masked(&p, m)) && prime_family_size(&p, m) > 7 {
                    println!("{}", p);
                    return;
                }
            }
        } else {
            for m in &hexa_patterns {
                if same(&get_masked(&p, m)) && prime_family_size(&p, m) > 7 {
                    println!("{}", p);
                    return;
                }
            }
        };
    }
}
<|endoftext|>


<commit_before>use vector::Vec3;
use ray::Ray;

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct HitRecord {
  pub t : f64,
  pub p : Vec3,
  pub normal : Vec3,
}

impl HitRecord {
  pub fn new(time : f64, point : Vec3, norm : Vec3) -> HitRecord {
    HitRecord { t: time, p: point, normal: norm }
  }
}

pub trait Hitable {
  fn hit(&self, r: Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool;
}<commit_msg>Remove trait derive for now In order to implement material on hit record, we will likely need to use Box, which makes implementing copy & clone difficult<commit_after>use vector::Vec3;
use ray::Ray;

pub struct HitRecord {
  pub t : f64,
  pub p : Vec3,
  pub normal : Vec3,
}

impl HitRecord {
  pub fn new(time : f64, point : Vec3, norm : Vec3) -> HitRecord {
    HitRecord { t: time, p: point, normal: norm }
  }
}

pub trait Hitable {
  fn hit(&self, r: Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool;
}<|endoftext|>


<commit_before>use Parameter;
use ndarray::{ArrayBase, Array1};
use std::ops::{AddAssign, MulAssign};

pub enum Trace {
    Accumulating {
        lambda: Parameter,
        eligibility: Array1<f64>,
    },
    Replacing {
        lambda: Parameter,
        eligibility: Array1<f64>,
    },
    // TODO: Dutch traces (need to be able to share alpha parameter)
}

impl Trace {
    pub fn get(&self) -> &Array1<f64> {
        match self {
            &Trace::Accumulating { ref eligibility, .. } |
                &Trace::Replacing { ref eligibility, .. } =>
            {
                eligibility
            },
        }
    }

    pub fn decay(&mut self, rate: f64) {
        match self {
            &mut Trace::Accumulating { ref mut eligibility, lambda } |
                &mut Trace::Replacing { ref mut eligibility, lambda } =>
            {
                eligibility.mul_assign(rate*lambda);
            },
        }
    }

    pub fn update(&mut self, phi: &Array1<f64>) {
        match self {
            &mut Trace::Accumulating { ref mut eligibility, lambda } => {
                eligibility.add_assign(phi);

            },
            &mut Trace::Replacing { ref mut eligibility, lambda } => {
                eligibility.add_assign(phi);
                eligibility.map_inplace(|val| *val = val.min(1.0));
            },
        }
    }
}
<commit_msg>Add tests for traces<commit_after>use Parameter;
use ndarray::{ArrayBase, Array1};
use std::ops::{AddAssign, MulAssign};

pub enum Trace {
    Accumulating {
        lambda: Parameter,
        eligibility: Array1<f64>,
    },
    Replacing {
        lambda: Parameter,
        eligibility: Array1<f64>,
    },
    // TODO: Dutch traces (need to be able to share alpha parameter)
}

impl Trace {
    pub fn get(&self) -> &Array1<f64> {
        match self {
            &Trace::Accumulating { ref eligibility, .. } |
                &Trace::Replacing { ref eligibility, .. } => eligibility,
        }
    }

    pub fn decay(&mut self, rate: f64) {
        match self {
            &mut Trace::Accumulating { ref mut eligibility, lambda } |
                &mut Trace::Replacing { ref mut eligibility, lambda } =>
            {
                eligibility.mul_assign(rate*lambda);
            },
        }
    }

    pub fn update(&mut self, phi: &Array1<f64>) {
        match self {
            &mut Trace::Accumulating { ref mut eligibility, lambda } =>
            {
                eligibility.add_assign(phi);
            },
            &mut Trace::Replacing { ref mut eligibility, lambda } =>
            {
                eligibility.add_assign(phi);
                eligibility.map_inplace(|val| *val = val.min(1.0));
            },
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Trace;
    use ndarray::{ArrayBase, arr1};

    #[test]
    fn test_accumulating() {
        let mut trace = Trace::Accumulating {
            lambda: 0.95.into(),
            eligibility: arr1(&[0.0f64; 10])
        };

        assert_eq!(trace.get(), &arr1(&[0.0f64; 10]));

        trace.decay(1.0);
        assert_eq!(trace.get(), &arr1(&[0.0f64; 10]));

        trace.update(&arr1(&[1.0f64; 10]));
        assert_eq!(trace.get(), &arr1(&[1.0f64; 10]));

        trace.decay(1.0);
        assert_eq!(trace.get(), &arr1(&[0.95f64; 10]));

        trace.update(&arr1(&[1.0f64; 10]));
        assert_eq!(trace.get(), &arr1(&[1.95f64; 10]));
    }

    #[test]
    fn test_replacing() {
        let mut trace = Trace::Replacing {
            lambda: 0.95.into(),
            eligibility: arr1(&[0.0f64; 10])
        };

        assert_eq!(trace.get(), &arr1(&[0.0f64; 10]));

        trace.decay(1.0);
        assert_eq!(trace.get(), &arr1(&[0.0f64; 10]));

        trace.update(&arr1(&[1.0f64; 10]));
        assert_eq!(trace.get(), &arr1(&[1.0f64; 10]));

        trace.decay(1.0);
        assert_eq!(trace.get(), &arr1(&[0.95f64; 10]));

        trace.update(&arr1(&[1.0f64; 10]));
        assert_eq!(trace.get(), &arr1(&[1.0f64; 10]));
    }
}
<|endoftext|>


<commit_before>// Copyright 2015-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

// Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/)

#![cfg(not(test))]
#![deny(warnings)]

extern crate getopts;
extern crate serde_json as json;

use std::env;
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::{Command, ExitStatus};
use std::str;
use std::collections::HashSet;
use std::iter::FromIterator;

use getopts::{Matches, Options};
use json::Value;

fn main() {
    let exit_status = execute();
    std::io::stdout().flush().unwrap();
    std::process::exit(exit_status);
}

fn execute() -> i32 {
    let success = 0;
    let failure = 1;

    let mut opts = getopts::Options::new();
    opts.optflag("h", "help", "show this message");
    opts.optflag("q", "quiet", "no output printed to stdout");
    opts.optflag("v", "verbose", "use verbose output");
    opts.optmulti(
        "p",
        "package",
        "specify package to format (only usable in workspaces)",
        "<package>",
    );
    opts.optflag("", "all", "format all packages (only usable in workspaces)");

    // If there is any invalid argument passed to `cargo fmt`, return without formatting.
    if let Some(arg) = env::args()
        .skip(2)
        .take_while(|a| a != "--")
        .find(|a| !a.starts_with('-'))
    {
        print_usage_to_stderr(&opts, &format!("Invalid argument: `{}`.", arg));
        return failure;
    }

    let matches = match opts.parse(env::args().skip(1).take_while(|a| a != "--")) {
        Ok(m) => m,
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            return failure;
        }
    };

    let verbosity = match (matches.opt_present("v"), matches.opt_present("q")) {
        (false, false) => Verbosity::Normal,
        (false, true) => Verbosity::Quiet,
        (true, false) => Verbosity::Verbose,
        (true, true) => {
            print_usage_to_stderr(&opts, "quiet mode and verbose mode are not compatible");
            return failure;
        }
    };

    if matches.opt_present("h") {
        print_usage_to_stdout(&opts, "");
        return success;
    }

    let workspace_hitlist = WorkspaceHitlist::from_matches(&matches);

    match format_crate(verbosity, &workspace_hitlist) {
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            failure
        }
        Ok(status) => if status.success() {
            success
        } else {
            status.code().unwrap_or(failure)
        },
    }
}

macro_rules! print_usage {
    ($print:ident, $opts:ident, $reason:expr) => ({
        let msg = format!("{}\nusage: cargo fmt [options]", $reason);
        $print!(
            "{}\nThis utility formats all bin and lib files of the current crate using rustfmt. \
             Arguments after `--` are passed to rustfmt.",
            $opts.usage(&msg)
        );
    })
}

fn print_usage_to_stdout(opts: &Options, reason: &str) {
    print_usage!(println, opts, reason);
}

fn print_usage_to_stderr(opts: &Options, reason: &str) {
    print_usage!(eprintln, opts, reason);
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Verbosity {
    Verbose,
    Normal,
    Quiet,
}

fn format_crate(
    verbosity: Verbosity,
    workspace_hitlist: &WorkspaceHitlist,
) -> Result<ExitStatus, io::Error> {
    let targets = get_targets(workspace_hitlist)?;

    // Currently only bin and lib files get formatted
    let files: Vec<_> = targets
        .into_iter()
        .filter(|t| t.kind.should_format())
        .inspect(|t| if verbosity == Verbosity::Verbose {
            println!("[{:?}] {:?}", t.kind, t.path)
        })
        .map(|t| t.path)
        .collect();

    format_files(&files, &get_fmt_args(), verbosity)
}

fn get_fmt_args() -> Vec<String> {
    // All arguments after -- are passed to rustfmt
    env::args().skip_while(|a| a != "--").skip(1).collect()
}

#[derive(Debug)]
enum TargetKind {
    Lib,         // dylib, staticlib, lib
    Bin,         // bin
    Example,     // example file
    Test,        // test file
    Bench,       // bench file
    CustomBuild, // build script
    ProcMacro,   // a proc macro implementation
    Other,       // plugin,...
}

impl TargetKind {
    fn should_format(&self) -> bool {
        match *self {
            TargetKind::Lib |
            TargetKind::Bin |
            TargetKind::Example |
            TargetKind::Test |
            TargetKind::Bench |
            TargetKind::CustomBuild |
            TargetKind::ProcMacro => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub struct Target {
    path: PathBuf,
    kind: TargetKind,
}

impl Target {
    pub fn from_json(json_val: &Value) -> Option<Self> {
        let jtarget = json_val.as_object()?;
        let path = PathBuf::from(jtarget.get("src_path")?.as_str()?);
        let kinds = jtarget.get("kind")?.as_array()?;
        let kind = match kinds[0].as_str()? {
            "bin" => TargetKind::Bin,
            "lib" | "dylib" | "staticlib" | "cdylib" | "rlib" => TargetKind::Lib,
            "test" => TargetKind::Test,
            "example" => TargetKind::Example,
            "bench" => TargetKind::Bench,
            "custom-build" => TargetKind::CustomBuild,
            "proc-macro" => TargetKind::ProcMacro,
            _ => TargetKind::Other,
        };

        Some(Target {
            path: path,
            kind: kind,
        })
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum WorkspaceHitlist {
    All,
    Some(Vec<String>),
    None,
}

impl WorkspaceHitlist {
    pub fn get_some(&self) -> Option<&[String]> {
        if let WorkspaceHitlist::Some(ref hitlist) = *self {
            Some(hitlist)
        } else {
            None
        }
    }

    pub fn from_matches(matches: &Matches) -> WorkspaceHitlist {
        match (matches.opt_present("all"), matches.opt_present("p")) {
            (false, false) => WorkspaceHitlist::None,
            (true, _) => WorkspaceHitlist::All,
            (false, true) => WorkspaceHitlist::Some(matches.opt_strs("p")),
        }
    }
}

fn get_cargo_metadata_from_utf8(v: &[u8]) -> Option<Value> {
    json::from_str(str::from_utf8(v).ok()?).ok()
}

fn get_json_array_with<'a>(v: &'a Value, key: &str) -> Option<&'a Vec<Value>> {
    v.as_object()?.get(key)?.as_array()
}

// `cargo metadata --no-deps | jq '.["packages"]'`
fn get_packages(v: &[u8]) -> Result<Vec<Value>, io::Error> {
    let e = io::Error::new(
        io::ErrorKind::NotFound,
        String::from("`cargo metadata` returned json without a 'packages' key"),
    );
    match get_cargo_metadata_from_utf8(v) {
        Some(ref json_obj) => get_json_array_with(json_obj, "packages").cloned().ok_or(e),
        None => Err(e),
    }
}

fn extract_target_from_package(package: &Value) -> Option<Vec<Target>> {
    let jtargets = get_json_array_with(package, "targets")?;
    let mut targets: Vec<Target> = vec![];
    for jtarget in jtargets {
        targets.push(Target::from_json(&jtarget)?);
    }
    Some(targets)
}

fn filter_packages_with_hitlist<'a>(
    packages: Vec<Value>,
    workspace_hitlist: &'a WorkspaceHitlist,
) -> Result<Vec<Value>, &'a String> {
    if *workspace_hitlist == WorkspaceHitlist::All {
        return Ok(packages);
    }
    let mut hitlist: HashSet<&String> = workspace_hitlist
        .get_some()
        .map_or(HashSet::new(), HashSet::from_iter);
    let members: Vec<Value> = packages
        .into_iter()
        .filter(|member| {
            member
                .as_object()
                .and_then(|member_obj| {
                    member_obj
                        .get("name")
                        .and_then(Value::as_str)
                        .map(|member_name| {
                            hitlist.take(&member_name.to_string()).is_some()
                        })
                })
                .unwrap_or(false)
        })
        .collect();
    if hitlist.is_empty() {
        Ok(members)
    } else {
        Err(hitlist.into_iter().next().unwrap())
    }
}

fn get_dependencies_from_package(package: &Value) -> Option<Vec<PathBuf>> {
    let jdependencies = get_json_array_with(package, "dependencies")?;
    let root_path = env::current_dir().ok()?;
    let mut dependencies: Vec<PathBuf> = vec![];
    for jdep in jdependencies {
        let jdependency = jdep.as_object()?;
        if !jdependency.get("source")?.is_null() {
            continue;
        }
        let name = jdependency.get("name")?.as_str()?;
        let mut path = root_path.clone();
        path.push(&name);
        dependencies.push(path);
    }
    Some(dependencies)
}

// Returns a vector of local dependencies under this crate
fn get_path_to_local_dependencies(packages: &[Value]) -> Vec<PathBuf> {
    let mut local_dependencies: Vec<PathBuf> = vec![];
    for package in packages {
        if let Some(mut d) = get_dependencies_from_package(package) {
            local_dependencies.append(&mut d);
        }
    }
    local_dependencies
}

// Returns a vector of all compile targets of a crate
fn get_targets(workspace_hitlist: &WorkspaceHitlist) -> Result<Vec<Target>, io::Error> {
    let output = Command::new("cargo")
        .args(&["metadata", "--no-deps", "--format-version=1"])
        .output()?;
    if output.status.success() {
        let cur_dir = env::current_dir()?;
        let mut targets: Vec<Target> = vec![];
        let packages = get_packages(&output.stdout)?;

        // If we can find any local dependencies, we will try to get targets from those as well.
        for path in get_path_to_local_dependencies(&packages) {
            env::set_current_dir(path)?;
            targets.append(&mut get_targets(workspace_hitlist)?);
        }

        env::set_current_dir(cur_dir)?;
        match filter_packages_with_hitlist(packages, workspace_hitlist) {
            Ok(packages) => {
                for package in packages {
                    if let Some(mut target) = extract_target_from_package(&package) {
                        targets.append(&mut target);
                    }
                }
                Ok(targets)
            }
            Err(package) => {
                // Mimick cargo of only outputting one <package> spec.
                Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    format!("package `{}` is not a member of the workspace", package),
                ))
            }
        }
    } else {
        Err(io::Error::new(
            io::ErrorKind::NotFound,
            str::from_utf8(&output.stderr).unwrap(),
        ))
    }
}

fn format_files(
    files: &[PathBuf],
    fmt_args: &[String],
    verbosity: Verbosity,
) -> Result<ExitStatus, io::Error> {
    let stdout = if verbosity == Verbosity::Quiet {
        std::process::Stdio::null()
    } else {
        std::process::Stdio::inherit()
    };
    if verbosity == Verbosity::Verbose {
        print!("rustfmt");
        for a in fmt_args.iter() {
            print!(" {}", a);
        }
        for f in files.iter() {
            print!(" {}", f.display());
        }
        println!("");
    }
    let mut command = Command::new("rustfmt")
        .stdout(stdout)
        .args(files)
        .args(fmt_args)
        .spawn()
        .map_err(|e| match e.kind() {
            io::ErrorKind::NotFound => io::Error::new(
                io::ErrorKind::Other,
                "Could not run rustfmt, please make sure it is in your PATH.",
            ),
            _ => e,
        })?;
    command.wait()
}
<commit_msg>Remove iter() in for loop<commit_after>// Copyright 2015-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

// Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/)

#![cfg(not(test))]
#![deny(warnings)]

extern crate getopts;
extern crate serde_json as json;

use std::env;
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::{Command, ExitStatus};
use std::str;
use std::collections::HashSet;
use std::iter::FromIterator;

use getopts::{Matches, Options};
use json::Value;

fn main() {
    let exit_status = execute();
    std::io::stdout().flush().unwrap();
    std::process::exit(exit_status);
}

fn execute() -> i32 {
    let success = 0;
    let failure = 1;

    let mut opts = getopts::Options::new();
    opts.optflag("h", "help", "show this message");
    opts.optflag("q", "quiet", "no output printed to stdout");
    opts.optflag("v", "verbose", "use verbose output");
    opts.optmulti(
        "p",
        "package",
        "specify package to format (only usable in workspaces)",
        "<package>",
    );
    opts.optflag("", "all", "format all packages (only usable in workspaces)");

    // If there is any invalid argument passed to `cargo fmt`, return without formatting.
    if let Some(arg) = env::args()
        .skip(2)
        .take_while(|a| a != "--")
        .find(|a| !a.starts_with('-'))
    {
        print_usage_to_stderr(&opts, &format!("Invalid argument: `{}`.", arg));
        return failure;
    }

    let matches = match opts.parse(env::args().skip(1).take_while(|a| a != "--")) {
        Ok(m) => m,
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            return failure;
        }
    };

    let verbosity = match (matches.opt_present("v"), matches.opt_present("q")) {
        (false, false) => Verbosity::Normal,
        (false, true) => Verbosity::Quiet,
        (true, false) => Verbosity::Verbose,
        (true, true) => {
            print_usage_to_stderr(&opts, "quiet mode and verbose mode are not compatible");
            return failure;
        }
    };

    if matches.opt_present("h") {
        print_usage_to_stdout(&opts, "");
        return success;
    }

    let workspace_hitlist = WorkspaceHitlist::from_matches(&matches);

    match format_crate(verbosity, &workspace_hitlist) {
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            failure
        }
        Ok(status) => if status.success() {
            success
        } else {
            status.code().unwrap_or(failure)
        },
    }
}

macro_rules! print_usage {
    ($print:ident, $opts:ident, $reason:expr) => ({
        let msg = format!("{}\nusage: cargo fmt [options]", $reason);
        $print!(
            "{}\nThis utility formats all bin and lib files of the current crate using rustfmt. \
             Arguments after `--` are passed to rustfmt.",
            $opts.usage(&msg)
        );
    })
}

fn print_usage_to_stdout(opts: &Options, reason: &str) {
    print_usage!(println, opts, reason);
}

fn print_usage_to_stderr(opts: &Options, reason: &str) {
    print_usage!(eprintln, opts, reason);
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Verbosity {
    Verbose,
    Normal,
    Quiet,
}

fn format_crate(
    verbosity: Verbosity,
    workspace_hitlist: &WorkspaceHitlist,
) -> Result<ExitStatus, io::Error> {
    let targets = get_targets(workspace_hitlist)?;

    // Currently only bin and lib files get formatted
    let files: Vec<_> = targets
        .into_iter()
        .filter(|t| t.kind.should_format())
        .inspect(|t| if verbosity == Verbosity::Verbose {
            println!("[{:?}] {:?}", t.kind, t.path)
        })
        .map(|t| t.path)
        .collect();

    format_files(&files, &get_fmt_args(), verbosity)
}

fn get_fmt_args() -> Vec<String> {
    // All arguments after -- are passed to rustfmt
    env::args().skip_while(|a| a != "--").skip(1).collect()
}

#[derive(Debug)]
enum TargetKind {
    Lib,         // dylib, staticlib, lib
    Bin,         // bin
    Example,     // example file
    Test,        // test file
    Bench,       // bench file
    CustomBuild, // build script
    ProcMacro,   // a proc macro implementation
    Other,       // plugin,...
}

impl TargetKind {
    fn should_format(&self) -> bool {
        match *self {
            TargetKind::Lib |
            TargetKind::Bin |
            TargetKind::Example |
            TargetKind::Test |
            TargetKind::Bench |
            TargetKind::CustomBuild |
            TargetKind::ProcMacro => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub struct Target {
    path: PathBuf,
    kind: TargetKind,
}

impl Target {
    pub fn from_json(json_val: &Value) -> Option<Self> {
        let jtarget = json_val.as_object()?;
        let path = PathBuf::from(jtarget.get("src_path")?.as_str()?);
        let kinds = jtarget.get("kind")?.as_array()?;
        let kind = match kinds[0].as_str()? {
            "bin" => TargetKind::Bin,
            "lib" | "dylib" | "staticlib" | "cdylib" | "rlib" => TargetKind::Lib,
            "test" => TargetKind::Test,
            "example" => TargetKind::Example,
            "bench" => TargetKind::Bench,
            "custom-build" => TargetKind::CustomBuild,
            "proc-macro" => TargetKind::ProcMacro,
            _ => TargetKind::Other,
        };

        Some(Target {
            path: path,
            kind: kind,
        })
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum WorkspaceHitlist {
    All,
    Some(Vec<String>),
    None,
}

impl WorkspaceHitlist {
    pub fn get_some(&self) -> Option<&[String]> {
        if let WorkspaceHitlist::Some(ref hitlist) = *self {
            Some(hitlist)
        } else {
            None
        }
    }

    pub fn from_matches(matches: &Matches) -> WorkspaceHitlist {
        match (matches.opt_present("all"), matches.opt_present("p")) {
            (false, false) => WorkspaceHitlist::None,
            (true, _) => WorkspaceHitlist::All,
            (false, true) => WorkspaceHitlist::Some(matches.opt_strs("p")),
        }
    }
}

fn get_cargo_metadata_from_utf8(v: &[u8]) -> Option<Value> {
    json::from_str(str::from_utf8(v).ok()?).ok()
}

fn get_json_array_with<'a>(v: &'a Value, key: &str) -> Option<&'a Vec<Value>> {
    v.as_object()?.get(key)?.as_array()
}

// `cargo metadata --no-deps | jq '.["packages"]'`
fn get_packages(v: &[u8]) -> Result<Vec<Value>, io::Error> {
    let e = io::Error::new(
        io::ErrorKind::NotFound,
        String::from("`cargo metadata` returned json without a 'packages' key"),
    );
    match get_cargo_metadata_from_utf8(v) {
        Some(ref json_obj) => get_json_array_with(json_obj, "packages").cloned().ok_or(e),
        None => Err(e),
    }
}

fn extract_target_from_package(package: &Value) -> Option<Vec<Target>> {
    let jtargets = get_json_array_with(package, "targets")?;
    let mut targets: Vec<Target> = vec![];
    for jtarget in jtargets {
        targets.push(Target::from_json(&jtarget)?);
    }
    Some(targets)
}

fn filter_packages_with_hitlist<'a>(
    packages: Vec<Value>,
    workspace_hitlist: &'a WorkspaceHitlist,
) -> Result<Vec<Value>, &'a String> {
    if *workspace_hitlist == WorkspaceHitlist::All {
        return Ok(packages);
    }
    let mut hitlist: HashSet<&String> = workspace_hitlist
        .get_some()
        .map_or(HashSet::new(), HashSet::from_iter);
    let members: Vec<Value> = packages
        .into_iter()
        .filter(|member| {
            member
                .as_object()
                .and_then(|member_obj| {
                    member_obj
                        .get("name")
                        .and_then(Value::as_str)
                        .map(|member_name| {
                            hitlist.take(&member_name.to_string()).is_some()
                        })
                })
                .unwrap_or(false)
        })
        .collect();
    if hitlist.is_empty() {
        Ok(members)
    } else {
        Err(hitlist.into_iter().next().unwrap())
    }
}

fn get_dependencies_from_package(package: &Value) -> Option<Vec<PathBuf>> {
    let jdependencies = get_json_array_with(package, "dependencies")?;
    let root_path = env::current_dir().ok()?;
    let mut dependencies: Vec<PathBuf> = vec![];
    for jdep in jdependencies {
        let jdependency = jdep.as_object()?;
        if !jdependency.get("source")?.is_null() {
            continue;
        }
        let name = jdependency.get("name")?.as_str()?;
        let mut path = root_path.clone();
        path.push(&name);
        dependencies.push(path);
    }
    Some(dependencies)
}

// Returns a vector of local dependencies under this crate
fn get_path_to_local_dependencies(packages: &[Value]) -> Vec<PathBuf> {
    let mut local_dependencies: Vec<PathBuf> = vec![];
    for package in packages {
        if let Some(mut d) = get_dependencies_from_package(package) {
            local_dependencies.append(&mut d);
        }
    }
    local_dependencies
}

// Returns a vector of all compile targets of a crate
fn get_targets(workspace_hitlist: &WorkspaceHitlist) -> Result<Vec<Target>, io::Error> {
    let output = Command::new("cargo")
        .args(&["metadata", "--no-deps", "--format-version=1"])
        .output()?;
    if output.status.success() {
        let cur_dir = env::current_dir()?;
        let mut targets: Vec<Target> = vec![];
        let packages = get_packages(&output.stdout)?;

        // If we can find any local dependencies, we will try to get targets from those as well.
        for path in get_path_to_local_dependencies(&packages) {
            env::set_current_dir(path)?;
            targets.append(&mut get_targets(workspace_hitlist)?);
        }

        env::set_current_dir(cur_dir)?;
        match filter_packages_with_hitlist(packages, workspace_hitlist) {
            Ok(packages) => {
                for package in packages {
                    if let Some(mut target) = extract_target_from_package(&package) {
                        targets.append(&mut target);
                    }
                }
                Ok(targets)
            }
            Err(package) => {
                // Mimick cargo of only outputting one <package> spec.
                Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    format!("package `{}` is not a member of the workspace", package),
                ))
            }
        }
    } else {
        Err(io::Error::new(
            io::ErrorKind::NotFound,
            str::from_utf8(&output.stderr).unwrap(),
        ))
    }
}

fn format_files(
    files: &[PathBuf],
    fmt_args: &[String],
    verbosity: Verbosity,
) -> Result<ExitStatus, io::Error> {
    let stdout = if verbosity == Verbosity::Quiet {
        std::process::Stdio::null()
    } else {
        std::process::Stdio::inherit()
    };
    if verbosity == Verbosity::Verbose {
        print!("rustfmt");
        for a in fmt_args {
            print!(" {}", a);
        }
        for f in files {
            print!(" {}", f.display());
        }
        println!("");
    }
    let mut command = Command::new("rustfmt")
        .stdout(stdout)
        .args(files)
        .args(fmt_args)
        .spawn()
        .map_err(|e| match e.kind() {
            io::ErrorKind::NotFound => io::Error::new(
                io::ErrorKind::Other,
                "Could not run rustfmt, please make sure it is in your PATH.",
            ),
            _ => e,
        })?;
    command.wait()
}
<|endoftext|>


<commit_before>extern crate url;

use std::process::Command;

use url::Url;

fn main() {
    let url = Url::parse("https://gitlab.\
                          com/api/v3/projects/2208459/repository/files?file_path=message.\
                          proto&ref=develop");

    let private_token =
        Command::new("cat").arg("$GITLAB_KEY").output().expect("Failed to get private token");
}
<commit_msg>Removal of initial rust binary<commit_after><|endoftext|>


<commit_before>/*!

BWT (Burrows-Wheeler Transform) forward and backward transformation

This module contains a bruteforce implementation of BWT encoding in Rust as well as standard decoding.
These are exposed as a standard `Reader` and `Writer` interfaces wrapping an underlying stream.

# Example

```rust
let stream = Path::new("path/to/file.bwt");
let decompressed = bwt::Decoder::new(stream,true).read_to_end();
```

# Credit

*/

use std::{iter,num,vec};

static MAGIC    : u32   = 0x74776272;	//=rbwt

struct Radix    {
    freq    : [uint,..257],
}

impl Radix  {
    /// create Radix sort instance
    fn new() -> Radix   {
        Radix   {
            freq : [0,..257],
        }
    }

    /// reset counters
    /// allows the struct to be re-used
    #[allow(dead_code)]
    fn reset(&mut self) {
        for i in range(0,257)   {
            self.freq[i] = 0;
        }
    }

    /// count elements in the input
    fn gather(&mut self, input: &[u8])  {
        for &b in input.iter()  {
            self.freq[b] += 1;
        }
    }

    /// build offset table
    fn accumulate(&mut self)    {
        let mut n = 0;
        for i in range(0,256)   {
            let f = self.freq[i];
            self.freq[i] = n;
            n += f;
        }
        self.freq[256] = n;
    }

    /// return next byte position
    fn position(&mut self, b: u8)-> uint   {
        let pos = self.freq[b];
        self.freq[b] += 1;
        assert!( self.freq[b] <= self.freq[b+1] );
        pos
    }

    /// shift frequences to the left
    /// allows the offsets to be re-used after all positions are obtained
    #[allow(dead_code)]
    fn shift(&mut self) {
        assert_eq!( self.freq[255], self.freq[256] );
        for i in range(256,0)   {
            self.freq[i] = self.freq[i-1];
        }
        self.freq[0] = 0;
    }
}

/// This structure is used to decode a stream of BWT blocks. This wraps an
/// internal reader which is read from when this decoder's read method is
/// called.
pub struct Decoder<R> {
    /// The internally wrapped reader. This is exposed so it may be moved out
    /// of. Note that if data is read from the reader while decoding is in
    /// progress the output stream will get corrupted.
    r: R,
    priv start  : uint,

    priv temp   : ~[u8],
    priv output : ~[u8],
    priv table  : ~[uint],

    priv header         : bool,
    priv max_block_size : uint,
    priv extra_memory   : bool,
}

impl<R: Reader> Decoder<R> {
    /// Creates a new decoder which will read data from the given stream. The
    /// inner stream can be re-acquired by moving out of the `r` field of this
    /// structure.
    /// 'extra' switch allows allocating extra N words of memory for better performance
    pub fn new(r: R, extra: bool) -> Decoder<R> {
        Decoder {
            r: r,
            start: 0,
            temp: ~[],
            output: ~[],
            table: ~[],
            header: false,
            max_block_size: 0,
            extra_memory: extra,
        }
    }

    /// Resets this decoder back to its initial state. Note that the underlying
    /// stream is not seeked on or has any alterations performed on it.
    pub fn reset(&mut self) {
        self.header = false;
        self.start = 0;
    }

    fn read_header(&mut self) -> Option<()> {
        if self.r.read_le_u32() != MAGIC { return None }
        self.max_block_size = self.r.read_le_u32() as uint;

        debug!("max size: {}", self.max_block_size);

        return Some(());
    }

    fn decode_block(&mut self) -> bool {
        let n = self.r.read_le_u32() as uint;
        if n==0 { return false }

        //TODO: insert a dummy $ to avoid an extra if later on
        self.temp.truncate(0);
        self.temp.reserve(n);
        self.r.push_bytes(&mut self.temp, n);

        let mut radix = Radix::new();
        radix.gather( self.temp );
        radix.accumulate();

        let origin = self.r.read_le_u32() as uint + 1;
        self.output.truncate(0);
        self.output.reserve(n);

        if self.extra_memory    {
            self.table.truncate(0);
            self.table.grow_fn(n+1, |_| 0);
            for i in range(0,n) {
                let b = self.temp[i];
                let p = radix.position(b);
                self.table[p+1] = if i<origin {i} else {i+1};
            }
            let mut i = origin;
            n.times(|| {
                i = self.table[i];
                let j = if i>origin {i-1} else {i};
                self.output.push( self.temp[j] );
            });
            assert_eq!(i, 0);
        }else   {
            self.output.grow_fn(n, |_| 0);
            let mut i = 0;
            for j in range(0,n) {
                let b = self.temp[if i>origin {i-1} else {i}];
                self.output[n-1-j] = b;
                i = (if i>origin {0} else {1}) + radix.freq[b] +
                    self.temp.slice_to(i).iter().count(|&k| k==b);
            }
            assert_eq!(i, origin);
        }

        self.start = 0;
        return true;
    }

    /// Tests whether the end of this BWT stream has been reached.
    pub fn eof(&mut self) -> bool {
        self.start >= self.output.len() && self.r.eof()
    }
}

impl<R: Reader> Reader for Decoder<R> {
    fn read(&mut self, dst: &mut [u8]) -> Option<uint> {
        if self.r.eof() { return None }
        if !self.header {
            self.read_header();
            self.header = true;
        }
        let mut amt = dst.len();
        let len = amt;

        while amt > 0 && !self.eof() {
            if self.output.len() == self.start    {
                if !self.decode_block() {
                   break
                }
            }
            let n = num::min( amt, self.output.len() - self.start );
            vec::bytes::copy_memory(
                dst.mut_slice_from(len - amt),
                self.output.slice_from(self.start)
                );
            self.start += n;
            amt -= n;
        }

        return Some(len - amt);
    }
}

/// This structure is used to compress a stream of bytes using the BWT.
/// This is a wrapper around an internal writer which bytes will be written to.
pub struct Encoder<W> {
    priv w: W,
    priv buf: ~[u8],
    priv suf: ~[uint],
    priv wrote_header: bool,
    priv block_size: uint,
}

impl<W: Writer> Encoder<W> {
    /// Creates a new encoder which will have its output written to the given
    /// output stream. The output stream can be re-acquired by calling
    /// `finish()`
    /// 'block_size' is idealy as big as your input, unless you know for sure that
    /// the input consists of multiple parts of different nature. Often set as 4Mb.
    pub fn new(w: W, block_size: uint) -> Encoder<W> {
        Encoder {
            w: w,
            buf: ~[],
            suf: ~[],
            wrote_header: false,
            block_size: block_size,
        }
    }

    fn encode_block(&mut self) {
        let n = self.buf.len();
        self.w.write_le_u32(n as u32);

        let mut radix = Radix::new();
        radix.gather( self.buf );
        radix.accumulate();

        self.suf.truncate(0);
        self.suf.grow_fn(n, |_| n);
        for i in range(0,n) {
            let b = self.buf[i];
            let p = radix.position(b);
            self.suf[p] = i;
        }

        for i in range(0,256)   {
            let lo = radix.freq[i];
            let hi = radix.freq[i+1];
            let slice = self.suf.mut_slice(lo,hi);
            slice.sort_by(|&a,&b| {
                iter::order::cmp(
                    self.buf.slice_from(a).iter(),
                    self.buf.slice_from(b).iter())
            });
        }

        let mut origin = n;
        self.w.write_u8( self.buf[n-1] );

        for i in range(0,n) {
            let s = self.suf[i];
            if s==0 {
                assert!( origin == n );
                origin = i;
            }else   {
                let b = self.buf[s-1];
                self.w.write_u8( b );
            }
        }
        assert!( origin != n );
        self.w.write_le_u32(origin as u32);
        self.buf.truncate(0);
    }

    /// This function is used to flag that this session of compression is done
    /// with. The stream is finished up (final bytes are written), and then the
    /// wrapped writer is returned.
    pub fn finish(mut self) -> W {
        self.flush();
        self.w
    }
}

impl<W: Writer> Writer for Encoder<W> {
    fn write(&mut self, mut buf: &[u8]) {
        if !self.wrote_header {
            self.w.write_le_u32(MAGIC);
            self.w.write_le_u32(self.block_size as u32);
            self.wrote_header = true;
        }

        while buf.len() > 0 {
            let amt = num::min( self.block_size - self.buf.len(), buf.len() );
            self.buf.push_all( buf.slice_to(amt) );

            if self.buf.len() == self.block_size {
                self.encode_block();
            }
            buf = buf.slice_from(amt);
        }
    }

    fn flush(&mut self) {
        if self.buf.len() > 0 {
            self.encode_block();
        }
    }
}

#[cfg(test)]
mod test {
    use extra::test;
    //use std::rand;
    use std::io::mem::{BufReader, MemWriter};
    use super::{Decoder, Encoder};

    fn test_decode(input: &[u8], output: &[u8], extra_memory: bool) {
        let mut d = Decoder::new( BufReader::new(input), extra_memory );

        let got = d.read_to_end();
        assert!( got.as_slice() == output );
    }

    #[test]
    fn decode() {
        let reference = include_bin!("data/test.txt");
        test_decode(include_bin!("data/test.bwt"), reference, true);
        test_decode(include_bin!("data/test.bwt"), reference, false);
    }

    fn roundtrip(bytes: &[u8]) {
        let mut e = Encoder::new( MemWriter::new(), 1<<10 );
        e.write(bytes);
        let encoded = e.finish().unwrap();

        let mut d = Decoder::new( BufReader::new(encoded), true );
        let decoded = d.read_to_end();
        assert_eq!(decoded.as_slice(), bytes);
    }

    #[test]
    fn some_roundtrips() {
        roundtrip(bytes!("test"));
        roundtrip(bytes!(""));
        roundtrip(include_bin!("data/test.txt"));
    }

    #[bench]
    fn decompress_speed(bh: &mut test::BenchHarness) {
        let input = include_bin!("data/test.bwt");
        let mut d = Decoder::new( BufReader::new(input), true );
        let mut output = [0u8, ..65536];
        let mut output_size = 0;
        bh.iter(|| {
            d.r = BufReader::new(input);
            d.reset();
            output_size = d.read(output).unwrap();
        });
        bh.bytes = output_size as u64;
    }
}
<commit_msg>Removing more usage of eof() from bwt<commit_after>/*!

BWT (Burrows-Wheeler Transform) forward and backward transformation

This module contains a bruteforce implementation of BWT encoding in Rust as well as standard decoding.
These are exposed as a standard `Reader` and `Writer` interfaces wrapping an underlying stream.

# Example

```rust
let stream = Path::new("path/to/file.bwt");
let decompressed = bwt::Decoder::new(stream,true).read_to_end();
```

# Credit

*/

use std::{iter,num,vec};

static MAGIC    : u32   = 0x74776272;	//=rbwt

struct Radix    {
    freq    : [uint,..257],
}

impl Radix  {
    /// create Radix sort instance
    fn new() -> Radix   {
        Radix   {
            freq : [0,..257],
        }
    }

    /// reset counters
    /// allows the struct to be re-used
    #[allow(dead_code)]
    fn reset(&mut self) {
        for i in range(0,257)   {
            self.freq[i] = 0;
        }
    }

    /// count elements in the input
    fn gather(&mut self, input: &[u8])  {
        for &b in input.iter()  {
            self.freq[b] += 1;
        }
    }

    /// build offset table
    fn accumulate(&mut self)    {
        let mut n = 0;
        for i in range(0,256)   {
            let f = self.freq[i];
            self.freq[i] = n;
            n += f;
        }
        self.freq[256] = n;
    }

    /// return next byte position
    fn position(&mut self, b: u8)-> uint   {
        let pos = self.freq[b];
        self.freq[b] += 1;
        assert!( self.freq[b] <= self.freq[b+1] );
        pos
    }

    /// shift frequences to the left
    /// allows the offsets to be re-used after all positions are obtained
    #[allow(dead_code)]
    fn shift(&mut self) {
        assert_eq!( self.freq[255], self.freq[256] );
        for i in range(256,0)   {
            self.freq[i] = self.freq[i-1];
        }
        self.freq[0] = 0;
    }
}

/// This structure is used to decode a stream of BWT blocks. This wraps an
/// internal reader which is read from when this decoder's read method is
/// called.
pub struct Decoder<R> {
    /// The internally wrapped reader. This is exposed so it may be moved out
    /// of. Note that if data is read from the reader while decoding is in
    /// progress the output stream will get corrupted.
    r: R,
    priv start  : uint,

    priv temp   : ~[u8],
    priv output : ~[u8],
    priv table  : ~[uint],

    priv header         : bool,
    priv max_block_size : uint,
    priv extra_memory   : bool,
}

impl<R: Reader> Decoder<R> {
    /// Creates a new decoder which will read data from the given stream. The
    /// inner stream can be re-acquired by moving out of the `r` field of this
    /// structure.
    /// 'extra' switch allows allocating extra N words of memory for better performance
    pub fn new(r: R, extra: bool) -> Decoder<R> {
        Decoder {
            r: r,
            start: 0,
            temp: ~[],
            output: ~[],
            table: ~[],
            header: false,
            max_block_size: 0,
            extra_memory: extra,
        }
    }

    /// Resets this decoder back to its initial state. Note that the underlying
    /// stream is not seeked on or has any alterations performed on it.
    pub fn reset(&mut self) {
        self.header = false;
        self.start = 0;
    }

    fn read_header(&mut self) -> Option<()> {
        if self.r.read_le_u32() != MAGIC { return None }
        self.max_block_size = self.r.read_le_u32() as uint;

        debug!("max size: {}", self.max_block_size);

        return Some(());
    }

    fn decode_block(&mut self) -> bool {
        let n = self.r.read_le_u32() as uint;
        if n==0 { return false }

        //TODO: insert a dummy $ to avoid an extra if later on
        self.temp.truncate(0);
        self.temp.reserve(n);
        self.r.push_bytes(&mut self.temp, n);

        let mut radix = Radix::new();
        radix.gather( self.temp );
        radix.accumulate();

        let origin = self.r.read_le_u32() as uint + 1;
        self.output.truncate(0);
        self.output.reserve(n);

        if self.extra_memory    {
            self.table.truncate(0);
            self.table.grow_fn(n+1, |_| 0);
            for i in range(0,n) {
                let b = self.temp[i];
                let p = radix.position(b);
                self.table[p+1] = if i<origin {i} else {i+1};
            }
            let mut i = origin;
            n.times(|| {
                i = self.table[i];
                let j = if i>origin {i-1} else {i};
                self.output.push( self.temp[j] );
            });
            assert_eq!(i, 0);
        }else   {
            self.output.grow_fn(n, |_| 0);
            let mut i = 0;
            for j in range(0,n) {
                let b = self.temp[if i>origin {i-1} else {i}];
                self.output[n-1-j] = b;
                i = (if i>origin {0} else {1}) + radix.freq[b] +
                    self.temp.slice_to(i).iter().count(|&k| k==b);
            }
            assert_eq!(i, origin);
        }

        self.start = 0;
        return true;
    }
}

impl<R: Reader> Reader for Decoder<R> {
    fn read(&mut self, dst: &mut [u8]) -> Option<uint> {
        if !self.header {
            self.read_header();
            self.header = true;
        }
        let mut amt = dst.len();
        let len = amt;

        while amt > 0 {
            if self.output.len() == self.start {
                if !self.decode_block() {
                   break
                }
            }
            let n = num::min( amt, self.output.len() - self.start );
            vec::bytes::copy_memory(
                dst.mut_slice_from(len - amt),
                self.output.slice_from(self.start)
                );
            self.start += n;
            amt -= n;
        }

        if len == amt {None} else {Some(len - amt)}
    }
}

/// This structure is used to compress a stream of bytes using the BWT.
/// This is a wrapper around an internal writer which bytes will be written to.
pub struct Encoder<W> {
    priv w: W,
    priv buf: ~[u8],
    priv suf: ~[uint],
    priv wrote_header: bool,
    priv block_size: uint,
}

impl<W: Writer> Encoder<W> {
    /// Creates a new encoder which will have its output written to the given
    /// output stream. The output stream can be re-acquired by calling
    /// `finish()`
    /// 'block_size' is idealy as big as your input, unless you know for sure that
    /// the input consists of multiple parts of different nature. Often set as 4Mb.
    pub fn new(w: W, block_size: uint) -> Encoder<W> {
        Encoder {
            w: w,
            buf: ~[],
            suf: ~[],
            wrote_header: false,
            block_size: block_size,
        }
    }

    fn encode_block(&mut self) {
        let n = self.buf.len();
        self.w.write_le_u32(n as u32);

        let mut radix = Radix::new();
        radix.gather( self.buf );
        radix.accumulate();

        self.suf.truncate(0);
        self.suf.grow_fn(n, |_| n);
        for i in range(0,n) {
            let b = self.buf[i];
            let p = radix.position(b);
            self.suf[p] = i;
        }

        for i in range(0,256)   {
            let lo = radix.freq[i];
            let hi = radix.freq[i+1];
            let slice = self.suf.mut_slice(lo,hi);
            slice.sort_by(|&a,&b| {
                iter::order::cmp(
                    self.buf.slice_from(a).iter(),
                    self.buf.slice_from(b).iter())
            });
        }

        let mut origin = n;
        self.w.write_u8( self.buf[n-1] );

        for i in range(0,n) {
            let s = self.suf[i];
            if s==0 {
                assert!( origin == n );
                origin = i;
            }else   {
                let b = self.buf[s-1];
                self.w.write_u8( b );
            }
        }
        assert!( origin != n );
        self.w.write_le_u32(origin as u32);
        self.buf.truncate(0);
    }

    /// This function is used to flag that this session of compression is done
    /// with. The stream is finished up (final bytes are written), and then the
    /// wrapped writer is returned.
    pub fn finish(mut self) -> W {
        self.flush();
        self.w
    }
}

impl<W: Writer> Writer for Encoder<W> {
    fn write(&mut self, mut buf: &[u8]) {
        if !self.wrote_header {
            self.w.write_le_u32(MAGIC);
            self.w.write_le_u32(self.block_size as u32);
            self.wrote_header = true;
        }

        while buf.len() > 0 {
            let amt = num::min( self.block_size - self.buf.len(), buf.len() );
            self.buf.push_all( buf.slice_to(amt) );

            if self.buf.len() == self.block_size {
                self.encode_block();
            }
            buf = buf.slice_from(amt);
        }
    }

    fn flush(&mut self) {
        if self.buf.len() > 0 {
            self.encode_block();
        }
    }
}

#[cfg(test)]
mod test {
    use extra::test;
    //use std::rand;
    use std::io::mem::{BufReader, MemWriter};
    use super::{Decoder, Encoder};

    fn test_decode(input: &[u8], output: &[u8], extra_memory: bool) {
        let mut d = Decoder::new( BufReader::new(input), extra_memory );

        let got = d.read_to_end();
        assert!( got.as_slice() == output );
    }

    #[test]
    fn decode() {
        let reference = include_bin!("data/test.txt");
        test_decode(include_bin!("data/test.bwt"), reference, true);
        test_decode(include_bin!("data/test.bwt"), reference, false);
    }

    fn roundtrip(bytes: &[u8]) {
        let mut e = Encoder::new( MemWriter::new(), 1<<10 );
        e.write(bytes);
        let encoded = e.finish().unwrap();

        let mut d = Decoder::new( BufReader::new(encoded), true );
        let decoded = d.read_to_end();
        assert_eq!(decoded.as_slice(), bytes);
    }

    #[test]
    fn some_roundtrips() {
        roundtrip(bytes!("test"));
        roundtrip(bytes!(""));
        roundtrip(include_bin!("data/test.txt"));
    }

    #[bench]
    fn decompress_speed(bh: &mut test::BenchHarness) {
        let input = include_bin!("data/test.bwt");
        let mut d = Decoder::new( BufReader::new(input), true );
        let mut output = [0u8, ..65536];
        let mut output_size = 0;
        bh.iter(|| {
            d.r = BufReader::new(input);
            d.reset();
            output_size = d.read(output).unwrap();
        });
        bh.bytes = output_size as u64;
    }
}
<|endoftext|>


<commit_before>use std::old_io::{File, Open, Read, Write};
use std::old_io::IoError;
use std::old_io::IoResult;
use std::ops::Deref;
use super::GapBuffer;
use super::gap_buffer;
use super::Position;
use super::Range;

pub struct Buffer {
    data: GapBuffer,
    pub path: Option<Path>,
    pub cursor: Cursor,
}

/// Read-only wrapper for a `Position`, to allow field level access to a
/// buffer's cursor while simultaneously enforcing bounds-checking when
/// updating its value.
pub struct Cursor {
    position: Position,
}

impl Deref for Cursor {
    type Target = Position;

    fn deref(&self) -> &Position {
        &self.position
    }
}

impl Buffer {
    /// Returns the contents of the buffer as a string.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// buffer.insert("scribe");
    /// assert_eq!(buffer.data(), "scribe");
    /// ```
    pub fn data(&self) -> String {
        self.data.to_string()
    }

    /// Writes the contents of the buffer to its path.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::old_io::{File, Open, Read};
    ///
    /// // Set up a buffer and point it to a path.
    /// let mut buffer = scribe::buffer::new();
    /// let write_path = Path::new("my_doc");
    /// buffer.path = Some(write_path.clone());
    ///
    /// // Put some data into the buffer and save it.
    /// buffer.insert("scribe");
    /// buffer.save();
    ///
    /// # let saved_data = File::open_mode(&write_path, Open, Read)
    /// #   .unwrap().read_to_string().unwrap();
    /// # assert_eq!(saved_data, "scribe");
    ///
    /// # std::old_io::fs::unlink(&write_path);
    /// ```
    pub fn save(&self) -> Option<IoError> {
        let path = match self.path.clone() {
            Some(p) => p,
            None => Path::new(""),
        };

        // Try to open and write to the file, returning any errors encountered.
        let mut file = match File::open_mode(&path, Open, Write) {
            Ok(f) => f,
            Err(error) => return Some(error),
        };
        match file.write(self.data().as_bytes()) {
            Ok(_) => (),
            Err(error) => return Some(error),
        }

        return None
    }

    /// Inserts `data` into the buffer at the cursor position.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// buffer.insert("scribe");
    /// assert_eq!(buffer.data(), "scribe");
    /// ```
    pub fn insert(&mut self, data: &str) {
        self.data.insert(data, &self.cursor);
    }

    /// Moves the buffer cursor to the specified location. The location is
    /// bounds-checked against the buffer data and the cursor will not be
    /// updated if it is out-of-bounds.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// let in_bounds = scribe::buffer::Position{ line: 0, offset: 2 };
    /// let out_of_bounds = scribe::buffer::Position{ line: 2, offset: 2 };
    /// buffer.insert("scribe");
    ///
    /// buffer.move_cursor(in_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    ///
    /// buffer.move_cursor(out_of_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    /// ```
    pub fn move_cursor(&mut self, position: Position) {
        if self.data.in_bounds(&position) {
            self.cursor.position = position;
        }
    }
}

/// Creates a new empty buffer. The buffer's cursor is set to the beginning of the buffer.
///
/// # Examples
///
/// ```
/// let buffer = scribe::buffer::new();
/// # assert_eq!(buffer.cursor.line, 0);
/// # assert_eq!(buffer.cursor.offset, 0);
/// ```
pub fn new() -> Buffer {
    let data = gap_buffer::new(String::new());
    let cursor = Cursor{ position: Position{ line: 0, offset: 0 }};

    Buffer{ data: data, path: None, cursor: cursor }
}

/// Creates a new buffer by reading the UTF-8 interpreted file contents of the specified path.
/// The buffer's cursor is set to the beginning of the buffer.
///
/// # Examples
///
/// ```
/// let buffer = scribe::buffer::from_file(&Path::new("tests/sample/file")).unwrap();
/// assert_eq!(buffer.data(), "it works!\n");
/// # assert_eq!(buffer.cursor.line, 0);
/// # assert_eq!(buffer.cursor.offset, 0);
/// ```
pub fn from_file(path: &Path) -> IoResult<Buffer> {
    // Try to open and read the file, returning any errors encountered.
    let mut file = match File::open_mode(path, Open, Read) {
        Ok(f) => f,
        Err(error) => return Err(error),
    };
    let mut data = match file.read_to_string() {
        Ok(d) => d,
        Err(error) => return Err(error),
    };

    let data = gap_buffer::new(data);
    let cursor = Cursor{ position: Position{ line: 0, offset: 0 }};

    // Create a new buffer using the loaded data, path, and other defaults.
    Ok(Buffer{ data: data, path: Some(path.clone()), cursor: cursor })
}
<commit_msg>Add documentation for buffer type.<commit_after>use std::old_io::{File, Open, Read, Write};
use std::old_io::IoError;
use std::old_io::IoResult;
use std::ops::Deref;
use super::GapBuffer;
use super::gap_buffer;
use super::Position;
use super::Range;

/// A UTF-8 buffer with bounds-checked cursor management and persistence.
pub struct Buffer {
    data: GapBuffer,
    pub path: Option<Path>,
    pub cursor: Cursor,
}

/// Read-only wrapper for a `Position`, to allow field level access to a
/// buffer's cursor while simultaneously enforcing bounds-checking when
/// updating its value.
pub struct Cursor {
    position: Position,
}

impl Deref for Cursor {
    type Target = Position;

    fn deref(&self) -> &Position {
        &self.position
    }
}

impl Buffer {
    /// Returns the contents of the buffer as a string.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// buffer.insert("scribe");
    /// assert_eq!(buffer.data(), "scribe");
    /// ```
    pub fn data(&self) -> String {
        self.data.to_string()
    }

    /// Writes the contents of the buffer to its path.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::old_io::{File, Open, Read};
    ///
    /// // Set up a buffer and point it to a path.
    /// let mut buffer = scribe::buffer::new();
    /// let write_path = Path::new("my_doc");
    /// buffer.path = Some(write_path.clone());
    ///
    /// // Put some data into the buffer and save it.
    /// buffer.insert("scribe");
    /// buffer.save();
    ///
    /// # let saved_data = File::open_mode(&write_path, Open, Read)
    /// #   .unwrap().read_to_string().unwrap();
    /// # assert_eq!(saved_data, "scribe");
    ///
    /// # std::old_io::fs::unlink(&write_path);
    /// ```
    pub fn save(&self) -> Option<IoError> {
        let path = match self.path.clone() {
            Some(p) => p,
            None => Path::new(""),
        };

        // Try to open and write to the file, returning any errors encountered.
        let mut file = match File::open_mode(&path, Open, Write) {
            Ok(f) => f,
            Err(error) => return Some(error),
        };
        match file.write(self.data().as_bytes()) {
            Ok(_) => (),
            Err(error) => return Some(error),
        }

        return None
    }

    /// Inserts `data` into the buffer at the cursor position.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// buffer.insert("scribe");
    /// assert_eq!(buffer.data(), "scribe");
    /// ```
    pub fn insert(&mut self, data: &str) {
        self.data.insert(data, &self.cursor);
    }

    /// Moves the buffer cursor to the specified location. The location is
    /// bounds-checked against the buffer data and the cursor will not be
    /// updated if it is out-of-bounds.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// let in_bounds = scribe::buffer::Position{ line: 0, offset: 2 };
    /// let out_of_bounds = scribe::buffer::Position{ line: 2, offset: 2 };
    /// buffer.insert("scribe");
    ///
    /// buffer.move_cursor(in_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    ///
    /// buffer.move_cursor(out_of_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    /// ```
    pub fn move_cursor(&mut self, position: Position) {
        if self.data.in_bounds(&position) {
            self.cursor.position = position;
        }
    }
}

/// Creates a new empty buffer. The buffer's cursor is set to the beginning of the buffer.
///
/// # Examples
///
/// ```
/// let buffer = scribe::buffer::new();
/// # assert_eq!(buffer.cursor.line, 0);
/// # assert_eq!(buffer.cursor.offset, 0);
/// ```
pub fn new() -> Buffer {
    let data = gap_buffer::new(String::new());
    let cursor = Cursor{ position: Position{ line: 0, offset: 0 }};

    Buffer{ data: data, path: None, cursor: cursor }
}

/// Creates a new buffer by reading the UTF-8 interpreted file contents of the specified path.
/// The buffer's cursor is set to the beginning of the buffer.
///
/// # Examples
///
/// ```
/// let buffer = scribe::buffer::from_file(&Path::new("tests/sample/file")).unwrap();
/// assert_eq!(buffer.data(), "it works!\n");
/// # assert_eq!(buffer.cursor.line, 0);
/// # assert_eq!(buffer.cursor.offset, 0);
/// ```
pub fn from_file(path: &Path) -> IoResult<Buffer> {
    // Try to open and read the file, returning any errors encountered.
    let mut file = match File::open_mode(path, Open, Read) {
        Ok(f) => f,
        Err(error) => return Err(error),
    };
    let mut data = match file.read_to_string() {
        Ok(d) => d,
        Err(error) => return Err(error),
    };

    let data = gap_buffer::new(data);
    let cursor = Cursor{ position: Position{ line: 0, offset: 0 }};

    // Create a new buffer using the loaded data, path, and other defaults.
    Ok(Buffer{ data: data, path: Some(path.clone()), cursor: cursor })
}
<|endoftext|>


<commit_before>use std::error::Error;
/// Create a program that downloads the time from this URL: http://tycho.usno.navy.mil/cgi-bin/timer.pl
/// and then prints the current UTC time by extracting just the UTC time from the web page's HTML.

fn extract_timestamp(raw_html: &str) -> Option<String> {
    // parse the response body by
 tags
    let mut lines = raw_html
        .split("
")
        .filter(|line| match line.find("UTC") {
            Some(_) => true,
            None => false,
        })
        .map(|line| {
            line.trim()
                .replace("UTC\t\tUniversal Time", "")
                .trim()
                .to_string()
        });
    lines.next()
}

fn main() -> Result<(), Box<dyn Error>> {
    let raw_html = reqwest::get("http://tycho.usno.navy.mil/cgi-bin/timer.pl")?.text()?;
    if let Some(timestamp) = extract_timestamp(&raw_html) {
        print!("{}", timestamp);
    } else {
        eprint!("Error: Could not parse URL for getting current time.");
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use crate::extract_timestamp;

    #[test]
    fn test_extract_timestamp() {
        let body = r#"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final"//EN>

            <TITLE>What time is it?</TITLE>

 US Naval Observatory Master Clock Time

Aug. 12, 23:55:08 UTC		Universal Time

Aug. 12, 07:55:08 PM EDT		Eastern Time

Aug. 12, 06:55:08 PM CDT		Central Time

Aug. 12, 05:55:08 PM MDT		Mountain Time

Aug. 12, 04:55:08 PM PDT		Pacific Time

Aug. 12, 03:55:08 PM AKDT	Alaska Time

Aug. 12, 01:55:08 PM HAST	Hawaii-Aleutian Time

 US Naval Observatory

            "#;
        assert_eq!(extract_timestamp(&body).unwrap(), "Aug. 12, 23:55:08");
    }
}
<commit_msg>use constant for URL value<commit_after>use std::error::Error;
/// Create a program that downloads the time from this URL: http://tycho.usno.navy.mil/cgi-bin/timer.pl
/// and then prints the current UTC time by extracting just the UTC time from the web page's HTML.

const A_URL: &str = "http://tycho.usno.navy.mil/cgi-bin/timer.pl";
fn extract_timestamp(raw_html: &str) -> Option<String> {
    // parse the response body by
 tags
    let mut lines = raw_html
        .split("
")
        .filter(|line| match line.find("UTC") {
            Some(_) => true,
            None => false,
        })
        .map(|line| {
            line.trim()
                .replace("UTC\t\tUniversal Time", "")
                .trim()
                .to_string()
        });
    lines.next()
}

fn main() -> Result<(), Box<dyn Error>> {
    let raw_html = reqwest::get(A_URL)?.text()?;
    if let Some(timestamp) = extract_timestamp(&raw_html) {
        print!("{}", timestamp);
    } else {
        eprint!("Error: Could not parse URL for getting current time.");
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use crate::extract_timestamp;

    #[test]
    fn test_extract_timestamp() {
        let body = r#"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final"//EN>

            <TITLE>What time is it?</TITLE>

 US Naval Observatory Master Clock Time

Aug. 12, 23:55:08 UTC		Universal Time

Aug. 12, 07:55:08 PM EDT		Eastern Time

Aug. 12, 06:55:08 PM CDT		Central Time

Aug. 12, 05:55:08 PM MDT		Mountain Time

Aug. 12, 04:55:08 PM PDT		Pacific Time

Aug. 12, 03:55:08 PM AKDT	Alaska Time

Aug. 12, 01:55:08 PM HAST	Hawaii-Aleutian Time

 US Naval Observatory

            "#;
        assert_eq!(extract_timestamp(&body).unwrap(), "Aug. 12, 23:55:08");
    }
}
<|endoftext|>


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

use std::num::{Zero, zero, One, one, sqrt};

use angle::{Rad, atan2, acos};
use array::{Array, build};

/// A 2-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec2<S> { x: S, y: S }

/// A 3-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec3<S> { x: S, y: S, z: S }

/// A 4-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec4<S> { x: S, y: S, z: S, w: S }

// Conversion traits
pub trait ToVec2<S: Primitive> { fn to_vec2(&self) -> Vec2<S>; }
pub trait ToVec3<S: Primitive> { fn to_vec3(&self) -> Vec3<S>; }
pub trait ToVec4<S: Primitive> { fn to_vec4(&self) -> Vec4<S>; }

// Utility macro for generating associated functions for the vectors
macro_rules! vec(
    (impl $Self:ident <$S:ident> { $($field:ident),+ }) => (
        impl<$S: Primitive> $Self<$S> {
            #[inline]
            pub fn new($($field: $S),+) -> $Self<$S> {
                $Self { $($field: $field),+ }
            }

            /// Construct a vector from a single value.
            #[inline]
            pub fn from_value(value: $S) -> $Self<$S> {
                $Self { $($field: value.clone()),+ }
            }

            /// The additive identity of the vector.
            #[inline]
            pub fn zero() -> $Self<$S> { $Self::from_value(zero()) }

            /// The additive identity of the vector.
            #[inline]
            pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
        }
    )
)

vec!(impl Vec2<S> { x, y })
vec!(impl Vec3<S> { x, y, z })
vec!(impl Vec4<S> { x, y, z, w })

impl<S: Primitive> Vec2<S> {
    #[inline] pub fn unit_x() -> Vec2<S> { Vec2::new(one(), zero()) }
    #[inline] pub fn unit_y() -> Vec2<S> { Vec2::new(zero(), one()) }
}

impl<S: Primitive> Vec3<S> {
    #[inline] pub fn unit_x() -> Vec3<S> { Vec3::new(one(), zero(), zero()) }
    #[inline] pub fn unit_y() -> Vec3<S> { Vec3::new(zero(), one(), zero()) }
    #[inline] pub fn unit_z() -> Vec3<S> { Vec3::new(zero(), zero(), one()) }
}

impl<S: Primitive> Vec4<S> {
    #[inline] pub fn unit_x() -> Vec4<S> { Vec4::new(one(), zero(), zero(), zero()) }
    #[inline] pub fn unit_y() -> Vec4<S> { Vec4::new(zero(), one(), zero(), zero()) }
    #[inline] pub fn unit_z() -> Vec4<S> { Vec4::new(zero(), zero(), one(), zero()) }
    #[inline] pub fn unit_w() -> Vec4<S> { Vec4::new(zero(), zero(), zero(), one()) }
}

array!(impl<S> Vec2<S> -> [S, ..2] _2)
array!(impl<S> Vec3<S> -> [S, ..3] _3)
array!(impl<S> Vec4<S> -> [S, ..4] _4)

approx_eq!(impl<S> Vec2<S>)
approx_eq!(impl<S> Vec3<S>)
approx_eq!(impl<S> Vec4<S>)

/// A trait that specifies a range of numeric operations for vectors. Not all
/// of these make sense from a linear algebra point of view, but are included
/// for pragmatic reasons.
pub trait Vector
<
    S: Primitive,
    Slice
>
:   Array<S, Slice>
+   Neg<Self>
+   Zero + One
{
    #[inline] fn add_s(&self, s: S) -> Self { build(|i| self.i(i).add(&s)) }
    #[inline] fn sub_s(&self, s: S) -> Self { build(|i| self.i(i).sub(&s)) }
    #[inline] fn mul_s(&self, s: S) -> Self { build(|i| self.i(i).mul(&s)) }
    #[inline] fn div_s(&self, s: S) -> Self { build(|i| self.i(i).div(&s)) }
    #[inline] fn rem_s(&self, s: S) -> Self { build(|i| self.i(i).rem(&s)) }

    #[inline] fn add_v(&self, other: &Self) -> Self { build(|i| self.i(i).add(other.i(i))) }
    #[inline] fn sub_v(&self, other: &Self) -> Self { build(|i| self.i(i).sub(other.i(i))) }
    #[inline] fn mul_v(&self, other: &Self) -> Self { build(|i| self.i(i).mul(other.i(i))) }
    #[inline] fn div_v(&self, other: &Self) -> Self { build(|i| self.i(i).div(other.i(i))) }
    #[inline] fn rem_v(&self, other: &Self) -> Self { build(|i| self.i(i).rem(other.i(i))) }

    #[inline] fn neg_self(&mut self) { self.each_mut(|_, x| *x = x.neg()) }

    #[inline] fn add_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.add(&s)) }
    #[inline] fn sub_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.sub(&s)) }
    #[inline] fn mul_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.mul(&s)) }
    #[inline] fn div_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.div(&s)) }
    #[inline] fn rem_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.rem(&s)) }

    #[inline] fn add_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.add(other.i(i))) }
    #[inline] fn sub_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.sub(other.i(i))) }
    #[inline] fn mul_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.mul(other.i(i))) }
    #[inline] fn div_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.div(other.i(i))) }
    #[inline] fn rem_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.rem(other.i(i))) }

    /// The sum of each component of the vector.
    #[inline] fn comp_add(&self) -> S { self.fold(|a, b| a.add(b)) }

    /// The product of each component of the vector.
    #[inline] fn comp_mul(&self) -> S { self.fold(|a, b| a.mul(b)) }

    /// Vector dot product.
    #[inline] fn dot(&self, other: &Self) -> S { self.mul_v(other).comp_add() }

    /// The minimum component of the vector.
    #[inline] fn comp_min(&self) -> S { self.iter().min().unwrap().clone() }

    /// The maximum component of the vector.
    #[inline] fn comp_max(&self) -> S { self.iter().max().unwrap().clone() }
}

#[inline] fn dot<S: Primitive, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }

impl<S: Primitive> One for Vec2<S> { #[inline] fn one() -> Vec2<S> { Vec2::ident() } }
impl<S: Primitive> One for Vec3<S> { #[inline] fn one() -> Vec3<S> { Vec3::ident() } }
impl<S: Primitive> One for Vec4<S> { #[inline] fn one() -> Vec4<S> { Vec4::ident() } }

impl<S: Primitive> Neg<Vec2<S>> for Vec2<S> { #[inline] fn neg(&self) -> Vec2<S> { build(|i| self.i(i).neg()) } }
impl<S: Primitive> Neg<Vec3<S>> for Vec3<S> { #[inline] fn neg(&self) -> Vec3<S> { build(|i| self.i(i).neg()) } }
impl<S: Primitive> Neg<Vec4<S>> for Vec4<S> { #[inline] fn neg(&self) -> Vec4<S> { build(|i| self.i(i).neg()) } }

impl<S: Primitive> Vector<S, [S, ..2]> for Vec2<S>;
impl<S: Primitive> Vector<S, [S, ..3]> for Vec3<S>;
impl<S: Primitive> Vector<S, [S, ..4]> for Vec4<S>;

/// Operations specific to numeric two-dimensional vectors.
impl<S: Primitive> Vec2<S> {
    /// The perpendicular dot product of the vector and `other`.
    #[inline]
    pub fn perp_dot(&self, other: &Vec2<S>) -> S {
        (self.x * other.y) - (self.y * other.x)
    }
}

/// Operations specific to numeric three-dimensional vectors.
impl<S: Primitive> Vec3<S> {
    /// Returns the cross product of the vector and `other`.
    #[inline]
    pub fn cross(&self, other: &Vec3<S>) -> Vec3<S> {
        Vec3::new((self.y * other.z) - (self.z * other.y),
                  (self.z * other.x) - (self.x * other.z),
                  (self.x * other.y) - (self.y * other.x))
    }

    /// Calculates the cross product of the vector and `other`, then stores the
    /// result in `self`.
    #[inline]
    pub fn cross_self(&mut self, other: &Vec3<S>) {
        *self = self.cross(other)
    }
}

/// Specifies geometric operations for vectors. This is only implemented for
/// 2-dimensional and 3-dimensional vectors.
pub trait EuclideanVector
<
    S: Float,
    Slice
>
:   Vector<S, Slice>
+   ApproxEq<S>
{
    /// Returns `true` if the vector is perpendicular (at right angles to)
    /// the other vector.
    fn is_perpendicular(&self, other: &Self) -> bool {
        self.dot(other).approx_eq(&zero())
    }

    /// Returns the squared length of the vector. This does not perform an
    /// expensive square root operation like in the `length` method and can
    /// therefore be more efficient for comparing the lengths of two vectors.
    #[inline]
    fn length2(&self) -> S {
        self.dot(self)
    }

    /// The norm of the vector.
    #[inline]
    fn length(&self) -> S {
        sqrt(self.dot(self))
    }

    /// The angle between the vector and `other`.
    fn angle(&self, other: &Self) -> Rad<S>;

    /// Returns a vector with the same direction, but with a `length` (or
    /// `norm`) of `1`.
    #[inline]
    fn normalize(&self) -> Self {
        self.normalize_to(one::<S>())
    }

    /// Returns a vector with the same direction and a given `length`.
    #[inline]
    fn normalize_to(&self, length: S) -> Self {
        self.mul_s(length / self.length())
    }

    /// Returns the result of linarly interpolating the length of the vector
    /// towards the length of `other` by the specified amount.
    #[inline]
    fn lerp(&self, other: &Self, amount: S) -> Self {
        self.add_v(&other.sub_v(self).mul_s(amount))
    }

    /// Normalises the vector to a length of `1`.
    #[inline]
    fn normalize_self(&mut self) {
        let rlen = self.length().recip();
        self.mul_self_s(rlen);
    }

    /// Normalizes the vector to `length`.
    #[inline]
    fn normalize_self_to(&mut self, length: S) {
        let n = length / self.length();
        self.mul_self_s(n);
    }

    /// Linearly interpolates the length of the vector towards the length of
    /// `other` by the specified amount.
    fn lerp_self(&mut self, other: &Self, amount: S) {
        let v = other.sub_v(self).mul_s(amount);
        self.add_self_v(&v);
    }
}

impl<S: Float> EuclideanVector<S, [S, ..2]> for Vec2<S> {
    #[inline]
    fn angle(&self, other: &Vec2<S>) -> Rad<S> {
        atan2(self.perp_dot(other), self.dot(other))
    }
}

impl<S: Float> EuclideanVector<S, [S, ..3]> for Vec3<S> {
    #[inline]
    fn angle(&self, other: &Vec3<S>) -> Rad<S> {
        atan2(self.cross(other).length(), self.dot(other))
    }
}

impl<S: Float> EuclideanVector<S, [S, ..4]> for Vec4<S> {
    #[inline]
    fn angle(&self, other: &Vec4<S>) -> Rad<S> {
        acos(self.dot(other) / (self.length() * other.length()))
    }
}

impl<S> ToStr for Vec2<S> {
    fn to_str(&self) -> ~str {
        fmt!("[%?, %?]", self.x, self.y)
    }
}

impl<S> ToStr for Vec3<S> {
    fn to_str(&self) -> ~str {
        fmt!("[%?, %?, %?]", self.x, self.y, self.z)
    }
}

impl<S> ToStr for Vec4<S> {
    fn to_str(&self) -> ~str {
        fmt!("[%?, %?, %?, %?]", self.x, self.y, self.z, self.w)
    }
}
<commit_msg>Use .fold for comp_min and comp_max<commit_after>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::{Zero, zero, One, one, sqrt};

use angle::{Rad, atan2, acos};
use array::{Array, build};

/// A 2-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec2<S> { x: S, y: S }

/// A 3-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec3<S> { x: S, y: S, z: S }

/// A 4-dimensional vector.
#[deriving(Eq, Clone, Zero)]
pub struct Vec4<S> { x: S, y: S, z: S, w: S }

// Conversion traits
pub trait ToVec2<S: Primitive> { fn to_vec2(&self) -> Vec2<S>; }
pub trait ToVec3<S: Primitive> { fn to_vec3(&self) -> Vec3<S>; }
pub trait ToVec4<S: Primitive> { fn to_vec4(&self) -> Vec4<S>; }

// Utility macro for generating associated functions for the vectors
macro_rules! vec(
    (impl $Self:ident <$S:ident> { $($field:ident),+ }) => (
        impl<$S: Primitive> $Self<$S> {
            #[inline]
            pub fn new($($field: $S),+) -> $Self<$S> {
                $Self { $($field: $field),+ }
            }

            /// Construct a vector from a single value.
            #[inline]
            pub fn from_value(value: $S) -> $Self<$S> {
                $Self { $($field: value.clone()),+ }
            }

            /// The additive identity of the vector.
            #[inline]
            pub fn zero() -> $Self<$S> { $Self::from_value(zero()) }

            /// The additive identity of the vector.
            #[inline]
            pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
        }
    )
)

vec!(impl Vec2<S> { x, y })
vec!(impl Vec3<S> { x, y, z })
vec!(impl Vec4<S> { x, y, z, w })

impl<S: Primitive> Vec2<S> {
    #[inline] pub fn unit_x() -> Vec2<S> { Vec2::new(one(), zero()) }
    #[inline] pub fn unit_y() -> Vec2<S> { Vec2::new(zero(), one()) }
}

impl<S: Primitive> Vec3<S> {
    #[inline] pub fn unit_x() -> Vec3<S> { Vec3::new(one(), zero(), zero()) }
    #[inline] pub fn unit_y() -> Vec3<S> { Vec3::new(zero(), one(), zero()) }
    #[inline] pub fn unit_z() -> Vec3<S> { Vec3::new(zero(), zero(), one()) }
}

impl<S: Primitive> Vec4<S> {
    #[inline] pub fn unit_x() -> Vec4<S> { Vec4::new(one(), zero(), zero(), zero()) }
    #[inline] pub fn unit_y() -> Vec4<S> { Vec4::new(zero(), one(), zero(), zero()) }
    #[inline] pub fn unit_z() -> Vec4<S> { Vec4::new(zero(), zero(), one(), zero()) }
    #[inline] pub fn unit_w() -> Vec4<S> { Vec4::new(zero(), zero(), zero(), one()) }
}

array!(impl<S> Vec2<S> -> [S, ..2] _2)
array!(impl<S> Vec3<S> -> [S, ..3] _3)
array!(impl<S> Vec4<S> -> [S, ..4] _4)

approx_eq!(impl<S> Vec2<S>)
approx_eq!(impl<S> Vec3<S>)
approx_eq!(impl<S> Vec4<S>)

/// A trait that specifies a range of numeric operations for vectors. Not all
/// of these make sense from a linear algebra point of view, but are included
/// for pragmatic reasons.
pub trait Vector
<
    S: Primitive,
    Slice
>
:   Array<S, Slice>
+   Neg<Self>
+   Zero + One
{
    #[inline] fn add_s(&self, s: S) -> Self { build(|i| self.i(i).add(&s)) }
    #[inline] fn sub_s(&self, s: S) -> Self { build(|i| self.i(i).sub(&s)) }
    #[inline] fn mul_s(&self, s: S) -> Self { build(|i| self.i(i).mul(&s)) }
    #[inline] fn div_s(&self, s: S) -> Self { build(|i| self.i(i).div(&s)) }
    #[inline] fn rem_s(&self, s: S) -> Self { build(|i| self.i(i).rem(&s)) }

    #[inline] fn add_v(&self, other: &Self) -> Self { build(|i| self.i(i).add(other.i(i))) }
    #[inline] fn sub_v(&self, other: &Self) -> Self { build(|i| self.i(i).sub(other.i(i))) }
    #[inline] fn mul_v(&self, other: &Self) -> Self { build(|i| self.i(i).mul(other.i(i))) }
    #[inline] fn div_v(&self, other: &Self) -> Self { build(|i| self.i(i).div(other.i(i))) }
    #[inline] fn rem_v(&self, other: &Self) -> Self { build(|i| self.i(i).rem(other.i(i))) }

    #[inline] fn neg_self(&mut self) { self.each_mut(|_, x| *x = x.neg()) }

    #[inline] fn add_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.add(&s)) }
    #[inline] fn sub_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.sub(&s)) }
    #[inline] fn mul_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.mul(&s)) }
    #[inline] fn div_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.div(&s)) }
    #[inline] fn rem_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.rem(&s)) }

    #[inline] fn add_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.add(other.i(i))) }
    #[inline] fn sub_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.sub(other.i(i))) }
    #[inline] fn mul_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.mul(other.i(i))) }
    #[inline] fn div_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.div(other.i(i))) }
    #[inline] fn rem_self_v(&mut self, other: &Self) { self.each_mut(|i, x| *x = x.rem(other.i(i))) }

    /// The sum of each component of the vector.
    #[inline] fn comp_add(&self) -> S { self.fold(|a, b| a.add(b)) }

    /// The product of each component of the vector.
    #[inline] fn comp_mul(&self) -> S { self.fold(|a, b| a.mul(b)) }

    /// Vector dot product.
    #[inline] fn dot(&self, other: &Self) -> S { self.mul_v(other).comp_add() }

    /// The minimum component of the vector.
    #[inline] fn comp_min(&self) -> S { self.fold(|a, b| a.min(b)) }

    /// The maximum component of the vector.
    #[inline] fn comp_max(&self) -> S { self.fold(|a, b| a.max(b)) }
}

#[inline] fn dot<S: Primitive, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }

impl<S: Primitive> One for Vec2<S> { #[inline] fn one() -> Vec2<S> { Vec2::ident() } }
impl<S: Primitive> One for Vec3<S> { #[inline] fn one() -> Vec3<S> { Vec3::ident() } }
impl<S: Primitive> One for Vec4<S> { #[inline] fn one() -> Vec4<S> { Vec4::ident() } }

impl<S: Primitive> Neg<Vec2<S>> for Vec2<S> { #[inline] fn neg(&self) -> Vec2<S> { build(|i| self.i(i).neg()) } }
impl<S: Primitive> Neg<Vec3<S>> for Vec3<S> { #[inline] fn neg(&self) -> Vec3<S> { build(|i| self.i(i).neg()) } }
impl<S: Primitive> Neg<Vec4<S>> for Vec4<S> { #[inline] fn neg(&self) -> Vec4<S> { build(|i| self.i(i).neg()) } }

impl<S: Primitive> Vector<S, [S, ..2]> for Vec2<S>;
impl<S: Primitive> Vector<S, [S, ..3]> for Vec3<S>;
impl<S: Primitive> Vector<S, [S, ..4]> for Vec4<S>;

/// Operations specific to numeric two-dimensional vectors.
impl<S: Primitive> Vec2<S> {
    /// The perpendicular dot product of the vector and `other`.
    #[inline]
    pub fn perp_dot(&self, other: &Vec2<S>) -> S {
        (self.x * other.y) - (self.y * other.x)
    }
}

/// Operations specific to numeric three-dimensional vectors.
impl<S: Primitive> Vec3<S> {
    /// Returns the cross product of the vector and `other`.
    #[inline]
    pub fn cross(&self, other: &Vec3<S>) -> Vec3<S> {
        Vec3::new((self.y * other.z) - (self.z * other.y),
                  (self.z * other.x) - (self.x * other.z),
                  (self.x * other.y) - (self.y * other.x))
    }

    /// Calculates the cross product of the vector and `other`, then stores the
    /// result in `self`.
    #[inline]
    pub fn cross_self(&mut self, other: &Vec3<S>) {
        *self = self.cross(other)
    }
}

/// Specifies geometric operations for vectors. This is only implemented for
/// 2-dimensional and 3-dimensional vectors.
pub trait EuclideanVector
<
    S: Float,
    Slice
>
:   Vector<S, Slice>
+   ApproxEq<S>
{
    /// Returns `true` if the vector is perpendicular (at right angles to)
    /// the other vector.
    fn is_perpendicular(&self, other: &Self) -> bool {
        self.dot(other).approx_eq(&zero())
    }

    /// Returns the squared length of the vector. This does not perform an
    /// expensive square root operation like in the `length` method and can
    /// therefore be more efficient for comparing the lengths of two vectors.
    #[inline]
    fn length2(&self) -> S {
        self.dot(self)
    }

    /// The norm of the vector.
    #[inline]
    fn length(&self) -> S {
        sqrt(self.dot(self))
    }

    /// The angle between the vector and `other`.
    fn angle(&self, other: &Self) -> Rad<S>;

    /// Returns a vector with the same direction, but with a `length` (or
    /// `norm`) of `1`.
    #[inline]
    fn normalize(&self) -> Self {
        self.normalize_to(one::<S>())
    }

    /// Returns a vector with the same direction and a given `length`.
    #[inline]
    fn normalize_to(&self, length: S) -> Self {
        self.mul_s(length / self.length())
    }

    /// Returns the result of linarly interpolating the length of the vector
    /// towards the length of `other` by the specified amount.
    #[inline]
    fn lerp(&self, other: &Self, amount: S) -> Self {
        self.add_v(&other.sub_v(self).mul_s(amount))
    }

    /// Normalises the vector to a length of `1`.
    #[inline]
    fn normalize_self(&mut self) {
        let rlen = self.length().recip();
        self.mul_self_s(rlen);
    }

    /// Normalizes the vector to `length`.
    #[inline]
    fn normalize_self_to(&mut self, length: S) {
        let n = length / self.length();
        self.mul_self_s(n);
    }

    /// Linearly interpolates the length of the vector towards the length of
    /// `other` by the specified amount.
    fn lerp_self(&mut self, other: &Self, amount: S) {
        let v = other.sub_v(self).mul_s(amount);
        self.add_self_v(&v);
    }
}

impl<S: Float> EuclideanVector<S, [S, ..2]> for Vec2<S> {
    #[inline]
    fn angle(&self, other: &Vec2<S>) -> Rad<S> {
        atan2(self.perp_dot(other), self.dot(other))
    }
}

impl<S: Float> EuclideanVector<S, [S, ..3]> for Vec3<S> {
    #[inline]
    fn angle(&self, other: &Vec3<S>) -> Rad<S> {
        atan2(self.cross(other).length(), self.dot(other))
    }
}

impl<S: Float> EuclideanVector<S, [S, ..4]> for Vec4<S> {
    #[inline]
    fn angle(&self, other: &Vec4<S>) -> Rad<S> {
        acos(self.dot(other) / (self.length() * other.length()))
    }
}

impl<S> ToStr for Vec2<S> {
    fn to_str(&self) -> ~str {
        fmt!("[%?, %?]", self.x, self.y)
    }
}

impl<S> ToStr for Vec3<S> {
    fn to_str(&self) -> ~str {
        fmt!("[%?, %?, %?]", self.x, self.y, self.z)
    }
}

impl<S> ToStr for Vec4<S> {
    fn to_str(&self) -> ~str {
        fmt!("[%?, %?, %?, %?]", self.x, self.y, self.z, self.w)
    }
}
<|endoftext|>


<commit_before>struct Gradient {
    start: Vec<i32>,
    steps: Vec<f32>,
    n: i32,
    total: i32,
}

impl Gradient {
    fn to_parts(hex: &str) -> Vec<i32> {
        [0, 2, 4].iter()
                 .map(|&n| i32::from_str_radix(&hex[n..(n + 2)], 16).unwrap())
                 .collect()
    }

    fn to_steps(start: &[i32], stop: &[i32], n: i32) -> Vec<f32> {
        start.iter()
             .zip(stop.iter())
             .map(|(&a, &b)| (a as f32 - b as f32) / (n as f32 - 1.0))
             .collect()
    }

    pub fn new(start: &str, stop: &str, n: i32) -> Gradient {
        let from = Gradient::to_parts(&start);
        let to = Gradient::to_parts(&stop);
        let steps = Gradient::to_steps(&from[..], &to[..], n);

        Gradient{
            start: from,
            steps: steps,
            n: 0,
            total: n,
        }
    }
}

impl Iterator for Gradient {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        match self.n {
            n if n == self.total => None,
            n => {
                let rgb: String = self.start
                    .iter()
                    .zip(self.steps.iter())
                    .map(|(&a, &b)| a - (n as f32 * b) as i32)
                    .map(|i| format!("{:02x}", i))
                    .collect();

                self.n += 1;

                Some(rgb)
            }
        }
    }
}

fn main() {
    // For benchmarking...
    let g = Gradient::new("000000", "ffffff", 10000);
    g.collect::<Vec<String>>();
}

#[test]
fn it_works() {
    let ga = Gradient::new("000000", "ffffff", 16);
    let gb = Gradient::new("ff334c", "d8ff1a", 10);
    let result_a = vec!["000000", "111111", "222222", "333333", "444444",
                        "555555", "666666", "777777", "888888", "999999",
                        "aaaaaa", "bbbbbb", "cccccc", "dddddd", "eeeeee",
                        "ffffff"];
    let result_b = vec!["ff334c", "fb4947", "f76041", "f2773c", "ee8d36",
                        "eaa431", "e5bb2b", "e1d126", "dde820", "d8ff1a"];

    assert_eq!(ga.collect::<Vec<String>>(), result_a.iter().map(|r| r.to_string()).collect::<Vec<String>>());
    assert_eq!(gb.collect::<Vec<String>>(), result_b.iter().map(|r| r.to_string()).collect::<Vec<String>>());
}
<commit_msg>Tiny refactor of calculation<commit_after>struct Gradient {
    start: Vec<i32>,
    steps: Vec<f32>,
    n: i32,
    total: i32,
}

impl Gradient {
    fn to_parts(hex: &str) -> Vec<i32> {
        [0, 2, 4].iter()
                 .map(|&n| i32::from_str_radix(&hex[n..(n + 2)], 16).unwrap())
                 .collect()
    }

    fn to_steps(start: &[i32], stop: &[i32], n: i32) -> Vec<f32> {
        start.iter()
             .zip(stop.iter())
             .map(|(&a, &b)| (a - b) as f32 / (n as f32 - 1.0))
             .collect()
    }

    pub fn new(start: &str, stop: &str, n: i32) -> Gradient {
        let from = Gradient::to_parts(&start);
        let to = Gradient::to_parts(&stop);
        let steps = Gradient::to_steps(&from[..], &to[..], n);

        Gradient{
            start: from,
            steps: steps,
            n: 0,
            total: n,
        }
    }
}

impl Iterator for Gradient {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        match self.n {
            n if n == self.total => None,
            n => {
                let rgb: String = self.start
                    .iter()
                    .zip(self.steps.iter())
                    .map(|(&a, &b)| a - (n as f32 * b) as i32)
                    .map(|i| format!("{:02x}", i))
                    .collect();

                self.n += 1;

                Some(rgb)
            }
        }
    }
}

fn main() {
    // For benchmarking...
    let g = Gradient::new("000000", "ffffff", 10000);
    g.collect::<Vec<String>>();
}

#[test]
fn it_works() {
    let ga = Gradient::new("000000", "ffffff", 16);
    let gb = Gradient::new("ff334c", "d8ff1a", 10);
    let result_a = vec!["000000", "111111", "222222", "333333", "444444",
                        "555555", "666666", "777777", "888888", "999999",
                        "aaaaaa", "bbbbbb", "cccccc", "dddddd", "eeeeee",
                        "ffffff"];
    let result_b = vec!["ff334c", "fb4947", "f76041", "f2773c", "ee8d36",
                        "eaa431", "e5bb2b", "e1d126", "dde820", "d8ff1a"];

    assert_eq!(ga.collect::<Vec<String>>(), result_a.iter().map(|r| r.to_string()).collect::<Vec<String>>());
    assert_eq!(gb.collect::<Vec<String>>(), result_b.iter().map(|r| r.to_string()).collect::<Vec<String>>());
}
<|endoftext|>