<commit_before>//! # generator
//!
//! Rust generator library
//!

#![cfg_attr(nightly, feature(asm))]
#![cfg_attr(nightly, feature(repr_simd))]
#![cfg_attr(nightly, feature(core_intrinsics))]
#![cfg_attr(nightly, feature(naked_functions))]
#![cfg_attr(nightly, feature(thread_local))]
// #![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]
#![allow(deprecated)]

#[macro_use]
extern crate log;

mod detail;
mod gen_impl;
mod reg_context;
mod rt;
mod scope;
mod stack;
mod yield_;

pub use crate::gen_impl::{Generator, GeneratorImpl, Gn};
pub use crate::rt::{get_local_data, is_generator, Error};
pub use crate::scope::Scope;
pub use crate::yield_::{
    co_get_yield, co_set_para, co_yield_with, done, get_yield, yield_, yield_from, yield_with,
};
<commit_msg>:pencil: deny warnings for test<commit_after>//! # generator
//!
//! Rust generator library
//!

#![cfg_attr(nightly, feature(asm))]
#![cfg_attr(nightly, feature(repr_simd))]
#![cfg_attr(nightly, feature(core_intrinsics))]
#![cfg_attr(nightly, feature(naked_functions))]
#![cfg_attr(nightly, feature(thread_local))]
#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]
#![allow(deprecated)]

#[macro_use]
extern crate log;

mod detail;
mod gen_impl;
mod reg_context;
mod rt;
mod scope;
mod stack;
mod yield_;

pub use crate::gen_impl::{Generator, GeneratorImpl, Gn};
pub use crate::rt::{get_local_data, is_generator, Error};
pub use crate::scope::Scope;
pub use crate::yield_::{
    co_get_yield, co_set_para, co_yield_with, done, get_yield, yield_, yield_from, yield_with,
};
<|endoftext|>


<commit_before>extern crate walkdir;
extern crate regex;
extern crate url;

mod git;
mod util;
mod remote;

use std::path::{Path, PathBuf};
use walkdir::WalkDir;

pub fn command_get(projects: Vec<String>, skip_pull: bool, shallow: bool) -> i32 {
  for project in projects {
    let repo = remote::RemoteRepository::new(project.as_str());
    let dest = repo.local_path(&get_local_repos_roots()[0]);

    git::clone_or_pull(repo.url(), dest.as_path(), skip_pull, shallow);
  }
  0
}

impl Repository {
  #[cfg(windows)]
  fn absolute_path(&self) -> String {
    let repo_path = Path::new(&self.root).join(&self.path);
    format!("{}", repo_path.display()).replace("/", "\\")
  }

  #[cfg(not(windows))]
  fn absolute_path(&self) -> String {
    let repo_path = Path::new(self.root).join(self.path);
    format!("{}", repo_path.display())
  }

  fn unique_path(&self) -> String {
    Path::new(&self.path)
      .file_name()
      .unwrap()
      .to_str()
      .unwrap()
      .to_owned()
  }
}

pub fn command_list(exact: bool, format: &str, query: Option<String>) -> i32 {
  let filter: Box<Fn(&str) -> bool> = {
    if let Some(query) = query {
      if exact {
        Box::new(move |s: &str| s == query)
      } else {
        Box::new(move |s: &str| s.contains(&query))
      }
    } else {
      Box::new(|_| true)
    }
  };

  for repo in get_local_repositories(filter) {
    let path = match format {
      "full" => repo.absolute_path(),
      "unique" => repo.unique_path(),
      _ => repo.path,
    };
    println!("{}", path);
  }

  0
}

pub fn command_root(all: bool) -> i32 {
  let roots = get_local_repos_roots();
  if all {
    for root in roots {
      println!("{}", root);
    }
  } else {
    println!("{}", roots[0]);
  }
  0
}

#[derive(Debug)]
struct Repository {
  vcs: String,
  root: String,
  path: String,
}

fn get_local_repositories(filter: Box<Fn(&str) -> bool>) -> Vec<Repository> {
  let mut dst = Vec::new();

  let roots = get_local_repos_roots();
  for root in roots {
    for entry in WalkDir::new(&root)
      .follow_links(true)
      .into_iter()
      .filter_map(|e| e.ok())
      .filter(|ref e| e.depth() == 3) {

      let path = format!("{}", entry.path().display())
        .replace(&format!("{}{}", root, std::path::MAIN_SEPARATOR), "");

      let vcs = vec![".git", ".svn", ".hg", "_darcs"]
        .into_iter()
        .find(|&e| {
          let mut buf = PathBuf::from(format!("{}", entry.path().display()));
          if !filter(buf.file_name().unwrap().to_str().unwrap()) {
            return false;
          }
          buf.push(e);
          buf.exists()
        })
        .map(|e| format!("{}", &e[1..]));

      if vcs.is_some() {
        dst.push(Repository {
          vcs: vcs.unwrap(),
          root: root.clone(),
          path: path.replace("\\", "/"),
        });
      }
    }
  }

  dst
}

fn get_local_repos_roots() -> Vec<String> {
  let mut local_repo_roots;

  let env_root: String = std::env::var("GHQ_ROOT").unwrap_or("".to_owned());
  if env_root == "" {
    local_repo_roots = vec![git::config("ghq.root")];
  } else {
    local_repo_roots = env_root.split(":").map(|s| s.to_owned()).collect();
  }

  if local_repo_roots.len() == 0 {
    let mut ghq_path = std::env::home_dir().unwrap();
    ghq_path.push(".ghq");
    local_repo_roots.push(format!("{}", ghq_path.display()));
  }

  assert!(local_repo_roots.len() >= 1);

  local_repo_roots
}
<commit_msg>chane the behaviour of 'list' command<commit_after>extern crate walkdir;
extern crate regex;
extern crate url;

mod git;
mod util;
mod remote;

use std::path::Path;
use walkdir::WalkDir;

pub fn command_get(projects: Vec<String>, skip_pull: bool, shallow: bool) -> i32 {
  for project in projects {
    let repo = remote::RemoteRepository::new(project.as_str());
    let dest = repo.local_path(&get_local_repos_roots()[0]);

    git::clone_or_pull(repo.url(), dest.as_path(), skip_pull, shallow);
  }
  0
}

impl Repository {
  #[cfg(windows)]
  fn absolute_path(&self) -> String {
    let repo_path = Path::new(&self.root).join(&self.path);
    format!("{}", repo_path.display()).replace("/", "\\")
  }

  #[cfg(not(windows))]
  fn absolute_path(&self) -> String {
    let repo_path = Path::new(self.root).join(self.path);
    format!("{}", repo_path.display())
  }

  fn unique_path(&self) -> String {
    Path::new(&self.path)
      .file_name()
      .unwrap()
      .to_str()
      .unwrap()
      .to_owned()
  }

  fn project_name(&self) -> String {
    Path::new(&self.path).file_name().unwrap().to_str().unwrap().to_owned()
  }

  fn contains(&self, query: &str) -> bool {
    let target: Vec<&str> = self.path.split("/").collect();
    let target: Vec<&str> = target.into_iter().rev().take(2).collect();
    format!("{}/{}", target[1], target[0]).contains(query)
  }
}

pub fn command_list(exact: bool, format: &str, query: Option<String>) -> i32 {
  let filter: Box<Fn(&Repository) -> bool> = {
    if let Some(query) = query {
      if exact {
        Box::new(move |repo: &Repository| repo.project_name() == query)
      } else {
        Box::new(move |repo: &Repository| repo.contains(&query))
      }
    } else {
      Box::new(|_| true)
    }
  };

  for repo in get_local_repositories().into_iter().filter(|ref repo| filter(repo)) {
    let path = match format {
      "full" => repo.absolute_path(),
      "unique" => repo.unique_path(),
      _ => repo.path,
    };
    println!("{}", path);
  }

  0
}

pub fn command_root(all: bool) -> i32 {
  let roots = get_local_repos_roots();
  if all {
    for root in roots {
      println!("{}", root);
    }
  } else {
    println!("{}", roots[0]);
  }
  0
}

#[derive(Debug)]
struct Repository {
  vcs: String,
  root: String,
  path: String,
}

fn get_local_repositories() -> Vec<Repository> {
  let mut dst = Vec::new();

  let roots = get_local_repos_roots();
  for root in roots {
    for entry in WalkDir::new(&root)
      .follow_links(true)
      .into_iter()
      .filter_map(|e| e.ok())
      .filter(|ref e| e.depth() == 3) {

      let path = format!("{}", entry.path().display())
        .replace(&format!("{}{}", root, std::path::MAIN_SEPARATOR), "");

      let vcs = vec![".git", ".svn", ".hg", "_darcs"]
        .into_iter()
        .find(|&vcs| entry.path().join(vcs).exists())
        .map(|e| format!("{}", &e[1..]));

      if vcs.is_some() {
        dst.push(Repository {
          vcs: vcs.unwrap(),
          root: root.clone(),
          path: path.replace("\\", "/"),
        });
      }
    }
  }

  dst
}

fn get_local_repos_roots() -> Vec<String> {
  let mut local_repo_roots;

  let env_root: String = std::env::var("GHQ_ROOT").unwrap_or("".to_owned());
  if env_root == "" {
    local_repo_roots = vec![git::config("ghq.root")];
  } else {
    local_repo_roots = env_root.split(":").map(|s| s.to_owned()).collect();
  }

  if local_repo_roots.len() == 0 {
    let mut ghq_path = std::env::home_dir().unwrap();
    ghq_path.push(".ghq");
    local_repo_roots.push(format!("{}", ghq_path.display()));
  }

  assert!(local_repo_roots.len() >= 1);

  local_repo_roots
}
<|endoftext|>


<commit_before>pub mod atkin {
    extern crate std;
    use std::thread;

    struct Squares {
        count: u64,
        max: u64,
    }

    impl Squares {
        pub fn new(max: u64) -> Squares {
            Squares { count: 0, max: max }
        }
    }

    impl Iterator for Squares {
        type Item = u64;
        fn next(&mut self) -> Option<Self::Item> {
            self.count += 1;
            let square = self.count*self.count;
            if square > self.max {
                None
            } else {
                Some(self.count*self.count)
            }
        }
    }

    #[derive(Copy)]
    #[derive(Eq)]
    struct TestInteger {
        value: u64,
        is_prime: bool
    }

    impl Clone for TestInteger {
        fn clone(&self) -> TestInteger { *self }
    }

    impl Ord for TestInteger {
        fn cmp(&self, other: &TestInteger) -> std::cmp::Ordering {
            self.value.cmp(&other.value)
        }
    }

    impl PartialOrd for TestInteger {
        fn partial_cmp(&self, other: &TestInteger) -> std::option::Option<std::cmp::Ordering> {
            Some(self.cmp(other))
        }
    }

    impl PartialEq for TestInteger {
        fn eq(&self, other: &TestInteger) -> bool {
            (self.value == other.value) && (self.is_prime == other.is_prime)
        }
    }

    impl TestInteger {
        pub fn is_prime(&self) -> bool {
            self.is_prime
        }

        pub fn value(&self) -> u64 {
            self.value
        }

        pub fn set_prime(&mut self, prime: bool) -> bool {
            self.is_prime = prime;
            self.is_prime
        }

        pub fn flip(&mut self) -> bool {
            self.is_prime ^= true;
            self.is_prime
        }
    }

    pub struct SieveOfAtkin {
        results: Vec<u64>,
        tests: Vec<TestInteger>,
    }

    enum AtkinCases {
        C1,
        C2,
        C3,
        C4,
    }

    impl SieveOfAtkin {
        pub fn new(limit: u64) -> SieveOfAtkin {
            let res = vec![2,3,5];
            let mut tests: Vec<TestInteger> = Vec::new();
            if limit < 2 {
                panic!("The limit for the sieve must be above 2. {} was set as limit.", limit);
            } else {

                for i in 2..limit {
                    tests.push(TestInteger{ value: i, is_prime: false });
                }
            }
            SieveOfAtkin { results: res, tests: tests }
        }

        // returns a copy so we don't need to worry about our vector being mutated
        pub fn get_results(&self) -> Vec<u64> {
            self.results.clone()
        }

        fn process_case(&mut self, n : u64, index : usize, case: AtkinCases) {
            //Case 1: flip for each solution to 4x^2 + y^2 = n
            //Case 2: flip for each solution to 3x^2 + y^2 = n
            //Case 3: flip for each solution to 3x^2 - y^2 = n where x > y
            //Case 4: do nothing

            let (co_x,co_y): (u64, u64) = match case {
                AtkinCases::C1  => (4,1),
                AtkinCases::C2  => (3,1),
                AtkinCases::C3  => (3,1),
                _               => { return; },
            };

            let expression: Box<Fn(u64, u64) -> u64> = match case {
                AtkinCases::C3  => Box::new( |x, y| { if x > y { co_x*x - co_y*y } else { 0 } } ),
                _               => Box::new( |x, y| { co_x*x + co_y*y } ),
            };

            for i in Squares::new(n) {
                for j in Squares::new(n) {
                    if expression(i, j) == n {
                        self.tests.get_mut(index)
                            .expect("Index passed in process is invalid. This shouldn't happen.")
                            .flip();
                    }
                }
            }
        }

        pub fn run(&mut self) {
            // process test integers for different cases
            for i in 0..self.tests.len()-1 {
                let val = self.tests.get(i)
                    .expect("Index passed in process is invalid. This shouldn't happen.")
                    .clone();
                let case: AtkinCases = match val.value() % 60 {
                    1  | 13 | 17 | 29 | 37 | 41 | 49 | 53   => AtkinCases::C1,
                    7  | 19 | 31 | 43                       => AtkinCases::C2,
                    11 | 23 | 47 | 59                       => AtkinCases::C3,
                    _                                       => AtkinCases::C4,
                };
                self.process_case(val.value(), i, case);
            }

            // start sieving
            while !self.tests.is_empty() {
                let first = self.tests.first()
                    .expect("Attempted to get item from tests vector while it was empty.")
                    .clone();
                if first.is_prime() {
                    self.results.push(first.value());
                    let square = first.value() * first.value();
                    let naturals = std::ops::RangeFrom{ start: 1 };
                    for i in naturals {
                        let n_square = i*square;
                        if n_square > self.tests.last()
                            .expect("Attempted to get item from tests vector while it was empty.")
                            .value() {
                            break;
                        }

                        match self.tests.binary_search(&TestInteger{ value: n_square, is_prime: true }) {
                            Ok(index)   => {
                                self.tests.get_mut(index)
                                        .expect("Attempted to get known index from tests vector. This shouldn't happen.")
                                        .set_prime(false);
                            },
                            Err(_)      => (),
                        }
                    }
                }
                self.tests.remove(0);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use atkin::*;
    #[test]
    fn atkin_test() {
        let primes_to_50 = [2u64, 3u64, 5u64, 7u64, 11u64, 13u64, 17u64, 19u64, 23u64, 29u64, 31u64, 37u64, 41u64, 43u64, 47u64];
        let mut sieve = SieveOfAtkin::new(50);

        sieve.run();
        assert_eq!(sieve.get_results(), primes_to_50);
    }

    #[test]
    fn atkin_output() {
        let mut sieve = SieveOfAtkin::new(10000);
        sieve.run();
        let results = sieve.get_results();
        for prime in results.iter() {
           assert!(is_n_prime(*prime), "Failed with {}", prime);
        }
    }

    fn is_n_prime(n: u64) -> bool {
        let mut prime: bool = true;
        if n > 2 {
            for i in 2..n/2 {
                if n % i == 0 {
                    prime = false;
                    break;
                }
            }
        }
        prime
    }
}

<commit_msg>removed unneeded "use std::thread;" from lib.rs<commit_after>pub mod atkin {
    extern crate std;

    struct Squares {
        count: u64,
        max: u64,
    }

    impl Squares {
        pub fn new(max: u64) -> Squares {
            Squares { count: 0, max: max }
        }
    }

    impl Iterator for Squares {
        type Item = u64;
        fn next(&mut self) -> Option<Self::Item> {
            self.count += 1;
            let square = self.count*self.count;
            if square > self.max {
                None
            } else {
                Some(self.count*self.count)
            }
        }
    }

    #[derive(Copy)]
    #[derive(Eq)]
    struct TestInteger {
        value: u64,
        is_prime: bool
    }

    impl Clone for TestInteger {
        fn clone(&self) -> TestInteger { *self }
    }

    impl Ord for TestInteger {
        fn cmp(&self, other: &TestInteger) -> std::cmp::Ordering {
            self.value.cmp(&other.value)
        }
    }

    impl PartialOrd for TestInteger {
        fn partial_cmp(&self, other: &TestInteger) -> std::option::Option<std::cmp::Ordering> {
            Some(self.cmp(other))
        }
    }

    impl PartialEq for TestInteger {
        fn eq(&self, other: &TestInteger) -> bool {
            (self.value == other.value) && (self.is_prime == other.is_prime)
        }
    }

    impl TestInteger {
        pub fn is_prime(&self) -> bool {
            self.is_prime
        }

        pub fn value(&self) -> u64 {
            self.value
        }

        pub fn set_prime(&mut self, prime: bool) -> bool {
            self.is_prime = prime;
            self.is_prime
        }

        pub fn flip(&mut self) -> bool {
            self.is_prime ^= true;
            self.is_prime
        }
    }

    pub struct SieveOfAtkin {
        results: Vec<u64>,
        tests: Vec<TestInteger>,
    }

    enum AtkinCases {
        C1,
        C2,
        C3,
        C4,
    }

    impl SieveOfAtkin {
        pub fn new(limit: u64) -> SieveOfAtkin {
            let res = vec![2,3,5];
            let mut tests: Vec<TestInteger> = Vec::new();
            if limit < 2 {
                panic!("The limit for the sieve must be above 2. {} was set as limit.", limit);
            } else {

                for i in 2..limit {
                    tests.push(TestInteger{ value: i, is_prime: false });
                }
            }
            SieveOfAtkin { results: res, tests: tests }
        }

        // returns a copy so we don't need to worry about our vector being mutated
        pub fn get_results(&self) -> Vec<u64> {
            self.results.clone()
        }

        fn process_case(&mut self, n : u64, index : usize, case: AtkinCases) {
            //Case 1: flip for each solution to 4x^2 + y^2 = n
            //Case 2: flip for each solution to 3x^2 + y^2 = n
            //Case 3: flip for each solution to 3x^2 - y^2 = n where x > y
            //Case 4: do nothing

            let (co_x,co_y): (u64, u64) = match case {
                AtkinCases::C1  => (4,1),
                AtkinCases::C2  => (3,1),
                AtkinCases::C3  => (3,1),
                _               => { return; },
            };

            let expression: Box<Fn(u64, u64) -> u64> = match case {
                AtkinCases::C3  => Box::new( |x, y| { if x > y { co_x*x - co_y*y } else { 0 } } ),
                _               => Box::new( |x, y| { co_x*x + co_y*y } ),
            };

            for i in Squares::new(n) {
                for j in Squares::new(n) {
                    if expression(i, j) == n {
                        self.tests.get_mut(index)
                            .expect("Index passed in process is invalid. This shouldn't happen.")
                            .flip();
                    }
                }
            }
        }

        pub fn run(&mut self) {
            // process test integers for different cases
            for i in 0..self.tests.len()-1 {
                let val = self.tests.get(i)
                    .expect("Index passed in process is invalid. This shouldn't happen.")
                    .clone();
                let case: AtkinCases = match val.value() % 60 {
                    1  | 13 | 17 | 29 | 37 | 41 | 49 | 53   => AtkinCases::C1,
                    7  | 19 | 31 | 43                       => AtkinCases::C2,
                    11 | 23 | 47 | 59                       => AtkinCases::C3,
                    _                                       => AtkinCases::C4,
                };
                self.process_case(val.value(), i, case);
            }

            // start sieving
            while !self.tests.is_empty() {
                let first = self.tests.first()
                    .expect("Attempted to get item from tests vector while it was empty.")
                    .clone();
                if first.is_prime() {
                    self.results.push(first.value());
                    let square = first.value() * first.value();
                    let naturals = std::ops::RangeFrom{ start: 1 };
                    for i in naturals {
                        let n_square = i*square;
                        if n_square > self.tests.last()
                            .expect("Attempted to get item from tests vector while it was empty.")
                            .value() {
                            break;
                        }

                        match self.tests.binary_search(&TestInteger{ value: n_square, is_prime: true }) {
                            Ok(index)   => {
                                self.tests.get_mut(index)
                                        .expect("Attempted to get known index from tests vector. This shouldn't happen.")
                                        .set_prime(false);
                            },
                            Err(_)      => (),
                        }
                    }
                }
                self.tests.remove(0);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use atkin::*;
    #[test]
    fn atkin_test() {
        let primes_to_50 = [2u64, 3u64, 5u64, 7u64, 11u64, 13u64, 17u64, 19u64, 23u64, 29u64, 31u64, 37u64, 41u64, 43u64, 47u64];
        let mut sieve = SieveOfAtkin::new(50);

        sieve.run();
        assert_eq!(sieve.get_results(), primes_to_50);
    }

    #[test]
    fn atkin_output() {
        let mut sieve = SieveOfAtkin::new(10000);
        sieve.run();
        let results = sieve.get_results();
        for prime in results.iter() {
           assert!(is_n_prime(*prime), "Failed with {}", prime);
        }
    }

    fn is_n_prime(n: u64) -> bool {
        let mut prime: bool = true;
        if n > 2 {
            for i in 2..n/2 {
                if n % i == 0 {
                    prime = false;
                    break;
                }
            }
        }
        prime
    }
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
mod ansi;
mod curses;
mod event;
mod field;
mod input;
mod item;
mod matcher;
mod model;
mod options;
mod orderedvec;
mod output;
mod previewer;
mod query;
mod reader;
mod score;
mod sender;
mod theme;
mod util;

use curses::Curses;
use event::Event::*;
use event::{EventReceiver, EventSender};
use item::Item;
pub use options::SkimOptions;
pub use output::SkimOutput;
use std::env;
use std::io::BufRead;
use std::sync::mpsc::{channel, sync_channel, Receiver, Sender};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use tuikit::term::{Term, TermHeight, TermOptions};

const REFRESH_DURATION: u64 = 200;

pub struct Skim {}

impl Skim {
    pub fn run_with(options: &SkimOptions, source: Option<Box<BufRead + Send>>) -> Option<SkimOutput> {
        let min_height = options
            .min_height
            .map(Skim::parse_height_string)
            .expect("min_height should have default values");
        let height = options
            .height
            .map(Skim::parse_height_string)
            .expect("height should have default values");

        let term = Arc::new(Term::with_options(TermOptions::default().min_height(min_height).height(height)).unwrap());

        //------------------------------------------------------------------------------
        // curses

        let curses = Curses::new(term.clone(), &options);

        //------------------------------------------------------------------------------
        // query
        let default_command = match env::var("SKIM_DEFAULT_COMMAND").as_ref().map(String::as_ref) {
            Ok("") | Err(_) => "find .".to_owned(),
            Ok(val) => val.to_owned(),
        };
        let mut query = query::Query::builder().base_cmd(&default_command).build();
        query.parse_options(&options);

        //------------------------------------------------------------------------------
        // reader -- read items from stdin or output of comment

        debug!("reader start");
        let (tx_reader, rx_reader) = channel();
        let (tx_item, rx_item) = sync_channel(128);
        let mut reader = reader::Reader::new(rx_reader, tx_item.clone(), source);
        reader.parse_options(&options);
        thread::spawn(move || {
            reader.run();
        });

        //------------------------------------------------------------------------------
        // input
        let (tx_input, rx_input): (EventSender, EventReceiver) = channel();
        let tx_input_clone = tx_input.clone();
        let mut input = input::Input::new(term.clone(), tx_input_clone);

        input.parse_keymaps(&options.bind);

        input.parse_expect_keys(options.expect.as_ref().map(|x| &**x));
        thread::spawn(move || {
            input.run();
        });

        //------------------------------------------------------------------------------
        // model + previewer
        let (tx_model, rx_model) = channel();
        let mut model = model::Model::new(rx_model);

        model.parse_options(&options);

        if options.preview.is_some() {
            let (tx_preview, rx_preview) = channel();
            model.set_previewer(tx_preview);
            // previewer
            let tx_model_clone = tx_model.clone();
            std::thread::spawn(move || {
                previewer::run(rx_preview, tx_model_clone);
            });
        }

        thread::spawn(move || {
            model.run(curses);
        });

        //------------------------------------------------------------------------------
        // matcher
        let tx_model_clone = tx_model.clone();
        let mut matcher = matcher::Matcher::new(tx_model_clone);
        matcher.parse_options(&options);

        thread::spawn(move || {
            matcher.run(rx_item);
        });

        //------------------------------------------------------------------------------
        // start a timer for notifying refresh
        let tx_model_clone = tx_model.clone();
        thread::spawn(move || loop {
            thread::sleep(Duration::from_millis(REFRESH_DURATION));
            let _ = tx_model_clone.send((EvModelDrawInfo, Box::new(true)));
        });

        //------------------------------------------------------------------------------
        // Helper functions

        // light up the fire
        let _ = tx_reader.send((EvReaderRestart, Box::new((query.get_cmd(), query.get_query(), false))));

        let redraw_query = |query: &query::Query| {
            let _ = tx_model.send((EvModelDrawQuery, Box::new(query.get_print_func())));
        };

        let on_query_change = |query: &query::Query| {
            // restart the reader with new parameter
            // send redraw event
            redraw_query(query);
            let _ = tx_reader.send((EvReaderRestart, Box::new((query.get_cmd(), query.get_query(), false))));
        };

        let on_query_force_update = |query: &query::Query| {
            // restart the reader with new parameter
            let _ = tx_reader.send((EvReaderRestart, Box::new((query.get_cmd(), query.get_query(), true))));
            // send redraw event
            redraw_query(query);
        };

        //------------------------------------------------------------------------------
        // main loop, listen for user input
        // now we can use
        // tx_reader: send message to reader
        // tx_model:  send message to model
        // rx_input:  receive keystroke events

        let mut ret = None;

        let _ = tx_input.send((EvActRedraw, Box::new(true))); // trigger draw
        while let Ok((ev, arg)) = rx_input.recv() {
            debug!("main: got event {:?}", ev);
            match ev {
                EvActAddChar => {
                    let ch: char = *arg.downcast().expect("EvActAddChar: failed to get argument");
                    query.act_add_char(ch);
                    on_query_change(&query);
                }

                EvActBackwardDeleteChar => {
                    query.act_backward_delete_char();
                    on_query_change(&query);
                }

                EvActDeleteChar => {
                    query.act_delete_char();
                    on_query_change(&query);
                }

                EvActDeleteCharEOF => {
                    if query.get_query() == "" {
                        let _ = tx_input.send((EvActAbort, Box::new(true))); // trigger draw
                    } else {
                        let _ = tx_input.send((EvActDeleteChar, Box::new(true))); // trigger draw
                    }
                }

                EvActBackwardChar => {
                    query.act_backward_char();
                    redraw_query(&query);
                }

                EvActForwardChar => {
                    query.act_forward_char();
                    redraw_query(&query);
                }

                EvActBackwardKillWord => {
                    query.act_backward_kill_word();
                    on_query_change(&query);
                }

                EvActUnixWordRubout => {
                    query.act_unix_word_rubout();
                    on_query_change(&query);
                }

                EvActBackwardWord => {
                    query.act_backward_word();
                    redraw_query(&query);
                }

                EvActForwardWord => {
                    query.act_forward_word();
                    redraw_query(&query);
                }

                EvActBeginningOfLine => {
                    query.act_beginning_of_line();
                    redraw_query(&query);
                }

                EvActEndOfLine => {
                    query.act_end_of_line();
                    redraw_query(&query);
                }

                EvActKillLine => {
                    query.act_kill_line();
                    on_query_change(&query);
                }

                EvActUnixLineDiscard => {
                    query.act_line_discard();
                    on_query_change(&query);
                }

                EvActKillWord => {
                    query.act_kill_word();
                    on_query_change(&query);
                }

                EvActYank => {
                    query.act_yank();
                    on_query_change(&query);
                }

                EvActToggleInteractive => {
                    query.act_query_toggle_interactive();
                    redraw_query(&query);
                }

                EvActRotateMode => {
                    // tell the matcher to switch mode
                    let _ = tx_item.send((EvActRotateMode, Box::new(false)));
                    on_query_force_update(&query);
                }

                EvActAccept => {
                    // kill reader
                    let (tx, rx): (Sender<usize>, Receiver<usize>) = channel();
                    let _ = tx_reader.send((EvActAccept, Box::new(tx)));
                    let _ = rx.recv();

                    // sync with model to quit
                    let accept_key = *arg.downcast::<Option<String>>().unwrap_or_else(|_| Box::new(None));

                    let (tx, rx): (Sender<Vec<Arc<Item>>>, Receiver<Vec<Arc<Item>>>) = channel();
                    let _ = tx_model.send((EvActAccept, Box::new(tx)));
                    let selected = rx.recv().expect("receiving selected item failure on accept");

                    ret = Some(SkimOutput {
                        accept_key,
                        query: query.get_query(),
                        cmd: query.get_cmd_query(),
                        selected_items: selected,
                    });

                    break;
                }

                EvActClearScreen | EvActRedraw => {
                    let _ = tx_model.send((EvActRedraw, Box::new(query.get_print_func())));
                }

                EvActAbort => {
                    // kill reader
                    let (tx, rx): (Sender<usize>, Receiver<usize>) = channel();
                    let _ = tx_reader.send((EvActAbort, Box::new(tx)));
                    let _ = rx.recv();

                    // kill model
                    let (tx, rx): (Sender<bool>, Receiver<bool>) = channel();
                    let _ = tx_model.send((EvActAbort, Box::new(tx)));
                    let _ = rx.recv();
                    break;
                }

                EvActUp | EvActDown | EvActToggle | EvActToggleDown | EvActToggleUp | EvActToggleAll
                | EvActSelectAll | EvActDeselectAll | EvActPageDown | EvActPageUp | EvActScrollLeft
                | EvActScrollRight => {
                    let _ = tx_model.send((ev, arg));
                }

                EvActTogglePreview => {
                    let _ = tx_model.send((ev, arg));
                    let _ = tx_model.send((EvActRedraw, Box::new(query.get_print_func())));
                }

                _ => {}
            }
        }

        ret
    }

    // 10 -> TermHeight::Fixed(10)
    // 10% -> TermHeight::Percent(10)
    fn parse_height_string(string: &str) -> TermHeight {
        if string.ends_with('%') {
            TermHeight::Percent(string[0..string.len() - 1].parse().unwrap_or(100))
        } else {
            TermHeight::Fixed(string.parse().unwrap_or(0))
        }
    }
}
<commit_msg>[stdin] fix piped input<commit_after>#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
mod ansi;
mod curses;
mod event;
mod field;
mod input;
mod item;
mod matcher;
mod model;
mod options;
mod orderedvec;
mod output;
mod previewer;
mod query;
mod reader;
mod score;
mod sender;
mod theme;
mod util;

use curses::Curses;
use event::Event::*;
use event::{EventReceiver, EventSender};
use item::Item;
use nix::unistd::isatty;
pub use options::SkimOptions;
pub use output::SkimOutput;
use std::env;
use std::io::BufRead;
use std::io::BufReader;
use std::os::unix::io::AsRawFd;
use std::sync::mpsc::{channel, sync_channel, Receiver, Sender};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use tuikit::term::{Term, TermHeight, TermOptions};

const REFRESH_DURATION: u64 = 200;

pub struct Skim {}

impl Skim {
    pub fn run_with(options: &SkimOptions, source: Option<Box<BufRead + Send>>) -> Option<SkimOutput> {
        let min_height = options
            .min_height
            .map(Skim::parse_height_string)
            .expect("min_height should have default values");
        let height = options
            .height
            .map(Skim::parse_height_string)
            .expect("height should have default values");

        let term = Arc::new(Term::with_options(TermOptions::default().min_height(min_height).height(height)).unwrap());

        //------------------------------------------------------------------------------
        // curses

        // in piped situation(e.g. `echo "a" | sk`) set source to the pipe
        let source = source.or_else(|| {
            let stdin = std::io::stdin();
            if !isatty(stdin.as_raw_fd()).unwrap_or(true) {
                Some(Box::new(BufReader::new(stdin)))
            } else {
                None
            }
        });

        let curses = Curses::new(term.clone(), &options);

        //------------------------------------------------------------------------------
        // query
        let default_command = match env::var("SKIM_DEFAULT_COMMAND").as_ref().map(String::as_ref) {
            Ok("") | Err(_) => "find .".to_owned(),
            Ok(val) => val.to_owned(),
        };
        let mut query = query::Query::builder().base_cmd(&default_command).build();
        query.parse_options(&options);

        //------------------------------------------------------------------------------
        // reader -- read items from stdin or output of comment

        debug!("reader start");
        let (tx_reader, rx_reader) = channel();
        let (tx_item, rx_item) = sync_channel(128);
        let mut reader = reader::Reader::new(rx_reader, tx_item.clone(), source);
        reader.parse_options(&options);
        thread::spawn(move || {
            reader.run();
        });

        //------------------------------------------------------------------------------
        // input
        let (tx_input, rx_input): (EventSender, EventReceiver) = channel();
        let tx_input_clone = tx_input.clone();
        let mut input = input::Input::new(term.clone(), tx_input_clone);

        input.parse_keymaps(&options.bind);

        input.parse_expect_keys(options.expect.as_ref().map(|x| &**x));
        thread::spawn(move || {
            input.run();
        });

        //------------------------------------------------------------------------------
        // model + previewer
        let (tx_model, rx_model) = channel();
        let mut model = model::Model::new(rx_model);

        model.parse_options(&options);

        if options.preview.is_some() {
            let (tx_preview, rx_preview) = channel();
            model.set_previewer(tx_preview);
            // previewer
            let tx_model_clone = tx_model.clone();
            std::thread::spawn(move || {
                previewer::run(rx_preview, tx_model_clone);
            });
        }

        thread::spawn(move || {
            model.run(curses);
        });

        //------------------------------------------------------------------------------
        // matcher
        let tx_model_clone = tx_model.clone();
        let mut matcher = matcher::Matcher::new(tx_model_clone);
        matcher.parse_options(&options);

        thread::spawn(move || {
            matcher.run(rx_item);
        });

        //------------------------------------------------------------------------------
        // start a timer for notifying refresh
        let tx_model_clone = tx_model.clone();
        thread::spawn(move || loop {
            thread::sleep(Duration::from_millis(REFRESH_DURATION));
            let _ = tx_model_clone.send((EvModelDrawInfo, Box::new(true)));
        });

        //------------------------------------------------------------------------------
        // Helper functions

        // light up the fire
        let _ = tx_reader.send((EvReaderRestart, Box::new((query.get_cmd(), query.get_query(), false))));

        let redraw_query = |query: &query::Query| {
            let _ = tx_model.send((EvModelDrawQuery, Box::new(query.get_print_func())));
        };

        let on_query_change = |query: &query::Query| {
            // restart the reader with new parameter
            // send redraw event
            redraw_query(query);
            let _ = tx_reader.send((EvReaderRestart, Box::new((query.get_cmd(), query.get_query(), false))));
        };

        let on_query_force_update = |query: &query::Query| {
            // restart the reader with new parameter
            let _ = tx_reader.send((EvReaderRestart, Box::new((query.get_cmd(), query.get_query(), true))));
            // send redraw event
            redraw_query(query);
        };

        //------------------------------------------------------------------------------
        // main loop, listen for user input
        // now we can use
        // tx_reader: send message to reader
        // tx_model:  send message to model
        // rx_input:  receive keystroke events

        let mut ret = None;

        let _ = tx_input.send((EvActRedraw, Box::new(true))); // trigger draw
        while let Ok((ev, arg)) = rx_input.recv() {
            debug!("main: got event {:?}", ev);
            match ev {
                EvActAddChar => {
                    let ch: char = *arg.downcast().expect("EvActAddChar: failed to get argument");
                    query.act_add_char(ch);
                    on_query_change(&query);
                }

                EvActBackwardDeleteChar => {
                    query.act_backward_delete_char();
                    on_query_change(&query);
                }

                EvActDeleteChar => {
                    query.act_delete_char();
                    on_query_change(&query);
                }

                EvActDeleteCharEOF => {
                    if query.get_query() == "" {
                        let _ = tx_input.send((EvActAbort, Box::new(true))); // trigger draw
                    } else {
                        let _ = tx_input.send((EvActDeleteChar, Box::new(true))); // trigger draw
                    }
                }

                EvActBackwardChar => {
                    query.act_backward_char();
                    redraw_query(&query);
                }

                EvActForwardChar => {
                    query.act_forward_char();
                    redraw_query(&query);
                }

                EvActBackwardKillWord => {
                    query.act_backward_kill_word();
                    on_query_change(&query);
                }

                EvActUnixWordRubout => {
                    query.act_unix_word_rubout();
                    on_query_change(&query);
                }

                EvActBackwardWord => {
                    query.act_backward_word();
                    redraw_query(&query);
                }

                EvActForwardWord => {
                    query.act_forward_word();
                    redraw_query(&query);
                }

                EvActBeginningOfLine => {
                    query.act_beginning_of_line();
                    redraw_query(&query);
                }

                EvActEndOfLine => {
                    query.act_end_of_line();
                    redraw_query(&query);
                }

                EvActKillLine => {
                    query.act_kill_line();
                    on_query_change(&query);
                }

                EvActUnixLineDiscard => {
                    query.act_line_discard();
                    on_query_change(&query);
                }

                EvActKillWord => {
                    query.act_kill_word();
                    on_query_change(&query);
                }

                EvActYank => {
                    query.act_yank();
                    on_query_change(&query);
                }

                EvActToggleInteractive => {
                    query.act_query_toggle_interactive();
                    redraw_query(&query);
                }

                EvActRotateMode => {
                    // tell the matcher to switch mode
                    let _ = tx_item.send((EvActRotateMode, Box::new(false)));
                    on_query_force_update(&query);
                }

                EvActAccept => {
                    // kill reader
                    let (tx, rx): (Sender<usize>, Receiver<usize>) = channel();
                    let _ = tx_reader.send((EvActAccept, Box::new(tx)));
                    let _ = rx.recv();

                    // sync with model to quit
                    let accept_key = *arg.downcast::<Option<String>>().unwrap_or_else(|_| Box::new(None));

                    let (tx, rx): (Sender<Vec<Arc<Item>>>, Receiver<Vec<Arc<Item>>>) = channel();
                    let _ = tx_model.send((EvActAccept, Box::new(tx)));
                    let selected = rx.recv().expect("receiving selected item failure on accept");

                    ret = Some(SkimOutput {
                        accept_key,
                        query: query.get_query(),
                        cmd: query.get_cmd_query(),
                        selected_items: selected,
                    });

                    break;
                }

                EvActClearScreen | EvActRedraw => {
                    let _ = tx_model.send((EvActRedraw, Box::new(query.get_print_func())));
                }

                EvActAbort => {
                    // kill reader
                    let (tx, rx): (Sender<usize>, Receiver<usize>) = channel();
                    let _ = tx_reader.send((EvActAbort, Box::new(tx)));
                    let _ = rx.recv();

                    // kill model
                    let (tx, rx): (Sender<bool>, Receiver<bool>) = channel();
                    let _ = tx_model.send((EvActAbort, Box::new(tx)));
                    let _ = rx.recv();
                    break;
                }

                EvActUp | EvActDown | EvActToggle | EvActToggleDown | EvActToggleUp | EvActToggleAll
                | EvActSelectAll | EvActDeselectAll | EvActPageDown | EvActPageUp | EvActScrollLeft
                | EvActScrollRight => {
                    let _ = tx_model.send((ev, arg));
                }

                EvActTogglePreview => {
                    let _ = tx_model.send((ev, arg));
                    let _ = tx_model.send((EvActRedraw, Box::new(query.get_print_func())));
                }

                _ => {}
            }
        }

        ret
    }

    // 10 -> TermHeight::Fixed(10)
    // 10% -> TermHeight::Percent(10)
    fn parse_height_string(string: &str) -> TermHeight {
        if string.ends_with('%') {
            TermHeight::Percent(string[0..string.len() - 1].parse().unwrap_or(100))
        } else {
            TermHeight::Fixed(string.parse().unwrap_or(0))
        }
    }
}
<|endoftext|>


<commit_before>extern crate bitflags;
extern crate memalloc;

#[cfg(target_os="linux")]
extern crate libc;
#[cfg(all(target_os="linux", not(feature = "jack")))]
extern crate alsa_sys;
#[cfg(all(target_os="linux", not(feature = "jack")))]
extern crate alsa;
#[cfg(all(feature = "jack", not(target_os = "windows")))]
extern crate jack_sys;

#[cfg(target_os="windows")] extern crate winapi;
#[cfg(target_os="windows")] extern crate winmm as winmm_sys;

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Ignore {
    None = 0x00,
    Sysex = 0x01,
    Time = 0x02,
    SysexAndTime = 0x03,
    ActiveSense = 0x04,
    SysexAndActiveSense = 0x05,
    TimeAndActiveSense = 0x06,
    All = 0x07
}

impl std::ops::BitOr for Ignore {
    type Output = Ignore;
    #[inline(always)]
    fn bitor(self, rhs: Self) -> Self::Output {
        // this is safe because all combinations also exist as variants
        unsafe { std::mem::transmute(self as u8 | rhs as u8) }
    }
}

impl Ignore {
    #[inline(always)]
    pub fn contains(self, other: Ignore) -> bool {
        self as u8 & other as u8 != 0
    }
}

/// A MIDI structure used internally by the class to store incoming
/// messages. Each message represents one and only one MIDI message.
#[derive(Debug, Clone)]
struct MidiMessage {
    bytes: Vec<u8>,
    timestamp: f64
}

impl MidiMessage {
    // TODO: probably not needed
    pub fn new() -> MidiMessage {
        MidiMessage {
            bytes: vec![],
            timestamp: 0.0
        }
    }
}

pub mod os; // include platform-specific behaviour

mod errors;
pub use errors::*;

mod common;
pub use common::*;

mod backend;<commit_msg>Fix JACK build<commit_after>extern crate memalloc;

#[cfg(target_os="linux")]
extern crate libc;
#[cfg(all(target_os="linux", not(feature = "jack")))]
extern crate alsa_sys;
#[cfg(all(target_os="linux", not(feature = "jack")))]
extern crate alsa;
#[cfg(all(feature = "jack", not(target_os = "windows")))]
extern crate jack_sys;
#[cfg(feature = "jack")]
#[macro_use] extern crate bitflags;

#[cfg(target_os="windows")] extern crate winapi;
#[cfg(target_os="windows")] extern crate winmm as winmm_sys;

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Ignore {
    None = 0x00,
    Sysex = 0x01,
    Time = 0x02,
    SysexAndTime = 0x03,
    ActiveSense = 0x04,
    SysexAndActiveSense = 0x05,
    TimeAndActiveSense = 0x06,
    All = 0x07
}

impl std::ops::BitOr for Ignore {
    type Output = Ignore;
    #[inline(always)]
    fn bitor(self, rhs: Self) -> Self::Output {
        // this is safe because all combinations also exist as variants
        unsafe { std::mem::transmute(self as u8 | rhs as u8) }
    }
}

impl Ignore {
    #[inline(always)]
    pub fn contains(self, other: Ignore) -> bool {
        self as u8 & other as u8 != 0
    }
}

/// A MIDI structure used internally by the class to store incoming
/// messages. Each message represents one and only one MIDI message.
#[derive(Debug, Clone)]
struct MidiMessage {
    bytes: Vec<u8>,
    timestamp: f64
}

impl MidiMessage {
    // TODO: probably not needed
    pub fn new() -> MidiMessage {
        MidiMessage {
            bytes: vec![],
            timestamp: 0.0
        }
    }
}

pub mod os; // include platform-specific behaviour

mod errors;
pub use errors::*;

mod common;
pub use common::*;

mod backend;<|endoftext|>


<commit_before>// Copyright 2016 Doug Goldstein
//
// 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.

//! A simple logger to provide symantics similar to what is expected
//! of most UNIX utilities by logging to stderr and the higher the
//! verbosity the higher the log level
//!
//! ### Examples
//!
//! ```rust
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! fn main() {
//!     stderrlog::new().module(module_path!()).init().unwrap();
//!
//!     info!("starting up");
//!
//!     // ...
//! }
//! ```
//!
//! ```rust
//! extern crate docopt;
//! #[macro_use]
//! extern crate log;
//! extern crate rustc_serialize;
//! extern crate stderrlog;
//!
//! use docopt::Docopt;
//!
//! const USAGE: &'static str = "
//! Usage: program [-q] [-v...]
//! ";
//!
//! #[derive(Debug, RustcDecodable)]
//! struct Args {
//!     flag_q: bool,
//!     flag_v: usize,
//! }
//!
//! fn main() {
//!     let args: Args = Docopt::new(USAGE)
//!                             .and_then(|d| d.decode())
//!                             .unwrap_or_else(|e| e.exit());
//!
//!     stderrlog::new()
//!             .module(module_path!())
//!             .quiet(args.flag_q)
//!             .timestamp(stderrlog::Timestamp::Second)
//!             .verbosity(args.flag_v)
//!             .init()
//!             .unwrap();
//!     info!("starting up");
//!
//!     // ...
//! }

extern crate log;
extern crate time;

use log::{LogLevelFilter, LogMetadata};
use std::io::Write;

/// State of the timestampping in the logger.
#[derive(Clone, Copy, Debug)]
pub enum Timestamp {
    /// Disable timestamping of log messages
    Off,
    /// Timestamp with second granularity
    Second,
}

#[derive(Clone, Debug)]
pub struct StdErrLog {
    verbosity: LogLevelFilter,
    quiet: bool,
    timestamp: Timestamp,
    modules: Vec<String>,
}

impl log::Log for StdErrLog {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.log_level_filter()
    }

    fn log(&self, record: &log::LogRecord) {

        // if logging isn't enabled for this level do a quick out
        if !self.enabled(record.metadata()) {
            return;
        }

        // module we are logging for
        let curr_mod = record.location().module_path();

        // create the timestamp prefix string
        let timestamp_prefix = match self.timestamp {
            Timestamp::Off => String::new(),
            Timestamp::Second => format!("{} - ", time::now().rfc3339()),
        };

        // this logger only logs the requested modules unless the
        // vector of modules is empty
        // modules will have module::file in the module_path
        if self.modules.is_empty() || self.modules.iter().any(|x| curr_mod.starts_with(x)) {
            let _ = writeln!(&mut ::std::io::stderr(),
                             "{}{} - {}",
                             timestamp_prefix,
                             record.level(),
                             record.args());
        }
    }
}

impl StdErrLog {
    pub fn new() -> StdErrLog {
        StdErrLog {
            verbosity: LogLevelFilter::Error,
            quiet: false,
            timestamp: Timestamp::Off,
            modules: vec![],
        }
    }

    /// Sets the verbosity level of messages that will be displayed
    pub fn verbosity(&mut self, verbosity: usize) -> &mut StdErrLog {
        let log_lvl = match verbosity {
            0 => LogLevelFilter::Error,
            1 => LogLevelFilter::Warn,
            2 => LogLevelFilter::Info,
            3 => LogLevelFilter::Debug,
            _ => LogLevelFilter::Trace,
        };

        self.verbosity = log_lvl;
        self
    }

    pub fn quiet(&mut self, quiet: bool) -> &mut StdErrLog {
        self.quiet = quiet;
        self
    }

    /// Enables or disables the use of timestamps in log messages
    pub fn timestamp(&mut self, timestamp: Timestamp) -> &mut StdErrLog {
        self.timestamp = timestamp;
        self
    }

    pub fn module(&mut self, module: &str) -> &mut StdErrLog {
        self.modules.push(module.to_owned());
        self
    }

    pub fn modules(&mut self, modules: Vec<String>) -> &mut StdErrLog {
        self.modules.extend(modules);
        self
    }

    fn log_level_filter(&self) -> LogLevelFilter {
        if self.quiet {
            LogLevelFilter::Off
        } else {
            self.verbosity
        }
    }

    pub fn init(&self) -> Result<(), log::SetLoggerError> {

        log::set_logger(|max_log_level| {
            max_log_level.set(self.log_level_filter());

            Box::new(self.clone())
        })
    }
}

pub fn new() -> StdErrLog {
    StdErrLog::new()
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_default_level() {
        extern crate log;

        super::new().module(module_path!()).init().unwrap();

        assert_eq!(log::LogLevel::Error, log::max_log_level())
    }
}
<commit_msg>Only format the timestamp if about to output<commit_after>// Copyright 2016 Doug Goldstein
//
// 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.

//! A simple logger to provide symantics similar to what is expected
//! of most UNIX utilities by logging to stderr and the higher the
//! verbosity the higher the log level
//!
//! ### Examples
//!
//! ```rust
//! #[macro_use]
//! extern crate log;
//! extern crate stderrlog;
//!
//! fn main() {
//!     stderrlog::new().module(module_path!()).init().unwrap();
//!
//!     info!("starting up");
//!
//!     // ...
//! }
//! ```
//!
//! ```rust
//! extern crate docopt;
//! #[macro_use]
//! extern crate log;
//! extern crate rustc_serialize;
//! extern crate stderrlog;
//!
//! use docopt::Docopt;
//!
//! const USAGE: &'static str = "
//! Usage: program [-q] [-v...]
//! ";
//!
//! #[derive(Debug, RustcDecodable)]
//! struct Args {
//!     flag_q: bool,
//!     flag_v: usize,
//! }
//!
//! fn main() {
//!     let args: Args = Docopt::new(USAGE)
//!                             .and_then(|d| d.decode())
//!                             .unwrap_or_else(|e| e.exit());
//!
//!     stderrlog::new()
//!             .module(module_path!())
//!             .quiet(args.flag_q)
//!             .timestamp(stderrlog::Timestamp::Second)
//!             .verbosity(args.flag_v)
//!             .init()
//!             .unwrap();
//!     info!("starting up");
//!
//!     // ...
//! }

extern crate log;
extern crate time;

use log::{LogLevelFilter, LogMetadata};
use std::io::{self, Write};

/// State of the timestampping in the logger.
#[derive(Clone, Copy, Debug)]
pub enum Timestamp {
    /// Disable timestamping of log messages
    Off,
    /// Timestamp with second granularity
    Second,
}

#[derive(Clone, Debug)]
pub struct StdErrLog {
    verbosity: LogLevelFilter,
    quiet: bool,
    timestamp: Timestamp,
    modules: Vec<String>,
}

impl log::Log for StdErrLog {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.log_level_filter()
    }

    fn log(&self, record: &log::LogRecord) {

        // if logging isn't enabled for this level do a quick out
        if !self.enabled(record.metadata()) {
            return;
        }

        // module we are logging for
        let curr_mod = record.location().module_path();

        // this logger only logs the requested modules unless the
        // vector of modules is empty
        // modules will have module::file in the module_path
        if self.modules.is_empty() || self.modules.iter().any(|x| curr_mod.starts_with(x)) {
            let mut writer = io::LineWriter::new(io::stderr());
            if let Timestamp::Second = self.timestamp {
                let _ = write!(writer, "{} - ", time::now().rfc3339());
            }
            let _ = writeln!(writer, "{} - {}", record.level(), record.args());
        }
    }
}

impl StdErrLog {
    pub fn new() -> StdErrLog {
        StdErrLog {
            verbosity: LogLevelFilter::Error,
            quiet: false,
            timestamp: Timestamp::Off,
            modules: vec![],
        }
    }

    /// Sets the verbosity level of messages that will be displayed
    pub fn verbosity(&mut self, verbosity: usize) -> &mut StdErrLog {
        let log_lvl = match verbosity {
            0 => LogLevelFilter::Error,
            1 => LogLevelFilter::Warn,
            2 => LogLevelFilter::Info,
            3 => LogLevelFilter::Debug,
            _ => LogLevelFilter::Trace,
        };

        self.verbosity = log_lvl;
        self
    }

    pub fn quiet(&mut self, quiet: bool) -> &mut StdErrLog {
        self.quiet = quiet;
        self
    }

    /// Enables or disables the use of timestamps in log messages
    pub fn timestamp(&mut self, timestamp: Timestamp) -> &mut StdErrLog {
        self.timestamp = timestamp;
        self
    }

    pub fn module(&mut self, module: &str) -> &mut StdErrLog {
        self.modules.push(module.to_owned());
        self
    }

    pub fn modules(&mut self, modules: Vec<String>) -> &mut StdErrLog {
        self.modules.extend(modules);
        self
    }

    fn log_level_filter(&self) -> LogLevelFilter {
        if self.quiet {
            LogLevelFilter::Off
        } else {
            self.verbosity
        }
    }

    pub fn init(&self) -> Result<(), log::SetLoggerError> {

        log::set_logger(|max_log_level| {
            max_log_level.set(self.log_level_filter());

            Box::new(self.clone())
        })
    }
}

pub fn new() -> StdErrLog {
    StdErrLog::new()
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_default_level() {
        extern crate log;

        super::new().module(module_path!()).init().unwrap();

        assert_eq!(log::LogLevel::Error, log::max_log_level())
    }
}
<|endoftext|>


<commit_before>extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate nom;

mod traits;
use traits::{StructMap, FromStr};
#[macro_use]
extern crate struct_map_derive;

use nom::{digit, line_ending, multispace};
use nom::IResult::Done;

#[derive(Debug, Serialize)]
pub struct Osu {
    version: u32,
    general: General,
    editor: Editor,
    metadata: Metadata,
    difficulty: Difficulty,
    events: Events,
}

#[derive(Debug, PartialEq, Serialize)]
enum Mode {
    Wrong = -1,
    Osu,
    Taiko,
    CatchTheBeat,
    OsuMania,
}

#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct General {
    audio_filename: String,
    audio_lead_in: u32,
    preview_time: u32,
    countdown: bool,
    sample_set: String,
    stack_leniency: f32,
    mode: Mode,
    letterbox_in_breaks: bool,
    widescreen_storyboard: bool,
}

#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct Editor {
    bookmarks: Vec<u32>,
    distance_spacing: f32,
    beat_divisor: u32,
    grid_size: u32,
    timeline_zoom: f32,
}

#[allow(non_snake_case)]
#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct Metadata {
    title: String,
    title_unicode: String,
    artist: String,
    artist_unicode: String,
    creator: String,
    version: String,
    source: String,
    tags: Vec<String>,
    beatmap_ID: u32,
    beatmap_set_ID: u32,
}

#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct Difficulty {
    hp_drain_rate: f32,
    circle_size: f32,
    overall_difficulty: f32,
    approach_rate: f32,
    slider_multiplier: f32,
    slider_tickrate: f32,
}

#[derive(Debug, PartialEq, Default, Serialize)]
struct Events {
    background: String,
    video: String,
    //break_periods: Vec<u32>,
}

#[derive(Debug, PartialEq, Default, Serialize)]
struct TimingPoints {
    tps: Vec<TimingPoint>,
}

#[derive(Debug, PartialEq, Default, Serialize)]
struct TimingPoint {
    offset: u32,
    msec_per_beat: f32,
    meter: u32,
    sample_type: u32,
    sample_set: u32,
    volume: u32,
    inherited: bool, // 1 => false, 0 => true
    kiai_mode: bool,
}

named!(comment<&str, Vec<()> >,
    many0!(do_parse!(tag!("//") >> take_until_and_consume_s!("\r\n") >> ()))
);

named!(key_value_pair<&str, (&str, &str)>,
    do_parse!(
                comment
        >> key: take_until_and_consume_s!(":")
        >>      opt!(multispace)
        >> val: take_until_and_consume_s!("\r\n")
        >>      comment
        >> (key, val)
    )
);

macro_rules! named_section {
    ( $func:ident<$T:ty> ) => (
named!($func<&str, $T>,
        do_parse!(
                                tag_s!(concat!("[", stringify!($T), "]"))
           >>                   opt!(multispace)
           >> pairs_with_end:   many_till!(key_value_pair, line_ending)
           >> (StructMap::from_tuples(pairs_with_end.0))
          )
        );
    )
}

named_section!(section_general<General>);
named_section!(section_editor<Editor>);
named_section!(section_metadata<Metadata>);
named_section!(section_difficulty<Difficulty>);

named!(section_events<&str, Events>,
    do_parse!(
                    tag_s!("[Events]")
        >>          opt!(multispace)
        >>          comment
        >> bg_ev:   separated_list!(char!(','), take_until_either!(",\r"))
        >>          line_ending
        >>          comment
        >>          tag_s!("Video,")
        >> mov_ev:  separated_list!(char!(','), take_until_either!(",\r"))
        >>          line_ending
        >>          take_until_s!("[")
        >> (Events {
            background: bg_ev[2].trim_matches('"').to_owned(),
            video: mov_ev[1].trim_matches('"').to_owned(),
            ..Default::default()
        })
    )
);

named!(parse_osu<&str, Osu>,
    do_parse!(
                    tag_s!("osu file format v")
    >>  version:    map_res!(digit, FromStr::from_str)
    >>              line_ending
    >>              opt!(multispace)
    >>  sections:   permutation!(call!(section_general),
                                 call!(section_editor),
                                 call!(section_metadata),
                                 call!(section_difficulty),
                                 call!(section_events))
    >>  (Osu {
        version:    version,
        general:    sections.0,
        editor:     sections.1,
        metadata:   sections.2,
        difficulty: sections.3,
        events:     sections.4,
        })
    )
);

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

    #[test]
    fn it_works() {
        let input = include_str!("../test.osu");
        let res = parse_osu(input);
        if let Done(_, osu) = res {
            println!("{:?}", osu);
            println!("{}", serde_json::to_string(&osu).unwrap());
        } else {
            println!("{:?}", res);
            assert!(false);
        }
    }
}
<commit_msg>parse timing points & colours<commit_after>extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate nom;

mod traits;
use traits::{StructMap, FromStr};
#[macro_use]
extern crate struct_map_derive;

use nom::{digit, line_ending, multispace};
use nom::IResult::Done;

#[derive(Debug, Serialize)]
pub struct Osu {
    version: u32,
    general: General,
    editor: Editor,
    metadata: Metadata,
    difficulty: Difficulty,
    events: Events,
    timing_points: Vec<TimingPoint>,
    colours: Vec<Colour>,
}

#[derive(Debug, PartialEq, Serialize)]
enum Mode {
    Wrong = -1,
    Osu,
    Taiko,
    CatchTheBeat,
    OsuMania,
}

#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct General {
    audio_filename: String,
    audio_lead_in: u32,
    preview_time: u32,
    countdown: bool,
    sample_set: String,
    stack_leniency: f32,
    mode: Mode,
    letterbox_in_breaks: bool,
    widescreen_storyboard: bool,
}

#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct Editor {
    bookmarks: Vec<u32>,
    distance_spacing: f32,
    beat_divisor: u32,
    grid_size: u32,
    timeline_zoom: f32,
}

#[allow(non_snake_case)]
#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct Metadata {
    title: String,
    title_unicode: String,
    artist: String,
    artist_unicode: String,
    creator: String,
    version: String,
    source: String,
    tags: Vec<String>,
    beatmap_ID: u32,
    beatmap_set_ID: u32,
}

#[derive(Debug, PartialEq, Default, Serialize, StructMap)]
struct Difficulty {
    hp_drain_rate: f32,
    circle_size: f32,
    overall_difficulty: f32,
    approach_rate: f32,
    slider_multiplier: f32,
    slider_tickrate: f32,
}

#[derive(Debug, PartialEq, Default, Serialize)]
struct Events {
    background: String,
    video: String,
    //break_periods: Vec<u32>,
}

#[derive(Debug, PartialEq, Default, Serialize)]
struct TimingPoint {
    offset: u32,
    msec_per_beat: f32,
    meter: u32,
    sample_type: u32,
    sample_set: u32,
    volume: u32,
    inherited: bool,
    kiai_mode: bool,
}

#[derive(Debug, PartialEq, Default, Serialize)]
struct Colour {
    red: u8,
    green: u8,
    blue: u8,
}

impl Colour {
    fn from_vec(v: Vec<u32>) -> Colour {
        Colour { red: v[0] as u8, green: v[1] as u8, blue: v[2] as u8 }
    }
}

named!(comment<&str, Vec<()> >,
    many0!(do_parse!(tag!("//") >> take_until_and_consume_s!("\r\n") >> ()))
);

named!(key_value_pair<&str, (&str, &str)>,
    do_parse!(
           key: take_until_and_consume_s!(":")
        >>      opt!(multispace)
        >> val: take_until_and_consume_s!("\r\n")
        >> (key, val)
    )
);

macro_rules! named_section {
    ( $func:ident<$T:ty> ) => (
named!($func<&str, $T>,
        do_parse!(
                                tag_s!(concat!("[", stringify!($T), "]"))
           >>                   opt!(multispace)
           >> pairs_with_end:   many_till!(key_value_pair, line_ending)
           >> (StructMap::from_tuples(pairs_with_end.0))
          )
        );
    )
}

named_section!(section_general<General>);
named_section!(section_editor<Editor>);
named_section!(section_metadata<Metadata>);
named_section!(section_difficulty<Difficulty>);

named!(section_events<&str, Events>,
    do_parse!(
                    tag_s!("[Events]")
        >>          opt!(multispace)
        >>          comment
        >> bg_ev:   separated_list!(char!(','), take_until_either!(",\r"))
        >>          line_ending
        >>          comment
        >>          tag_s!("Video,")
        >> mov_ev:  separated_list!(char!(','), take_until_either!(",\r"))
        >>          line_ending
        >>          take_until_s!("[")
        >> (Events {
            background: if bg_ev.len() == 5 { bg_ev[2].trim_matches('"').to_owned() } else { "".to_owned() },
            video: if mov_ev.len() == 2 { mov_ev[1].trim_matches('"').to_owned() } else { "".to_owned() },
            ..Default::default()
        })
    )
);

named!(parse_timing_point<&str, TimingPoint>,
    do_parse!(
           line: separated_nonempty_list!(char!(','), take_until_either!(",\r"))
        >>       line_ending
        >> (TimingPoint {
                offset: FromStr::from_str(line[0]).unwrap(),
                msec_per_beat: FromStr::from_str(line[1]).unwrap(),
                meter: FromStr::from_str(line[2]).unwrap(),
                sample_type: FromStr::from_str(line[3]).unwrap(),
                sample_set: FromStr::from_str(line[4]).unwrap(),
                volume: FromStr::from_str(line[5]).unwrap(),
                inherited: u32::from_str(line[6]).unwrap() == 1,
                kiai_mode: u32::from_str(line[7]).unwrap() == 1,
        })
    )
);

named!(section_timing_points<&str, Vec<TimingPoint> >,
    do_parse!(
                            tag_s!("[TimingPoints]")
        >>                  opt!(multispace)
        >> tps_with_end:    many_till!(parse_timing_point, line_ending)
        >>                  take_until_s!("[")
        >> (tps_with_end.0)
    )
);

named!(parse_colour<&str, Colour>,
    do_parse!(
           pair:    key_value_pair
        >> (Colour::from_vec(FromStr::from_str(pair.1).unwrap()))
    )
);

named!(section_colours<&str, Vec<Colour> >,
    do_parse!(
                            tag_s!("[Colours]")
        >>                  opt!(multispace)
        >> cs_with_end:     many_till!(parse_colour, line_ending)
        >>                  take_until_s!("[")
        >> (cs_with_end.0)
    )
);

named!(parse_osu<&str, Osu>,
    do_parse!(
                    tag_s!("osu file format v")
    >>  version:    map_res!(digit, FromStr::from_str)
    >>              line_ending
    >>              opt!(multispace)
    >>  sections:   permutation!(call!(section_general),
                                 call!(section_editor),
                                 call!(section_metadata),
                                 call!(section_difficulty),
                                 call!(section_events),
                                 call!(section_timing_points),
                                 call!(section_colours)
                                 )
    >>  (Osu {
        version:        version,
        general:        sections.0,
        editor:         sections.1,
        metadata:       sections.2,
        difficulty:     sections.3,
        events:         sections.4,
        timing_points:  sections.5,
        colours:        sections.6,
        })
    )
);

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

    #[test]
    fn it_works() {
        let input = include_str!("../test.osu");
        let res = parse_osu(input);
        if let Done(_, osu) = res {
            println!("{:?}", osu);
            println!("{}", serde_json::to_string(&osu).unwrap());
        } else {
            println!("{:?}", res);
            assert!(false);
        }
    }
}
<|endoftext|>


<commit_before>use grid::{Grid, StaticGrid, IterGrid};
use math::{Dot, Vector2, Vector3};
use coord::Coord;

use rand::{Rng, StdRng, SeedableRng};

use std::fmt;
use std::io;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum PerlinWrapType {
    Repeat,
    Regenerate,
}

#[derive(Clone, Copy, Debug)]
struct PerlinVector(Vector3<f64>);

impl PerlinVector {
    fn new(rng: &mut StdRng) -> Self {
        // random number from 0 to 15
        let index = rng.gen::<usize>() & GRADIENT_MASK;
        PerlinVector(GRADIENTS[index].normalize())
    }
}

#[derive(Debug, Clone)]
struct PerlinSlice {
    grid: StaticGrid<PerlinVector>,
    z: f64,
}

impl PerlinSlice {
    fn reset(&mut self, rng: &mut StdRng) {
        for cell in self.grid.iter_mut() {
            *cell = PerlinVector::new(rng);
        }
    }
}

#[derive(Clone)]
pub struct PerlinGrid {
    slices: Vec<PerlinSlice>,
    grid_width: usize,
    grid_height: usize,
    z: f64,
    width: f64,
    height: f64,
    depth: f64,
    minor_offset: Vector2<f64>,
    major_offset: Vector2<usize>,
    wrap_type: PerlinWrapType,
    rng: StdRng,
}

const NUM_CORNERS: usize = 8;
const NUM_SLICE_CORNERS: usize = 4;
const NUM_SLICES: usize = 2;

pub fn ease_curve(x: f64) -> f64 {
    6.0 * x.powi(5) - 15.0 * x.powi(4) + 10.0 * x.powi(3)
}

impl PerlinGrid {
    pub fn new(width: usize, height: usize, wrap_type: PerlinWrapType) -> io::Result<Self> {
        let rng = try!(StdRng::new());
        Ok(PerlinGrid::new_with_rng(width, height, wrap_type, rng))
    }

    pub fn new_from_seed(width: usize,
                         height: usize,
                         wrap_type: PerlinWrapType,
                         seed: usize)
                         -> Self {
        let rng = StdRng::from_seed(&[seed]);
        PerlinGrid::new_with_rng(width, height, wrap_type, rng)
    }

    fn new_with_rng(width: usize,
                    height: usize,
                    wrap_type: PerlinWrapType,
                    mut rng: StdRng)
                    -> PerlinGrid {
        let grid_width = width + 2;
        let grid_height = height + 2;
        PerlinGrid {
            slices: {
                let mut v = Vec::with_capacity(NUM_SLICES);
                for i in 0..2 as isize {
                    v.push(PerlinSlice {
                        grid: StaticGrid::new_call(grid_width,
                                                   grid_height,
                                                   |_, _| PerlinVector::new(&mut rng)),
                        z: i as f64,
                    });
                }
                v
            },
            grid_width: grid_width,
            grid_height: grid_height,
            width: (width + 1) as f64,
            height: (height + 1) as f64,
            depth: 1.0,
            z: 0.0,
            minor_offset: Vector2::new(0.0, 0.0),
            major_offset: Vector2::new(0, 0),
            wrap_type: wrap_type,
            rng: rng,
        }
    }

    fn make_vector(&mut self) -> PerlinVector {
        PerlinVector::new(&mut self.rng)
    }

    fn swap_slices(&mut self) {
        self.slices.reverse();
        for (i, slice) in izip!(0..self.slices.len(), self.slices.iter_mut()) {
            slice.z = i as f64;
        }
    }

    pub fn mutate(&mut self, value: f64) {
        self.z += value;
        if self.z > 1.0 && self.z <= 2.0 {
            self.z -= 1.0;
            self.slices[0].reset(&mut self.rng);
            self.swap_slices();
        } else if self.z < 0.0 && self.z >= -1.0 {
            self.z += 1.0;
            self.slices[1].reset(&mut self.rng);
            self.swap_slices();
        } else if self.z > 2.0 || self.z < -1.0 {
            self.z = 0.0;
            for slice in self.slices.iter_mut() {
                slice.reset(&mut self.rng);
            }
        }
    }

    pub fn scroll(&mut self, x: f64, y: f64) {
        self.minor_offset.x += x;
        self.minor_offset.y += y;

        let floor_f = Vector2::new(self.minor_offset.x.floor(), self.minor_offset.y.floor());

        let floor_i = Vector2::new(floor_f.x as usize, floor_f.y as usize);

        if floor_i.x != 0 {
            if self.wrap_type == PerlinWrapType::Regenerate {
                if floor_i.x > 0 {
                    for i in (self.major_offset.x)..(self.major_offset.x + floor_i.x) {
                        let x = ((i + self.grid_width) % self.grid_width) as isize;
                        for j in 0..self.grid_height {
                            let coord = Coord::new(x, j as isize);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                } else {
                    for i in (self.major_offset.x + floor_i.x)..(self.major_offset.x) {
                        let x = ((i + self.grid_width) % self.grid_width) as isize;
                        for j in 0..self.grid_height {
                            let coord = Coord::new(x, j as isize);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                }
            }
            self.major_offset.x += floor_i.x;
            self.major_offset.x = (self.major_offset.x + self.grid_width) % self.grid_width;
        }

        if floor_i.y != 0 {
            if self.wrap_type == PerlinWrapType::Regenerate {
                if floor_i.y > 0 {
                    for i in (self.major_offset.y)..(self.major_offset.y + floor_i.y) {
                        let y = ((i + self.grid_height) % self.grid_height) as isize;
                        for j in 0..self.grid_width {
                            let coord = Coord::new(j as isize, y);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                } else {
                    for i in (self.major_offset.y + floor_i.y)..(self.major_offset.y) {
                        let y = ((i + self.grid_height) % self.grid_height) as isize;
                        for j in 0..self.grid_width {
                            let coord = Coord::new(j as isize, y);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                }
            }
            self.major_offset.y += floor_i.y;
            self.major_offset.y = (self.major_offset.y + self.grid_height) % self.grid_height;
        }

        self.minor_offset -= floor_f;

    }

    pub fn noise(&self, global_x: f64, global_y: f64) -> Option<f64> {
        assert!(self.z >= 0.0 && self.z <= self.depth);

        let x = global_x + self.minor_offset.x;
        let y = global_y + self.minor_offset.y;

        if x > self.width || y > self.height {
            return None;
        }

        let global_coord = Vector3::new(x, y, self.z);

        let top_left_f = Vector2::new(x.floor(), y.floor());
        let top_left_i = Vector2::<isize>::from(self.major_offset) +
                         Vector2::new(top_left_f.x as isize, top_left_f.y as isize);

        let mut corner_coords_i = [top_left_i,
                                   top_left_i + Vector2::new(1, 0),
                                   top_left_i + Vector2::new(0, 1),
                                   top_left_i + Vector2::new(1, 1)];

        for corner_coord_i in &mut corner_coords_i {
            corner_coord_i.x %= self.grid_width as isize;
            corner_coord_i.y %= self.grid_height as isize;
        }

        let corner_coords_f = [top_left_f,
                               top_left_f + Vector2::new(1.0, 0.0),
                               top_left_f + Vector2::new(0.0, 1.0),
                               top_left_f + Vector2::new(1.0, 1.0)];

        let mut dots: [f64; NUM_CORNERS] = [0.0; NUM_CORNERS];

        let mut i = 0;
        while i != NUM_CORNERS {
            let slice = &self.slices[i / NUM_SLICE_CORNERS];
            let corner_coord_i = corner_coords_i[i % NUM_SLICE_CORNERS];
            let corner_coord_f = corner_coords_f[i % NUM_SLICE_CORNERS];

            let gradient = unsafe { slice.grid.get_unchecked(corner_coord_i).0 };
            let corner_coord_f3 = Vector3::new(corner_coord_f.x, corner_coord_f.y, slice.z);
            let relative = global_coord - corner_coord_f3;
            dots[i] = gradient.dot(relative);

            i += 1;
        }

        let weight_x = ease_curve(x - top_left_f.x);
        let weight_y = ease_curve(y - top_left_f.y);
        let weight_z = ease_curve(self.z.fract());

        let square_avgs = [dots[0] + weight_z * (dots[4] - dots[0]),
                           dots[1] + weight_z * (dots[5] - dots[1]),
                           dots[2] + weight_z * (dots[6] - dots[2]),
                           dots[3] + weight_z * (dots[7] - dots[3])];

        let line_avgs = [square_avgs[0] + weight_x * (square_avgs[1] - square_avgs[0]),
                         square_avgs[2] + weight_x * (square_avgs[3] - square_avgs[2])];

        let avg = line_avgs[0] + weight_y * (line_avgs[1] - line_avgs[0]);

        Some(avg.max(-1.0).min(1.0))
    }
}

impl fmt::Debug for PerlinGrid {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "PerlinGrid")
    }
}

const NUM_GRADIENTS: usize = 16;
const GRADIENT_MASK: usize = 0xf;
static GRADIENTS: [Vector3<f64>; NUM_GRADIENTS] = [
    Vector3 {
        x: 1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: -1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: 1.0,
        y: -1.0,
        z: 0.0,
    },
    Vector3 {
        x: -1.0,
        y: -1.0,
        z: 0.0,
    },
    Vector3 {
        x: 1.0,
        y: 0.0,
        z: 1.0,
    },
    Vector3 {
        x: -1.0,
        y: 0.0,
        z: 1.0,
    },
    Vector3 {
        x: 1.0,
        y: 0.0,
        z: -1.0,
    },
    Vector3 {
        x: -1.0,
        y: 0.0,
        z: -1.0,
    },
    Vector3 {
        x: 0.0,
        y: 1.0,
        z: 1.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: 1.0,
    },
    Vector3 {
        x: 0.0,
        y: 1.0,
        z: -1.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: -1.0,
    },

    // repetition
    Vector3 {
        x: 1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: -1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: 1.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: -1.0,
    }
];
<commit_msg>Trivial: style<commit_after>use std::fmt;
use std::io;

use rand::{Rng, StdRng, SeedableRng};

use grid::{Grid, StaticGrid, IterGrid};
use math::{Dot, Vector2, Vector3};
use coord::Coord;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum PerlinWrapType {
    Repeat,
    Regenerate,
}

#[derive(Clone, Copy, Debug)]
struct PerlinVector(Vector3<f64>);

impl PerlinVector {
    fn new(rng: &mut StdRng) -> Self {
        // random number from 0 to 15
        let index = rng.gen::<usize>() & GRADIENT_MASK;
        PerlinVector(GRADIENTS[index].normalize())
    }
}

#[derive(Debug, Clone)]
struct PerlinSlice {
    grid: StaticGrid<PerlinVector>,
    z: f64,
}

impl PerlinSlice {
    fn reset(&mut self, rng: &mut StdRng) {
        for cell in self.grid.iter_mut() {
            *cell = PerlinVector::new(rng);
        }
    }
}

#[derive(Clone)]
pub struct PerlinGrid {
    slices: Vec<PerlinSlice>,
    grid_width: usize,
    grid_height: usize,
    z: f64,
    width: f64,
    height: f64,
    depth: f64,
    minor_offset: Vector2<f64>,
    major_offset: Vector2<usize>,
    wrap_type: PerlinWrapType,
    rng: StdRng,
}

const NUM_CORNERS: usize = 8;
const NUM_SLICE_CORNERS: usize = 4;
const NUM_SLICES: usize = 2;

pub fn ease_curve(x: f64) -> f64 {
    6.0 * x.powi(5) - 15.0 * x.powi(4) + 10.0 * x.powi(3)
}

impl PerlinGrid {
    pub fn new(width: usize, height: usize, wrap_type: PerlinWrapType) -> io::Result<Self> {
        let rng = try!(StdRng::new());
        Ok(PerlinGrid::new_with_rng(width, height, wrap_type, rng))
    }

    pub fn new_from_seed(width: usize,
                         height: usize,
                         wrap_type: PerlinWrapType,
                         seed: usize)
                         -> Self {
        let rng = StdRng::from_seed(&[seed]);
        PerlinGrid::new_with_rng(width, height, wrap_type, rng)
    }

    fn new_with_rng(width: usize,
                    height: usize,
                    wrap_type: PerlinWrapType,
                    mut rng: StdRng)
                    -> PerlinGrid {
        let grid_width = width + 2;
        let grid_height = height + 2;
        PerlinGrid {
            slices: {
                let mut v = Vec::with_capacity(NUM_SLICES);
                for i in 0..2 as isize {
                    v.push(PerlinSlice {
                        grid: StaticGrid::new_call(grid_width,
                                                   grid_height,
                                                   |_, _| PerlinVector::new(&mut rng)),
                        z: i as f64,
                    });
                }
                v
            },
            grid_width: grid_width,
            grid_height: grid_height,
            width: (width + 1) as f64,
            height: (height + 1) as f64,
            depth: 1.0,
            z: 0.0,
            minor_offset: Vector2::new(0.0, 0.0),
            major_offset: Vector2::new(0, 0),
            wrap_type: wrap_type,
            rng: rng,
        }
    }

    fn make_vector(&mut self) -> PerlinVector {
        PerlinVector::new(&mut self.rng)
    }

    fn swap_slices(&mut self) {
        self.slices.reverse();
        for (i, slice) in izip!(0..self.slices.len(), self.slices.iter_mut()) {
            slice.z = i as f64;
        }
    }

    pub fn mutate(&mut self, value: f64) {
        self.z += value;
        if self.z > 1.0 && self.z <= 2.0 {
            self.z -= 1.0;
            self.slices[0].reset(&mut self.rng);
            self.swap_slices();
        } else if self.z < 0.0 && self.z >= -1.0 {
            self.z += 1.0;
            self.slices[1].reset(&mut self.rng);
            self.swap_slices();
        } else if self.z > 2.0 || self.z < -1.0 {
            self.z = 0.0;
            for slice in self.slices.iter_mut() {
                slice.reset(&mut self.rng);
            }
        }
    }

    pub fn scroll(&mut self, x: f64, y: f64) {
        self.minor_offset.x += x;
        self.minor_offset.y += y;

        let floor_f = Vector2::new(self.minor_offset.x.floor(), self.minor_offset.y.floor());

        let floor_i = Vector2::new(floor_f.x as usize, floor_f.y as usize);

        if floor_i.x != 0 {
            if self.wrap_type == PerlinWrapType::Regenerate {
                if floor_i.x > 0 {
                    for i in (self.major_offset.x)..(self.major_offset.x + floor_i.x) {
                        let x = ((i + self.grid_width) % self.grid_width) as isize;
                        for j in 0..self.grid_height {
                            let coord = Coord::new(x, j as isize);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                } else {
                    for i in (self.major_offset.x + floor_i.x)..(self.major_offset.x) {
                        let x = ((i + self.grid_width) % self.grid_width) as isize;
                        for j in 0..self.grid_height {
                            let coord = Coord::new(x, j as isize);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                }
            }
            self.major_offset.x += floor_i.x;
            self.major_offset.x = (self.major_offset.x + self.grid_width) % self.grid_width;
        }

        if floor_i.y != 0 {
            if self.wrap_type == PerlinWrapType::Regenerate {
                if floor_i.y > 0 {
                    for i in (self.major_offset.y)..(self.major_offset.y + floor_i.y) {
                        let y = ((i + self.grid_height) % self.grid_height) as isize;
                        for j in 0..self.grid_width {
                            let coord = Coord::new(j as isize, y);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                } else {
                    for i in (self.major_offset.y + floor_i.y)..(self.major_offset.y) {
                        let y = ((i + self.grid_height) % self.grid_height) as isize;
                        for j in 0..self.grid_width {
                            let coord = Coord::new(j as isize, y);
                            unsafe {
                                for z in 0..NUM_SLICES {
                                    *self.slices[z].grid.get_unchecked_mut(coord) = self.make_vector();
                                }
                            }
                        }
                    }
                }
            }
            self.major_offset.y += floor_i.y;
            self.major_offset.y = (self.major_offset.y + self.grid_height) % self.grid_height;
        }

        self.minor_offset -= floor_f;

    }

    pub fn noise(&self, global_x: f64, global_y: f64) -> Option<f64> {
        assert!(self.z >= 0.0 && self.z <= self.depth);

        let x = global_x + self.minor_offset.x;
        let y = global_y + self.minor_offset.y;

        if x > self.width || y > self.height {
            return None;
        }

        let global_coord = Vector3::new(x, y, self.z);

        let top_left_f = Vector2::new(x.floor(), y.floor());
        let top_left_i = Vector2::<isize>::from(self.major_offset) +
                         Vector2::new(top_left_f.x as isize, top_left_f.y as isize);

        let mut corner_coords_i = [top_left_i,
                                   top_left_i + Vector2::new(1, 0),
                                   top_left_i + Vector2::new(0, 1),
                                   top_left_i + Vector2::new(1, 1)];

        for corner_coord_i in &mut corner_coords_i {
            corner_coord_i.x %= self.grid_width as isize;
            corner_coord_i.y %= self.grid_height as isize;
        }

        let corner_coords_f = [top_left_f,
                               top_left_f + Vector2::new(1.0, 0.0),
                               top_left_f + Vector2::new(0.0, 1.0),
                               top_left_f + Vector2::new(1.0, 1.0)];

        let mut dots: [f64; NUM_CORNERS] = [0.0; NUM_CORNERS];

        let mut i = 0;
        while i != NUM_CORNERS {
            let slice = &self.slices[i / NUM_SLICE_CORNERS];
            let corner_coord_i = corner_coords_i[i % NUM_SLICE_CORNERS];
            let corner_coord_f = corner_coords_f[i % NUM_SLICE_CORNERS];

            let gradient = unsafe { slice.grid.get_unchecked(corner_coord_i).0 };
            let corner_coord_f3 = Vector3::new(corner_coord_f.x, corner_coord_f.y, slice.z);
            let relative = global_coord - corner_coord_f3;
            dots[i] = gradient.dot(relative);

            i += 1;
        }

        let weight_x = ease_curve(x - top_left_f.x);
        let weight_y = ease_curve(y - top_left_f.y);
        let weight_z = ease_curve(self.z.fract());

        let square_avgs = [dots[0] + weight_z * (dots[4] - dots[0]),
                           dots[1] + weight_z * (dots[5] - dots[1]),
                           dots[2] + weight_z * (dots[6] - dots[2]),
                           dots[3] + weight_z * (dots[7] - dots[3])];

        let line_avgs = [square_avgs[0] + weight_x * (square_avgs[1] - square_avgs[0]),
                         square_avgs[2] + weight_x * (square_avgs[3] - square_avgs[2])];

        let avg = line_avgs[0] + weight_y * (line_avgs[1] - line_avgs[0]);

        Some(avg.max(-1.0).min(1.0))
    }
}

impl fmt::Debug for PerlinGrid {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "PerlinGrid")
    }
}

const NUM_GRADIENTS: usize = 16;
const GRADIENT_MASK: usize = 0xf;
static GRADIENTS: [Vector3<f64>; NUM_GRADIENTS] = [
    Vector3 {
        x: 1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: -1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: 1.0,
        y: -1.0,
        z: 0.0,
    },
    Vector3 {
        x: -1.0,
        y: -1.0,
        z: 0.0,
    },
    Vector3 {
        x: 1.0,
        y: 0.0,
        z: 1.0,
    },
    Vector3 {
        x: -1.0,
        y: 0.0,
        z: 1.0,
    },
    Vector3 {
        x: 1.0,
        y: 0.0,
        z: -1.0,
    },
    Vector3 {
        x: -1.0,
        y: 0.0,
        z: -1.0,
    },
    Vector3 {
        x: 0.0,
        y: 1.0,
        z: 1.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: 1.0,
    },
    Vector3 {
        x: 0.0,
        y: 1.0,
        z: -1.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: -1.0,
    },

    // repetition
    Vector3 {
        x: 1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: -1.0,
        y: 1.0,
        z: 0.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: 1.0,
    },
    Vector3 {
        x: 0.0,
        y: -1.0,
        z: -1.0,
    }
];
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A library for storing viewport information

extern crate float;

use float::*;

/// Stores viewport information.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Viewport {
    /// Viewport in pixels.
    /// ```[x, y, width height]``` where ```(x, y)``` is lower left corner.
    pub rect: [i32; 4],
    /// The size of frame buffer in pixels.
    pub draw_size: [u32; 2],
    /// The size of window in points.
    pub window_size: [u32; 2],
}

impl Viewport {
    /// Computes absolute transform for 2D graphics,
    /// which uses a row major 2x3 matrix.
    ////
    /// The origin is in the upper left corner of the viewport rectangle.
    /// The x axis points to the right, and the y axis points down.
    /// The units are in points (window coordinates).
    ///
    /// It is assumed that the underlying coordinate system is normalized
    /// with the origin in the center, such that ```(-1.0, 1.0)``` in the
    /// underlying coordinate system corresponds to the
    /// upper left corner of the viewport.
    pub fn abs_transform<T: Float>(&self) -> [[T; 3]; 2] {
        let (dw, dh) = (self.draw_size[0] as f64, self.draw_size[1] as f64);
        let (ww, wh) = (self.window_size[0] as f64, self.window_size[1] as f64);
        let sx = 2.0 * (dw / ww) / self.rect[2] as f64;
        let sy = -2.0 * (dh / wh) / self.rect[3] as f64;
        let f = |x| FromPrimitive::from_f64(x);
        [
            [f(sx), f(0.0), f(-1.0)],
            [f(0.0), f(sy), f(1.0)]
        ]
    }
}

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

    #[test]
    fn abs() {
        let transform = |mat: [[f64; 3]; 2], (px, py)| -> (f64, f64) {
            (mat[0][0] * px + mat[0][1] * py + mat[0][2],
            mat[1][0] * px + mat[1][1] * py + mat[1][2])
         };

        let viewport = Viewport {
            rect: [0, 0, 100, 200],
            draw_size: [100, 200],
            window_size: [100, 200],
        };
        let abs = viewport.abs_transform();
        assert_eq!(abs, [
                [0.02, 0.0, -1.0],
                [0.0, -0.01, 1.0]
            ]);
        assert_eq!(transform(abs, (0.0, 0.0)), (-1.0, 1.0));
        assert_eq!(transform(abs, (50.0, 100.0)), (0.0, 0.0));
        assert_eq!(transform(abs, (100.0, 200.0)), (1.0, -1.0));

        let viewport = Viewport {
            rect: [10, 10, 80, 80],
            draw_size: [100, 100],
            window_size: [50, 50],
        };
        let abs = viewport.abs_transform();
        assert_eq!(abs, [
                [0.05, 0.0, -1.0],
                [0.0, -0.05, 1.0]
            ]);
        assert_eq!(transform(abs, (0.0, 0.0)), (-1.0, 1.0));
        // The viewport size is 80 pixels, 40 points, therefore center is 20.
        assert_eq!(transform(abs, (20.0, 20.0)), (0.0, 0.0));
        assert_eq!(transform(abs, (40.0, 40.0)), (1.0, -1.0));
    }
}
<commit_msg>Change `window_size` to `[f64; 2]`<commit_after>#![deny(missing_docs)]

//! A library for storing viewport information

extern crate float;

use float::*;

/// Stores viewport information.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Viewport {
    /// Viewport in pixels.
    /// ```[x, y, width height]``` where ```(x, y)``` is lower left corner.
    pub rect: [i32; 4],
    /// The size of frame buffer in pixels.
    pub draw_size: [u32; 2],
    /// The size of window in points.
    pub window_size: [f64; 2],
}

impl Viewport {
    /// Computes absolute transform for 2D graphics,
    /// which uses a row major 2x3 matrix.
    ////
    /// The origin is in the upper left corner of the viewport rectangle.
    /// The x axis points to the right, and the y axis points down.
    /// The units are in points (window coordinates).
    ///
    /// It is assumed that the underlying coordinate system is normalized
    /// with the origin in the center, such that ```(-1.0, 1.0)``` in the
    /// underlying coordinate system corresponds to the
    /// upper left corner of the viewport.
    pub fn abs_transform<T: Float>(&self) -> [[T; 3]; 2] {
        let (dw, dh) = (self.draw_size[0] as f64, self.draw_size[1] as f64);
        let sx = 2.0 * (dw / self.window_size[0]) / self.rect[2] as f64;
        let sy = -2.0 * (dh / self.window_size[1]) / self.rect[3] as f64;
        let f = |x| FromPrimitive::from_f64(x);
        [
            [f(sx), f(0.0), f(-1.0)],
            [f(0.0), f(sy), f(1.0)]
        ]
    }
}

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

    #[test]
    fn abs() {
        let transform = |mat: [[f64; 3]; 2], (px, py)| -> (f64, f64) {
            (mat[0][0] * px + mat[0][1] * py + mat[0][2],
            mat[1][0] * px + mat[1][1] * py + mat[1][2])
         };

        let viewport = Viewport {
            rect: [0, 0, 100, 200],
            draw_size: [100, 200],
            window_size: [100.0, 200.0],
        };
        let abs = viewport.abs_transform();
        assert_eq!(abs, [
                [0.02, 0.0, -1.0],
                [0.0, -0.01, 1.0]
            ]);
        assert_eq!(transform(abs, (0.0, 0.0)), (-1.0, 1.0));
        assert_eq!(transform(abs, (50.0, 100.0)), (0.0, 0.0));
        assert_eq!(transform(abs, (100.0, 200.0)), (1.0, -1.0));

        let viewport = Viewport {
            rect: [10, 10, 80, 80],
            draw_size: [100, 100],
            window_size: [50.0, 50.0],
        };
        let abs = viewport.abs_transform();
        assert_eq!(abs, [
                [0.05, 0.0, -1.0],
                [0.0, -0.05, 1.0]
            ]);
        assert_eq!(transform(abs, (0.0, 0.0)), (-1.0, 1.0));
        // The viewport size is 80 pixels, 40 points, therefore center is 20.
        assert_eq!(transform(abs, (20.0, 20.0)), (0.0, 0.0));
        assert_eq!(transform(abs, (40.0, 40.0)), (1.0, -1.0));
    }
}
<|endoftext|>