<commit_before>#![crate_name = "uu_pr"]

// This file is part of the uutils coreutils package.
//
// For the full copyright and license information, please view the LICENSE file
// that was distributed with this source code.
//

extern crate getopts;
extern crate chrono;

//#[macro_use]
//extern crate uucore;
use std::fs;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::vec::Vec;
use chrono::offset::Local;
use chrono::DateTime;

//use uucore::fs::is_stdin_interactive;

static NAME: &str = "pr";
static VERSION: &str = env!("CARGO_PKG_VERSION");
static LINES_PER_PAGE: usize = 66;
static HEADER_LINES_PER_PAGE: usize = 5;
static TRAILER_LINES_PER_PAGE: usize = 5;
static CONTENT_LINES_PER_PAGE: usize = LINES_PER_PAGE - HEADER_LINES_PER_PAGE - TRAILER_LINES_PER_PAGE;

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = getopts::Options::new();

    opts.optopt(
        "h",
        "",
        "Use the string header to replace the file name \
     in the header line.",
        "STRING",
    );
    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("V", "version", "output version information and exit");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(e) => panic!("Invalid options\n{}", e),
    };

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }

    if matches.opt_present("help") || matches.free.is_empty() {
        println!("{} {} -- print files", NAME, VERSION);
        println!();
        println!("Usage: {} [+page] [-column] [-adFfmprt] [[-e] [char] [gap]]
        [-L locale] [-h header] [[-i] [char] [gap]]
        [-l lines] [-o offset] [[-s] [char]] [[-n] [char]
        [width]] [-w width] [-] [file ...].", NAME);
        println!();
        println!(
            "{}",
            opts.usage(
                "The pr utility is a printing and pagination filter
     for text files.  When multiple input files are spec-
     ified, each is read, formatted, and written to stan-
     dard output.  By default, the input is separated
     into 66-line pages, each with

     o   A 5-line header with the page number, date,
         time, and the pathname of the file.

     o   A 5-line trailer consisting of blank lines.

     If standard output is associated with a terminal,
     diagnostic messages are suppressed until the pr
     utility has completed processing.

     When multiple column output is specified, text col-
     umns are of equal width.  By default text columns
     are separated by at least one <blank>.  Input lines
     that do not fit into a text column are truncated.
     Lines are not truncated under single column output."
            )
        );
        if matches.free.is_empty() {
            return 1;
        }
        return 0;
    }

    let path = &matches.free[0];
    open(&path);

    0
}

fn open(path: &str) -> std::io::Result<()> {
    let file = File::open(path)?;
    let file_last_modified_time = file_last_modified_time(path);
    let lines = BufReader::new(file).lines();
    let mut i = 0;
    let mut page: i32 = 0;
    let mut buffered_content: Vec<String> = Vec::new();
    for line in lines {
        if i == CONTENT_LINES_PER_PAGE {
            page = page + 1;
            i = 0;
            let header = header_content(&file_last_modified_time, path, page);
            print!("{}", print_page(&header, &buffered_content));
            buffered_content.clear();
        }
        i = i + 1;
        buffered_content.push(line?);
    }
    if i != 0 {
        let header = header_content(&file_last_modified_time, path, page);
        print!("{}", print_page(&header, &buffered_content));
        buffered_content.clear();
    }
    Ok(())
}

fn print_page(header_content: &Vec<String>, lines: &Vec<String>) -> String {
    let mut page_content: Vec<String> = Vec::new();
    let trailer_content = trailer_content();
    assert_eq!(lines.len() <= CONTENT_LINES_PER_PAGE, true, "Only {} lines of content allowed in a pr output page", CONTENT_LINES_PER_PAGE.to_string());
    assert_eq!(header_content.len(), HEADER_LINES_PER_PAGE, "Only {} lines of content allowed in a pr header", HEADER_LINES_PER_PAGE.to_string());
    assert_eq!(trailer_content.len(), TRAILER_LINES_PER_PAGE, "Only {} lines of content allowed in a pr trailer", TRAILER_LINES_PER_PAGE.to_string());
    for x in header_content {
        page_content.push(x.to_string());
    }
    for x in lines {
        page_content.push(x.to_string());
    }
    page_content.extend(trailer_content);
    page_content.join("\n")
}

fn header_content(last_modified: &String, path: &str, page: i32) -> Vec<String> {
    let first_line: String = format!("{} {} Page {}", last_modified, path, page.to_string());
    vec![first_line, "".to_string(), "".to_string(), "".to_string(), "".to_string()]
}

fn file_last_modified_time(path: &str) -> String {
    let file_metadata = fs::metadata(path);
    return file_metadata.map(|i| {
        return i.modified().map(|x| {
            let datetime: DateTime<Local> = x.into();
            datetime.format("%b %d %H:%M %Y").to_string()
        }).unwrap_or(String::new());
    }).unwrap_or(String::new());
}

fn trailer_content() -> Vec<String> {
    vec!["".to_string(), "".to_string(), "".to_string(), "".to_string(), "".to_string()]
}
<commit_msg>pr: add -h to print header and -n to print line numbers<commit_after>#![crate_name = "uu_pr"]

// This file is part of the uutils coreutils package.
//
// For the full copyright and license information, please view the LICENSE file
// that was distributed with this source code.
//

extern crate getopts;
extern crate chrono;

//#[macro_use]
//extern crate uucore;
use std::fs;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::vec::Vec;
use chrono::offset::Local;
use chrono::DateTime;

//use uucore::fs::is_stdin_interactive;

static NAME: &str = "pr";
static VERSION: &str = env!("CARGO_PKG_VERSION");
static LINES_PER_PAGE: usize = 66;
static HEADER_LINES_PER_PAGE: usize = 5;
static TRAILER_LINES_PER_PAGE: usize = 5;
static CONTENT_LINES_PER_PAGE: usize = LINES_PER_PAGE - HEADER_LINES_PER_PAGE - TRAILER_LINES_PER_PAGE;
static NUMBERING_MODE_DEFAULT_SEPARATOR: &str = "\t";
static NUMBERING_MODE_DEFAULT_WIDTH: usize = 5;

struct OutputOptions {
    /// Line numbering mode
    number: Option<NumberingMode>,
    header: String,
}

impl AsRef<OutputOptions> for OutputOptions {
    fn as_ref(&self) -> &OutputOptions {
        self
    }
}

struct NumberingMode {
    /// Line numbering mode
    width: usize,
    separator: String,
}

impl Default for NumberingMode {
    fn default() -> NumberingMode {
        NumberingMode {
            width: NUMBERING_MODE_DEFAULT_WIDTH,
            separator: NUMBERING_MODE_DEFAULT_SEPARATOR.to_string(),
        }
    }
}

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = getopts::Options::new();

    opts.optopt(
        "h",
        "",
        "Use the string header to replace the file name \
     in the header line.",
        "STRING",
    );

    opts.optflagopt(
        "n",
        "",
        "Provide width digit line numbering.  The default for width, if not specified, is 5.  The number occupies
           the first width column positions of each text column or each line of -m output.  If char (any nondigit
           character) is given, it is appended to the line number to separate it from whatever follows.  The default
           for char is a <tab>.  Line numbers longer than width columns are truncated.",
        "[char][width]",
    );

    opts.optflag("", "help", "display this help and exit");
    opts.optflag("V", "version", "output version information and exit");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(e) => panic!("Invalid options\n{}", e),
    };

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }

    if matches.opt_present("help") || matches.free.is_empty() {
        println!("{} {} -- print files", NAME, VERSION);
        println!();
        println!("Usage: {} [+page] [-column] [-adFfmprt] [[-e] [char] [gap]]
        [-L locale] [-h header] [[-i] [char] [gap]]
        [-l lines] [-o offset] [[-s] [char]] [[-n] [char]
        [width]] [-w width] [-] [file ...].", NAME);
        println!();
        let usage: &str = "The pr utility is a printing and pagination filter
     for text files.  When multiple input files are spec-
     ified, each is read, formatted, and written to stan-
     dard output.  By default, the input is separated
     into 66-line pages, each with

     o   A 5-line header with the page number, date,
         time, and the pathname of the file.

     o   A 5-line trailer consisting of blank lines.

     If standard output is associated with a terminal,
     diagnostic messages are suppressed until the pr
     utility has completed processing.

     When multiple column output is specified, text col-
     umns are of equal width.  By default text columns
     are separated by at least one <blank>.  Input lines
     that do not fit into a text column are truncated.
     Lines are not truncated under single column output.";
        println!("{}", opts.usage(usage));
        if matches.free.is_empty() {
            return 1;
        }
        return 0;
    }

    let path = &matches.free[0];
    let header: String = matches.opt_str("h").unwrap_or(path.to_string());
    let numbering_options = matches.opt_str("n").map(|i| {
        NumberingMode {
            width: i.parse::<usize>().unwrap_or(NumberingMode::default().width),
            separator: NumberingMode::default().separator,
        }
    }).or_else(|| {
        if matches.opt_present("n") {
            return Some(NumberingMode::default());
        }
        return None;
    });

    let options = OutputOptions {
        number: numbering_options,
        header,
    };

    pr(&path, options);

    0
}

fn pr(path: &str, options: OutputOptions) -> std::io::Result<()> {
    let file = File::open(path)?;
    let file_last_modified_time = file_last_modified_time(path);
    let lines = BufReader::new(file).lines();
    let mut i = 0;
    let mut page: usize = 0;
    let mut buffered_content: Vec<String> = Vec::new();
    for line in lines {
        if i == CONTENT_LINES_PER_PAGE {
            page = page + 1;
            i = 0;
            flush_buffered_page(&file_last_modified_time, &mut buffered_content, &options, page);
        }
        i = i + 1;
        buffered_content.push(line?);
    }
    if i != 0 {
        page = page + 1;
        flush_buffered_page(&file_last_modified_time, &mut buffered_content, &options, page);
    }
    Ok(())
}

fn print_page(header_content: &Vec<String>, lines: &Vec<String>, options: &OutputOptions, page: usize) -> String {
    let mut page_content: Vec<String> = Vec::new();
    let trailer_content = trailer_content();
    assert_eq!(lines.len() <= CONTENT_LINES_PER_PAGE, true, "Only {} lines of content allowed in a pr output page", CONTENT_LINES_PER_PAGE.to_string());
    assert_eq!(header_content.len(), HEADER_LINES_PER_PAGE, "Only {} lines of content allowed in a pr header", HEADER_LINES_PER_PAGE.to_string());
    assert_eq!(trailer_content.len(), TRAILER_LINES_PER_PAGE, "Only {} lines of content allowed in a pr trailer", TRAILER_LINES_PER_PAGE.to_string());
    for x in header_content {
        page_content.push(x.to_string());
    }

    let width: usize = options.as_ref()
        .number.as_ref()
        .map(|i| i.width)
        .unwrap_or(0);
    let separator: String = options.as_ref()
        .number.as_ref()
        .map(|i| i.separator.to_string())
        .unwrap_or(NumberingMode::default().separator);

    let prev_lines = CONTENT_LINES_PER_PAGE * (page - 1);
    let mut i = 1;
    for x in lines {
        if options.number.is_none() {
            page_content.push(x.to_string());
        } else {
            let fmtd_line_number: String = get_fmtd_line_number(width, prev_lines + i, &separator);
            page_content.push(format!("{}{}", fmtd_line_number, x.to_string()));
        }
        i = i + 1;
    }
    page_content.extend(trailer_content);
    page_content.join("\n")
}

fn get_fmtd_line_number(width: usize, line_number: usize, separator: &String) -> String {
    format!("{:>width$}{}", take_last_n(&line_number.to_string(), width), separator, width = width)
}

fn take_last_n(s: &String, n: usize) -> &str {
    if s.len() >= n {
        &s[s.len() - n..]
    } else {
        s
    }
}

fn flush_buffered_page(file_last_modified_time: &String, buffered_content: &mut Vec<String>, options: &OutputOptions, page: usize) {
    let header = header_content(file_last_modified_time, &options.header, page);
    print!("{}", print_page(&header, buffered_content, &options, page));
    buffered_content.clear();
}

fn header_content(last_modified: &String, header: &String, page: usize) -> Vec<String> {
    let first_line: String = format!("{} {} Page {}", last_modified, header, page.to_string());
    vec!["".to_string(), "".to_string(), first_line, "".to_string(), "".to_string()]
}

fn file_last_modified_time(path: &str) -> String {
    let file_metadata = fs::metadata(path);
    return file_metadata.map(|i| {
        return i.modified().map(|x| {
            let datetime: DateTime<Local> = x.into();
            datetime.format("%b %d %H:%M %Y").to_string()
        }).unwrap_or(String::new());
    }).unwrap_or(String::new());
}

fn trailer_content() -> Vec<String> {
    vec!["".to_string(), "".to_string(), "".to_string(), "".to_string(), "".to_string()]
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Rot-13

fn rot13(string: &str) -> String {
    fn rot13u8(c: char) -> char {
        let d = c as u8;
        match c {
            'a'...'m' |
            'A'...'M' => (d + 13) as char,
            'n'...'z' |
            'N'...'Z' => (d - 13) as char,
            _ => c,
        }
    }

    string.chars().map(rot13u8).collect()
}

fn main() {
    let string = "Do you love apples?";

    println!("Original: {}", string);
    println!("Encoded: {}", rot13(string));
}

#[test]
fn test_basic() {
    assert_eq!(rot13("abc"), "nop");
}

#[test]

fn test_coherence() {
    assert!((50000i32..50050).map(|x| format!("{}", x)).all(|s| {
        let encoded = rot13(&s[..]);
        let decoded = rot13(&encoded[..]);
        decoded == s
    }));
}
<commit_msg>avoid complex closures in if statements<commit_after>// http://rosettacode.org/wiki/Rot-13

fn rot13(string: &str) -> String {
    fn rot13u8(c: char) -> char {
        let d = c as u8;
        match c {
            'a'...'m' | 'A'...'M' => (d + 13) as char,
            'n'...'z' | 'N'...'Z' => (d - 13) as char,
            _ => c,
        }
    }

    string.chars().map(rot13u8).collect()
}

fn main() {
    let string = "Do you love apples?";

    println!("Original: {}", string);
    println!("Encoded: {}", rot13(string));
}

#[test]
fn test_basic() {
    assert_eq!(rot13("abc"), "nop");
}

#[test]
fn test_coherence() {
    let coherence_test = (50000i32..50050).map(|x| format!("{}", x)).all(|s| {
        let encoded = rot13(&s[..]);
        let decoded = rot13(&encoded[..]);
        decoded == s
    });

    assert!(coherence_test);
}
<|endoftext|>


<commit_before>use std::mem;
use libc::{c_int, c_uint, c_void, c_ulong};
use errno::Errno;
use {Result, Error};

pub type CloneFlags = c_uint;

pub static CLONE_VM:             CloneFlags = 0x00000100;
pub static CLONE_FS:             CloneFlags = 0x00000200;
pub static CLONE_FILES:          CloneFlags = 0x00000400;
pub static CLONE_SIGHAND:        CloneFlags = 0x00000800;
pub static CLONE_PTRACE:         CloneFlags = 0x00002000;
pub static CLONE_VFORK:          CloneFlags = 0x00004000;
pub static CLONE_PARENT:         CloneFlags = 0x00008000;
pub static CLONE_THREAD:         CloneFlags = 0x00010000;
pub static CLONE_NEWNS:          CloneFlags = 0x00020000;
pub static CLONE_SYSVSEM:        CloneFlags = 0x00040000;
pub static CLONE_SETTLS:         CloneFlags = 0x00080000;
pub static CLONE_PARENT_SETTID:  CloneFlags = 0x00100000;
pub static CLONE_CHILD_CLEARTID: CloneFlags = 0x00200000;
pub static CLONE_DETACHED:       CloneFlags = 0x00400000;
pub static CLONE_UNTRACED:       CloneFlags = 0x00800000;
pub static CLONE_CHILD_SETTID:   CloneFlags = 0x01000000;
pub static CLONE_NEWUTS:         CloneFlags = 0x04000000;
pub static CLONE_NEWIPC:         CloneFlags = 0x08000000;
pub static CLONE_NEWUSER:        CloneFlags = 0x10000000;
pub static CLONE_NEWPID:         CloneFlags = 0x20000000;
pub static CLONE_NEWNET:         CloneFlags = 0x40000000;
pub static CLONE_IO:             CloneFlags = 0x80000000;

// Support a maximum CPU set of 1024 nodes
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
mod cpuset_attribs {
    use super::CpuMask;
    pub const CPU_SETSIZE:           usize = 1024;
    pub const CPU_MASK_BITS:         usize = 64;

    #[inline]
    pub fn set_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur | (1u64 << bit)
    }

    #[inline]
    pub fn clear_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur & !(1u64 << bit)
    }
}

#[cfg(all(target_arch = "x86", target_os = "linux"))]
mod cpuset_attribs {
    use super::CpuMask;
    pub const CPU_SETSIZE:           usize = 1024;
    pub const CPU_MASK_BITS:         usize = 32;

    #[inline]
    pub fn set_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur | (1u32 << bit)
    }

    #[inline]
    pub fn clear_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur & !(1u32 << bit)
    }
}

#[cfg(all(target_arch = "arm", target_os = "android"))]
mod cpuset_attribs {
    use super::CpuMask;
    // bionic only supports up to 32 independent CPUs, instead of 1024.
    pub const CPU_SETSIZE:          usize = 32;
    pub const CPU_MASK_BITS:        usize = 32;

    #[inline]
    pub fn set_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur | (1u32 << bit)
    }

    #[inline]
    pub fn clear_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur & !(1u32 << bit)
    }
}

pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>;

// A single CPU mask word
pub type CpuMask = c_ulong;

// Structure representing the CPU set to apply
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CpuSet {
    cpu_mask: [CpuMask; cpuset_attribs::CPU_SETSIZE/cpuset_attribs::CPU_MASK_BITS]
}

impl CpuSet {
    pub fn new() -> CpuSet {
        CpuSet {
            cpu_mask: unsafe { mem::zeroed() }
        }
    }

    pub fn set(&mut self, field: usize) {
        let word = field / cpuset_attribs::CPU_MASK_BITS;
        let bit = field % cpuset_attribs::CPU_MASK_BITS;

        self.cpu_mask[word] = cpuset_attribs::set_cpu_mask_flag(self.cpu_mask[word], bit);
    }

    pub fn unset(&mut self, field: usize) {
        let word = field / cpuset_attribs::CPU_MASK_BITS;
        let bit = field % cpuset_attribs::CPU_MASK_BITS;

        self.cpu_mask[word] = cpuset_attribs::clear_cpu_mask_flag(self.cpu_mask[word], bit);
    }
}

mod ffi {
    use libc::{c_void, c_int, pid_t, size_t};
    use super::CpuSet;

    type CloneCb = extern "C" fn (data: *const super::CloneCb) -> c_int;

    // We cannot give a proper #[repr(C)] to super::CloneCb
    #[allow(improper_ctypes)]
    extern {
        // create a child process
        // doc: http://man7.org/linux/man-pages/man2/clone.2.html
        pub fn clone(
            cb: *const CloneCb,
            child_stack: *mut c_void,
            flags: super::CloneFlags,
            arg: *mut super::CloneCb,
            ...) -> c_int;

        // disassociate parts of the process execution context
        // doc: http://man7.org/linux/man-pages/man2/unshare.2.html
        pub fn unshare(flags: super::CloneFlags) -> c_int;

        // Set the current CPU set that a task is allowed to run on
        pub fn sched_setaffinity(__pid: pid_t, __cpusetsize: size_t, __cpuset: *const CpuSet) -> c_int;
    }
}

pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> Result<()> {
    use libc::{pid_t, size_t};

    let res = unsafe {
        ffi::sched_setaffinity(pid as pid_t, mem::size_of::<CpuSet>() as size_t, mem::transmute(cpuset))
    };

    if res != 0 {
        Err(Error::Sys(Errno::last()))
    } else {
        Ok(())
    }
}

pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> Result<()> {
    extern "C" fn callback(data: *mut CloneCb) -> c_int {
        let cb: &mut CloneCb = unsafe { &mut *data };
        (*cb)() as c_int
    }

    let res = unsafe {
        let ptr = stack.as_mut_ptr().offset(stack.len() as isize);
        ffi::clone(mem::transmute(callback), ptr as *mut c_void, flags, &mut cb)
    };

    if res != 0 {
        return Err(Error::Sys(Errno::last()));
    }

    Ok(())
}

pub fn unshare(flags: CloneFlags) -> Result<()> {
    let res = unsafe { ffi::unshare(flags) };

    if res != 0 {
        return Err(Error::Sys(Errno::last()));
    }

    Ok(())
}
<commit_msg>sched: add support for arm linux using same cpuset_attribs as android<commit_after>use std::mem;
use libc::{c_int, c_uint, c_void, c_ulong};
use errno::Errno;
use {Result, Error};

pub type CloneFlags = c_uint;

pub static CLONE_VM:             CloneFlags = 0x00000100;
pub static CLONE_FS:             CloneFlags = 0x00000200;
pub static CLONE_FILES:          CloneFlags = 0x00000400;
pub static CLONE_SIGHAND:        CloneFlags = 0x00000800;
pub static CLONE_PTRACE:         CloneFlags = 0x00002000;
pub static CLONE_VFORK:          CloneFlags = 0x00004000;
pub static CLONE_PARENT:         CloneFlags = 0x00008000;
pub static CLONE_THREAD:         CloneFlags = 0x00010000;
pub static CLONE_NEWNS:          CloneFlags = 0x00020000;
pub static CLONE_SYSVSEM:        CloneFlags = 0x00040000;
pub static CLONE_SETTLS:         CloneFlags = 0x00080000;
pub static CLONE_PARENT_SETTID:  CloneFlags = 0x00100000;
pub static CLONE_CHILD_CLEARTID: CloneFlags = 0x00200000;
pub static CLONE_DETACHED:       CloneFlags = 0x00400000;
pub static CLONE_UNTRACED:       CloneFlags = 0x00800000;
pub static CLONE_CHILD_SETTID:   CloneFlags = 0x01000000;
pub static CLONE_NEWUTS:         CloneFlags = 0x04000000;
pub static CLONE_NEWIPC:         CloneFlags = 0x08000000;
pub static CLONE_NEWUSER:        CloneFlags = 0x10000000;
pub static CLONE_NEWPID:         CloneFlags = 0x20000000;
pub static CLONE_NEWNET:         CloneFlags = 0x40000000;
pub static CLONE_IO:             CloneFlags = 0x80000000;

// Support a maximum CPU set of 1024 nodes
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
mod cpuset_attribs {
    use super::CpuMask;
    pub const CPU_SETSIZE:           usize = 1024;
    pub const CPU_MASK_BITS:         usize = 64;

    #[inline]
    pub fn set_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur | (1u64 << bit)
    }

    #[inline]
    pub fn clear_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur & !(1u64 << bit)
    }
}

#[cfg(all(target_arch = "x86", target_os = "linux"))]
mod cpuset_attribs {
    use super::CpuMask;
    pub const CPU_SETSIZE:           usize = 1024;
    pub const CPU_MASK_BITS:         usize = 32;

    #[inline]
    pub fn set_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur | (1u32 << bit)
    }

    #[inline]
    pub fn clear_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur & !(1u32 << bit)
    }
}

#[cfg(all(target_arch = "arm", any(target_os = "linux", target_os = "android")))]
mod cpuset_attribs {
    use super::CpuMask;
    // bionic only supports up to 32 independent CPUs, instead of 1024.
    pub const CPU_SETSIZE:          usize = 32;
    pub const CPU_MASK_BITS:        usize = 32;

    #[inline]
    pub fn set_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur | (1u32 << bit)
    }

    #[inline]
    pub fn clear_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
        cur & !(1u32 << bit)
    }
}

pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>;

// A single CPU mask word
pub type CpuMask = c_ulong;

// Structure representing the CPU set to apply
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CpuSet {
    cpu_mask: [CpuMask; cpuset_attribs::CPU_SETSIZE/cpuset_attribs::CPU_MASK_BITS]
}

impl CpuSet {
    pub fn new() -> CpuSet {
        CpuSet {
            cpu_mask: unsafe { mem::zeroed() }
        }
    }

    pub fn set(&mut self, field: usize) {
        let word = field / cpuset_attribs::CPU_MASK_BITS;
        let bit = field % cpuset_attribs::CPU_MASK_BITS;

        self.cpu_mask[word] = cpuset_attribs::set_cpu_mask_flag(self.cpu_mask[word], bit);
    }

    pub fn unset(&mut self, field: usize) {
        let word = field / cpuset_attribs::CPU_MASK_BITS;
        let bit = field % cpuset_attribs::CPU_MASK_BITS;

        self.cpu_mask[word] = cpuset_attribs::clear_cpu_mask_flag(self.cpu_mask[word], bit);
    }
}

mod ffi {
    use libc::{c_void, c_int, pid_t, size_t};
    use super::CpuSet;

    type CloneCb = extern "C" fn (data: *const super::CloneCb) -> c_int;

    // We cannot give a proper #[repr(C)] to super::CloneCb
    #[allow(improper_ctypes)]
    extern {
        // create a child process
        // doc: http://man7.org/linux/man-pages/man2/clone.2.html
        pub fn clone(
            cb: *const CloneCb,
            child_stack: *mut c_void,
            flags: super::CloneFlags,
            arg: *mut super::CloneCb,
            ...) -> c_int;

        // disassociate parts of the process execution context
        // doc: http://man7.org/linux/man-pages/man2/unshare.2.html
        pub fn unshare(flags: super::CloneFlags) -> c_int;

        // Set the current CPU set that a task is allowed to run on
        pub fn sched_setaffinity(__pid: pid_t, __cpusetsize: size_t, __cpuset: *const CpuSet) -> c_int;
    }
}

pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> Result<()> {
    use libc::{pid_t, size_t};

    let res = unsafe {
        ffi::sched_setaffinity(pid as pid_t, mem::size_of::<CpuSet>() as size_t, mem::transmute(cpuset))
    };

    if res != 0 {
        Err(Error::Sys(Errno::last()))
    } else {
        Ok(())
    }
}

pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> Result<()> {
    extern "C" fn callback(data: *mut CloneCb) -> c_int {
        let cb: &mut CloneCb = unsafe { &mut *data };
        (*cb)() as c_int
    }

    let res = unsafe {
        let ptr = stack.as_mut_ptr().offset(stack.len() as isize);
        ffi::clone(mem::transmute(callback), ptr as *mut c_void, flags, &mut cb)
    };

    if res != 0 {
        return Err(Error::Sys(Errno::last()));
    }

    Ok(())
}

pub fn unshare(flags: CloneFlags) -> Result<()> {
    let res = unsafe { ffi::unshare(flags) };

    if res != 0 {
        return Err(Error::Sys(Errno::last()));
    }

    Ok(())
}
<|endoftext|>


<commit_before>#![no_std]

use libtock_platform::{
    share::Handle, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall,
};

/// The Buttons driver
///
/// # Example
/// ```ignore
/// use libtock2::Buttons;
///
/// // Read button state
/// Buttons::is_pressed(0);
///
/// // Register for events
///
/// let listener = ButtonListener(|button, state| {
///     // make use of the button's state
/// });
///
/// share::scope(|subscribe| {
///     if let Ok(()) = Buttons::register_listener(&listener, subscribe) {
///         // yield
///     }
/// });
/// ```
pub struct Buttons<S: Syscalls>(S);

#[derive(Debug, PartialEq)]
pub enum ButtonState {
    Pressed,
    Released,
    Unknown,
}

impl From<u32> for ButtonState {
    fn from(original: u32) -> ButtonState {
        match original {
            0 => ButtonState::Released,
            1 => ButtonState::Pressed,
            _ => ButtonState::Unknown,
        }
    }
}

impl<S: Syscalls> Buttons<S> {
    /// Run a check against the buttons capsule to ensure it is present.
    ///
    /// Returns `Some(number_of_buttons)` if the driver was present. This does not necessarily mean
    /// that the driver is working, as it may still fail to allocate grant
    /// memory.
    pub fn count() -> Result<u32, ErrorCode> {
        S::command(DRIVER_ID, BUTTONS_COUNT, 0, 0).to_result()
    }

    pub fn read(button: u32) -> Result<ButtonState, ErrorCode> {
        let button_state: u32 = S::command(DRIVER_ID, BUTTONS_READ, button, 0).to_result()?;
        Ok(button_state.into())
    }

    pub fn is_pressed(button: u32) -> bool {
        Self::read(button)
            .map(|state| state == ButtonState::Pressed)
            .unwrap_or(false)
    }

    pub fn is_released(button: u32) -> bool {
        Self::read(button)
            .map(|state| state == ButtonState::Released)
            .unwrap_or(false)
    }

    pub fn enable_interrupts(button: u32) -> Result<(), ErrorCode> {
        S::command(DRIVER_ID, BUTTONS_ENABLE_INTERRUPTS, button, 0).to_result()
    }

    pub fn disable_interrupts(button: u32) -> Result<(), ErrorCode> {
        S::command(DRIVER_ID, BUTTONS_DISABLE_INTERRUPTS, button, 0).to_result()
    }

    pub fn register_listener<'share, F: Fn(u32, ButtonState)>(
        listener: &'share ButtonListener<F>,
        subscribe: Handle<Subscribe<'share, S, DRIVER_ID, 0>>,
    ) -> Result<(), ErrorCode> {
        S::subscribe::<_, _, DefaultConfig, DRIVER_ID, 0>(subscribe, listener)
    }

    pub fn unregister_listener() {
        S::unsubscribe(DRIVER_ID, 0)
    }
}

pub struct ButtonListener<F: Fn(u32, ButtonState)>(pub F);

impl<F: Fn(u32, ButtonState)> Upcall<OneId<DRIVER_ID, 0>> for ButtonListener<F> {
    fn upcall(&self, button_index: u32, state: u32, _arg2: u32) {
        self.0(button_index, state.into())
    }
}

const DRIVER_ID: u32 = 3;

// Command IDs
const BUTTONS_COUNT: u32 = 0;

const BUTTONS_ENABLE_INTERRUPTS: u32 = 1;
const BUTTONS_DISABLE_INTERRUPTS: u32 = 2;

const BUTTONS_READ: u32 = 3;

#[cfg(test)]
mod tests;
<commit_msg>documentation<commit_after>#![no_std]

use libtock_platform::{
    share::Handle, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall,
};

/// The Buttons driver
///
/// # Example
/// ```ignore
/// use libtock2::Buttons;
///
/// // Read button state
/// Buttons::is_pressed(0);
///
/// // Register for events
///
/// let listener = ButtonListener(|button, state| {
///     // make use of the button's state
/// });
///
/// share::scope(|subscribe| {
///     if let Ok(()) = Buttons::register_listener(&listener, subscribe) {
///         // yield
///     }
/// });
/// ```
pub struct Buttons<S: Syscalls>(S);

#[derive(Debug, PartialEq)]
pub enum ButtonState {
    Pressed,
    Released,
    Unknown,
}

impl From<u32> for ButtonState {
    fn from(original: u32) -> ButtonState {
        match original {
            0 => ButtonState::Released,
            1 => ButtonState::Pressed,
            _ => ButtonState::Unknown,
        }
    }
}

impl<S: Syscalls> Buttons<S> {
    /// Run a check against the buttons capsule to ensure it is present.
    ///
    /// Returns `Ok(number_of_buttons)` if the driver was present. This does not necessarily mean
    /// that the driver is working.
    pub fn count() -> Result<u32, ErrorCode> {
        S::command(DRIVER_ID, BUTTONS_COUNT, 0, 0).to_result()
    }

    /// Read the state of a button
    pub fn read(button: u32) -> Result<ButtonState, ErrorCode> {
        let button_state: u32 = S::command(DRIVER_ID, BUTTONS_READ, button, 0).to_result()?;
        Ok(button_state.into())
    }

    /// Returns `true` if a button is pressed
    ///
    /// This function returns `false` if:
    /// - the button is released
    /// - the button number is invalid
    /// - there is an error
    pub fn is_pressed(button: u32) -> bool {
        Self::read(button)
            .map(|state| state == ButtonState::Pressed)
            .unwrap_or(false)
    }

    /// Returns `true` if a button is released
    ///
    /// This function returns `false` if:
    /// - the button is pressed
    /// - the button number is invalid
    /// - there is an error
    pub fn is_released(button: u32) -> bool {
        Self::read(button)
            .map(|state| state == ButtonState::Released)
            .unwrap_or(false)
    }

    /// Enable events (interrupts) for a button
    pub fn enable_interrupts(button: u32) -> Result<(), ErrorCode> {
        S::command(DRIVER_ID, BUTTONS_ENABLE_INTERRUPTS, button, 0).to_result()
    }

    /// Disable events (interrupts) for a button
    pub fn disable_interrupts(button: u32) -> Result<(), ErrorCode> {
        S::command(DRIVER_ID, BUTTONS_DISABLE_INTERRUPTS, button, 0).to_result()
    }

    /// Register an events listener
    ///
    /// There can be only one single listener registered at a time.
    /// Each time this function is used, it will replace the
    /// previously registered listener.
    pub fn register_listener<'share, F: Fn(u32, ButtonState)>(
        listener: &'share ButtonListener<F>,
        subscribe: Handle<Subscribe<'share, S, DRIVER_ID, 0>>,
    ) -> Result<(), ErrorCode> {
        S::subscribe::<_, _, DefaultConfig, DRIVER_ID, 0>(subscribe, listener)
    }

    /// Unregister the events listener
    ///
    /// This function may be used even if there was no
    /// previously registered listener.
    pub fn unregister_listener() {
        S::unsubscribe(DRIVER_ID, 0)
    }
}

pub struct ButtonListener<F: Fn(u32, ButtonState)>(pub F);

impl<F: Fn(u32, ButtonState)> Upcall<OneId<DRIVER_ID, 0>> for ButtonListener<F> {
    fn upcall(&self, button_index: u32, state: u32, _arg2: u32) {
        self.0(button_index, state.into())
    }
}

const DRIVER_ID: u32 = 3;

// Command IDs
const BUTTONS_COUNT: u32 = 0;

const BUTTONS_ENABLE_INTERRUPTS: u32 = 1;
const BUTTONS_DISABLE_INTERRUPTS: u32 = 2;

const BUTTONS_READ: u32 = 3;

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>//! This module contains `Key` and `Track` types.

use interpolation::*;

#[derive(Debug, Clone, Copy)]
/// The `Key` Type.
pub struct Key {
    row: u32,
    value: f32,
    interpolation: Interpolation,
}

impl Key {
    /// Construct a new `Key`.
    pub fn new(row: u32, value: f32, interp: Interpolation) -> Key {
        Key {
            row: row,
            value: value,
            interpolation: interp,
        }
    }
}

#[derive(Debug)]
/// The `Track` Type. This is a collection of `Key`s with a name.
pub struct Track {
    name: String,
    keys: Vec<Key>,
}

impl Track {
    /// Construct a new Track with a name.
    pub fn new<S: Into<String>>(name: S) -> Track {
        Track {
            name: name.into(),
            keys: Vec::new(),
        }
    }

    /// Get the name of the track.
    pub fn get_name(&self) -> &str {
        self.name.as_str()
    }

    fn get_exact_position(&self, row: u32) -> Option<usize> {
        self.keys.iter().position(|k| k.row == row)
    }

    fn get_insert_position(&self, row: u32) -> Option<usize> {
        match self.keys.iter().position(|k| k.row >= row) {
            Some(pos) => Some(pos),
            None => None,
        }
    }

    /// Insert or update a key on a track.
    pub fn set_key(&mut self, key: Key) {
        if let Some(pos) = self.get_exact_position(key.row) {
            self.keys[pos] = key;
            println!("Updating {}", pos);
        } else if let Some(pos) = self.get_insert_position(key.row) {
            println!("inserting {}", pos);
            self.keys.insert(pos, key);
        } else {
            self.keys.push(key);
            println!("pushing");
        }

        println!("{:?}", self.keys);
    }

    /// Delete a key from a track.
    ///
    /// If a key does not exist this will do nothing.
    pub fn delete_key(&mut self, row: u32) {
        if let Some(pos) = self.get_exact_position(row) {
            self.keys.remove(pos);
        }
    }

    /// Get a value based on a row.
    ///
    /// The row can be between two integers.
    /// This will perform the required interpolation.
    pub fn get_value(&self, row: f32) -> f32 {
        if self.keys.is_empty() {
            return 0.0;
        }

        let lower_row = row.floor() as u32;

        if lower_row <= self.keys[0].row {
            return self.keys[0].value;
        }

        if lower_row >= self.keys[self.keys.len() - 1].row {
            return self.keys[self.keys.len() - 1].value;
        }

        let pos = self.get_insert_position(lower_row).unwrap() - 1;

        let lower = &self.keys[pos];
        let higher = &self.keys[pos + 1];

        let t = (row - (lower.row as f32)) / ((higher.row as f32) - (lower.row as f32));
        let it = lower.interpolation.interpolate(t);

        (lower.value as f32) + ((higher.value as f32) - (lower.value as f32)) * it
    }
}
<commit_msg>Remove debug info<commit_after>//! This module contains `Key` and `Track` types.

use interpolation::*;

#[derive(Debug, Clone, Copy)]
/// The `Key` Type.
pub struct Key {
    row: u32,
    value: f32,
    interpolation: Interpolation,
}

impl Key {
    /// Construct a new `Key`.
    pub fn new(row: u32, value: f32, interp: Interpolation) -> Key {
        Key {
            row: row,
            value: value,
            interpolation: interp,
        }
    }
}

#[derive(Debug)]
/// The `Track` Type. This is a collection of `Key`s with a name.
pub struct Track {
    name: String,
    keys: Vec<Key>,
}

impl Track {
    /// Construct a new Track with a name.
    pub fn new<S: Into<String>>(name: S) -> Track {
        Track {
            name: name.into(),
            keys: Vec::new(),
        }
    }

    /// Get the name of the track.
    pub fn get_name(&self) -> &str {
        self.name.as_str()
    }

    fn get_exact_position(&self, row: u32) -> Option<usize> {
        self.keys.iter().position(|k| k.row == row)
    }

    fn get_insert_position(&self, row: u32) -> Option<usize> {
        match self.keys.iter().position(|k| k.row >= row) {
            Some(pos) => Some(pos),
            None => None,
        }
    }

    /// Insert or update a key on a track.
    pub fn set_key(&mut self, key: Key) {
        if let Some(pos) = self.get_exact_position(key.row) {
            self.keys[pos] = key;
        } else if let Some(pos) = self.get_insert_position(key.row) {
            self.keys.insert(pos, key);
        } else {
            self.keys.push(key);
        }
    }

    /// Delete a key from a track.
    ///
    /// If a key does not exist this will do nothing.
    pub fn delete_key(&mut self, row: u32) {
        if let Some(pos) = self.get_exact_position(row) {
            self.keys.remove(pos);
        }
    }

    /// Get a value based on a row.
    ///
    /// The row can be between two integers.
    /// This will perform the required interpolation.
    pub fn get_value(&self, row: f32) -> f32 {
        if self.keys.is_empty() {
            return 0.0;
        }

        let lower_row = row.floor() as u32;

        if lower_row <= self.keys[0].row {
            return self.keys[0].value;
        }

        if lower_row >= self.keys[self.keys.len() - 1].row {
            return self.keys[self.keys.len() - 1].value;
        }

        let pos = self.get_insert_position(lower_row).unwrap() - 1;

        let lower = &self.keys[pos];
        let higher = &self.keys[pos + 1];

        let t = (row - (lower.row as f32)) / ((higher.row as f32) - (lower.row as f32));
        let it = lower.interpolation.interpolate(t);

        (lower.value as f32) + ((higher.value as f32) - (lower.value as f32)) * it
    }
}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

// This module provides types that are intrinsic in GIR, so they do not
// get defined through other types. It should ultimately have a name defined
// for every basic type listed in the documentation:
// https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Default_Basic_Types
//
// Exceptions are:
// 1. Fixed-size integer types. These have straightforward machine-independent
//    counterparts in Rust.
// 2. Strings annotated as "utf8" or "filename". These types are not named
//    as such in the C API, being only aliases for gchar*.
//    Their representation in Rust is quite intricate and involves multiple
//    types, so they each get their own module.
//
// Rust aliases are needed for machine-dependent basic types used in GIR,
// since the GLib types are not necessarily identical to their Rust namesakes
// (the issue similarly addressed by libc::c_int and the like).
// GIR uses the GLib names for these types as well.

#![allow(non_camel_case_types)]

use libc;

pub type gboolean       = libc::c_int;
pub type gchar          = libc::c_char;
pub type gint           = libc::c_int;
pub type guint          = libc::c_uint;
pub type gsize          = libc::size_t;
pub type gssize         = libc::ssize_t;
pub type gpointer       = *mut   libc::c_void;
pub type gconstpointer  = *const libc::c_void;

pub static FALSE: gboolean = 0;
pub static TRUE : gboolean = 1;
<commit_msg>Define the gboolean constants with const<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

// This module provides types that are intrinsic in GIR, so they do not
// get defined through other types. It should ultimately have a name defined
// for every basic type listed in the documentation:
// https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Default_Basic_Types
//
// Exceptions are:
// 1. Fixed-size integer types. These have straightforward machine-independent
//    counterparts in Rust.
// 2. Strings annotated as "utf8" or "filename". These types are not named
//    as such in the C API, being only aliases for gchar*.
//    Their representation in Rust is quite intricate and involves multiple
//    types, so they each get their own module.
//
// Rust aliases are needed for machine-dependent basic types used in GIR,
// since the GLib types are not necessarily identical to their Rust namesakes
// (the issue similarly addressed by libc::c_int and the like).
// GIR uses the GLib names for these types as well.

#![allow(non_camel_case_types)]

use libc;

pub type gboolean       = libc::c_int;
pub type gchar          = libc::c_char;
pub type gint           = libc::c_int;
pub type guint          = libc::c_uint;
pub type gsize          = libc::size_t;
pub type gssize         = libc::ssize_t;
pub type gpointer       = *mut   libc::c_void;
pub type gconstpointer  = *const libc::c_void;

pub const FALSE: gboolean = 0;
pub const TRUE : gboolean = 1;
<|endoftext|>


<commit_before>use traits::{AtEof,Compare,CompareResult,InputLength,InputIter,InputTake,Slice,FindSubstring,FindToken,ParseTo};
use util::Offset;

use std::str::{self,FromStr,Chars,CharIndices};
use std::ops::{Range,RangeTo,RangeFrom,RangeFull};
use std::iter::Enumerate;
use std::slice::Iter;

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteStr<'a>(pub &'a str);

impl<'a> AtEof for CompleteStr<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteStr<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteStr<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteStr<'a> {
  type Item     = char;
  type RawItem  = char;
  type Iter     = CharIndices<'a>;
  type IterElem = Chars<'a>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteStr<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteStr(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteStr(s1), CompleteStr(s2)))
  }
}

impl<'a> InputLength for CompleteStr<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b str> for CompleteStr<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteStr<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a> FindToken<CompleteStr<'a>> for u8 {
  fn find_token(&self, input: CompleteStr<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, 'b> FindToken<CompleteStr<'a>> for &'b u8 {
  fn find_token(&self, input: CompleteStr<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteStr<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse().ok()
  }
}

impl<'a> Offset for CompleteStr<'a> {
  fn offset(&self, second:&CompleteStr<'a>) -> usize {
    self.0.offset(second.0)
  }
}

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteByteSlice<'a>(pub &'a [u8]);

impl<'a> AtEof for CompleteByteSlice<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteByteSlice<'a> {
  type Item     = &'a u8;
  type RawItem  = u8;
  type Iter     = Enumerate<Iter<'a, Self::RawItem>>;
  type IterElem = Iter<'a, Self::RawItem>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteByteSlice<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteByteSlice(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteByteSlice(s1), CompleteByteSlice(s2)))
  }
}

impl<'a> InputLength for CompleteByteSlice<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b [u8]> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> Compare<&'b str> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b [u8]> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b [u8]) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a> FindToken<CompleteByteSlice<'a>> for u8 {
  fn find_token(&self, input: CompleteByteSlice<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, 'b> FindToken<CompleteByteSlice<'a>> for &'b u8 {
  fn find_token(&self, input: CompleteByteSlice<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteByteSlice<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse_to()
  }
}

impl<'a> Offset for CompleteByteSlice<'a> {
  fn offset(&self, second:&CompleteByteSlice<'a>) -> usize {
    self.0.offset(second.0)
  }
}
<commit_msg>impl FindToken<Complete{Str,ByteSlice}> for char<commit_after>use traits::{AtEof,Compare,CompareResult,InputLength,InputIter,InputTake,Slice,FindSubstring,FindToken,ParseTo};
use util::Offset;

use std::str::{self,FromStr,Chars,CharIndices};
use std::ops::{Range,RangeTo,RangeFrom,RangeFull};
use std::iter::Enumerate;
use std::slice::Iter;

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteStr<'a>(pub &'a str);

impl<'a> AtEof for CompleteStr<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteStr<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteStr<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteStr<'a> {
  type Item     = char;
  type RawItem  = char;
  type Iter     = CharIndices<'a>;
  type IterElem = Chars<'a>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteStr<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteStr(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteStr(s1), CompleteStr(s2)))
  }
}

impl<'a> InputLength for CompleteStr<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b str> for CompleteStr<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteStr<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a> FindToken<CompleteStr<'a>> for char {
  fn find_token(&self, input: CompleteStr<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a> FindToken<CompleteStr<'a>> for u8 {
  fn find_token(&self, input: CompleteStr<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, 'b> FindToken<CompleteStr<'a>> for &'b u8 {
  fn find_token(&self, input: CompleteStr<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteStr<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse().ok()
  }
}

impl<'a> Offset for CompleteStr<'a> {
  fn offset(&self, second:&CompleteStr<'a>) -> usize {
    self.0.offset(second.0)
  }
}

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteByteSlice<'a>(pub &'a [u8]);

impl<'a> AtEof for CompleteByteSlice<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteByteSlice<'a> {
  type Item     = &'a u8;
  type RawItem  = u8;
  type Iter     = Enumerate<Iter<'a, Self::RawItem>>;
  type IterElem = Iter<'a, Self::RawItem>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteByteSlice<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteByteSlice(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteByteSlice(s1), CompleteByteSlice(s2)))
  }
}

impl<'a> InputLength for CompleteByteSlice<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b [u8]> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> Compare<&'b str> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b [u8]> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b [u8]) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a> FindToken<CompleteByteSlice<'a>> for char {
  fn find_token(&self, input: CompleteByteSlice<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a> FindToken<CompleteByteSlice<'a>> for u8 {
  fn find_token(&self, input: CompleteByteSlice<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, 'b> FindToken<CompleteByteSlice<'a>> for &'b u8 {
  fn find_token(&self, input: CompleteByteSlice<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteByteSlice<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse_to()
  }
}

impl<'a> Offset for CompleteByteSlice<'a> {
  fn offset(&self, second:&CompleteByteSlice<'a>) -> usize {
    self.0.offset(second.0)
  }
}
<|endoftext|>


<commit_before>use anyhow::*;
use app_dirs::{app_root, AppDataType, AppInfo};
use std::fs;
use std::path::{Path, PathBuf};

#[cfg(not(target_os = "linux"))]
const APP_INFO: AppInfo = AppInfo {
	name: "Polaris",
	author: "Permafrost",
};

#[cfg(target_os = "linux")]
const APP_INFO: AppInfo = AppInfo {
	name: "polaris",
	author: "permafrost",
};

pub fn get_data_root() -> Result<PathBuf> {
	if let Ok(root) = app_root(AppDataType::UserData, &APP_INFO) {
		fs::create_dir_all(&root)?;
		return Ok(root);
	}
	bail!("Could not retrieve data directory root");
}

#[derive(Debug, PartialEq)]
pub enum AudioFormat {
	FLAC,
	MP3,
	MP4,
	MPC,
	OGG,
}

#[cfg_attr(feature = "profile-index", flame)]
pub fn get_audio_format(path: &Path) -> Option<AudioFormat> {
	let extension = match path.extension() {
		Some(e) => e,
		_ => return None,
	};
	let extension = match extension.to_str() {
		Some(e) => e,
		_ => return None,
	};
	match extension.to_lowercase().as_str() {
		"flac" => Some(AudioFormat::FLAC),
		"mp3" => Some(AudioFormat::MP3),
		"m4a" => Some(AudioFormat::MP4),
		"mpc" => Some(AudioFormat::MPC),
		"ogg" => Some(AudioFormat::OGG),
		_ => None,
	}
}

#[test]
fn test_get_audio_format() {
	assert_eq!(get_audio_format(Path::new("animals/🐷/my🐖file.jpg")), None);
	assert_eq!(
		get_audio_format(Path::new("animals/🐷/my🐖file.flac")),
		Some(AudioFormat::FLAC)
	);
}
<commit_msg>Support UNIX platforms that aren't Linux<commit_after>use anyhow::*;
use app_dirs::{app_root, AppDataType, AppInfo};
use std::fs;
use std::path::{Path, PathBuf};

#[cfg(target_family = "windows")]
const APP_INFO: AppInfo = AppInfo {
	name: "Polaris",
	author: "Permafrost",
};

#[cfg(not(target_family = "windows"))]
const APP_INFO: AppInfo = AppInfo {
	name: "polaris",
	author: "permafrost",
};

pub fn get_data_root() -> Result<PathBuf> {
	if let Ok(root) = app_root(AppDataType::UserData, &APP_INFO) {
		fs::create_dir_all(&root)?;
		return Ok(root);
	}
	bail!("Could not retrieve data directory root");
}

#[derive(Debug, PartialEq)]
pub enum AudioFormat {
	FLAC,
	MP3,
	MP4,
	MPC,
	OGG,
}

#[cfg_attr(feature = "profile-index", flame)]
pub fn get_audio_format(path: &Path) -> Option<AudioFormat> {
	let extension = match path.extension() {
		Some(e) => e,
		_ => return None,
	};
	let extension = match extension.to_str() {
		Some(e) => e,
		_ => return None,
	};
	match extension.to_lowercase().as_str() {
		"flac" => Some(AudioFormat::FLAC),
		"mp3" => Some(AudioFormat::MP3),
		"m4a" => Some(AudioFormat::MP4),
		"mpc" => Some(AudioFormat::MPC),
		"ogg" => Some(AudioFormat::OGG),
		_ => None,
	}
}

#[test]
fn test_get_audio_format() {
	assert_eq!(get_audio_format(Path::new("animals/🐷/my🐖file.jpg")), None);
	assert_eq!(
		get_audio_format(Path::new("animals/🐷/my🐖file.flac")),
		Some(AudioFormat::FLAC)
	);
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::{CString, OsString};
use std::os::unix::ffi::OsStringExt;
use std::ptr;

use errno;
use libc;

fn osstring2cstring(s: OsString) -> CString {
    unsafe { CString::from_vec_unchecked(s.into_vec()) }
}

fn split_string(s: &OsString) -> Vec<OsString> {
    match s.clone().into_string() {
        Ok(cmd) => cmd.split_whitespace().map(OsString::from).collect(),
        Err(cmd) => vec![cmd],
    }
}

// Helper wrappers around libc::* API
pub fn fork() -> libc::pid_t {
    unsafe { libc::fork() }
}

pub fn execvp(cmd: &OsString) {
    let cstrings = split_string(cmd)
        .into_iter()
        .map(osstring2cstring)
        .collect::<Vec<_>>();
    let mut args = cstrings.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
    args.push(ptr::null());
    errno::set_errno(errno::Errno(0));
    unsafe { libc::execvp(args[0], args.as_ptr()) };
}

pub fn dup2(fd1: i32, fd2: i32) {
    assert!(unsafe { libc::dup2(fd1, fd2) } > -1);
}

pub fn close(fd: i32) {
    assert_eq!(unsafe { libc::close(fd) }, 0);
}

pub fn pipe() -> (i32, i32) {
    let mut fds = [0; 2];
    assert_eq!(unsafe { libc::pipe(fds.as_mut_ptr()) }, 0);
    (fds[0], fds[1])
}

fn which(exec: &str) -> Option<OsString> {
    if let Some(path) = env::var_os("PATH") {
        let paths = env::split_paths(&path);
        for path in paths {
            let candidate = path.join(exec);
            if path.join(exec).exists() {
                return Some(candidate.into_os_string());
            }
        }
    }
    None
}

pub fn find_pager(env: &str) -> Option<OsString> {
    if env::var_os("NOPAGER").is_some() {
        return None;
    }
    let default_pager = || which("more");
    env::var_os(env).or_else(default_pager)
}

#[cfg(test)]
mod tests {
    use super::{find_pager, which};
    use std::ffi::OsString;

    #[cfg(target_os = "linux")]
    const MORE: &'static str = "/bin/more";

    #[cfg(target_os = "macos")]
    const MORE: &'static str = "/usr/bin/more";

    #[test]
    fn more_found_in_path() {
        assert!(which("more").is_some())
    }

    #[test]
    fn erom_not_found_in_path() {
        assert!(which("erom").is_none())
    }

    #[test]
    fn which_more() {
        assert_eq!(which("more"), Some(OsString::from(MORE)));
    }

    #[test]
    fn usr_bin_more_default_pager() {
        assert_eq!(find_pager("__RANDOM_NAME"), Some(OsString::from(MORE)));
    }
}
<commit_msg>Add nopager test<commit_after>use std::env;
use std::ffi::{CString, OsString};
use std::os::unix::ffi::OsStringExt;
use std::ptr;

use errno;
use libc;

fn osstring2cstring(s: OsString) -> CString {
    unsafe { CString::from_vec_unchecked(s.into_vec()) }
}

fn split_string(s: &OsString) -> Vec<OsString> {
    match s.clone().into_string() {
        Ok(cmd) => cmd.split_whitespace().map(OsString::from).collect(),
        Err(cmd) => vec![cmd],
    }
}

// Helper wrappers around libc::* API
pub fn fork() -> libc::pid_t {
    unsafe { libc::fork() }
}

pub fn execvp(cmd: &OsString) {
    let cstrings = split_string(cmd)
        .into_iter()
        .map(osstring2cstring)
        .collect::<Vec<_>>();
    let mut args = cstrings.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
    args.push(ptr::null());
    errno::set_errno(errno::Errno(0));
    unsafe { libc::execvp(args[0], args.as_ptr()) };
}

pub fn dup2(fd1: i32, fd2: i32) {
    assert!(unsafe { libc::dup2(fd1, fd2) } > -1);
}

pub fn close(fd: i32) {
    assert_eq!(unsafe { libc::close(fd) }, 0);
}

pub fn pipe() -> (i32, i32) {
    let mut fds = [0; 2];
    assert_eq!(unsafe { libc::pipe(fds.as_mut_ptr()) }, 0);
    (fds[0], fds[1])
}

fn which(exec: &str) -> Option<OsString> {
    if let Some(path) = env::var_os("PATH") {
        let paths = env::split_paths(&path);
        for path in paths {
            let candidate = path.join(exec);
            if path.join(exec).exists() {
                return Some(candidate.into_os_string());
            }
        }
    }
    None
}

pub fn find_pager(env: &str) -> Option<OsString> {
    if env::var_os("NOPAGER").is_some() {
        return None;
    }
    let default_pager = || which("more");
    env::var_os(env).or_else(default_pager)
}

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

    #[cfg(target_os = "linux")]
    const MORE: &'static str = "/bin/more";

    #[cfg(target_os = "macos")]
    const MORE: &'static str = "/usr/bin/more";

    #[test]
    fn more_found_in_path() {
        assert!(which("more").is_some())
    }

    #[test]
    fn erom_not_found_in_path() {
        assert!(which("erom").is_none())
    }

    #[test]
    fn which_more() {
        assert_eq!(which("more"), Some(OsString::from(MORE)));
    }

    #[test]
    fn usr_bin_more_default_pager() {
        assert_eq!(find_pager("__RANDOM_NAME"), Some(OsString::from(MORE)));
    }

    #[test]
    fn nopager() {
        env::set_var("NOPAGER", "");
        assert!(find_pager("more").is_none());
        env::remove_var("NOPAGER");
    }
}
<|endoftext|>


<commit_before>
use std::f32;
use std::num::Float;

use math::{LineSeg, Vec2};

pub struct World {
    _sectors: Vec<Sector>,
}

pub struct Sector {
    pub info: SectorInfo,
    pub walls: Vec<Wall>,
}

#[derive(Copy)]
pub struct SectorInfo {
    pub floor_elev: f32,
    pub ceiling_elev: f32,
}

#[derive(Copy)]
pub struct Wall {
    pub seg: LineSeg,
    pub portal: Option<(usize,usize)>, // (sector index, wall index) for matching wall in another sector.
}

#[derive(Copy)]
pub struct RayCastResult {
    pub along: f32,
    pub hit_pos: Vec2,
    pub in_info: SectorInfo,
    pub out_info: Option<SectorInfo>,
}

pub static W_ZERO: Wall = Wall {
    seg: LineSeg {
        a: Vec2 { x: 0.0, y: 0.0 },
        b: Vec2 { x: 0.0, y: 0.0 },
    },
    portal: None
};

impl Wall {
    pub fn new(x0: f32, y0: f32, x1: f32, y1: f32, portal: Option<(usize,usize)>) -> Wall {
        Wall {
            seg: LineSeg::new(x0, y0, x1, y1),
            portal: portal,
        }
    }
}

impl World {
    pub fn get_walls(&self) -> &[Wall] {
        self._sectors[0].walls.as_slice()
    }

    pub fn get_elevation(&self, sector: usize) -> f32 {
        self._sectors[sector].info.floor_elev
    }

    // Returns (new position, new sector)
    pub fn move_object(&self, sector: usize, old_pos: Vec2, new_pos: Vec2) -> usize {
        let move_seg = LineSeg { a: old_pos, b: new_pos };

        let crossed_portal = self._sectors[sector].walls.iter()
            .filter_map(|&wall| move_seg.intersects_at(wall.seg).and(wall.portal))
            .last();

        match crossed_portal {
            Some((new_sector, _)) => new_sector,
            None => sector,
        }
    }

    pub fn cast_ray(&self, sector: usize, pos: Vec2, angle: f32) -> Vec<RayCastResult> {
        let mut result = vec![];
        self._cast_ray(sector, None, pos, angle, &mut result);
        result
    }

    fn _cast_ray(&self, sector: usize, source_wall: Option<usize>, pos: Vec2, angle: f32, results: &mut Vec<RayCastResult>) {
        let ray = LineSeg::new(
            pos.x, pos.y,
            pos.x + 1000.0*Float::sin(angle),
            pos.y - 1000.0*Float::cos(angle)
        );

        let mut d2 = f32::MAX;
        let mut wall = W_ZERO;
        let mut t = 0.0;

        for i in 0..self._sectors[sector].walls.len() {
            if source_wall.is_some() && i == source_wall.unwrap() { continue; }
            let wall_ = self._sectors[sector].walls[i];

            ray.intersects_at(wall_.seg).map(|t_| {
                let d2_ = (pos - wall_.seg.at(t_)).get_length_sqr();
                if d2_ < d2 {
                    d2 = d2_;
                    wall = wall_;
                    t = t_;
                }
            });
        }

        if d2 == f32::MAX { return; }

        results.push(RayCastResult {
            along: wall.seg.get_length()*t,
            hit_pos: wall.seg.at(t),
            in_info: self._sectors[sector].info,
            out_info: wall.portal.map(|(sec, _)| self._sectors[sec].info),
        });

        match wall.portal {
            Some((next_sector, next_wall)) => {
                self._cast_ray(next_sector, Some(next_wall), wall.seg.at(t), angle, results);
            }
            None => {}
        }
    }
}

pub fn temp() -> World {
    World {
        _sectors: vec![
            Sector {
                info: SectorInfo {
                    floor_elev: 0.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new(-40.0, -40.0,  40.0, -40.0, None),
                    Wall::new( 40.0, -40.0,  40.0,  40.0, None),
                    Wall::new( 40.0,  40.0, -40.0,  40.0, None),
                    Wall::new(-40.0,  40.0, -40.0, -40.0, None),
                    Wall::new(-25.0, -25.0, -10.0, -25.0, Some((1,0))),
                    Wall::new(-10.0, -25.0, -10.0, -10.0, Some((1,1))),
                    Wall::new(-10.0, -10.0, -25.0, -10.0, Some((1,2))),
                    Wall::new(-25.0, -10.0, -25.0, -25.0, Some((1,3))),
                    Wall::new( 25.0,  25.0,  10.0,  25.0, Some((2,0))),
                    Wall::new( 10.0,  25.0,  10.0,  10.0, Some((2,1))),
                    Wall::new( 10.0,  10.0,  25.0,  10.0, Some((2,2))),
                    Wall::new( 25.0,  10.0,  25.0,  25.0, Some((2,3)))
                ]
            },
            Sector {
                info: SectorInfo {
                    floor_elev: 2.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new(-25.0, -25.0, -10.0, -25.0, Some((0,4))),
                    Wall::new(-10.0, -25.0, -10.0, -10.0, Some((0,5))),
                    Wall::new(-10.0, -10.0, -25.0, -10.0, Some((0,6))),
                    Wall::new(-25.0, -10.0, -25.0, -25.0, Some((0,7))),
                ]
            },
            Sector {
                info: SectorInfo {
                    floor_elev: -2.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new( 25.0,  25.0,  10.0,  25.0, Some((0,8))),
                    Wall::new( 10.0,  25.0,  10.0,  10.0, Some((0,9))),
                    Wall::new( 10.0,  10.0,  25.0,  10.0, Some((0,10))),
                    Wall::new( 25.0,  10.0,  25.0,  25.0, Some((0,11)))
                ]
            }
        ]
    }
}

<commit_msg>Replaced cast_ray for loop with cleaner iterator solution<commit_after>
use std::f32;
use std::num::Float;

use math::{LineSeg, Vec2};

pub struct World {
    _sectors: Vec<Sector>,
}

pub struct Sector {
    pub info: SectorInfo,
    pub walls: Vec<Wall>,
}

#[derive(Copy)]
pub struct SectorInfo {
    pub floor_elev: f32,
    pub ceiling_elev: f32,
}

#[derive(Copy)]
pub struct Wall {
    pub seg: LineSeg,
    pub portal: Option<(usize,usize)>, // (sector index, wall index) for matching wall in another sector.
}

#[derive(Copy)]
pub struct RayCastResult {
    pub along: f32,
    pub hit_pos: Vec2,
    pub in_info: SectorInfo,
    pub out_info: Option<SectorInfo>,
}

pub static W_ZERO: Wall = Wall {
    seg: LineSeg {
        a: Vec2 { x: 0.0, y: 0.0 },
        b: Vec2 { x: 0.0, y: 0.0 },
    },
    portal: None
};

impl Wall {
    pub fn new(x0: f32, y0: f32, x1: f32, y1: f32, portal: Option<(usize,usize)>) -> Wall {
        Wall {
            seg: LineSeg::new(x0, y0, x1, y1),
            portal: portal,
        }
    }
}

impl World {
    pub fn get_walls(&self) -> &[Wall] {
        self._sectors[0].walls.as_slice()
    }

    pub fn get_elevation(&self, sector: usize) -> f32 {
        self._sectors[sector].info.floor_elev
    }

    // Returns (new position, new sector)
    pub fn move_object(&self, sector: usize, old_pos: Vec2, new_pos: Vec2) -> usize {
        let move_seg = LineSeg { a: old_pos, b: new_pos };

        let crossed_portal = self._sectors[sector].walls.iter()
            .filter_map(|&wall| move_seg.intersects_at(wall.seg).and(wall.portal))
            .last();

        match crossed_portal {
            Some((new_sector, _)) => new_sector,
            None => sector,
        }
    }

    pub fn cast_ray(&self, sector: usize, pos: Vec2, angle: f32) -> Vec<RayCastResult> {
        let mut result = vec![];
        self._cast_ray(sector, None, pos, angle, &mut result);
        result
    }

    fn _cast_ray(&self, sector: usize, source_wall: Option<usize>, pos: Vec2, angle: f32, results: &mut Vec<RayCastResult>) {
        let ray = LineSeg::new(
            pos.x, pos.y,
            pos.x + 1000.0*Float::sin(angle),
            pos.y - 1000.0*Float::cos(angle)
        );

        //Hopefully min_by will accept a compare function so we don't have to convert to int here
        //to get a min on some floats.
        //    https://github.com/rust-lang/rust/issues/15311
        //
        let closest_wall = self._sectors[sector].walls.iter().enumerate()
            .filter(|&(i, wall)| source_wall.is_none() || i != source_wall.unwrap())
            .filter_map(|(i, wall)| ray.intersects_at(wall.seg).map(|t| (wall, t)))
            .min_by(|&(&wall, t)| {
                ((pos - wall.seg.at(t)).get_length_sqr() * 100.0) as i32
            });

        if closest_wall.is_none() { return; }

        let (wall, t) = closest_wall.unwrap();

        results.push(RayCastResult {
            along: wall.seg.get_length()*t,
            hit_pos: wall.seg.at(t),
            in_info: self._sectors[sector].info,
            out_info: wall.portal.map(|(sec, _)| self._sectors[sec].info),
        });

        match wall.portal {
            Some((next_sector, next_wall)) => {
                self._cast_ray(next_sector, Some(next_wall), wall.seg.at(t), angle, results)
            }
            None => {}
        };
    }
}

pub fn temp() -> World {
    World {
        _sectors: vec![
            Sector {
                info: SectorInfo {
                    floor_elev: 0.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new(-40.0, -40.0,  40.0, -40.0, None),
                    Wall::new( 40.0, -40.0,  40.0,  40.0, None),
                    Wall::new( 40.0,  40.0, -40.0,  40.0, None),
                    Wall::new(-40.0,  40.0, -40.0, -40.0, None),
                    Wall::new(-25.0, -25.0, -10.0, -25.0, Some((1,0))),
                    Wall::new(-10.0, -25.0, -10.0, -10.0, Some((1,1))),
                    Wall::new(-10.0, -10.0, -25.0, -10.0, Some((1,2))),
                    Wall::new(-25.0, -10.0, -25.0, -25.0, Some((1,3))),
                    Wall::new( 25.0,  25.0,  10.0,  25.0, Some((2,0))),
                    Wall::new( 10.0,  25.0,  10.0,  10.0, Some((2,1))),
                    Wall::new( 10.0,  10.0,  25.0,  10.0, Some((2,2))),
                    Wall::new( 25.0,  10.0,  25.0,  25.0, Some((2,3)))
                ]
            },
            Sector {
                info: SectorInfo {
                    floor_elev: 2.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new(-25.0, -25.0, -10.0, -25.0, Some((0,4))),
                    Wall::new(-10.0, -25.0, -10.0, -10.0, Some((0,5))),
                    Wall::new(-10.0, -10.0, -25.0, -10.0, Some((0,6))),
                    Wall::new(-25.0, -10.0, -25.0, -25.0, Some((0,7))),
                ]
            },
            Sector {
                info: SectorInfo {
                    floor_elev: -2.0,
                    ceiling_elev: 20.0,
                },
                walls: vec![
                    Wall::new( 25.0,  25.0,  10.0,  25.0, Some((0,8))),
                    Wall::new( 10.0,  25.0,  10.0,  10.0, Some((0,9))),
                    Wall::new( 10.0,  10.0,  25.0,  10.0, Some((0,10))),
                    Wall::new( 25.0,  10.0,  25.0,  25.0, Some((0,11)))
                ]
            }
        ]
    }
}

<|endoftext|>


<commit_before>#![feature(box_syntax)]

extern crate two_three;

use two_three::{Node, TTTree, Two, Three, LeafTwo, LeafThree};

#[test]
fn it_works() {
    let mut tree: TTTree<uint> = TTTree::new();

    tree.insert(50);
    match tree {
        TTTree{root: Some(Node::LeafTwo(LeafTwo(50)))} => (),
        _ => panic!(),
    }

    tree.insert(50);
    match tree {
        TTTree{root: Some(Node::LeafTwo(LeafTwo(50)))} => (),
        _ => panic!(),
    }

    tree.insert(60);
    match tree {
        TTTree{root: Some(Node::LeafThree(LeafThree(50, 60)))} => (),
        _ => panic!(),
    }

    tree.insert(70);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::LeafTwo(LeafTwo(50)),
                box Node::LeafTwo(LeafTwo(70))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(100);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::LeafTwo(LeafTwo(50)),
                box Node::LeafThree(LeafThree(70, 100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(55);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::LeafThree(LeafThree(50, 55)),
                box Node::LeafThree(LeafThree(70, 100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(68);
    match tree {
        TTTree{root: Some(
            Node::Three(Three(60, 70,
                box Node::LeafThree(LeafThree(50, 55)),
                box Node::LeafTwo(LeafTwo(68)),
                box Node::LeafTwo(LeafTwo(100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(75);
    match tree {
        TTTree{root: Some(
            Node::Three(Three(60, 70,
                box Node::LeafThree(LeafThree(50, 55)),
                box Node::LeafTwo(LeafTwo(68)),
                box Node::LeafThree(LeafThree(75, 100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(52);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::Two(Two(52,
                    box Node::LeafTwo(LeafTwo(50)),
                    box Node::LeafTwo(LeafTwo(55)),
                )),
                box Node::Two(Two(70,
                    box Node::LeafTwo(LeafTwo(68)),
                    box Node::LeafThree(LeafThree(75, 100)),
                )),
            ))
        )} => (),
        _ => panic!(),
    }
}
<commit_msg>Use better num type<commit_after>#![feature(box_syntax)]

extern crate two_three;

use two_three::{Node, TTTree, Two, Three, LeafTwo, LeafThree};

#[test]
fn it_works() {
    let mut tree: TTTree<u64> = TTTree::new();

    tree.insert(50);
    match tree {
        TTTree{root: Some(Node::LeafTwo(LeafTwo(50)))} => (),
        _ => panic!(),
    }

    tree.insert(50);
    match tree {
        TTTree{root: Some(Node::LeafTwo(LeafTwo(50)))} => (),
        _ => panic!(),
    }

    tree.insert(60);
    match tree {
        TTTree{root: Some(Node::LeafThree(LeafThree(50, 60)))} => (),
        _ => panic!(),
    }

    tree.insert(70);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::LeafTwo(LeafTwo(50)),
                box Node::LeafTwo(LeafTwo(70))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(100);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::LeafTwo(LeafTwo(50)),
                box Node::LeafThree(LeafThree(70, 100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(55);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::LeafThree(LeafThree(50, 55)),
                box Node::LeafThree(LeafThree(70, 100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(68);
    match tree {
        TTTree{root: Some(
            Node::Three(Three(60, 70,
                box Node::LeafThree(LeafThree(50, 55)),
                box Node::LeafTwo(LeafTwo(68)),
                box Node::LeafTwo(LeafTwo(100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(75);
    match tree {
        TTTree{root: Some(
            Node::Three(Three(60, 70,
                box Node::LeafThree(LeafThree(50, 55)),
                box Node::LeafTwo(LeafTwo(68)),
                box Node::LeafThree(LeafThree(75, 100))
            ))
        )} => (),
        _ => panic!(),
    }

    tree.insert(52);
    match tree {
        TTTree{root: Some(
            Node::Two(Two(60,
                box Node::Two(Two(52,
                    box Node::LeafTwo(LeafTwo(50)),
                    box Node::LeafTwo(LeafTwo(55)),
                )),
                box Node::Two(Two(70,
                    box Node::LeafTwo(LeafTwo(68)),
                    box Node::LeafThree(LeafThree(75, 100)),
                )),
            ))
        )} => (),
        _ => panic!(),
    }
}
<|endoftext|>


<commit_before>#![deny(unused_must_use)]

extern crate rayon;

// Check that we are flagged for ignoring `must_use` parallel adaptors.

use rayon::prelude::*;

fn main() {
    let v: Vec<_> = (0..100).map(Some).collect();

    v.par_iter().chain(&v);                 //~ ERROR unused result
    v.par_iter().cloned();                  //~ ERROR unused result
    v.par_iter().enumerate();               //~ ERROR unused result
    v.par_iter().filter(|_| true);          //~ ERROR unused result
    v.par_iter().filter_map(|x| *x);        //~ ERROR unused result
    v.par_iter().flat_map(|x| *x);          //~ ERROR unused result
    v.par_iter().fold(|| 0, |x, _| x);      //~ ERROR unused result
    v.par_iter().fold_with(0, |x, _| x);    //~ ERROR unused result
    v.par_iter().inspect(|_| {});           //~ ERROR unused result
    v.par_iter().map(|x| x);                //~ ERROR unused result
    v.par_iter().map_with(0, |_, x| x);     //~ ERROR unused result
    v.par_iter().rev();                     //~ ERROR unused result
    v.par_iter().skip(1);                   //~ ERROR unused result
    v.par_iter().take(1);                   //~ ERROR unused result
    v.par_iter().cloned().while_some();     //~ ERROR unused result
    v.par_iter().with_max_len(1);           //~ ERROR unused result
    v.par_iter().with_min_len(1);           //~ ERROR unused result
    v.par_iter().zip(&v);                   //~ ERROR unused result
}
<commit_msg>test: update the `unused_must_use` error pattern<commit_after>#![deny(unused_must_use)]

extern crate rayon;

// Check that we are flagged for ignoring `must_use` parallel adaptors.

use rayon::prelude::*;

fn main() {
    let v: Vec<_> = (0..100).map(Some).collect();

    v.par_iter().chain(&v);                 //~ ERROR must be used
    v.par_iter().cloned();                  //~ ERROR must be used
    v.par_iter().enumerate();               //~ ERROR must be used
    v.par_iter().filter(|_| true);          //~ ERROR must be used
    v.par_iter().filter_map(|x| *x);        //~ ERROR must be used
    v.par_iter().flat_map(|x| *x);          //~ ERROR must be used
    v.par_iter().fold(|| 0, |x, _| x);      //~ ERROR must be used
    v.par_iter().fold_with(0, |x, _| x);    //~ ERROR must be used
    v.par_iter().inspect(|_| {});           //~ ERROR must be used
    v.par_iter().map(|x| x);                //~ ERROR must be used
    v.par_iter().map_with(0, |_, x| x);     //~ ERROR must be used
    v.par_iter().rev();                     //~ ERROR must be used
    v.par_iter().skip(1);                   //~ ERROR must be used
    v.par_iter().take(1);                   //~ ERROR must be used
    v.par_iter().cloned().while_some();     //~ ERROR must be used
    v.par_iter().with_max_len(1);           //~ ERROR must be used
    v.par_iter().with_min_len(1);           //~ ERROR must be used
    v.par_iter().zip(&v);                   //~ ERROR must be used
}
<|endoftext|>