<commit_before>extern crate rand;

#[macro_use]
extern crate lazy_static;

use rand::{XorShiftRng, Rng, thread_rng, SeedableRng};
use std::fmt;
use std::fmt::{Formatter, Debug};
use std::sync::Mutex;

trait Specimen: Sized {
    fn score(&self) -> f32;
    fn reevaluate(&mut self);
    fn mutate(generation: &mut[Self], rng: &mut XorShiftRng);
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self;
    fn filter_strongest(species: &mut Vec<Self>);

    fn initial() -> Vec<Self>;
}

fn genetic<S: Specimen>(threshold: f32, max_iters: usize, nparents: usize, nchildren: usize) -> S {
    let mut species: Vec<S> = S::initial();
    let mut best = (0f32, 0);
    for _ in 0..max_iters {
        species = next_gen(species, nparents, nchildren);

        for (i, specimen) in species.iter().enumerate() {
            let score = specimen.score();
            if best.0 <= score {
                best = (score, i)
            }
        }

        if best.0 >= threshold {
            println!("found!");
            break;
        }
    }

    species.swap_remove(best.1)
}

#[inline(never)]
fn next_gen<S: Specimen>(mut species: Vec<S>, nparents: usize, nchildren: usize) -> Vec<S> {
    let mut rng = RNG.lock().unwrap();

    // 1. filter strongest
    S::filter_strongest(&mut species);

    // 2. bear children
    let mut children = vec![];
    let mut family = vec![];
    for _ in 0..nchildren {
        make_family(&mut species, nparents, &mut family, &mut rng);
        let child = S::breed(&family, &mut rng);
        children.push(child);
        species.extend(family.drain(..));
    }

    // 3. mutate
    S::mutate(&mut children, &mut rng);
    for child in children.iter_mut() {
        child.reevaluate();
    }

    if KILL_PARENTS {
        children
    } else {
        species.extend(children);
        species
    }
}

fn make_family<S: Specimen>(species: &mut Vec<S>, nparents: usize, family: &mut Vec<S>, rng: &mut XorShiftRng) {
    assert!(family.is_empty());
    for _ in 0..nparents {
        let next = rng.gen_range(0, species.len());
        let s = species.swap_remove(next);
        family.push(s);
    }
}

//---------------------------------------------------

// BEST FOR SIZE=1000
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 1000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 2;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 355;
const KILL_PARENTS: bool = true;
const SIZE: usize = 1000;
const MUTATION_PROBABILITY: f32 = 1.0f32;
const POPULATION: usize = 4;
const MAX_ITERS: usize = 5000;
const NPARENTS: usize = 2;
//const NCHILDREN: usize = 250;
const NCHILDREN: usize = 110;

//
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 10000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 20;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 1000;

lazy_static! {
    static ref RNG: Mutex<XorShiftRng> = Mutex::new(XorShiftRng::new_unseeded());
}

struct Board {
    score: f32,
    queens: Vec<usize>,
}

impl Board {
    fn new(queens: Vec<usize>) -> Board {
        Board { score: 0f32, queens: queens }
    }

    #[inline(never)]
    fn do_mutate(&mut self, rng: &mut XorShiftRng) {
        let i = rng.gen_range(0, SIZE);
        let mut j = rng.gen_range(0, SIZE-1);

        if j >= i {
            j += 1;
        }

        let t = self.queens[i];
        self.queens[i] = self.queens[j];
        self.queens[j] = t;
    }

//    fn breed_pmx_norng(parents: &[Self], rng: &mut XorShiftRng) -> Self {
//        let mut child = Board::new(parents[0].queens.clone());
//
//        // it turns out this check makes the code run 3x faster, because the compiler is able to generate more efficient code
//        // alternatively, we could assert!(parents.len() == NPARENTS)
//        if parents.len() != NPARENTS {
//            // we need a function to put #[cold] annotation on
//            #[cold] fn noop() {}
//            noop();
//            return child;
//        }
//
//        let mut inverse = vec![0; SIZE];
//        for i in 0..SIZE {
//            let y = child.queens[i];
//            inverse[y] = i;
//        }
//
//        let mut x = rng.gen_range(0, SIZE);
//        for _ in 0..SIZE/2 {
//            x += 1;
//            if x == SIZE {
//                x = 0;
//            }
////            let parent = rng.gen_range(0, parents.len());
//            let parent = 1;
//            if parent != 0 {
//                let mother_y = child.queens[x];
//                let father_y = parents[parent].queens[x];
//                let father_x = inverse[father_y];
//                child.queens[father_x] = mother_y;
//                child.queens[x] = father_y;
//                inverse[mother_y] = father_x;
//                if NPARENTS > 2 { // Optimization: this is not required when NPARENTS==2
//                    inverse[father_y] = x;
//                }
//            }
//        }
//
//        child
//    }

    // The algorithm is described in "Genetic Algorithm Solution of the TSP Avoiding Special Crossover and Mutation"
    // http://user.ceng.metu.edu.tr/~ucoluk/research/publications/tspnew.pdf
    #[inline(never)]
    fn breed_pmx(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        let mut child = Board::new(parents[0].queens.clone());
        {
            let mut inverse = vec![0; SIZE];
            let cq = &mut child.queens;
            for i in 0..SIZE {
                let y = cq[i];
                inverse[y] = i;
            }

            for x in 0..SIZE {
                let parent = rng.gen_range(0, parents.len());
                if parent == 1 {
                    let mother_y = cq[x];
                    let father_y = parents[parent].queens[x];
                    let father_x = inverse[father_y];
                    cq[father_x] = mother_y;
                    cq[x] = father_y;
                    inverse[mother_y] = father_x;
                    if NPARENTS > 2 { // Optimization: this is not required when NPARENTS==2
                        inverse[father_y] = x;
                    }
                }
            }
        }

        child
    }

//    fn permutation_valid(p: &[usize]) -> bool {
//        let mut used = vec![0; p.len()];
//        for &i in p.iter() {
//            used[i] = 1;
//        }
//        for &u in used.iter() {
//            if u != 1 {
//                return false;
//            }
//        }
//
//        true
//    }
}

impl Specimen for Board {
    #[inline(never)]
    fn reevaluate(&mut self) {
        let mut occurences = vec![0; 2*SIZE-1];
        let mut nonconflicting = Vec::with_capacity(SIZE);

        for x in 0..SIZE {
            let d = SIZE-1 + x - self.queens[x];
            occurences[d] += 1;
        }
        for x in 0..SIZE {
            let d = SIZE-1 + x - self.queens[x];
            if occurences[d] == 1 {
                nonconflicting.push(x);
            }
        }

        // backward diagonals
        for y in 0..2*SIZE-1 {
            occurences[y] = 0;
        }
        for x in 0..SIZE {
            let d = x + self.queens[x];
            occurences[d] += 1;
        }

        let mut s = 0;
        for x in nonconflicting {
            let d = x + self.queens[x];
            if occurences[d] == 1 {
                s += 1;
            }
        }

        self.score = s as f32 + 0.000001;
    }

    fn score(&self) -> f32 {
        self.score
    }

    #[inline(never)]
    fn mutate(new_gen: &mut [Self], rng: &mut XorShiftRng) {
        for board in new_gen.iter_mut() {
            if rng.next_f32() < MUTATION_PROBABILITY {
                board.do_mutate(rng);
            }
        }
    }

    #[inline(never)]
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        Self::breed_pmx(parents, rng)
//        Self::breed_pmx_norng(parents, rng)
    }

    #[inline(never)]
    fn filter_strongest(species: &mut Vec<Self>) {
        if species.len() <= POPULATION {
            return;
        }

        species.sort_by(|s, t| t.score.partial_cmp(&s.score).unwrap());
        species.truncate(POPULATION);
    }

    #[inline(never)]
    fn initial() -> Vec<Self> {
        let mut boards = Vec::with_capacity(POPULATION);

        let mut ys = Vec::with_capacity(SIZE);

        let mut rng = RNG.lock().unwrap();
        for _ in 0..POPULATION {
            let mut board = Board::new(Vec::with_capacity(SIZE));

            for y in 0..SIZE {
                ys.push(y);
            }

            for _ in 0..SIZE {
                let z = rng.gen_range(0, ys.len());
                let y = ys.swap_remove(z);
                board.queens.push(y);
            }

            board.reevaluate();
            boards.push(board);
        }
        boards
    }
}

impl Debug for Board {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "score={}, queens=[{:?}]", self.score, self.queens)
    }
}

fn genetic_queens() {
    {
        let mut rng = RNG.lock().unwrap();
        let mut trng = thread_rng();
        rng.reseed([trng.next_u32(), trng.next_u32(), trng.next_u32(), trng.next_u32()]);
    }

    let best = genetic::<Board>(SIZE as f32, MAX_ITERS, NPARENTS, NCHILDREN);
    println!("best: {:?}", &best);
}

fn main() {
    for _ in 0..10 {
        genetic_queens()
    }
}

<commit_msg>slight optimizations<commit_after>extern crate rand;

#[macro_use]
extern crate lazy_static;

use rand::{XorShiftRng, Rng, thread_rng, SeedableRng};
use std::fmt;
use std::fmt::{Formatter, Debug};
use std::sync::Mutex;

trait Specimen: Sized {
    fn score(&self) -> f32;
    fn reevaluate(&mut self);
    fn mutate(generation: &mut[Self], rng: &mut XorShiftRng);
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self;
    fn filter_strongest(species: &mut Vec<Self>);

    fn initial() -> Vec<Self>;
}

fn genetic<S: Specimen>(threshold: f32, max_iters: usize, nparents: usize, nchildren: usize) -> S {
    let mut species: Vec<S> = S::initial();
    let mut best = (0f32, 0);
    for _ in 0..max_iters {
        species = next_gen(species, nparents, nchildren);

        for (i, specimen) in species.iter().enumerate() {
            let score = specimen.score();
            if best.0 <= score {
                best = (score, i)
            }
        }

        if best.0 >= threshold {
            println!("found!");
            break;
        }
    }

    species.swap_remove(best.1)
}

#[inline(never)]
fn next_gen<S: Specimen>(mut species: Vec<S>, nparents: usize, nchildren: usize) -> Vec<S> {
    let mut rng = RNG.lock().unwrap();

    // 1. filter strongest
    S::filter_strongest(&mut species);

    // 2. bear children
    let mut children = vec![];
    let mut family = vec![];
    for _ in 0..nchildren {
        make_family(&mut species, nparents, &mut family, &mut rng);
        let child = S::breed(&family, &mut rng);
        children.push(child);
        species.extend(family.drain(..));
    }

    // 3. mutate
    S::mutate(&mut children, &mut rng);
    for child in children.iter_mut() {
        child.reevaluate();
    }

    if KILL_PARENTS {
        children
    } else {
        species.extend(children);
        species
    }
}

fn make_family<S: Specimen>(species: &mut Vec<S>, nparents: usize, family: &mut Vec<S>, rng: &mut XorShiftRng) {
    assert!(family.is_empty());
    for _ in 0..nparents {
        let next = rng.gen_range(0, species.len());
        let s = species.swap_remove(next);
        family.push(s);
    }
}

//---------------------------------------------------

// BEST FOR SIZE=1000
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 1000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 2;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 355;
const KILL_PARENTS: bool = true;
const SIZE: usize = 1000;
const MUTATION_PROBABILITY: f32 = 1.0f32;
const ELITE: usize = 4;
const MAX_ITERS: usize = 5000;
const NPARENTS: usize = 2;
const NCHILDREN: usize = 250;
//const NCHILDREN: usize = 110;

//
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 10000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 20;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 1000;

lazy_static! {
    static ref RNG: Mutex<XorShiftRng> = Mutex::new(XorShiftRng::new_unseeded());
}

struct Board {
    score: f32,
    queens: Vec<usize>,
}

impl Board {
    fn new(queens: Vec<usize>) -> Board {
        Board { score: 0f32, queens: queens }
    }

    #[inline(never)]
    fn do_mutate(&mut self, rng: &mut XorShiftRng) {
        let i = rng.gen_range(0, SIZE);
        let mut j = rng.gen_range(0, SIZE-1);

        if j >= i {
            j += 1;
        }

        let t = self.queens[i];
        self.queens[i] = self.queens[j];
        self.queens[j] = t;
    }

    fn breed_pmx_norng(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        let mut child = Board::new(parents[0].queens.clone());

        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        {
            let cq: &mut [usize] = &mut child.queens;
            let mut inverse = vec![0; SIZE];
            for i in 0..SIZE {
                let y = cq[i];
                inverse[y] = i;
            }

            let mut x = rng.gen_range(0, SIZE);
            for _ in 0..SIZE/2 {
                x += 1;
                if x == SIZE {
                    x = 0;
                }

                let parent = 1;
                let mother_y = cq[x];
                let father_y = parents[parent].queens[x];
                let father_x = inverse[father_y];
                cq[father_x] = mother_y;
                cq[x] = father_y;
                inverse[mother_y] = father_x;
                if NPARENTS > 2 {
                    // Optimization: this is not required when NPARENTS==2
                    inverse[father_y] = x;
                }
            }
        }

        child
    }

    // The algorithm is described in "Genetic Algorithm Solution of the TSP Avoiding Special Crossover and Mutation"
    // http://user.ceng.metu.edu.tr/~ucoluk/research/publications/tspnew.pdf
    #[inline(never)]
    fn breed_pmx(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        let mut child = Board::new(parents[0].queens.clone());
        {
            let mut inverse = vec![0; SIZE];
            let cq = &mut child.queens;
            for i in 0..SIZE {
                let y = cq[i];
                inverse[y] = i;
            }

            for x in 0..SIZE {
                let parent = rng.gen_range(0, parents.len());
                if parent == 1 {
                    let mother_y = cq[x];
                    let father_y = parents[parent].queens[x];
                    let father_x = inverse[father_y];
                    cq[father_x] = mother_y;
                    cq[x] = father_y;
                    inverse[mother_y] = father_x;
                    if NPARENTS > 2 { // Optimization: this is not required when NPARENTS==2
                        inverse[father_y] = x;
                    }
                }
            }
        }

        child
    }

//    fn permutation_valid(p: &[usize]) -> bool {
//        let mut used = vec![0; p.len()];
//        for &i in p.iter() {
//            used[i] = 1;
//        }
//        for &u in used.iter() {
//            if u != 1 {
//                return false;
//            }
//        }
//
//        true
//    }
}

impl Specimen for Board {
    #[inline(never)]
    fn reevaluate(&mut self) {
        let q: &[usize] = &self.queens;
        let mut diag_counts = vec![0; 4*SIZE-2];
        let (diag_counts1, diag_counts2) = diag_counts.split_at_mut(2*SIZE-1);
        for x in 0..SIZE {
            let d1 = SIZE-1 + x - q[x];
            let d2 = x + q[x];
            diag_counts1[d1] += 1;
            diag_counts2[d2] += 1;
        }

        let mut s = 0;
        for x in 0..SIZE {
            let d1 = SIZE-1 + x - q[x];
            let d2 = x + q[x];
            if diag_counts1[d1] == 1 && diag_counts2[d2] == 1 {
                s += 1;
            }
        }

        self.score = s as f32 + 0.000001;
    }

    fn score(&self) -> f32 {
        self.score
    }

    #[inline(never)]
    fn mutate(new_gen: &mut [Self], rng: &mut XorShiftRng) {
        for board in new_gen.iter_mut() {
            if rng.next_f32() < MUTATION_PROBABILITY {
                board.do_mutate(rng);
            }
        }
    }

    #[inline(never)]
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self {
//        Self::breed_pmx(parents, rng)
        Self::breed_pmx_norng(parents, rng)
    }

    #[inline(never)]
    fn filter_strongest(species: &mut Vec<Self>) {
        if species.len() <= ELITE {
            return;
        }

        species.sort_by(|s, t| t.score.partial_cmp(&s.score).unwrap());
        species.truncate(ELITE);
    }

    #[inline(never)]
    fn initial() -> Vec<Self> {
        let mut boards = Vec::with_capacity(NCHILDREN);

        let mut ys = Vec::with_capacity(SIZE);

        let mut rng = RNG.lock().unwrap();
        for _ in 0..NCHILDREN {
            let mut board = Board::new(Vec::with_capacity(SIZE));

            for y in 0..SIZE {
                ys.push(y);
            }

            for _ in 0..SIZE {
                let z = rng.gen_range(0, ys.len());
                let y = ys.swap_remove(z);
                board.queens.push(y);
            }

            board.reevaluate();
            boards.push(board);
        }
        boards
    }
}

impl Debug for Board {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "score={}, queens=[{:?}]", self.score, self.queens)
    }
}

fn genetic_queens() {
    {
        let mut rng = RNG.lock().unwrap();
        let mut trng = thread_rng();
        rng.reseed([trng.next_u32(), trng.next_u32(), trng.next_u32(), trng.next_u32()]);
    }

    let best = genetic::<Board>(SIZE as f32, MAX_ITERS, NPARENTS, NCHILDREN);
    println!("best: {:?}", &best);
}

fn main() {
    for _ in 0..10 {
        genetic_queens()
    }
}

<|endoftext|>


<commit_before>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate ogg;
extern crate oven;
extern crate params;
extern crate regex;
extern crate rustc_serialize;
extern crate staticfile;
extern crate sqlite;
extern crate toml;
extern crate url;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::Arc;

mod api;
mod collection;
mod config;
mod ddns;
mod errors;
mod index;
mod metadata;
mod ui;
mod utils;
mod thumbnails;
mod vfs;

fn main() {
    if let Err(ref e) = run() {
        println!("Error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }
        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }
        ::std::process::exit(1);
    }
}

fn run() -> Result<()> {

    // Parse CLI options
    let args: Vec<String> = std::env::args().collect();
    let mut options = Options::new();
    options.optopt("c", "config", "set the configuration file", "FILE");
    let matches = match options.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };
    let config_file_name = matches.opt_str("c");
    let config_file_path = config_file_name.map(|n| Path::new(n.as_str()).to_path_buf());

    // Parse config
    let config = config::Config::parse(config_file_path)?;

    // Init VFS
    let vfs = Arc::new(vfs::Vfs::new(config.vfs.clone()));

    // Init index
    println!("Starting up index");
    let index = Arc::new(index::Index::new(vfs.clone(), &config.index).unwrap());
    let index_ref = index.clone();
    std::thread::spawn(move || index_ref.run());

    // Start server
    println!("Starting up server");
    let mut api_chain;
    {
        let api_handler;
        {
            let mut collection = collection::Collection::new(vfs, index);
            collection.load_config(&config).unwrap();
            let collection = Arc::new(collection);
            api_handler = api::get_api_handler(collection);
        }
        api_chain = Chain::new(api_handler);

        let auth_secret = config.secret.to_owned();
        let cookie_middleware = oven::new(auth_secret.into_bytes());
        api_chain.link(cookie_middleware);
    }

    let mut mount = Mount::new();
    mount.mount("/api/", api_chain);
    mount.mount("/", Static::new(Path::new("web")));
    let mut server = Iron::new(mount).http(("0.0.0.0", 5050))?;

    // Start DDNS updates
    match config.ddns {
        Some(ref ddns_config) => {
            let ddns_config = ddns_config.clone();
            std::thread::spawn(|| {
                ddns::run(ddns_config);
            });
        }
        None => (),
    };

    // Run UI
    ui::run();

    println!("Shutting down server");
    server.close().unwrap();

    Ok(())
}
<commit_msg>No longer panic on startup/shutdown errors<commit_after>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate ogg;
extern crate oven;
extern crate params;
extern crate regex;
extern crate rustc_serialize;
extern crate staticfile;
extern crate sqlite;
extern crate toml;
extern crate url;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::Arc;

mod api;
mod collection;
mod config;
mod ddns;
mod errors;
mod index;
mod metadata;
mod ui;
mod utils;
mod thumbnails;
mod vfs;

fn main() {
    if let Err(ref e) = run() {
        println!("Error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }
        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }
        ::std::process::exit(1);
    }
}

fn run() -> Result<()> {

    // Parse CLI options
    let args: Vec<String> = std::env::args().collect();
    let mut options = Options::new();
    options.optopt("c", "config", "set the configuration file", "FILE");
    let matches = match options.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };
    let config_file_name = matches.opt_str("c");
    let config_file_path = config_file_name.map(|n| Path::new(n.as_str()).to_path_buf());

    // Parse config
    let config = config::Config::parse(config_file_path)?;

    // Init VFS
    let vfs = Arc::new(vfs::Vfs::new(config.vfs.clone()));

    // Init index
    println!("Starting up index");
    let index = Arc::new(index::Index::new(vfs.clone(), &config.index)?);
    let index_ref = index.clone();
    std::thread::spawn(move || index_ref.run());

    // Start server
    println!("Starting up server");
    let mut api_chain;
    {
        let api_handler;
        {
            let mut collection = collection::Collection::new(vfs, index);
            collection.load_config(&config)?;
            let collection = Arc::new(collection);
            api_handler = api::get_api_handler(collection);
        }
        api_chain = Chain::new(api_handler);

        let auth_secret = config.secret.to_owned();
        let cookie_middleware = oven::new(auth_secret.into_bytes());
        api_chain.link(cookie_middleware);
    }

    let mut mount = Mount::new();
    mount.mount("/api/", api_chain);
    mount.mount("/", Static::new(Path::new("web")));
    let mut server = Iron::new(mount).http(("0.0.0.0", 5050))?;

    // Start DDNS updates
    match config.ddns {
        Some(ref ddns_config) => {
            let ddns_config = ddns_config.clone();
            std::thread::spawn(|| {
                ddns::run(ddns_config);
            });
        }
        None => (),
    };

    // Run UI
    ui::run();

    println!("Shutting down server");
    server.close()?;

    Ok(())
}
<|endoftext|>


<commit_before>extern crate rand;

use rand::Rng;
use rand::distributions;
use individual::Individual;

mod individual;

fn select<R: Rng>(population: &Vec<Individual>, rng: &mut R)
                  -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

fn main() {
    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-512.03_f64, 511.97);

    // initialize population
    let mut population: Vec<_> = (0..128).map(|_| {
        Individual::new(&range, &mut rng)
    }).collect();

    for i in 0..10000 {
        // select, mutate, and recombine individuals for next population
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in (0..population.len()/2) {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());
        population = offspring;

        if let Some(x) = population.iter().min() {
            if i % 100 == 0 {
                println!("{}th fitness: {}", i, x.fitness);
            }

            if x.fitness < 1000_f64 {
                println!("{}th solution converged at {}: {:?}",
                         i, x.fitness, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<commit_msg>Increase population size to 512<commit_after>extern crate rand;

use rand::Rng;
use rand::distributions;
use individual::Individual;

mod individual;

fn select<R: Rng>(population: &Vec<Individual>, rng: &mut R)
                  -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

fn main() {
    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-512.03_f64, 511.97);

    // initialize population
    let mut population: Vec<_> = (0..512).map(|_| {
        Individual::new(&range, &mut rng)
    }).collect();

    for i in 0..10000 {
        // select, mutate, and recombine individuals for next population
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in (0..population.len()/2) {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());
        population = offspring;

        if let Some(x) = population.iter().min() {
            if i % 100 == 0 {
                println!("{}th fitness: {}", i, x.fitness);
            }

            if x.fitness < 1000_f64 {
                println!("{}th solution converged at {}: {:?}",
                         i, x.fitness, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<|endoftext|>


<commit_before>// This is so cargo actually considers linking to the fucking manifest,
// since the build scripts' documentation can do the digital equivalent of fucking off
#[cfg(target_os="windows")]
#[link(name="cargo-install-update-manifest", kind="static")]
extern "C" {}

extern crate cargo_update;
extern crate tabwriter;
extern crate regex;

use std::process::{Command, exit};
use std::io::{Write, stdout};
use std::fs::{self, File};
use tabwriter::TabWriter;
use regex::Regex;
use std::env;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::Options::parse();

    if cfg!(target_os = "windows") {
        let old_version_r = Regex::new(r"cargo-install-update\.exe-v.+").unwrap();
        for old_version in fs::read_dir(env::current_exe().unwrap().parent().unwrap().canonicalize().unwrap())
            .unwrap()
            .map(Result::unwrap)
            .filter(|f| old_version_r.is_match(&f.file_name().into_string().unwrap())) {
            fs::remove_file(old_version.path()).unwrap();
        }
    }

    let mut packages = cargo_update::ops::installed_main_repo_packages(&opts.cargo_dir.1);

    if !opts.to_update.is_empty() {
        packages = cargo_update::ops::intersect_packages(packages, &opts.to_update);
    }

    {
        // Searching for "" will just update the registry
        let search_res = Command::new("cargo").arg("search").arg("").status().unwrap();
        if !search_res.success() {
            try!(Err(search_res.code().unwrap_or(-1)));
        }
        println!("");
    }

    let registry = cargo_update::ops::get_index_path(&opts.cargo_dir.1);

    for package in &mut packages {
        package.pull_version(&registry);
    }

    {
        let mut out = TabWriter::new(stdout());
        writeln!(out, "Package\tInstalled\tLatest\tNeeds update").unwrap();
        for package in &packages {
            writeln!(out,
                     "{}\tv{}\tv{}\t{}",
                     package.name,
                     package.version,
                     package.newest_version.as_ref().unwrap(),
                     if package.version < *package.newest_version.as_ref().unwrap() {
                         "Yes"
                     } else {
                         "No"
                     })
                .unwrap();
        }
        writeln!(out, "").unwrap();
        out.flush().unwrap();
    }

    if opts.update {
        if !opts.force {
            packages = packages.into_iter().filter(|pkg| pkg.version < *pkg.newest_version.as_ref().unwrap()).collect();
        }

        if !packages.is_empty() {
            let (success_n, errored, result): (usize, Vec<String>, Option<i32>) = packages.into_iter()
                .map(|package| -> Result<(), (i32, String)> {
                    println!("Updating {}", package.name);

                    if cfg!(target_os = "windows") && package.name == "cargo-update" {
                        let cur_exe = env::current_exe().unwrap();
                        let mut new_exe = cur_exe.clone();

                        new_exe.set_extension(format!("exe-v{}", package.version));
                        fs::rename(&cur_exe, new_exe).unwrap();
                        // This way the past-current exec will be "replaced" we'll get no dupes in .cargo.toml
                        File::create(cur_exe).unwrap();
                    }

                    let install_res = Command::new("cargo").arg("install").arg("-f").arg(&package.name).status().unwrap();
                    if !install_res.success() {
                        try!(Err((install_res.code().unwrap_or(-1), package.name)));
                    }

                    println!("");

                    Ok(())
                })
                .fold((0, vec![], None), |(s, mut e, r), p| match p {
                    Ok(()) => (s + 1, e, r),
                    Err((pr, pn)) => {
                        e.push(pn);
                        (s, e, r.or(Some(pr)))
                    }
                });

            println!("");
            println!("Updated {} package{}.", success_n, if success_n == 1 { "" } else { "s" });
            if !errored.is_empty() && result.is_some() {
                println!("Failed to update {}.", &errored.iter().fold("".to_string(), |s, e| s + ", " + e)[2..]);
                try!(Err(result.unwrap()));
            }
        } else {
            println!("No packages need updating.");
        }
    }

    Ok(())
}
<commit_msg>Fix line spacing after failed updates<commit_after>// This is so cargo actually considers linking to the fucking manifest,
// since the build scripts' documentation can do the digital equivalent of fucking off
#[cfg(target_os="windows")]
#[link(name="cargo-install-update-manifest", kind="static")]
extern "C" {}

extern crate cargo_update;
extern crate tabwriter;
extern crate regex;

use std::process::{Command, exit};
use std::io::{Write, stdout};
use std::fs::{self, File};
use tabwriter::TabWriter;
use regex::Regex;
use std::env;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::Options::parse();

    if cfg!(target_os = "windows") {
        let old_version_r = Regex::new(r"cargo-install-update\.exe-v.+").unwrap();
        for old_version in fs::read_dir(env::current_exe().unwrap().parent().unwrap().canonicalize().unwrap())
            .unwrap()
            .map(Result::unwrap)
            .filter(|f| old_version_r.is_match(&f.file_name().into_string().unwrap())) {
            fs::remove_file(old_version.path()).unwrap();
        }
    }

    let mut packages = cargo_update::ops::installed_main_repo_packages(&opts.cargo_dir.1);

    if !opts.to_update.is_empty() {
        packages = cargo_update::ops::intersect_packages(packages, &opts.to_update);
    }

    {
        // Searching for "" will just update the registry
        let search_res = Command::new("cargo").arg("search").arg("").status().unwrap();
        if !search_res.success() {
            try!(Err(search_res.code().unwrap_or(-1)));
        }
        println!("");
    }

    let registry = cargo_update::ops::get_index_path(&opts.cargo_dir.1);

    for package in &mut packages {
        package.pull_version(&registry);
    }

    {
        let mut out = TabWriter::new(stdout());
        writeln!(out, "Package\tInstalled\tLatest\tNeeds update").unwrap();
        for package in &packages {
            writeln!(out,
                     "{}\tv{}\tv{}\t{}",
                     package.name,
                     package.version,
                     package.newest_version.as_ref().unwrap(),
                     if package.version < *package.newest_version.as_ref().unwrap() {
                         "Yes"
                     } else {
                         "No"
                     })
                .unwrap();
        }
        writeln!(out, "").unwrap();
        out.flush().unwrap();
    }

    if opts.update {
        if !opts.force {
            packages = packages.into_iter().filter(|pkg| pkg.version < *pkg.newest_version.as_ref().unwrap()).collect();
        }

        if !packages.is_empty() {
            let (success_n, errored, result): (usize, Vec<String>, Option<i32>) = packages.into_iter()
                .map(|package| -> Result<(), (i32, String)> {
                    println!("Updating {}", package.name);

                    if cfg!(target_os = "windows") && package.name == "cargo-update" {
                        let cur_exe = env::current_exe().unwrap();
                        let mut new_exe = cur_exe.clone();

                        new_exe.set_extension(format!("exe-v{}", package.version));
                        fs::rename(&cur_exe, new_exe).unwrap();
                        // This way the past-current exec will be "replaced" we'll get no dupes in .cargo.toml
                        File::create(cur_exe).unwrap();
                    }

                    let install_res = Command::new("cargo").arg("install").arg("-f").arg(&package.name).status().unwrap();

                    println!("");
                    if !install_res.success() {
                        Err((install_res.code().unwrap_or(-1), package.name))
                    } else {
                        Ok(())
                    }
                })
                .fold((0, vec![], None), |(s, mut e, r), p| match p {
                    Ok(()) => (s + 1, e, r),
                    Err((pr, pn)) => {
                        e.push(pn);
                        (s, e, r.or(Some(pr)))
                    }
                });

            println!("");
            println!("Updated {} package{}.", success_n, if success_n == 1 { "" } else { "s" });
            if !errored.is_empty() && result.is_some() {
                println!("Failed to update {}.", &errored.iter().fold("".to_string(), |s, e| s + ", " + e)[2..]);
                try!(Err(result.unwrap()));
            }
        } else {
            println!("No packages need updating.");
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>use futures::stream::{self, StreamExt};
use futures::Future;
use log::{self, *};
use std::io::Write;
use tokio::task;
use trust_dns_resolver::config::*;
use trust_dns_resolver::lookup::Lookup;
use trust_dns_resolver::proto::rr::RecordType;
use trust_dns_resolver::proto::xfer::DnsRequestOptions;
use trust_dns_resolver::TokioAsyncResolver;

type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

/// Async lookup algorithm -- no work is done
async fn lookup(i: usize) -> Result<Vec<Lookup>> {
    let config = match i {
        1 => ResolverConfig::google(),
        2 => ResolverConfig::cloudflare(),
        _ => ResolverConfig::quad9(),
    };
    let resolver = TokioAsyncResolver::tokio(config, ResolverOpts::default()).await?;
    debug!("Created {} Resolver.", i);

    let futures: Vec<_> = vec![
        RecordType::A,
        RecordType::A,
        RecordType::A,
        RecordType::AAAA,
        RecordType::AAAA,
        RecordType::AAAA,
        RecordType::TXT,
        RecordType::TXT,
        RecordType::TXT,
    ]
    .into_iter()
    .map(|x| make_lookup(i, &resolver, x))
    .collect();

    let mut res = Vec::new();
    let stream = stream::iter(futures);
    let mut buffered_stream = stream.buffer_unordered(2);
    while let Some(f) = buffered_stream.next().await {
        trace!("Received lookup {:?}", f);
        let f = f?;
        res.push(f)
    }

    Ok(res)
}

async fn make_lookup(i: usize, resolver: &TokioAsyncResolver, record_type: RecordType) -> Result<Lookup> {
    let lookup = resolver
        .lookup("www.example.com.", record_type, DnsRequestOptions::default())
        .await?;
    debug!("Received {} Lookup for record type {}.", i, record_type);

    Ok(lookup)
}

/// Create the futures -- no work is done
fn lookup_futures() -> Vec<impl Future<Output = Result<Vec<Lookup>>>> {
    let google = lookup(1);
    let cloudflare = lookup(2);
    let quad6 = lookup(3);

    vec![google, cloudflare, quad6]
}

/// Spawn the futures -- work is started
fn lookups_spawns() -> Vec<task::JoinHandle<Result<Vec<Lookup>>>> {
    let tasks: Vec<_> = lookup_futures().into_iter().map(task::spawn).collect();

    tasks
}

/// Wait asyncly for the work to finish
async fn lookups() -> Result<Vec<Lookup>> {
    let tasks: Vec<_> = lookups_spawns();

    let mut res = Vec::new();
    for t in tasks {
        let r = t.await??;
        res.push(r);
    }

    Ok(res.into_iter().flatten().collect())
}

fn main() {
    let start = std::time::Instant::now();
    env_logger::Builder::from_default_env()
        .format(move |buf, rec| {
            let t = start.elapsed().as_secs_f32();
            writeln!(buf, "{:.03} [{}] - {}", t, rec.level(), rec.args())
        })
        .init();

    let mut rt = tokio::runtime::Runtime::new().unwrap();

    match rt.block_on(lookups()) {
        //Ok(lookup) => info!("Lookup: {:#?}", lookup),
        Ok(_) => info!("Done."),
        Err(e) => error!("An error occurred: {}", e),
    };
}
<commit_msg>Reformatting, syn and sem<commit_after>use futures::stream::{self, StreamExt};
use futures::Future;
use log::{self, *};
use std::io::Write;
use std::thread;
use tokio::task;
use trust_dns_resolver::config::*;
use trust_dns_resolver::lookup::Lookup;
use trust_dns_resolver::proto::rr::RecordType;
use trust_dns_resolver::proto::xfer::DnsRequestOptions;
use trust_dns_resolver::TokioAsyncResolver;

type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

/// Async lookup algorithm -- no work is done
async fn lookup(i: usize) -> Result<Vec<Lookup>> {
    let config = match i {
        1 => ResolverConfig::google(),
        2 => ResolverConfig::cloudflare(),
        _ => ResolverConfig::quad9(),
    };
    let resolver = TokioAsyncResolver::tokio(config, ResolverOpts::default()).await?;
    debug!("Created {} Resolver.", i);

    let futures: Vec<_> = vec![
        RecordType::A,
        RecordType::A,
        RecordType::A,
        RecordType::AAAA,
        RecordType::AAAA,
        RecordType::AAAA,
        RecordType::TXT,
        RecordType::TXT,
        RecordType::TXT,
    ]
    .into_iter()
    .map(|x| make_lookup(i, &resolver, x))
    .collect();

    let mut res = Vec::new();
    let stream = stream::iter(futures);
    let mut buffered_stream = stream.buffer_unordered(2);
    while let Some(f) = buffered_stream.next().await {
        trace!("Received lookup {:?}", f);
        let f = f?;
        res.push(f)
    }

    Ok(res)
}

async fn make_lookup(i: usize, resolver: &TokioAsyncResolver, record_type: RecordType) -> Result<Lookup> {
    let lookup = resolver
        .lookup("www.example.com.", record_type, DnsRequestOptions::default())
        .await?;
    debug!("Received {} Lookup for record type {}.", i, record_type);

    Ok(lookup)
}

/// Create the futures -- no work is done
fn lookup_futures() -> Vec<impl Future<Output = Result<Vec<Lookup>>>> {
    let google = lookup(1);
    let cloudflare = lookup(2);
    let quad6 = lookup(3);

    vec![google, cloudflare, quad6]
}

/// Spawn the futures -- work is started
fn lookups_spawns(lookup_futures: Vec<impl Future<Output = Result<Vec<Lookup>>> + Send + 'static>) -> Vec<task::JoinHandle<Result<Vec<Lookup>>>> {
    lookup_futures.into_iter().map(task::spawn).collect()
}

/// Wait asyncly for the work to finish
async fn lookups(tasks: Vec<task::JoinHandle<Result<Vec<Lookup>>>>) -> Result<Vec<Lookup>> {
    let mut res = Vec::new();
    for t in tasks {
        let r = t.await??;
        res.push(r);
    }

    Ok(res.into_iter().flatten().collect())
}

fn main() -> Result<()> {
    let start = std::time::Instant::now();
    env_logger::Builder::from_default_env()
        .format(move |buf, rec| {
            let t = start.elapsed().as_secs_f32();
            writeln!(buf, "{:.03} [{}] ({:?})- {}", t, rec.level(), thread::current().id(), rec.args())
        })
        .init();

    let mut rt = tokio::runtime::Runtime::new()
        .expect("Failed to create runtime.");

    rt.block_on(async {
        let futures = lookup_futures();
        let tasks = lookups_spawns(futures);
        let lookups = lookups(tasks).await;
        match lookups {
            //Ok(lookup) => info!("Lookup: {:#?}", lookup),
            Ok(_) => info!("Done."),
            Err(e) => error!("An error occurred: {}", e),
        }
    });

    Ok(())
}
<|endoftext|>


<commit_before>extern crate piston_window;

mod entity;

use piston_window::*;
use entity::Entity;
use std::time::SystemTime;

#[derive(Debug, Clone)]
pub struct Point(f64, f64);

const MU: f64 = 1.0;
const WIDTH: u32 = 1024;
const HEIGHT: u32 = 800;
const WAIT_TIME: u32 = 300_000_000; //nanoseconds

fn main() {
    let title = "Goober";
    let mut inputs_submitted = false;
    let mut inputs = Vec::new();
    let mut timestamp = SystemTime::now();
    let mut i: usize = 0;
    let mut goobs = vec![
        Entity::new(Point(0.0, 0.0), [0.3, 0.0, 0.7, 0.5], 25.0, 25.0)
    ];

    let mut window: PistonWindow = WindowSettings::new(title, [WIDTH, HEIGHT])
        .exit_on_esc(true)
        .build()
        .unwrap_or_else(|e| panic!("Failed to build PistonWindow: {}", e));

    let sprite_path = "./assets/green-blob-hi.png";
    let sprite = Texture::from_path(
            &mut window.factory,
            &sprite_path,
            Flip::None,
            &TextureSettings::new())
            .unwrap();

    let font = "assets/FiraSans-Regular.ttf";
    let factory = window.factory.clone();
    let mut glyphs = Glyphs::new(font, factory).unwrap();

    while let Some(e) = window.next() {

        if let Some(_) = e.render_args() {
            window.draw_2d(&e, |c, g| {
                clear([0.8, 0.0, 0.8, 1.0], g);
                for goob in &goobs {
                    image(&sprite, c.transform.trans(goob.geometry()[0], goob.geometry()[1]), g);
                }

                text::Text::new_color([0.0, 1.0, 0.0, 1.0], 16).draw(
                    &format_inputs(&inputs),
                    &mut glyphs,
                    &c.draw_state,
                    c.transform.trans(40.0, 40.0), g
                );
            });
        }

        if let Some(button) = e.press_args() {
            if !inputs_submitted {
                match button {
                    Button::Keyboard(Key::Up)     => inputs.push(button),
                    Button::Keyboard(Key::Down)   => inputs.push(button),
                    Button::Keyboard(Key::Left)   => inputs.push(button),
                    Button::Keyboard(Key::Right)  => inputs.push(button),
                    Button::Keyboard(Key::Space)  => inputs.push(button),
                    Button::Keyboard(Key::A)      => {
                        goobs.push(
                            Entity::new(
                            Point(0.0, 0.0),
                            [0.3, 0.0, 0.7, 0.5],
                            25.0, 25.0
                            )
                        );
                        inputs.push(button);
                    },
                    Button::Keyboard(Key::Return) => {inputs_submitted = true; inputs.reverse()},
                    _ => ()
                }
            }
        }

        if let Some(_) = e.update_args() {
            if inputs_submitted && wait_time_elapsed(timestamp) {
                timestamp = SystemTime::now();
                match inputs.pop() {
                    Some(button) => handle_input(button, &mut goobs, &mut i),
                    None => ()
                }
            }
            for goob in goobs.iter_mut() {
                goob.nudge();
            }
        }
    }

    fn handle_input(button: Button, goobs: &mut [Entity], i: &mut usize) {
        match button {
            Button::Keyboard(Key::Up)     => goobs[*i].adjust_dy(-1.0),
            Button::Keyboard(Key::Down)   => goobs[*i].adjust_dy(1.0),
            Button::Keyboard(Key::Left)   => goobs[*i].adjust_dx(-1.0),
            Button::Keyboard(Key::Right)  => goobs[*i].adjust_dx(1.0),
            Button::Keyboard(Key::Space)  => if *i == goobs.len() - 1 { *i = 0 } else { *i += 1 },
            _ => ()
        }
    }

    fn wait_time_elapsed(timestamp: SystemTime) -> bool {
        match timestamp.elapsed() {
            Ok(elapsed) => elapsed.subsec_nanos() >= WAIT_TIME,
            Err(e) => {println!("{:?}", e); false}
        }
    }

    fn format_inputs(inputs: &Vec<Button>) -> String {
        inputs.iter().map(|button|
            match *button {
                Button::Keyboard(Key::Up)    => "↑",
                Button::Keyboard(Key::Down)  => "↓",
                Button::Keyboard(Key::Left)  => "←",
                Button::Keyboard(Key::Right) => "→",
                Button::Keyboard(Key::Space) => "↔",
                Button::Keyboard(Key::A)     => "+",
                _ => ""
            }
        ).collect::<Vec<_>>().concat()
    }
}
<commit_msg>Increase friction slightly<commit_after>extern crate piston_window;

mod entity;

use piston_window::*;
use entity::Entity;
use std::time::SystemTime;

#[derive(Debug, Clone)]
pub struct Point(f64, f64);

const MU: f64 = 0.99;
const WIDTH: u32 = 1024;
const HEIGHT: u32 = 800;
const WAIT_TIME: u32 = 300_000_000; //nanoseconds

fn main() {
    let title = "Goober";
    let mut inputs_submitted = false;
    let mut inputs = Vec::new();
    let mut timestamp = SystemTime::now();
    let mut i: usize = 0;
    let mut goobs = vec![
        Entity::new(Point(0.0, 0.0), [0.3, 0.0, 0.7, 0.5], 25.0, 25.0)
    ];

    let mut window: PistonWindow = WindowSettings::new(title, [WIDTH, HEIGHT])
        .exit_on_esc(true)
        .build()
        .unwrap_or_else(|e| panic!("Failed to build PistonWindow: {}", e));

    let sprite_path = "./assets/green-blob-hi.png";
    let sprite = Texture::from_path(
            &mut window.factory,
            &sprite_path,
            Flip::None,
            &TextureSettings::new())
            .unwrap();

    let font = "assets/FiraSans-Regular.ttf";
    let factory = window.factory.clone();
    let mut glyphs = Glyphs::new(font, factory).unwrap();

    while let Some(e) = window.next() {

        if let Some(_) = e.render_args() {
            window.draw_2d(&e, |c, g| {
                clear([0.8, 0.0, 0.8, 1.0], g);
                for goob in &goobs {
                    image(&sprite, c.transform.trans(goob.geometry()[0], goob.geometry()[1]), g);
                }

                text::Text::new_color([0.0, 1.0, 0.0, 1.0], 16).draw(
                    &format_inputs(&inputs),
                    &mut glyphs,
                    &c.draw_state,
                    c.transform.trans(40.0, 40.0), g
                );
            });
        }

        if let Some(button) = e.press_args() {
            if !inputs_submitted {
                match button {
                    Button::Keyboard(Key::Up)     => inputs.push(button),
                    Button::Keyboard(Key::Down)   => inputs.push(button),
                    Button::Keyboard(Key::Left)   => inputs.push(button),
                    Button::Keyboard(Key::Right)  => inputs.push(button),
                    Button::Keyboard(Key::Space)  => inputs.push(button),
                    Button::Keyboard(Key::A)      => {
                        goobs.push(
                            Entity::new(
                            Point(0.0, 0.0),
                            [0.3, 0.0, 0.7, 0.5],
                            25.0, 25.0
                            )
                        );
                        inputs.push(button);
                    },
                    Button::Keyboard(Key::Return) => {inputs_submitted = true; inputs.reverse()},
                    _ => ()
                }
            }
        }

        if let Some(_) = e.update_args() {
            if inputs_submitted && wait_time_elapsed(timestamp) {
                timestamp = SystemTime::now();
                match inputs.pop() {
                    Some(button) => handle_input(button, &mut goobs, &mut i),
                    None => ()
                }
            }
            for goob in goobs.iter_mut() {
                goob.nudge();
            }
        }
    }

    fn handle_input(button: Button, goobs: &mut [Entity], i: &mut usize) {
        match button {
            Button::Keyboard(Key::Up)     => goobs[*i].adjust_dy(-1.0),
            Button::Keyboard(Key::Down)   => goobs[*i].adjust_dy(1.0),
            Button::Keyboard(Key::Left)   => goobs[*i].adjust_dx(-1.0),
            Button::Keyboard(Key::Right)  => goobs[*i].adjust_dx(1.0),
            Button::Keyboard(Key::Space)  => if *i == goobs.len() - 1 { *i = 0 } else { *i += 1 },
            _ => ()
        }
    }

    fn wait_time_elapsed(timestamp: SystemTime) -> bool {
        match timestamp.elapsed() {
            Ok(elapsed) => elapsed.subsec_nanos() >= WAIT_TIME,
            Err(e) => {println!("{:?}", e); false}
        }
    }

    fn format_inputs(inputs: &Vec<Button>) -> String {
        inputs.iter().map(|button|
            match *button {
                Button::Keyboard(Key::Up)    => "↑",
                Button::Keyboard(Key::Down)  => "↓",
                Button::Keyboard(Key::Left)  => "←",
                Button::Keyboard(Key::Right) => "→",
                Button::Keyboard(Key::Space) => "↔",
                Button::Keyboard(Key::A)     => "+",
                _ => ""
            }
        ).collect::<Vec<_>>().concat()
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate rustful;
use std::error::Error;

use rustful::{Server, Context, Response, TreeRouter, Handler};

fn print_packet(context: Context, response: Response) {
    // Print headers
    println!("Headers: ");
    for value in context.headers.iter() {
        print!(">> {}", value);
    }

    println!("Variables: ");
    for (key, value) in context.variables.iter() {
        println!("{} -> {}", key.as_utf8().unwrap(), value.as_utf8().unwrap());
    }

    println!("Query: ");
    for (key, value) in context.query.iter() {
        println!("{} -> {}", key.as_utf8().unwrap(), value.as_utf8().unwrap());
    }

    println!("Fragment: ");
    for value in context.fragment.iter() {
        println!(">> {}", value.as_utf8().unwrap());
    }

    response.send("ok");
}

// Simple structure to handle requests
// This is useful when adding endoint handlers,
// so we can set different functions to each endpoint.
struct HandlerRequest(fn(Context, Response));
impl Handler for HandlerRequest {
    fn handle_request(&self, context: Context, response: Response) {
        self.0(context, response);
    }
}

fn main() {
    let server_result = Server {
        host: 8080.into(),
        handlers: insert_routes!{
            TreeRouter::new() => {
                "/" => Get: HandlerRequest(print_packet),
                // Just an example.
                "/:endpoint/:id" => Get: HandlerRequest(print_packet)
            }
        },
        .. Server::default()
    }.run();

    match server_result {
        Ok(_server) => {},
        Err(e) => println!("could not start server: {}", e.description())
    }
}<commit_msg>Adding a mutex so that the requests are properly printed.<commit_after>#[macro_use]
extern crate rustful;
use std::error::Error;
use std::sync::Mutex;
use rustful::{Server, Context, Response, TreeRouter, Handler};

fn print_packet(context: Context, response: Response) {
    // Print headers
    println!("Headers: ");
    for value in context.headers.iter() {
        print!(">> {}", value);
    }

    println!("Variables: ");
    for (key, value) in context.variables.iter() {
        println!("{} -> {}", key.as_utf8().unwrap(), value.as_utf8().unwrap());
    }

    println!("Query: ");
    for (key, value) in context.query.iter() {
        println!("{} -> {}", key.as_utf8().unwrap(), value.as_utf8().unwrap());
    }

    println!("Fragment: ");
    for value in context.fragment.iter() {
        println!(">> {}", value.as_utf8().unwrap());
    }

    response.send("ok");
}

struct RequestHandler {
    mutex: Mutex<u32>,
    callback: fn(Context, Response),
}

impl RequestHandler {
    fn new(cbk: fn(Context, Response)) -> RequestHandler {
        RequestHandler {
            mutex: Mutex::new(0),
            callback: cbk
        }
    }
}

impl Handler for RequestHandler {
    fn handle_request(&self, context: Context, response: Response) {
        let _g = self.mutex.lock().unwrap();
        (self.callback)(context, response);
    }
}

fn main() {
    let server_result = Server {
            host: 8080.into(),
            handlers: insert_routes!{
            TreeRouter::new() => {
                "/" => Get: RequestHandler
            ::new(print_packet),
                // Just an example.
                "/:endpoint/:id" => Get: RequestHandler
            ::new(print_packet)
            }
        },
            ..Server::default()
        }
        .run();

    match server_result {
        Ok(_server) => {}
        Err(e) => println!("could not start server: {}", e.description()),
    }
}<|endoftext|>


<commit_before>extern crate docsrs2docset;
extern crate html5ever;

use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
use html5ever::tree_builder::TreeBuilderOpts;

use std::fs::File;
use std::io::Write;
use std::string::String;

use docsrs2docset::dom::{manipulator, parser};

// #### read https://thesquareplanet.com/blog/rust-tips-and-tricks/ Cloning iterators
// #### read https://thesquareplanet.com/blog/rust-tips-and-tricks/ Partial matching

fn main() {
    docset_file_from_rs_doc("index.html".to_string(), "index-out.html".to_string())
}

fn docset_file_from_rs_doc(input: String, output: String) {
    let opts = ParseOpts {
        tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() },
        ..Default::default()
    };

    let mut in_file = match File::open(&input) {
        Ok(f) => f,
        Err(e) => {
            println!("Error opening {}: {}", input, e);
            return;
        }
    };

    let mut dom = parse_document(RcDom::default(), opts)
                      .from_utf8()
                      .read_from(&mut in_file)
                      .unwrap();

    let entries = parser::find_entry_elements(&mut dom);
    manipulator::add_dash_links(&mut dom, &entries);

    let mut bytes = vec![];
    serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
    let result = String::from_utf8(bytes).unwrap();

    let mut out_file = match File::create(&output) {
        Ok(f) => f,
        Err(e) => {
            println!("Error creating file {}: {}", output, e);
            return;
        }
    };

    match out_file.write_all(result.as_ref()) {
        Ok(_) => println!("Successfully added docset links from {} -> {}",
                          input,
                          output),
        Err(e) => println!("Error writing {}: {}", output, e),
    }
}
<commit_msg>First primitive version with recursive dirs<commit_after>extern crate docsrs2docset;
extern crate html5ever;

use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
use html5ever::tree_builder::TreeBuilderOpts;

use std::fs::{self, DirBuilder, DirEntry, File, ReadDir};
use std::io::{self, Error, ErrorKind, Write};
use std::path::Path;
use std::string::String;

use docsrs2docset::dom::{manipulator, parser};

// #### read https://thesquareplanet.com/blog/rust-tips-and-tricks/ Cloning iterators
// #### read https://thesquareplanet.com/blog/rust-tips-and-tricks/ Partial matching

fn main() {
    let out_dir = "out-dir".to_string();

    if let Err(e) = docset_tree_from_rs_doc_tree(Path::new("target/doc"),
                                                 &out_dir,
                                                 &docset_file_from_rs_doc) {
        println!{"error: {}", e}
    }
}

fn docset_tree_from_rs_doc_tree(source_dir: &Path, out_dir: &String, cb: &Fn(&DirEntry, &String))
                                -> io::Result<()> {
    if source_dir.is_dir() {
        for entry in try!(fs::read_dir(source_dir)) {
            let entry = try!(entry);
            let path = entry.path();
            if path.is_dir() {
                try!(docset_tree_from_rs_doc_tree(&path, &out_dir, cb));
            } else {
                cb(&entry, &out_dir);
            }
        }
    }
    Ok(())
}

fn docset_file_from_rs_doc(input: &DirEntry, output_prefix: &String) {
    let out_dir = Path::new(output_prefix).join(input.path());
    let output = out_dir.join(input.file_name());

    DirBuilder::new()
        .recursive(true)
        .create(out_dir)
        .unwrap();

    let opts = ParseOpts {
        tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() },
        ..Default::default()
    };

    let mut in_file = match File::open(&input.path()) {
        Ok(f) => f,
        Err(e) => {
            println!("Error opening {}: {}", input.path().display(), e);
            return;
        }
    };

    let mut dom = parse_document(RcDom::default(), opts)
                      .from_utf8()
                      .read_from(&mut in_file)
                      .unwrap();

    let entries = parser::find_entry_elements(&mut dom);
    manipulator::add_dash_links(&mut dom, &entries);

    let mut bytes = vec![];
    serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
    let result = String::from_utf8(bytes).unwrap();

    let mut out_file = match File::create(&output) {
        Ok(f) => f,
        Err(e) => {
            println!("Error creating file {}: {}", output.display(), e);
            return;
        }
    };

    match out_file.write_all(result.as_ref()) {
        Ok(_) => println!("Successfully added docset links from {} -> {}",
                          input.path().display(),
                          output.display()),
        Err(e) => println!("Error writing {}: {}", output.display(), e),
    }
}
<|endoftext|>


<commit_before>mod app;
mod error;
mod exec;
mod exit_codes;
mod filesystem;
mod filetypes;
mod filter;
mod options;
mod output;
mod regex_helper;
mod walk;

use std::env;
use std::path::{Path, PathBuf};
use std::process;
use std::sync::Arc;
use std::time;

use anyhow::{anyhow, Context, Result};
use atty::Stream;
use globset::GlobBuilder;
use lscolors::LsColors;
use regex::bytes::{RegexBuilder, RegexSetBuilder};

use crate::exec::CommandTemplate;
use crate::exit_codes::ExitCode;
use crate::filetypes::FileTypes;
use crate::filter::{SizeFilter, TimeFilter};
use crate::options::Options;
use crate::regex_helper::pattern_has_uppercase_char;

// We use jemalloc for performance reasons, see https://github.com/sharkdp/fd/pull/481
#[cfg(all(not(windows), not(target_env = "musl")))]
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

fn run() -> Result<ExitCode> {
    let matches = app::build_app().get_matches_from(env::args_os());

    // Set the current working directory of the process
    if let Some(base_directory) = matches.value_of_os("base-directory") {
        let base_directory = Path::new(base_directory);
        if !filesystem::is_dir(base_directory) {
            return Err(anyhow!(
                "The '--base-directory' path '{}' is not a directory.",
                base_directory.to_string_lossy()
            ));
        }
        env::set_current_dir(base_directory).with_context(|| {
            format!(
                "Could not set '{}' as the current working directory.",
                base_directory.to_string_lossy()
            )
        })?;
    }

    let current_directory = Path::new(".");
    if !filesystem::is_dir(current_directory) {
        return Err(anyhow!(
            "Could not retrieve current directory (has it been deleted?)."
        ));
    }

    // Get the search pattern
    let pattern = matches
        .value_of_os("pattern")
        .map(|p| {
            p.to_str().ok_or(anyhow!(
                "The search pattern includes invalid UTF-8 sequences."
            ))
        })
        .transpose()?
        .unwrap_or("");

    // Get one or more root directories to search.
    let mut dir_vec: Vec<_> = match matches
        .values_of_os("path")
        .or_else(|| matches.values_of_os("search-path"))
    {
        Some(paths) => paths
            .map(|path| {
                let path_buffer = PathBuf::from(path);
                if filesystem::is_dir(&path_buffer) {
                    Ok(path_buffer)
                } else {
                    Err(anyhow!(
                        "Search path '{}' is not a directory.",
                        path_buffer.to_string_lossy()
                    ))
                }
            })
            .collect::<Result<Vec<_>>>()?,
        None => vec![current_directory.to_path_buf()],
    };

    if matches.is_present("absolute-path") {
        dir_vec = dir_vec
            .iter()
            .map(|path_buffer| {
                path_buffer
                    .canonicalize()
                    .and_then(|pb| filesystem::absolute_path(pb.as_path()))
                    .unwrap()
            })
            .collect();
    }

    // Detect if the user accidentally supplied a path instead of a search pattern
    if !matches.is_present("full-path")
        && pattern.contains(std::path::MAIN_SEPARATOR)
        && filesystem::is_dir(Path::new(pattern))
    {
        return Err(anyhow!(
            "The search pattern '{pattern}' contains a path-separation character ('{sep}') \
             and will not lead to any search results.\n\n\
             If you want to search for all files inside the '{pattern}' directory, use a match-all pattern:\n\n  \
             fd . '{pattern}'\n\n\
             Instead, if you want your pattern to match the full file path, use:\n\n  \
             fd --full-path '{pattern}'",
            pattern = pattern,
            sep = std::path::MAIN_SEPARATOR,
        ));
    }

    let pattern_regex = if matches.is_present("glob") {
        let glob = GlobBuilder::new(pattern).literal_separator(true).build()?;
        glob.regex().to_owned()
    } else if matches.is_present("fixed-strings") {
        // Treat pattern as literal string if '--fixed-strings' is used
        regex::escape(pattern)
    } else {
        String::from(pattern)
    };

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = !matches.is_present("ignore-case")
        && (matches.is_present("case-sensitive") || pattern_has_uppercase_char(&pattern_regex));

    let interactive_terminal = atty::is(Stream::Stdout);
    let colored_output = match matches.value_of("color") {
        Some("always") => true,
        Some("never") => false,
        _ => env::var_os("NO_COLOR").is_none() && interactive_terminal,
    };

    let path_separator = matches.value_of("path-separator").map(|str| str.to_owned());

    #[cfg(windows)]
    ansi_term::enable_ansi_support().ok();

    let ls_colors = if colored_output {
        Some(LsColors::from_env().unwrap_or_default())
    } else {
        None
    };

    let command = if let Some(args) = matches.values_of("exec") {
        Some(CommandTemplate::new(args))
    } else if let Some(args) = matches.values_of("exec-batch") {
        Some(CommandTemplate::new_batch(args)?)
    } else if matches.is_present("list-details") {
        let color = matches.value_of("color").unwrap_or("auto");
        #[allow(unused)]
        let color_arg = ["--color=", color].concat();

        let cmd: Vec<&str> = if cfg!(unix) {
            if !cfg!(target_os = "macos") {
                // Non-MacOS Unix
                vec![
                    "ls",
                    "-l",               // long listing format
                    "--human-readable", // human readable file sizes
                    "--directory",      // list directories themselves, not their contents
                    &color_arg,
                ]
            } else {
                // MacOS
                use std::process::{Command, Stdio};

                // Use GNU ls, if available (support for --color=auto, better LS_COLORS support)
                let gnu_ls_exists = Command::new("gls")
                    .arg("--version")
                    .stdout(Stdio::null())
                    .stderr(Stdio::null())
                    .status()
                    .is_ok();

                if gnu_ls_exists {
                    vec![
                        "gls",
                        "-l",               // long listing format
                        "--human-readable", // human readable file sizes
                        "--directory",      // list directories themselves, not their contents
                        &color_arg,
                    ]
                } else {
                    let mut cmd = vec![
                        "ls", // MacOS version of ls
                        "-l", // long listing format
                        "-h", // '--human-readable' is not available on MacOS, '-h' is
                        "-d", // '--directory' is not available, but '-d' is
                    ];

                    if colored_output {
                        cmd.push("-G");
                    }

                    cmd
                }
            }
        } else {
            return Err(anyhow!(
                "'fd --list-details' is not supported on this platform."
            ));
        };

        Some(CommandTemplate::new_batch(&cmd).unwrap())
    } else {
        None
    };

    let size_limits = if let Some(vs) = matches.values_of("size") {
        vs.map(|sf| {
            SizeFilter::from_string(sf).ok_or(anyhow!(
                "'{}' is not a valid size constraint. See 'fd --help'.",
                sf
            ))
        })
        .collect::<Result<Vec<_>>>()?
    } else {
        vec![]
    };

    let now = time::SystemTime::now();
    let mut time_constraints: Vec<TimeFilter> = Vec::new();
    if let Some(t) = matches.value_of("changed-within") {
        if let Some(f) = TimeFilter::after(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }
    if let Some(t) = matches.value_of("changed-before") {
        if let Some(f) = TimeFilter::before(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }

    let config = Options {
        case_sensitive,
        search_full_path: matches.is_present("full-path"),
        ignore_hidden: !(matches.is_present("hidden")
            || matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
        read_fdignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")),
        read_vcsignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")
            || matches.is_present("no-ignore-vcs")),
        follow_links: matches.is_present("follow"),
        one_file_system: matches.is_present("one-file-system"),
        null_separator: matches.is_present("null_separator"),
        max_depth: matches
            .value_of("max-depth")
            .or_else(|| matches.value_of("rg-depth"))
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        min_depth: matches
            .value_of("min-depth")
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        threads: std::cmp::max(
            matches
                .value_of("threads")
                .and_then(|n| usize::from_str_radix(n, 10).ok())
                .unwrap_or_else(num_cpus::get),
            1,
        ),
        max_buffer_time: matches
            .value_of("max-buffer-time")
            .and_then(|n| u64::from_str_radix(n, 10).ok())
            .map(time::Duration::from_millis),
        ls_colors,
        interactive_terminal,
        file_types: matches.values_of("file-type").map(|values| {
            let mut file_types = FileTypes::default();
            for value in values {
                match value {
                    "f" | "file" => file_types.files = true,
                    "d" | "directory" => file_types.directories = true,
                    "l" | "symlink" => file_types.symlinks = true,
                    "x" | "executable" => {
                        file_types.executables_only = true;
                        file_types.files = true;
                    }
                    "e" | "empty" => {
                        file_types.empty_only = true;
                    }
                    _ => unreachable!(),
                }
            }

            // If only 'empty' was specified, search for both files and directories:
            if file_types.empty_only && !(file_types.files || file_types.directories) {
                file_types.files = true;
                file_types.directories = true;
            }

            file_types
        }),
        extensions: matches
            .values_of("extension")
            .map(|exts| {
                let patterns = exts
                    .map(|e| e.trim_start_matches('.'))
                    .map(|e| format!(r".\.{}$", regex::escape(e)));
                RegexSetBuilder::new(patterns)
                    .case_insensitive(true)
                    .build()
            })
            .transpose()?,
        command: command.map(Arc::new),
        exclude_patterns: matches
            .values_of("exclude")
            .map(|v| v.map(|p| String::from("!") + p).collect())
            .unwrap_or_else(|| vec![]),
        ignore_files: matches
            .values_of("ignore-file")
            .map(|vs| vs.map(PathBuf::from).collect())
            .unwrap_or_else(|| vec![]),
        size_constraints: size_limits,
        time_constraints,
        show_filesystem_errors: matches.is_present("show-errors"),
        path_separator,
        max_results: matches
            .value_of("max-results")
            .and_then(|n| usize::from_str_radix(n, 10).ok())
            .filter(|&n| n != 0)
            .or_else(|| {
                if matches.is_present("max-one-result") {
                    Some(1)
                } else {
                    None
                }
            }),
    };

    let re = RegexBuilder::new(&pattern_regex)
        .case_insensitive(!config.case_sensitive)
        .dot_matches_new_line(true)
        .build()
        .map_err(|e| {
            anyhow!(
                "{}\n\nNote: You can use the '--fixed-strings' option to search for a \
                 literal string instead of a regular expression. Alternatively, you can \
                 also use the '--glob' option to match on a glob pattern.",
                e.to_string()
            )
        })?;

    walk::scan(&dir_vec, Arc::new(re), Arc::new(config))
}

fn main() {
    let result = run();
    match result {
        Ok(exit_code) => {
            process::exit(exit_code.into());
        }
        Err(err) => {
            eprintln!("[fd error]: {}", err);
            process::exit(ExitCode::GeneralError.into());
        }
    }
}
<commit_msg>Windows support (if GNU ls is installed)<commit_after>mod app;
mod error;
mod exec;
mod exit_codes;
mod filesystem;
mod filetypes;
mod filter;
mod options;
mod output;
mod regex_helper;
mod walk;

use std::env;
use std::path::{Path, PathBuf};
use std::process;
use std::sync::Arc;
use std::time;

use anyhow::{anyhow, Context, Result};
use atty::Stream;
use globset::GlobBuilder;
use lscolors::LsColors;
use regex::bytes::{RegexBuilder, RegexSetBuilder};

use crate::exec::CommandTemplate;
use crate::exit_codes::ExitCode;
use crate::filetypes::FileTypes;
use crate::filter::{SizeFilter, TimeFilter};
use crate::options::Options;
use crate::regex_helper::pattern_has_uppercase_char;

// We use jemalloc for performance reasons, see https://github.com/sharkdp/fd/pull/481
#[cfg(all(not(windows), not(target_env = "musl")))]
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

fn run() -> Result<ExitCode> {
    let matches = app::build_app().get_matches_from(env::args_os());

    // Set the current working directory of the process
    if let Some(base_directory) = matches.value_of_os("base-directory") {
        let base_directory = Path::new(base_directory);
        if !filesystem::is_dir(base_directory) {
            return Err(anyhow!(
                "The '--base-directory' path '{}' is not a directory.",
                base_directory.to_string_lossy()
            ));
        }
        env::set_current_dir(base_directory).with_context(|| {
            format!(
                "Could not set '{}' as the current working directory.",
                base_directory.to_string_lossy()
            )
        })?;
    }

    let current_directory = Path::new(".");
    if !filesystem::is_dir(current_directory) {
        return Err(anyhow!(
            "Could not retrieve current directory (has it been deleted?)."
        ));
    }

    // Get the search pattern
    let pattern = matches
        .value_of_os("pattern")
        .map(|p| {
            p.to_str().ok_or(anyhow!(
                "The search pattern includes invalid UTF-8 sequences."
            ))
        })
        .transpose()?
        .unwrap_or("");

    // Get one or more root directories to search.
    let mut dir_vec: Vec<_> = match matches
        .values_of_os("path")
        .or_else(|| matches.values_of_os("search-path"))
    {
        Some(paths) => paths
            .map(|path| {
                let path_buffer = PathBuf::from(path);
                if filesystem::is_dir(&path_buffer) {
                    Ok(path_buffer)
                } else {
                    Err(anyhow!(
                        "Search path '{}' is not a directory.",
                        path_buffer.to_string_lossy()
                    ))
                }
            })
            .collect::<Result<Vec<_>>>()?,
        None => vec![current_directory.to_path_buf()],
    };

    if matches.is_present("absolute-path") {
        dir_vec = dir_vec
            .iter()
            .map(|path_buffer| {
                path_buffer
                    .canonicalize()
                    .and_then(|pb| filesystem::absolute_path(pb.as_path()))
                    .unwrap()
            })
            .collect();
    }

    // Detect if the user accidentally supplied a path instead of a search pattern
    if !matches.is_present("full-path")
        && pattern.contains(std::path::MAIN_SEPARATOR)
        && filesystem::is_dir(Path::new(pattern))
    {
        return Err(anyhow!(
            "The search pattern '{pattern}' contains a path-separation character ('{sep}') \
             and will not lead to any search results.\n\n\
             If you want to search for all files inside the '{pattern}' directory, use a match-all pattern:\n\n  \
             fd . '{pattern}'\n\n\
             Instead, if you want your pattern to match the full file path, use:\n\n  \
             fd --full-path '{pattern}'",
            pattern = pattern,
            sep = std::path::MAIN_SEPARATOR,
        ));
    }

    let pattern_regex = if matches.is_present("glob") {
        let glob = GlobBuilder::new(pattern).literal_separator(true).build()?;
        glob.regex().to_owned()
    } else if matches.is_present("fixed-strings") {
        // Treat pattern as literal string if '--fixed-strings' is used
        regex::escape(pattern)
    } else {
        String::from(pattern)
    };

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = !matches.is_present("ignore-case")
        && (matches.is_present("case-sensitive") || pattern_has_uppercase_char(&pattern_regex));

    let interactive_terminal = atty::is(Stream::Stdout);
    let colored_output = match matches.value_of("color") {
        Some("always") => true,
        Some("never") => false,
        _ => env::var_os("NO_COLOR").is_none() && interactive_terminal,
    };

    let path_separator = matches.value_of("path-separator").map(|str| str.to_owned());

    #[cfg(windows)]
    ansi_term::enable_ansi_support().ok();

    let ls_colors = if colored_output {
        Some(LsColors::from_env().unwrap_or_default())
    } else {
        None
    };

    let command = if let Some(args) = matches.values_of("exec") {
        Some(CommandTemplate::new(args))
    } else if let Some(args) = matches.values_of("exec-batch") {
        Some(CommandTemplate::new_batch(args)?)
    } else if matches.is_present("list-details") {
        let color = matches.value_of("color").unwrap_or("auto");
        #[allow(unused)]
        let color_arg = ["--color=", color].concat();

        let gnu_ls = |command_name| {
            vec![
                command_name,
                "-l",               // long listing format
                "--human-readable", // human readable file sizes
                "--directory",      // list directories themselves, not their contents
                &color_arg,
            ]
        };

        let cmd: Vec<&str> = if cfg!(unix) {
            if !cfg!(target_os = "macos") {
                // Non-MacOS Unix
                gnu_ls("ls")
            } else {
                // MacOS
                use std::process::{Command, Stdio};

                // Use GNU ls, if available (support for --color=auto, better LS_COLORS support)
                let gnu_ls_exists = Command::new("gls")
                    .arg("--version")
                    .stdout(Stdio::null())
                    .stderr(Stdio::null())
                    .status()
                    .is_ok();

                if gnu_ls_exists {
                    gnu_ls("gls")
                } else {
                    let mut cmd = vec![
                        "ls", // MacOS version of ls
                        "-l", // long listing format
                        "-h", // '--human-readable' is not available on MacOS, '-h' is
                        "-d", // '--directory' is not available, but '-d' is
                    ];

                    if colored_output {
                        cmd.push("-G");
                    }

                    cmd
                }
            }
        } else if cfg!(windows) {
            use std::process::{Command, Stdio};

            // Use GNU ls, if available
            let gnu_ls_exists = Command::new("ls")
                .arg("--version")
                .stdout(Stdio::null())
                .stderr(Stdio::null())
                .status()
                .is_ok();

            if gnu_ls_exists {
                gnu_ls("ls")
            } else {
                return Err(anyhow!(
                    "'fd --list-details' is not supported on this platform."
                ));
            }
        } else {
            return Err(anyhow!(
                "'fd --list-details' is not supported on Windows unless GNU 'ls' is installed."
            ));
        };

        Some(CommandTemplate::new_batch(&cmd).unwrap())
    } else {
        None
    };

    let size_limits = if let Some(vs) = matches.values_of("size") {
        vs.map(|sf| {
            SizeFilter::from_string(sf).ok_or(anyhow!(
                "'{}' is not a valid size constraint. See 'fd --help'.",
                sf
            ))
        })
        .collect::<Result<Vec<_>>>()?
    } else {
        vec![]
    };

    let now = time::SystemTime::now();
    let mut time_constraints: Vec<TimeFilter> = Vec::new();
    if let Some(t) = matches.value_of("changed-within") {
        if let Some(f) = TimeFilter::after(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }
    if let Some(t) = matches.value_of("changed-before") {
        if let Some(f) = TimeFilter::before(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }

    let config = Options {
        case_sensitive,
        search_full_path: matches.is_present("full-path"),
        ignore_hidden: !(matches.is_present("hidden")
            || matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
        read_fdignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")),
        read_vcsignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")
            || matches.is_present("no-ignore-vcs")),
        follow_links: matches.is_present("follow"),
        one_file_system: matches.is_present("one-file-system"),
        null_separator: matches.is_present("null_separator"),
        max_depth: matches
            .value_of("max-depth")
            .or_else(|| matches.value_of("rg-depth"))
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        min_depth: matches
            .value_of("min-depth")
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        threads: std::cmp::max(
            matches
                .value_of("threads")
                .and_then(|n| usize::from_str_radix(n, 10).ok())
                .unwrap_or_else(num_cpus::get),
            1,
        ),
        max_buffer_time: matches
            .value_of("max-buffer-time")
            .and_then(|n| u64::from_str_radix(n, 10).ok())
            .map(time::Duration::from_millis),
        ls_colors,
        interactive_terminal,
        file_types: matches.values_of("file-type").map(|values| {
            let mut file_types = FileTypes::default();
            for value in values {
                match value {
                    "f" | "file" => file_types.files = true,
                    "d" | "directory" => file_types.directories = true,
                    "l" | "symlink" => file_types.symlinks = true,
                    "x" | "executable" => {
                        file_types.executables_only = true;
                        file_types.files = true;
                    }
                    "e" | "empty" => {
                        file_types.empty_only = true;
                    }
                    _ => unreachable!(),
                }
            }

            // If only 'empty' was specified, search for both files and directories:
            if file_types.empty_only && !(file_types.files || file_types.directories) {
                file_types.files = true;
                file_types.directories = true;
            }

            file_types
        }),
        extensions: matches
            .values_of("extension")
            .map(|exts| {
                let patterns = exts
                    .map(|e| e.trim_start_matches('.'))
                    .map(|e| format!(r".\.{}$", regex::escape(e)));
                RegexSetBuilder::new(patterns)
                    .case_insensitive(true)
                    .build()
            })
            .transpose()?,
        command: command.map(Arc::new),
        exclude_patterns: matches
            .values_of("exclude")
            .map(|v| v.map(|p| String::from("!") + p).collect())
            .unwrap_or_else(|| vec![]),
        ignore_files: matches
            .values_of("ignore-file")
            .map(|vs| vs.map(PathBuf::from).collect())
            .unwrap_or_else(|| vec![]),
        size_constraints: size_limits,
        time_constraints,
        show_filesystem_errors: matches.is_present("show-errors"),
        path_separator,
        max_results: matches
            .value_of("max-results")
            .and_then(|n| usize::from_str_radix(n, 10).ok())
            .filter(|&n| n != 0)
            .or_else(|| {
                if matches.is_present("max-one-result") {
                    Some(1)
                } else {
                    None
                }
            }),
    };

    let re = RegexBuilder::new(&pattern_regex)
        .case_insensitive(!config.case_sensitive)
        .dot_matches_new_line(true)
        .build()
        .map_err(|e| {
            anyhow!(
                "{}\n\nNote: You can use the '--fixed-strings' option to search for a \
                 literal string instead of a regular expression. Alternatively, you can \
                 also use the '--glob' option to match on a glob pattern.",
                e.to_string()
            )
        })?;

    walk::scan(&dir_vec, Arc::new(re), Arc::new(config))
}

fn main() {
    let result = run();
    match result {
        Ok(exit_code) => {
            process::exit(exit_code.into());
        }
        Err(err) => {
            eprintln!("[fd error]: {}", err);
            process::exit(ExitCode::GeneralError.into());
        }
    }
}
<|endoftext|>


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

use perlinish;

pub const WINDOW_WIDTH: u32 = 1800;
pub const WINDOW_HEIGHT: u32 = 1000;

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

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

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

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

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

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

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

  let heightmap = make_heightmap(gl);

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

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

  let empty_vao = ArrayHandle::new(gl);

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

  let mut event_pump = sdl.event_pump();

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

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

  timers.print();
}

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

    out vec4 world_pos;

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

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

    uniform samplerBuffer heightmap;

    in vec4 world_pos;

    layout(location=0) out vec4 frag_color;

    void main() {{
      int x = int(round(gl_FragCoord.x));
      float h = texelFetch(heightmap, x).r;
      if (world_pos.y <= h) {{
        frag_color = vec4(1, 0, 0, 1);
      }} else {{
        frag_color = vec4(0, 0, 0, 1);
      }}
    }}
  ");

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

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

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

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

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

  window.build().unwrap()
}

fn make_heightmap<'a, 'b:'a>(
  gl: &'a mut GLContext,
) -> BufferTexture<'b, f32> {
  let mut ram_heightmap = [0.0; WINDOW_WIDTH as usize];

  for i in 0..WINDOW_WIDTH as usize {
    let x = i as f32;
    let x = x / WINDOW_WIDTH as f32 * 16.0;
    let h = perlinish::eval(1.0 / 16.0, x);
    ram_heightmap[i] = h;
  }

  let mut vram_heightmap = BufferTexture::new(gl, gl::R32F, WINDOW_WIDTH as usize);
  vram_heightmap.buffer.push(gl, &ram_heightmap);
  vram_heightmap
}

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

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

use perlinish;

pub const WINDOW_WIDTH: u32 = 1800;
pub const WINDOW_HEIGHT: u32 = 1000;

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

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

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

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

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

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

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

  let heightmap = make_heightmap(gl);

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

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

  let empty_vao = ArrayHandle::new(gl);

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

  let mut event_pump = sdl.event_pump();

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

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

  timers.print();
}

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

    out vec4 world_pos;

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

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

    uniform samplerBuffer heightmap;

    in vec4 world_pos;

    layout(location=0) out vec4 frag_color;

    void main() {{
      int x = int(round(gl_FragCoord.x));
      float h = texelFetch(heightmap, x).r;
      if (world_pos.y <= h) {{
        frag_color = vec4(1, 0, 0, 1);
      }} else {{
        frag_color = vec4(0, 0, 0, 1);
      }}
    }}
  ");

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

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

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

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

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

  window.build().unwrap()
}

fn make_heightmap<'a, 'b:'a>(
  gl: &'a mut GLContext,
) -> BufferTexture<'b, f32> {
  let mut ram_heightmap = [0.0; WINDOW_WIDTH as usize];

  for i in 0..WINDOW_WIDTH as usize {
    let x = i as f32;
    let x = x / WINDOW_WIDTH as f32 * 16.0;
    let h = perlinish::eval(1.0, x);
    ram_heightmap[i] = h;
  }

  let mut vram_heightmap = BufferTexture::new(gl, gl::R32F, WINDOW_WIDTH as usize);
  vram_heightmap.buffer.push(gl, &ram_heightmap);
  vram_heightmap
}

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

  true
}
<|endoftext|>


<commit_before>use std::thread;
use std::sync::mpsc;

fn main() {

    let (sender, receiver): (mpsc::Sender<i32>, mpsc::Receiver<i32>) = mpsc::channel();

    thread::Builder::new()
                        .name("thread_1".to_string())
                        .stack_size(1024 * 1024 * 5)
                        .spawn(move || {
                            sender.send(111).unwrap();
                        }).unwrap();

    println!("{:?}", receiver.recv().unwrap());
}<commit_msg>test: mutex<commit_after>use std::thread;
use std::sync::{Arc, Mutex, Condvar};

fn main() {

    let wrapper = Arc::new((Mutex::new(false), Condvar::new()));
    let wrapper_temp = wrapper.clone();

    let (ref lock, ref cvar) = *wrapper;
    let mut state = lock.lock().unwrap();

    thread::spawn(move || {
        let (ref lock, ref cvar) = *wrapper_temp;
        let mut state = lock.lock().unwrap();

        *state = true;
        cvar.notify_one();
        println!("notify main");
    });

    while !*state {
        println!("before main wait");

        state = cvar.wait(state).unwrap();

        println!("after main wait");
    }
}<|endoftext|>