<commit_before>// -*- rust-indent-offset: 2 -*-
// More compact, just for slides.

use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Error;

use rand::Rng;
use quickcheck::{Arbitrary, Gen, Shrinker, empty_shrinker};

/// A legal divisor.
/// Keep field private to prevent direct construction.
/// Only allow creation with Divisor::new.
#[derive(Debug, PartialEq, Clone)]
pub struct Divisor(i32);

//// Validation of divisors.

pub static MIN: i32 = 2;
pub static MAX: i32 = 100;

#[derive(Debug, PartialEq)]
pub enum MyError {
  TooSmall(i32),
  TooBig(i32)
}

impl Display for MyError {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    match self {
      &MyError::TooSmall(size) => write!(f, "{} is too small", size),
      &MyError::TooBig(size) => write!(f, "{} is too big", size),
    }
  }
}

impl Display for Vec<MyError> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    try!(write!(f, "Errors: ["));
    for e in self {
      try!(write!(f, "{}", e));
      try!(write!(f, "\n"));
    }
    write!(f, "]")
  }
}

impl Divisor {
  /// Warning: this logic of if/else only makes sense if MIN <= MAX.
  /// Do not in general trust chained if/else.
  pub fn new(d: i32) -> Result<Divisor, MyError> {
    if d < MIN {
      Err(MyError::TooSmall(d))
    } else if d > MAX {
      Err(MyError::TooBig(d))
    } else {
      Ok(Divisor(d))
    }
  }

  pub fn get(&self) -> i32 {
    match self {
      &Divisor(d) => d
    }
  }
}

// For quickcheck.
impl Arbitrary for Divisor {
  fn arbitrary<G: Gen>(g: &mut G) -> Divisor {
    let d = g.gen_range(MIN, MAX+1);
    //Divisor(d)
    // It is best to use our safe API even though in this case
    // we "know" that we are generating only valid divisors.
    Divisor::new(d).unwrap()
  }

  fn shrink(&self) -> Box<Shrinker<Divisor>+'static> {
    // TODO: no shrinker for now.
    empty_shrinker()
  }
}

#[cfg(test)]
mod test {
  use super::*;
  use super::MyError::*;
  use quickcheck::TestResult;

  #[test]
  fn min_and_max_make_sense() {
    assert!(MIN <= MAX)
  }

  #[test]
  fn validate_all_cases() {
    fn validate_all_cases(d: i32) -> TestResult {
      match (d >= MIN, d <= MAX) {
        (true, true) =>
          TestResult::from_bool(Divisor::new(d) == Ok(Divisor(d))),
        (false, true) =>
          TestResult::from_bool(Divisor::new(d) == Err(TooSmall(d))),
        (true, false) =>
          TestResult::from_bool(Divisor::new(d) == Err(TooBig(d))),
        (false, false) =>
          TestResult::error("Impossible combination"),
      }
    }
    ::quickcheck::quickcheck(validate_all_cases as fn(i32) -> TestResult)
  }
}
<commit_msg>Style: dereference match target.<commit_after>// -*- rust-indent-offset: 2 -*-
// More compact, just for slides.

use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Error;

use rand::Rng;
use quickcheck::{Arbitrary, Gen, Shrinker, empty_shrinker};

/// A legal divisor.
/// Keep field private to prevent direct construction.
/// Only allow creation with Divisor::new.
#[derive(Debug, PartialEq, Clone)]
pub struct Divisor(i32);

//// Validation of divisors.

pub static MIN: i32 = 2;
pub static MAX: i32 = 100;

#[derive(Debug, PartialEq)]
pub enum MyError {
  TooSmall(i32),
  TooBig(i32)
}

impl Display for MyError {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    match *self {
      MyError::TooSmall(size) => write!(f, "{} is too small", size),
      MyError::TooBig(size) => write!(f, "{} is too big", size),
    }
  }
}

impl Display for Vec<MyError> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    try!(write!(f, "Errors: ["));
    for e in self {
      try!(write!(f, "{}", e));
      try!(write!(f, "\n"));
    }
    write!(f, "]")
  }
}

impl Divisor {
  /// Warning: this logic of if/else only makes sense if MIN <= MAX.
  /// Do not in general trust chained if/else.
  pub fn new(d: i32) -> Result<Divisor, MyError> {
    if d < MIN {
      Err(MyError::TooSmall(d))
    } else if d > MAX {
      Err(MyError::TooBig(d))
    } else {
      Ok(Divisor(d))
    }
  }

  pub fn get(&self) -> i32 {
    match *self {
      Divisor(d) => d
    }
  }
}

// For quickcheck.
impl Arbitrary for Divisor {
  fn arbitrary<G: Gen>(g: &mut G) -> Divisor {
    let d = g.gen_range(MIN, MAX+1);
    //Divisor(d)
    // It is best to use our safe API even though in this case
    // we "know" that we are generating only valid divisors.
    Divisor::new(d).unwrap()
  }

  fn shrink(&self) -> Box<Shrinker<Divisor>+'static> {
    // TODO: no shrinker for now.
    empty_shrinker()
  }
}

#[cfg(test)]
mod test {
  use super::*;
  use super::MyError::*;
  use quickcheck::TestResult;

  #[test]
  fn min_and_max_make_sense() {
    assert!(MIN <= MAX)
  }

  #[test]
  fn validate_all_cases() {
    fn validate_all_cases(d: i32) -> TestResult {
      match (d >= MIN, d <= MAX) {
        (true, true) =>
          TestResult::from_bool(Divisor::new(d) == Ok(Divisor(d))),
        (false, true) =>
          TestResult::from_bool(Divisor::new(d) == Err(TooSmall(d))),
        (true, false) =>
          TestResult::from_bool(Divisor::new(d) == Err(TooBig(d))),
        (false, false) =>
          TestResult::error("Impossible combination"),
      }
    }
    ::quickcheck::quickcheck(validate_all_cases as fn(i32) -> TestResult)
  }
}
<|endoftext|>


<commit_before>use std::io::Error;
// use std::fs::File;
use std::fs::OpenOptions;
use std::process::{Command, Stdio};
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::os::unix::process::CommandExt;

use nix::unistd::pipe;
use nix::sys::signal;
use libc;
use tools;
use jobs;

extern "C" fn handle_sigchld(_: i32) {
    // When handle waitpid here & for commands like `ls | cmd-not-exist`
    // will got panic: "wait() should either return Ok or panic"
    // which I currently don't know how to fix.

    /*
    unsafe {
        let mut stat: i32 = 0;
        let ptr: *mut i32 = &mut stat;
        tools::rlog(format!("waiting...\n"));
        let pid = libc::waitpid(-1, ptr, libc::WNOHANG);
        tools::rlog(format!("child {} exit\n", pid));
    }
    */
}

fn args_to_cmds(args: Vec<String>) -> Vec<Vec<String>> {
    let mut cmd: Vec<String> = Vec::new();
    let mut cmds: Vec<Vec<String>> = Vec::new();
    for token in &args {
        if token != "|" {
            cmd.push(token.trim().to_string());
        } else {
            cmds.push(cmd.clone());
            cmd = Vec::new();
        }
    }
    cmds.push(cmd.clone());
    cmds
}

pub fn run_pipeline(args: Vec<String>, redirect: &str, append: bool) -> i32 {
    let sig_action = signal::SigAction::new(signal::SigHandler::Handler(handle_sigchld),
                                            signal::SaFlags::empty(),
                                            signal::SigSet::empty());
    unsafe {
        signal::sigaction(signal::SIGCHLD, &sig_action).unwrap();
    }

    let mut vec_redirected = Vec::new();
    let mut args_new = args.clone();
    let mut redirected_to = 0;
    for arg in &args_new {
        if arg == "2>&1" {
            redirected_to = 1;
        }
        if arg == "1>&2" {
            redirected_to = 2;
        }
        if arg == "|" {
            vec_redirected.push(redirected_to);
            redirected_to = 0;
        }
    }
    vec_redirected.push(redirected_to);

    while args_new.iter().position(|x| *x == "2>&1").is_some() ||
            args_new.iter().position(|x| *x == "1>&2").is_some() {
        if let Some(index) = args_new.iter().position(|x| *x == "2>&1") {
            args_new.remove(index);
        }
        if let Some(index) = args_new.iter().position(|x| *x == "1>&2") {
            args_new.remove(index);
        }
    }

    let cmds = args_to_cmds(args_new);
    let length = cmds.len();
    let mut pipes = Vec::new();
    for _ in 0..length - 1 {
        let fds = pipe().unwrap();
        pipes.push(fds);
    }

    let mut i = 0;
    let mut pgid: u32 = 0;
    let mut children: Vec<u32> = Vec::new();
    let mut status = 0;
    for cmd in &cmds {
        let mut p = Command::new(&cmd[0]);
        p.args(&cmd[1..]);
        p.before_exec(move || {
            unsafe {
                if i == 0 {
                    // set the first process as progress group leader
                    let pid = libc::getpid();
                    libc::setpgid(0, pid);
                    tools::rlog(format!("set self gid to {}\n", pid));
                } else {
                    libc::setpgid(0, pgid as i32);
                    tools::rlog(format!("set other gid to {}\n", pgid));
                }
            }
            Ok(())
        });

        if i < length - 1 {
            let fds = pipes[i];
            let pipe_out = unsafe { Stdio::from_raw_fd(fds.1) };
            p.stdout(pipe_out);

            if vec_redirected[i] > 0 {
                if vec_redirected[i] == 1 {
                    let fds = pipes[i];
                    let pipe_out = unsafe { Stdio::from_raw_fd(fds.1) };
                    p.stderr(pipe_out);
                }
                /* else if vec_redirected[i] == 2 {
                    unsafe { p.stdout(Stdio::from_raw_fd(2)) };
                }
                */
            }
        }

        if i > 0 {
            // redirect to stderr has some issues now:
            // run commands like `ls | wc 1>&2 | cat` a second time will crash
            /*
            if vec_redirected[i - 1] == 2 {
                match File::open("/dev/null") {
                    Ok(x) => {
                        let dev_null = x.into_raw_fd();
                        let pipe_in = unsafe { Stdio::from_raw_fd(dev_null) };
                        p.stdin(pipe_in);
                    }
                    Err(e) => {
                        println!("open dev null error: {:?}", e);
                    }
                }
            } else {
            */
                let fds_prev = pipes[i - 1];
                let pipe_in = unsafe { Stdio::from_raw_fd(fds_prev.0) };
                p.stdin(pipe_in);
            /*
            }
            */
        }

        // redirect output if needed
        if redirect != "" && i == length - 1 {
            let mut oos = OpenOptions::new();
            if append {
                oos.append(true);
            } else {
                oos.write(true);
                oos.truncate(true);
            }
            let fd = oos.create(true).open(redirect).unwrap().into_raw_fd();
            let file_out = unsafe { Stdio::from_raw_fd(fd) };
            p.stdout(file_out);
        }

        let mut child;
        match p.spawn() {
            Ok(x) => {
                child = x;
                if i != length - 1 {
                    children.push(child.id());
                }
            }
            Err(e) => {
                println!("child spawn error: {:?}", e);
                continue;
            }
        }

        if i == 0 {
            pgid = child.id();
            tools::rlog(format!("try give term to {}\n", pgid));
            unsafe {
                jobs::give_terminal_to(pgid as i32);
            }
        }

        if i == length - 1 {
            let pid = child.id();
            tools::rlog(format!("wait pid {}\n", pid));
            match child.wait() {
                Ok(ecode) => {
                    if ecode.success() {
                        status = 0;
                    } else {
                        status = 1;
                    }
                }
                Err(_) => {
                    match Error::last_os_error().raw_os_error() {
                        Some(10) => {
                            // no such process; it's already done
                            status = 0;
                        }
                        Some(e) => {
                            status = e;
                        }
                        None => {
                            status = 1;
                        }
                    }
                }
            }

            // ack of the zombies
            // TODO: better wait in signal handlers, but.. see above.
            for pid in &children {
                unsafe {
                    let mut stat: i32 = 0;
                    let ptr: *mut i32 = &mut stat;
                    tools::rlog(format!("wait zombie pid {}\n", pid));
                    libc::waitpid(*pid as i32, ptr, 0);
                }
            }
        }
        i += 1;
    }
    return status;
}

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

    #[test]
    fn test_args_to_cmd() {
        let s = vec![String::from("ls")];
        let result = args_to_cmds(s);
        let expected = vec![vec!["ls".to_string()]];
        assert_eq!(result.len(), expected.len());
        for (i, item) in result.iter().enumerate() {
            assert_eq!(*item, expected[i]);
        }

        let s = vec![
            String::from("ls"),
            String::from("|"),
            String::from("wc"),
        ];
        let result = args_to_cmds(s);
        let expected = vec![vec!["ls".to_string()], vec!["wc".to_string()]];
        assert_eq!(result.len(), expected.len());
        for (i, item) in result.iter().enumerate() {
            assert_eq!(*item, expected[i]);
        }

        let s = vec![
            String::from("  ls   "),
            String::from("-lh"),
            String::from("|"),
            String::from("wc  "),
            String::from("-l"),
            String::from("|"),
            String::from("  less"),
        ];
        let result = args_to_cmds(s);
        let expected = vec![
            vec!["ls".to_string(), "-lh".to_string()],
            vec!["wc".to_string(), "-l".to_string()],
            vec!["less".to_string()],
        ];
        assert_eq!(result.len(), expected.len());
        for (i, item) in result.iter().enumerate() {
            assert_eq!(*item, expected[i]);
        }

    }
}
<commit_msg>a bit refactoring<commit_after>use std::io::Error;
// use std::fs::File;
use std::fs::OpenOptions;
use std::process::{Command, Stdio};
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::os::unix::process::CommandExt;

use nix::unistd::pipe;
use nix::sys::signal;
use libc;
use tools;
use jobs;

extern "C" fn handle_sigchld(_: i32) {
    // When handle waitpid here & for commands like `ls | cmd-not-exist`
    // will got panic: "wait() should either return Ok or panic"
    // which I currently don't know how to fix.

    /*
    unsafe {
        let mut stat: i32 = 0;
        let ptr: *mut i32 = &mut stat;
        tools::rlog(format!("waiting...\n"));
        let pid = libc::waitpid(-1, ptr, libc::WNOHANG);
        tools::rlog(format!("child {} exit\n", pid));
    }
    */
}

fn args_to_cmds(args: Vec<String>) -> Vec<Vec<String>> {
    let mut cmd: Vec<String> = Vec::new();
    let mut cmds: Vec<Vec<String>> = Vec::new();
    for token in &args {
        if token != "|" {
            cmd.push(token.trim().to_string());
        } else {
            cmds.push(cmd.clone());
            cmd = Vec::new();
        }
    }
    cmds.push(cmd.clone());
    cmds
}

fn args_to_redirections(args: Vec<String>) -> (Vec<String>, Vec<i32>) {
    let mut vec_redirected = Vec::new();
    let mut args_new = args.clone();
    let mut redirected_to = 0;
    for arg in &args_new {
        if arg == "2>&1" {
            redirected_to = 1;
        }
        if arg == "1>&2" {
            redirected_to = 2;
        }
        if arg == "|" {
            vec_redirected.push(redirected_to);
            redirected_to = 0;
        }
    }
    vec_redirected.push(redirected_to);

    while args_new.iter().position(|x| *x == "2>&1").is_some() {
        let index = args_new.iter().position(|x| *x == "2>&1").unwrap();
        args_new.remove(index);
    }
    while args_new.iter().position(|x| *x == "1>&2").is_some() {
        let index = args_new.iter().position(|x| *x == "1>&2").unwrap();
        args_new.remove(index);
    }
    (args_new, vec_redirected)
}

pub fn run_pipeline(args: Vec<String>, redirect: &str, append: bool) -> i32 {
    let sig_action = signal::SigAction::new(signal::SigHandler::Handler(handle_sigchld),
                                            signal::SaFlags::empty(),
                                            signal::SigSet::empty());
    unsafe {
        signal::sigaction(signal::SIGCHLD, &sig_action).unwrap();
    }

    let (args_new, vec_redirected) = args_to_redirections(args);
    let cmds = args_to_cmds(args_new);
    let length = cmds.len();
    let mut pipes = Vec::new();
    for _ in 0..length - 1 {
        let fds = pipe().unwrap();
        pipes.push(fds);
    }

    let mut i = 0;
    let mut pgid: u32 = 0;
    let mut children: Vec<u32> = Vec::new();
    let mut status = 0;
    for cmd in &cmds {
        let mut p = Command::new(&cmd[0]);
        p.args(&cmd[1..]);
        p.before_exec(move || {
            unsafe {
                if i == 0 {
                    // set the first process as progress group leader
                    let pid = libc::getpid();
                    libc::setpgid(0, pid);
                    tools::rlog(format!("set self gid to {}\n", pid));
                } else {
                    libc::setpgid(0, pgid as i32);
                    tools::rlog(format!("set other gid to {}\n", pgid));
                }
            }
            Ok(())
        });

        if i < length - 1 {
            let fds = pipes[i];
            let pipe_out = unsafe { Stdio::from_raw_fd(fds.1) };
            p.stdout(pipe_out);

            if vec_redirected[i] > 0 {
                if vec_redirected[i] == 1 {
                    let fds = pipes[i];
                    let pipe_out = unsafe { Stdio::from_raw_fd(fds.1) };
                    p.stderr(pipe_out);
                }
                /* else if vec_redirected[i] == 2 {
                    unsafe { p.stdout(Stdio::from_raw_fd(2)) };
                }
                */
            }
        }

        if i > 0 {
            // redirect to stderr has some issues now:
            // run commands like `ls | wc 1>&2 | cat` a second time will crash
            /*
            if vec_redirected[i - 1] == 2 {
                match File::open("/dev/null") {
                    Ok(x) => {
                        let dev_null = x.into_raw_fd();
                        let pipe_in = unsafe { Stdio::from_raw_fd(dev_null) };
                        p.stdin(pipe_in);
                    }
                    Err(e) => {
                        println!("open dev null error: {:?}", e);
                    }
                }
            } else {
            */
                let fds_prev = pipes[i - 1];
                let pipe_in = unsafe { Stdio::from_raw_fd(fds_prev.0) };
                p.stdin(pipe_in);
            /*
            }
            */
        }

        // redirect output if needed
        if redirect != "" && i == length - 1 {
            let mut oos = OpenOptions::new();
            if append {
                oos.append(true);
            } else {
                oos.write(true);
                oos.truncate(true);
            }
            let fd = oos.create(true).open(redirect).unwrap().into_raw_fd();
            let file_out = unsafe { Stdio::from_raw_fd(fd) };
            p.stdout(file_out);
        }

        let mut child;
        match p.spawn() {
            Ok(x) => {
                child = x;
                if i != length - 1 {
                    children.push(child.id());
                }
            }
            Err(e) => {
                println!("child spawn error: {:?}", e);
                continue;
            }
        }

        if i == 0 {
            pgid = child.id();
            tools::rlog(format!("try give term to {}\n", pgid));
            unsafe {
                jobs::give_terminal_to(pgid as i32);
            }
        }

        if i == length - 1 {
            let pid = child.id();
            tools::rlog(format!("wait pid {}\n", pid));
            match child.wait() {
                Ok(ecode) => {
                    if ecode.success() {
                        status = 0;
                    } else {
                        status = 1;
                    }
                }
                Err(_) => {
                    match Error::last_os_error().raw_os_error() {
                        Some(10) => {
                            // no such process; it's already done
                            status = 0;
                        }
                        Some(e) => {
                            status = e;
                        }
                        None => {
                            status = 1;
                        }
                    }
                }
            }

            // ack of the zombies
            // TODO: better wait in signal handlers, but.. see above.
            for pid in &children {
                unsafe {
                    let mut stat: i32 = 0;
                    let ptr: *mut i32 = &mut stat;
                    tools::rlog(format!("wait zombie pid {}\n", pid));
                    libc::waitpid(*pid as i32, ptr, 0);
                }
            }
        }
        i += 1;
    }
    return status;
}

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

    #[test]
    fn test_args_to_cmd() {
        let s = vec![String::from("ls")];
        let result = args_to_cmds(s);
        let expected = vec![vec!["ls".to_string()]];
        assert_eq!(result.len(), expected.len());
        for (i, item) in result.iter().enumerate() {
            assert_eq!(*item, expected[i]);
        }

        let s = vec![
            String::from("ls"),
            String::from("|"),
            String::from("wc"),
        ];
        let result = args_to_cmds(s);
        let expected = vec![vec!["ls".to_string()], vec!["wc".to_string()]];
        assert_eq!(result.len(), expected.len());
        for (i, item) in result.iter().enumerate() {
            assert_eq!(*item, expected[i]);
        }

        let s = vec![
            String::from("  ls   "),
            String::from("-lh"),
            String::from("|"),
            String::from("wc  "),
            String::from("-l"),
            String::from("|"),
            String::from("  less"),
        ];
        let result = args_to_cmds(s);
        let expected = vec![
            vec!["ls".to_string(), "-lh".to_string()],
            vec!["wc".to_string(), "-l".to_string()],
            vec!["less".to_string()],
        ];
        assert_eq!(result.len(), expected.len());
        for (i, item) in result.iter().enumerate() {
            assert_eq!(*item, expected[i]);
        }

    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use std::sync::Arc;

use libfuzzer_sys::arbitrary::{Arbitrary, Error, Unstructured};

use crate::prelude::*;

// Adding new fuzz targets
//
// 1. Add a function to this file which looks like this:
//
//    pub fn fuzz_something(data: Data) {
//      // Invoke everything you need.
//      //
//      // Your function may accept a value of any type that implements
//      // Arbitrary [1]. This is how fuzzer affects the execution—by
//      // feeding in different bytes, which result in different
//      // arbitrary values being generated.
//      // [1]: https://docs.rs/arbitrary/0.3.3/arbitrary/trait.Arbitrary.html
//      //
//      // Derive Debug for the structures you create with arbitrary data.
//    }
//
// 2. cargo fuzz add something
// 3. Copy the contents of any other .rs file from fuzz/fuzz_targets/ into the
//    newly created fuzz/fuzz_targets/something.rs and change the function
//    being called to fuzz_something.
//
// Now you can fuzz the new target with cargo fuzz.

#[derive(Debug)]
pub struct ArbitraryConfig {
  config: Config,
}

impl Arbitrary for ArbitraryConfig {
  fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self, Error> {
    let mut enc = EncoderConfig::with_speed_preset(Arbitrary::arbitrary(u)?);
    enc.width = Arbitrary::arbitrary(u)?;
    enc.height = Arbitrary::arbitrary(u)?;
    enc.bit_depth = u.int_in_range(0..=16)?;
    enc.still_picture = Arbitrary::arbitrary(u)?;
    enc.time_base =
      Rational::new(Arbitrary::arbitrary(u)?, Arbitrary::arbitrary(u)?);
    enc.min_key_frame_interval = Arbitrary::arbitrary(u)?;
    enc.max_key_frame_interval = Arbitrary::arbitrary(u)?;
    enc.reservoir_frame_delay = Arbitrary::arbitrary(u)?;
    enc.low_latency = Arbitrary::arbitrary(u)?;
    enc.quantizer = Arbitrary::arbitrary(u)?;
    enc.min_quantizer = Arbitrary::arbitrary(u)?;
    enc.bitrate = Arbitrary::arbitrary(u)?;
    enc.tile_cols = Arbitrary::arbitrary(u)?;
    enc.tile_rows = Arbitrary::arbitrary(u)?;
    enc.tiles = Arbitrary::arbitrary(u)?;
    enc.rdo_lookahead_frames = Arbitrary::arbitrary(u)?;
    let config = Config::new().with_encoder_config(enc).with_threads(1);
    Ok(Self { config })
  }
}

pub fn fuzz_construct_context(arbitrary: ArbitraryConfig) {
  let _: Result<Context<u16>, _> = arbitrary.config.new_context();
}

fn encode_frames(
  ctx: &mut Context<u8>, mut frames: impl Iterator<Item = Frame<u8>>,
) -> Result<(), EncoderStatus> {
  loop {
    let rv = ctx.receive_packet();
    debug!("ctx.receive_packet() = {:#?}", rv);

    match rv {
      Ok(_packet) => {}
      Err(EncoderStatus::Encoded) => {}
      Err(EncoderStatus::LimitReached) => {
        break;
      }
      Err(EncoderStatus::NeedMoreData) => {
        ctx.send_frame(frames.next().map(Arc::new))?;
      }
      Err(EncoderStatus::EnoughData) => {
        unreachable!();
      }
      Err(EncoderStatus::NotReady) => {
        unreachable!();
      }
      Err(EncoderStatus::Failure) => {
        return Err(EncoderStatus::Failure);
      }
    }
  }

  Ok(())
}

#[derive(Debug)]
pub struct ArbitraryEncoder {
  config: Config,
  frame_count: u8,
  pixels: Box<[u8]>,
}

impl Arbitrary for ArbitraryEncoder {
  fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self, Error> {
    let mut enc = EncoderConfig::with_speed_preset(10);
    enc.width = u.int_in_range(1..=256)?;
    enc.height = u.int_in_range(1..=256)?;
    enc.still_picture = Arbitrary::arbitrary(u)?;
    enc.time_base =
      Rational::new(Arbitrary::arbitrary(u)?, Arbitrary::arbitrary(u)?);
    enc.min_key_frame_interval = u.int_in_range(0..=3)?;
    enc.max_key_frame_interval = u.int_in_range(1..=4)?;
    enc.low_latency = Arbitrary::arbitrary(u)?;
    enc.quantizer = Arbitrary::arbitrary(u)?;
    enc.min_quantizer = Arbitrary::arbitrary(u)?;
    enc.bitrate = Arbitrary::arbitrary(u)?;
    // enc.tile_cols = Arbitrary::arbitrary(u)?;
    // enc.tile_rows = Arbitrary::arbitrary(u)?;
    // enc.tiles = Arbitrary::arbitrary(u)?;
    enc.rdo_lookahead_frames = Arbitrary::arbitrary(u)?;
    let frame_count = u.int_in_range(1..=3)?;
    if u.is_empty() {
      return Err(Error::NotEnoughData);
    }
    let pixels = u.get_bytes(u.len())?.to_vec().into_boxed_slice();
    let config = Config::new().with_encoder_config(enc).with_threads(1);
    Ok(Self { config, frame_count, pixels })
  }
}

pub fn fuzz_encode(arbitrary: ArbitraryEncoder) {
  let res = arbitrary.config.new_context();
  if res.is_err() {
    return;
  }
  let mut context: Context<u8> = res.unwrap();

  let mut pixels = arbitrary.pixels.iter().cycle();
  let mut frame = context.new_frame();
  let frames = (0..arbitrary.frame_count).map(|_| {
    for plane in &mut frame.planes {
      let stride = plane.cfg.stride;
      for row in plane.data_origin_mut().chunks_mut(stride) {
        for pixel in row {
          *pixel = *pixels.next().unwrap();
        }
      }
    }

    frame.clone()
  });

  let _ = encode_frames(&mut context, frames);
}

#[derive(Debug)]
pub struct DecodeTestParameters {
  w: usize,
  h: usize,
  speed: usize,
  q: usize,
  limit: usize,
  bit_depth: usize,
  chroma_sampling: ChromaSampling,
  min_keyint: u64,
  max_keyint: u64,
  switch_frame_interval: u64,
  low_latency: bool,
  error_resilient: bool,
  bitrate: i32,
  tile_cols_log2: usize,
  tile_rows_log2: usize,
  still_picture: bool,
}

impl Arbitrary for DecodeTestParameters {
  fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self, Error> {
    Ok(Self {
      w: u.int_in_range(16..=16 + 255)?,
      h: u.int_in_range(16..=16 + 255)?,
      speed: 10,
      q: u8::arbitrary(u)?.into(),
      limit: u.int_in_range(1..=3)?,
      bit_depth: 8,
      chroma_sampling: Default::default(),
      min_keyint: u.int_in_range(0..=3)?,
      max_keyint: u.int_in_range(1..=4)?,
      switch_frame_interval: 0,
      low_latency: bool::arbitrary(u)?,
      error_resilient: false,
      bitrate: i32::arbitrary(u)?,
      tile_cols_log2: 1,
      tile_rows_log2: 1,
      still_picture: false,
    })
  }
}

#[cfg(feature = "decode_test_dav1d")]
pub fn fuzz_encode_decode(p: DecodeTestParameters) {
  use crate::test_encode_decode::*;

  let mut dec = get_decoder::<u8>("dav1d", p.w, p.h);
  dec.encode_decode(
    p.w,
    p.h,
    p.speed,
    p.q,
    p.limit,
    p.bit_depth,
    p.chroma_sampling,
    p.min_keyint,
    p.max_keyint,
    p.switch_frame_interval,
    p.low_latency,
    p.error_resilient,
    p.bitrate,
    p.tile_cols_log2,
    p.tile_rows_log2,
    p.still_picture,
  );
}
<commit_msg>fuzz: Increase coverage of encode_decode<commit_after>// Copyright (c) 2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use std::sync::Arc;

use libfuzzer_sys::arbitrary::{Arbitrary, Error, Unstructured};

use crate::prelude::*;

// Adding new fuzz targets
//
// 1. Add a function to this file which looks like this:
//
//    pub fn fuzz_something(data: Data) {
//      // Invoke everything you need.
//      //
//      // Your function may accept a value of any type that implements
//      // Arbitrary [1]. This is how fuzzer affects the execution—by
//      // feeding in different bytes, which result in different
//      // arbitrary values being generated.
//      // [1]: https://docs.rs/arbitrary/0.3.3/arbitrary/trait.Arbitrary.html
//      //
//      // Derive Debug for the structures you create with arbitrary data.
//    }
//
// 2. cargo fuzz add something
// 3. Copy the contents of any other .rs file from fuzz/fuzz_targets/ into the
//    newly created fuzz/fuzz_targets/something.rs and change the function
//    being called to fuzz_something.
//
// Now you can fuzz the new target with cargo fuzz.

#[derive(Debug)]
pub struct ArbitraryConfig {
  config: Config,
}

impl Arbitrary for ArbitraryConfig {
  fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self, Error> {
    let mut enc = EncoderConfig::with_speed_preset(Arbitrary::arbitrary(u)?);
    enc.width = Arbitrary::arbitrary(u)?;
    enc.height = Arbitrary::arbitrary(u)?;
    enc.bit_depth = u.int_in_range(0..=16)?;
    enc.still_picture = Arbitrary::arbitrary(u)?;
    enc.time_base =
      Rational::new(Arbitrary::arbitrary(u)?, Arbitrary::arbitrary(u)?);
    enc.min_key_frame_interval = Arbitrary::arbitrary(u)?;
    enc.max_key_frame_interval = Arbitrary::arbitrary(u)?;
    enc.reservoir_frame_delay = Arbitrary::arbitrary(u)?;
    enc.low_latency = Arbitrary::arbitrary(u)?;
    enc.quantizer = Arbitrary::arbitrary(u)?;
    enc.min_quantizer = Arbitrary::arbitrary(u)?;
    enc.bitrate = Arbitrary::arbitrary(u)?;
    enc.tile_cols = Arbitrary::arbitrary(u)?;
    enc.tile_rows = Arbitrary::arbitrary(u)?;
    enc.tiles = Arbitrary::arbitrary(u)?;
    enc.rdo_lookahead_frames = Arbitrary::arbitrary(u)?;
    let config = Config::new().with_encoder_config(enc).with_threads(1);
    Ok(Self { config })
  }
}

pub fn fuzz_construct_context(arbitrary: ArbitraryConfig) {
  let _: Result<Context<u16>, _> = arbitrary.config.new_context();
}

fn encode_frames(
  ctx: &mut Context<u8>, mut frames: impl Iterator<Item = Frame<u8>>,
) -> Result<(), EncoderStatus> {
  loop {
    let rv = ctx.receive_packet();
    debug!("ctx.receive_packet() = {:#?}", rv);

    match rv {
      Ok(_packet) => {}
      Err(EncoderStatus::Encoded) => {}
      Err(EncoderStatus::LimitReached) => {
        break;
      }
      Err(EncoderStatus::NeedMoreData) => {
        ctx.send_frame(frames.next().map(Arc::new))?;
      }
      Err(EncoderStatus::EnoughData) => {
        unreachable!();
      }
      Err(EncoderStatus::NotReady) => {
        unreachable!();
      }
      Err(EncoderStatus::Failure) => {
        return Err(EncoderStatus::Failure);
      }
    }
  }

  Ok(())
}

#[derive(Debug)]
pub struct ArbitraryEncoder {
  config: Config,
  frame_count: u8,
  pixels: Box<[u8]>,
}

impl Arbitrary for ArbitraryEncoder {
  fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self, Error> {
    let mut enc = EncoderConfig::with_speed_preset(10);
    enc.width = u.int_in_range(1..=256)?;
    enc.height = u.int_in_range(1..=256)?;
    enc.still_picture = Arbitrary::arbitrary(u)?;
    enc.time_base =
      Rational::new(Arbitrary::arbitrary(u)?, Arbitrary::arbitrary(u)?);
    enc.min_key_frame_interval = u.int_in_range(0..=3)?;
    enc.max_key_frame_interval = u.int_in_range(1..=4)?;
    enc.low_latency = Arbitrary::arbitrary(u)?;
    enc.quantizer = Arbitrary::arbitrary(u)?;
    enc.min_quantizer = Arbitrary::arbitrary(u)?;
    enc.bitrate = Arbitrary::arbitrary(u)?;
    // enc.tile_cols = Arbitrary::arbitrary(u)?;
    // enc.tile_rows = Arbitrary::arbitrary(u)?;
    // enc.tiles = Arbitrary::arbitrary(u)?;
    enc.rdo_lookahead_frames = Arbitrary::arbitrary(u)?;
    let frame_count = u.int_in_range(1..=3)?;
    if u.is_empty() {
      return Err(Error::NotEnoughData);
    }
    let pixels = u.get_bytes(u.len())?.to_vec().into_boxed_slice();
    let config = Config::new().with_encoder_config(enc).with_threads(1);
    Ok(Self { config, frame_count, pixels })
  }
}

pub fn fuzz_encode(arbitrary: ArbitraryEncoder) {
  let res = arbitrary.config.new_context();
  if res.is_err() {
    return;
  }
  let mut context: Context<u8> = res.unwrap();

  let mut pixels = arbitrary.pixels.iter().cycle();
  let mut frame = context.new_frame();
  let frames = (0..arbitrary.frame_count).map(|_| {
    for plane in &mut frame.planes {
      let stride = plane.cfg.stride;
      for row in plane.data_origin_mut().chunks_mut(stride) {
        for pixel in row {
          *pixel = *pixels.next().unwrap();
        }
      }
    }

    frame.clone()
  });

  let _ = encode_frames(&mut context, frames);
}

#[derive(Debug)]
pub struct DecodeTestParameters {
  w: usize,
  h: usize,
  speed: usize,
  q: usize,
  limit: usize,
  bit_depth: usize,
  chroma_sampling: ChromaSampling,
  min_keyint: u64,
  max_keyint: u64,
  switch_frame_interval: u64,
  low_latency: bool,
  error_resilient: bool,
  bitrate: i32,
  tile_cols_log2: usize,
  tile_rows_log2: usize,
  still_picture: bool,
}

impl Arbitrary for DecodeTestParameters {
  fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self, Error> {
    let mut p = Self {
      w: u.int_in_range(16..=16 + 255)?,
      h: u.int_in_range(16..=16 + 255)?,
      speed: u.int_in_range(0..=10)?,
      q: u8::arbitrary(u)?.into(),
      limit: u.int_in_range(1..=3)?,
      bit_depth: 8,
      chroma_sampling: *u.choose(&[
        ChromaSampling::Cs420,
        ChromaSampling::Cs422,
        ChromaSampling::Cs444,
        ChromaSampling::Cs400,
      ])?,
      min_keyint: u.int_in_range(0..=3)?,
      max_keyint: u.int_in_range(1..=4)?,
      switch_frame_interval: 0,
      low_latency: bool::arbitrary(u)?,
      error_resilient: bool::arbitrary(u)?,
      bitrate: u16::arbitrary(u)?.into(),
      tile_cols_log2: u.int_in_range(0..=2)?,
      tile_rows_log2: u.int_in_range(0..=2)?,
      still_picture: bool::arbitrary(u)?,
    };
    if p.still_picture {
      p.limit = 1
    }
    Ok(p)
  }
}

#[cfg(feature = "decode_test_dav1d")]
pub fn fuzz_encode_decode(p: DecodeTestParameters) {
  use crate::test_encode_decode::*;

  let mut dec = get_decoder::<u8>("dav1d", p.w, p.h);
  dec.encode_decode(
    p.w,
    p.h,
    p.speed,
    p.q,
    p.limit,
    p.bit_depth,
    p.chroma_sampling,
    p.min_keyint,
    p.max_keyint,
    p.switch_frame_interval,
    p.low_latency,
    p.error_resilient,
    p.bitrate,
    p.tile_cols_log2,
    p.tile_rows_log2,
    p.still_picture,
  );
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// GPIO direction.
pub enum GPIODirection {
  In,
  Out,
}

#[deriving(PartialEq)]
pub enum GPIOLevel {
  Low,
  High,
}

pub trait GPIO {
  fn set_high(&self);
  fn set_low(&self);
  fn level(&self) -> GPIOLevel;
  fn set_direction(&self, new_mode: GPIODirection);
}
<commit_msg>Document GPIO<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// GPIO direction.
pub enum GPIODirection {
  In,
  Out,
}

/// Logic levels.
#[deriving(PartialEq)]
pub enum GPIOLevel {
  Low,
  High,
}

/// General Purpose I/O
pub trait GPIO {
  /// Set to logic high
  fn set_high(&self);

  /// Set to logic low
  fn set_low(&self);

  /// Read current logic level
  fn level(&self) -> GPIOLevel;

  /// Set directio to `Low` or `High`
  fn set_direction(&self, new_mode: GPIODirection);
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use actix::Actor;
use futures::Future;
use serde_json;
use serde::Serialize;
use regex::Regex;
use http::{header, StatusCode, Error as HttpError};

use body::Body;
use error::Error;
use context::{HttpContext, IoContext};
use httprequest::HttpRequest;
use httpresponse::HttpResponse;

/// Trait defines object that could be regestered as route handler
#[allow(unused_variables)]
pub trait Handler<S>: 'static {

    /// The type of value that handler will return.
    type Result: FromRequest;

    /// Handle request
    fn handle(&self, req: HttpRequest<S>) -> Self::Result;
}

pub trait FromRequest {
    /// The associated item which can be returned.
    type Item: Into<Reply>;

    /// The associated error which can be returned.
    type Error: Into<Error>;

    fn from_request(self, req: HttpRequest) -> Result<Self::Item, Self::Error>;
}

/// Handler<S> for Fn()
impl<F, R, S> Handler<S> for F
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: FromRequest + 'static
{
    type Result = R;

    fn handle(&self, req: HttpRequest<S>) -> R {
        (self)(req)
    }
}

/// Represents response process.
pub struct Reply(ReplyItem);

pub(crate) enum ReplyItem {
    Message(HttpResponse),
    Actor(Box<IoContext>),
    Future(Box<Future<Item=HttpResponse, Error=Error>>),
}

impl Reply {

    /// Create actor response
    pub fn actor<A, S>(ctx: HttpContext<A, S>) -> Reply
        where A: Actor<Context=HttpContext<A, S>>, S: 'static
    {
        Reply(ReplyItem::Actor(Box::new(ctx)))
    }

    /// Create async response
    pub fn async<F>(fut: F) -> Reply
        where F: Future<Item=HttpResponse, Error=Error> + 'static
    {
        Reply(ReplyItem::Future(Box::new(fut)))
    }

    /// Send response
    pub fn response<R: Into<HttpResponse>>(response: R) -> Reply {
        Reply(ReplyItem::Message(response.into()))
    }

    pub(crate) fn into(self) -> ReplyItem {
        self.0
    }
}

impl FromRequest for Reply {
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(self)
    }
}

impl FromRequest for HttpResponse {
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(Reply(ReplyItem::Message(self)))
    }
}

impl From<HttpResponse> for Reply {

    fn from(resp: HttpResponse) -> Reply {
        Reply(ReplyItem::Message(resp))
    }
}

impl<T: FromRequest, E: Into<Error>> FromRequest for Result<T, E>
{
    type Item = <T as FromRequest>::Item;
    type Error = Error;

    fn from_request(self, req: HttpRequest) -> Result<Self::Item, Self::Error> {
        match self {
            Ok(val) => match val.from_request(req) {
                Ok(val) => Ok(val),
                Err(err) => Err(err.into()),
            },
            Err(err) => Err(err.into()),
        }
    }
}

impl<E: Into<Error>> From<Result<Reply, E>> for Reply {
    fn from(res: Result<Reply, E>) -> Self {
        match res {
            Ok(val) => val,
            Err(err) => Reply(ReplyItem::Message(err.into().into())),
        }
    }
}

impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> FromRequest for HttpContext<A, S>
{
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(Reply(ReplyItem::Actor(Box::new(self))))
    }
}

impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> From<HttpContext<A, S>> for Reply {

    fn from(ctx: HttpContext<A, S>) -> Reply {
        Reply(ReplyItem::Actor(Box::new(ctx)))
    }
}

impl FromRequest for Box<Future<Item=HttpResponse, Error=Error>>
{
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(Reply(ReplyItem::Future(self)))
    }
}

/// Trait defines object that could be regestered as resource route
pub(crate) trait RouteHandler<S>: 'static {
    fn handle(&self, req: HttpRequest<S>) -> Reply;
}

/// Route handler wrapper for Handler
pub(crate)
struct WrapHandler<S, H, R>
    where H: Handler<S, Result=R>,
          R: FromRequest,
          S: 'static,
{
    h: H,
    s: PhantomData<S>,
}

impl<S, H, R> WrapHandler<S, H, R>
    where H: Handler<S, Result=R>,
          R: FromRequest,
          S: 'static,
{
    pub fn new(h: H) -> Self {
        WrapHandler{h: h, s: PhantomData}
    }
}

impl<S, H, R> RouteHandler<S> for WrapHandler<S, H, R>
    where H: Handler<S, Result=R>,
          R: FromRequest + 'static,
          S: 'static,
{
    fn handle(&self, req: HttpRequest<S>) -> Reply {
        let req2 = req.clone_without_state();
        match self.h.handle(req).from_request(req2) {
            Ok(reply) => reply.into(),
            Err(err) => Reply::response(err.into()),
        }
    }
}

/// Async route handler
pub(crate)
struct AsyncHandler<S, R, F>
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: Future<Item=HttpResponse, Error=Error> + 'static,
          S: 'static,
{
    f: Box<F>,
    s: PhantomData<S>,
}

impl<S, R, F> AsyncHandler<S, R, F>
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: Future<Item=HttpResponse, Error=Error> + 'static,
          S: 'static,
{
    pub fn new(f: F) -> Self {
        AsyncHandler{f: Box::new(f), s: PhantomData}
    }
}

impl<S, R, F> RouteHandler<S> for AsyncHandler<S, R, F>
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: Future<Item=HttpResponse, Error=Error> + 'static,
          S: 'static,
{
    fn handle(&self, req: HttpRequest<S>) -> Reply {
        Reply::async((self.f)(req))
    }
}

/// Json response helper
///
/// The `Json` type allows you to respond with well-formed JSON data: simply return a value of
/// type Json<T> where T is the type of a structure to serialize into *JSON*. The
/// type `T` must implement the `Serialize` trait from *serde*.
///
/// ```rust
/// # extern crate actix_web;
/// # #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// #
/// #[derive(Serialize)]
/// struct MyObj {
///     name: String,
/// }
///
/// fn index(req: HttpRequest) -> Result<Json<MyObj>> {
///     Ok(Json(MyObj{name: req.match_info().query("name")?}))
/// }
/// # fn main() {}
/// ```
pub struct Json<T: Serialize> (pub T);

impl<T: Serialize> FromRequest for Json<T> {
    type Item = HttpResponse;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<HttpResponse, Error> {
        let body = serde_json::to_string(&self.0)?;

        Ok(HttpResponse::Ok()
           .content_type("application/json")
           .body(body)?)
    }
}

/// Handler that normalizes the path of a request. By normalizing it means:
///
/// - Add a trailing slash to the path.
/// - Double slashes are replaced by one.
///
/// The handler returns as soon as it finds a path that resolves
/// correctly. The order if all enable is 1) merge, 2) append
/// and 3) both merge and append. If the path resolves with
/// at least one of those conditions, it will redirect to the new path.
///
/// If *append* is *true* append slash when needed. If a resource is
/// defined with trailing slash and the request comes without it, it will
/// append it automatically.
///
/// If *merge* is *true*, merge multiple consecutive slashes in the path into one.
///
/// This handler designed to be use as a handler for application's *default resource*.
pub struct NormalizePath {
    append: bool,
    merge: bool,
    re_merge: Regex,
    redirect: StatusCode,
    not_found: StatusCode,
}

impl Default for NormalizePath {
    fn default() -> NormalizePath {
        NormalizePath {
            append: true,
            merge: true,
            re_merge: Regex::new("//+").unwrap(),
            redirect: StatusCode::MOVED_PERMANENTLY,
            not_found: StatusCode::NOT_FOUND,
        }
    }
}

impl NormalizePath {
    pub fn new(append: bool, merge: bool, redirect: StatusCode) -> NormalizePath {
        NormalizePath {
            append: append,
            merge: merge,
            re_merge: Regex::new("//+").unwrap(),
            redirect: redirect,
            not_found: StatusCode::NOT_FOUND,
        }
    }
}

impl<S> Handler<S> for NormalizePath {
    type Result = Result<HttpResponse, HttpError>;

    fn handle(&self, req: HttpRequest<S>) -> Self::Result {
        if let Some(router) = req.router() {
            if self.merge {
                // merge slashes
                let p = self.re_merge.replace_all(req.path(), "/");
                if p.len() != req.path().len() {
                    if router.has_route(p.as_ref()) {
                        return HttpResponse::build(self.redirect)
                            .header(header::LOCATION, p.as_ref())
                            .body(Body::Empty);
                    }
                    // merge slashes and append trailing slash
                    if self.append && !p.ends_with('/') {
                        let p = p.as_ref().to_owned() + "/";
                        if router.has_route(&p) {
                            return HttpResponse::build(self.redirect)
                                .header(header::LOCATION, p.as_str())
                                .body(Body::Empty);
                        }
                    }
                }
            }
            // append trailing slash
            if self.append && !req.path().ends_with('/') {
                let p = req.path().to_owned() + "/";
                if router.has_route(&p) {
                    return HttpResponse::build(self.redirect)
                        .header(header::LOCATION, p.as_str())
                        .body(Body::Empty);
                }
            }
        }
        Ok(HttpResponse::new(self.not_found, Body::Empty))
    }
}

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

    #[derive(Serialize)]
    struct MyObj {
        name: &'static str,
    }

    #[test]
    fn test_json() {
        let json = Json(MyObj{name: "test"});
        let resp = json.from_request(HttpRequest::default()).unwrap();
        assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), "application/json");
    }
}
<commit_msg>update doc string for NormalizePath<commit_after>use std::marker::PhantomData;

use actix::Actor;
use futures::Future;
use serde_json;
use serde::Serialize;
use regex::Regex;
use http::{header, StatusCode, Error as HttpError};

use body::Body;
use error::Error;
use context::{HttpContext, IoContext};
use httprequest::HttpRequest;
use httpresponse::HttpResponse;

/// Trait defines object that could be regestered as route handler
#[allow(unused_variables)]
pub trait Handler<S>: 'static {

    /// The type of value that handler will return.
    type Result: FromRequest;

    /// Handle request
    fn handle(&self, req: HttpRequest<S>) -> Self::Result;
}

pub trait FromRequest {
    /// The associated item which can be returned.
    type Item: Into<Reply>;

    /// The associated error which can be returned.
    type Error: Into<Error>;

    fn from_request(self, req: HttpRequest) -> Result<Self::Item, Self::Error>;
}

/// Handler<S> for Fn()
impl<F, R, S> Handler<S> for F
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: FromRequest + 'static
{
    type Result = R;

    fn handle(&self, req: HttpRequest<S>) -> R {
        (self)(req)
    }
}

/// Represents response process.
pub struct Reply(ReplyItem);

pub(crate) enum ReplyItem {
    Message(HttpResponse),
    Actor(Box<IoContext>),
    Future(Box<Future<Item=HttpResponse, Error=Error>>),
}

impl Reply {

    /// Create actor response
    pub fn actor<A, S>(ctx: HttpContext<A, S>) -> Reply
        where A: Actor<Context=HttpContext<A, S>>, S: 'static
    {
        Reply(ReplyItem::Actor(Box::new(ctx)))
    }

    /// Create async response
    pub fn async<F>(fut: F) -> Reply
        where F: Future<Item=HttpResponse, Error=Error> + 'static
    {
        Reply(ReplyItem::Future(Box::new(fut)))
    }

    /// Send response
    pub fn response<R: Into<HttpResponse>>(response: R) -> Reply {
        Reply(ReplyItem::Message(response.into()))
    }

    pub(crate) fn into(self) -> ReplyItem {
        self.0
    }
}

impl FromRequest for Reply {
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(self)
    }
}

impl FromRequest for HttpResponse {
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(Reply(ReplyItem::Message(self)))
    }
}

impl From<HttpResponse> for Reply {

    fn from(resp: HttpResponse) -> Reply {
        Reply(ReplyItem::Message(resp))
    }
}

impl<T: FromRequest, E: Into<Error>> FromRequest for Result<T, E>
{
    type Item = <T as FromRequest>::Item;
    type Error = Error;

    fn from_request(self, req: HttpRequest) -> Result<Self::Item, Self::Error> {
        match self {
            Ok(val) => match val.from_request(req) {
                Ok(val) => Ok(val),
                Err(err) => Err(err.into()),
            },
            Err(err) => Err(err.into()),
        }
    }
}

impl<E: Into<Error>> From<Result<Reply, E>> for Reply {
    fn from(res: Result<Reply, E>) -> Self {
        match res {
            Ok(val) => val,
            Err(err) => Reply(ReplyItem::Message(err.into().into())),
        }
    }
}

impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> FromRequest for HttpContext<A, S>
{
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(Reply(ReplyItem::Actor(Box::new(self))))
    }
}

impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> From<HttpContext<A, S>> for Reply {

    fn from(ctx: HttpContext<A, S>) -> Reply {
        Reply(ReplyItem::Actor(Box::new(ctx)))
    }
}

impl FromRequest for Box<Future<Item=HttpResponse, Error=Error>>
{
    type Item = Reply;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
        Ok(Reply(ReplyItem::Future(self)))
    }
}

/// Trait defines object that could be regestered as resource route
pub(crate) trait RouteHandler<S>: 'static {
    fn handle(&self, req: HttpRequest<S>) -> Reply;
}

/// Route handler wrapper for Handler
pub(crate)
struct WrapHandler<S, H, R>
    where H: Handler<S, Result=R>,
          R: FromRequest,
          S: 'static,
{
    h: H,
    s: PhantomData<S>,
}

impl<S, H, R> WrapHandler<S, H, R>
    where H: Handler<S, Result=R>,
          R: FromRequest,
          S: 'static,
{
    pub fn new(h: H) -> Self {
        WrapHandler{h: h, s: PhantomData}
    }
}

impl<S, H, R> RouteHandler<S> for WrapHandler<S, H, R>
    where H: Handler<S, Result=R>,
          R: FromRequest + 'static,
          S: 'static,
{
    fn handle(&self, req: HttpRequest<S>) -> Reply {
        let req2 = req.clone_without_state();
        match self.h.handle(req).from_request(req2) {
            Ok(reply) => reply.into(),
            Err(err) => Reply::response(err.into()),
        }
    }
}

/// Async route handler
pub(crate)
struct AsyncHandler<S, R, F>
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: Future<Item=HttpResponse, Error=Error> + 'static,
          S: 'static,
{
    f: Box<F>,
    s: PhantomData<S>,
}

impl<S, R, F> AsyncHandler<S, R, F>
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: Future<Item=HttpResponse, Error=Error> + 'static,
          S: 'static,
{
    pub fn new(f: F) -> Self {
        AsyncHandler{f: Box::new(f), s: PhantomData}
    }
}

impl<S, R, F> RouteHandler<S> for AsyncHandler<S, R, F>
    where F: Fn(HttpRequest<S>) -> R + 'static,
          R: Future<Item=HttpResponse, Error=Error> + 'static,
          S: 'static,
{
    fn handle(&self, req: HttpRequest<S>) -> Reply {
        Reply::async((self.f)(req))
    }
}

/// Json response helper
///
/// The `Json` type allows you to respond with well-formed JSON data: simply return a value of
/// type Json<T> where T is the type of a structure to serialize into *JSON*. The
/// type `T` must implement the `Serialize` trait from *serde*.
///
/// ```rust
/// # extern crate actix_web;
/// # #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// #
/// #[derive(Serialize)]
/// struct MyObj {
///     name: String,
/// }
///
/// fn index(req: HttpRequest) -> Result<Json<MyObj>> {
///     Ok(Json(MyObj{name: req.match_info().query("name")?}))
/// }
/// # fn main() {}
/// ```
pub struct Json<T: Serialize> (pub T);

impl<T: Serialize> FromRequest for Json<T> {
    type Item = HttpResponse;
    type Error = Error;

    fn from_request(self, _: HttpRequest) -> Result<HttpResponse, Error> {
        let body = serde_json::to_string(&self.0)?;

        Ok(HttpResponse::Ok()
           .content_type("application/json")
           .body(body)?)
    }
}

/// Path normalization helper
///
/// By normalizing it means:
///
/// - Add a trailing slash to the path.
/// - Double slashes are replaced by one.
///
/// The handler returns as soon as it finds a path that resolves
/// correctly. The order if all enable is 1) merge, 3) both merge and append
/// and 3) append. If the path resolves with
/// at least one of those conditions, it will redirect to the new path.
///
/// If *append* is *true* append slash when needed. If a resource is
/// defined with trailing slash and the request comes without it, it will
/// append it automatically.
///
/// If *merge* is *true*, merge multiple consecutive slashes in the path into one.
///
/// This handler designed to be use as a handler for application's *default resource*.
///
/// ```rust
/// # extern crate actix_web;
/// # #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// #
/// # fn index(req: HttpRequest) -> httpcodes::StaticResponse {
/// #     httpcodes::HTTPOk
/// # }
/// fn main() {
///     let app = Application::new("/")
///         .resource("/test/", |r| r.f(index))
///         .default_resource(|r| r.h(NormalizePath::default()))
///         .finish();
/// }
/// ```
/// In this example `/test`, `/test///` will be redirected to `/test/` url.
pub struct NormalizePath {
    append: bool,
    merge: bool,
    re_merge: Regex,
    redirect: StatusCode,
    not_found: StatusCode,
}

impl Default for NormalizePath {
    /// Create default `NormalizePath` instance, *append* is set to *true*,
    /// *merge* is set to *true* and *redirect* is set to `StatusCode::MOVED_PERMANENTLY`
    fn default() -> NormalizePath {
        NormalizePath {
            append: true,
            merge: true,
            re_merge: Regex::new("//+").unwrap(),
            redirect: StatusCode::MOVED_PERMANENTLY,
            not_found: StatusCode::NOT_FOUND,
        }
    }
}

impl NormalizePath {
    /// Create new `NoramlizePath` instance
    pub fn new(append: bool, merge: bool, redirect: StatusCode) -> NormalizePath {
        NormalizePath {
            append: append,
            merge: merge,
            re_merge: Regex::new("//+").unwrap(),
            redirect: redirect,
            not_found: StatusCode::NOT_FOUND,
        }
    }
}

impl<S> Handler<S> for NormalizePath {
    type Result = Result<HttpResponse, HttpError>;

    fn handle(&self, req: HttpRequest<S>) -> Self::Result {
        if let Some(router) = req.router() {
            if self.merge {
                // merge slashes
                let p = self.re_merge.replace_all(req.path(), "/");
                if p.len() != req.path().len() {
                    if router.has_route(p.as_ref()) {
                        return HttpResponse::build(self.redirect)
                            .header(header::LOCATION, p.as_ref())
                            .body(Body::Empty);
                    }
                    // merge slashes and append trailing slash
                    if self.append && !p.ends_with('/') {
                        let p = p.as_ref().to_owned() + "/";
                        if router.has_route(&p) {
                            return HttpResponse::build(self.redirect)
                                .header(header::LOCATION, p.as_str())
                                .body(Body::Empty);
                        }
                    }
                }
            }
            // append trailing slash
            if self.append && !req.path().ends_with('/') {
                let p = req.path().to_owned() + "/";
                if router.has_route(&p) {
                    return HttpResponse::build(self.redirect)
                        .header(header::LOCATION, p.as_str())
                        .body(Body::Empty);
                }
            }
        }
        Ok(HttpResponse::new(self.not_found, Body::Empty))
    }
}

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

    #[derive(Serialize)]
    struct MyObj {
        name: &'static str,
    }

    #[test]
    fn test_json() {
        let json = Json(MyObj{name: "test"});
        let resp = json.from_request(HttpRequest::default()).unwrap();
        assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), "application/json");
    }
}
<|endoftext|>


<commit_before>// check-pass

// This is issue #85435. But the real story is reflected in issue #85561, where
// a bug in the implementation of feature(capture_disjoint_fields) () was
// exposed to non-feature-gated code by a diagnostic changing PR that removed
// the gating in one case.

// This test is double-checking that the case of interest continues to work as
// expected in the *absence* of that feature gate. At the time of this writing,
// enabling the feature gate will cause this test to fail. We obviously cannot
// stabilize that feature until it can correctly handle this test.

fn main() {
    let val: u8 = 5;
    let u8_ptr: *const u8 = &val;
    let _closure = || {
        unsafe {
            // Fails compilation with:
            // error[E0133]: dereference of raw pointer is unsafe and
            //               requires unsafe function or block
            let tmp = *u8_ptr;
            tmp

            // Just dereferencing and returning directly compiles fine:
            // *u8_ptr
        }
    };
}
<commit_msg>Apply suggestions from code review<commit_after>// check-pass

// This is issue #85435. But the real story is reflected in issue #85561, where
// a bug in the implementation of feature(capture_disjoint_fields) () was
// exposed to non-feature-gated code by a diagnostic changing PR that removed
// the gating in one case.

// This test is double-checking that the case of interest continues to work as
// expected in the *absence* of that feature gate. At the time of this writing,
// enabling the feature gate will cause this test to fail. We obviously cannot
// stabilize that feature until it can correctly handle this test.

fn main() {
    let val: u8 = 5;
    let u8_ptr: *const u8 = &val;
    let _closure = || {
        unsafe {
            let tmp = *u8_ptr;
            tmp

            // Just dereferencing and returning directly compiles fine:
            // *u8_ptr
        }
    };
}
<|endoftext|>


<commit_before>//! Defines a generic 2D image type.

use ndarray;
use ndarray::prelude::*;
use num_traits::{Zero};

use std::iter::{IntoIterator};

use errors::*;
use traits::Pixel;

/// 2-dimensional image type.
pub struct Image2D

    where P: Pixel
{
    buffer: Array2

}

/// Type of immutable `Image2D` views.
pub type Image2DView<'a, P> = ndarray::ArrayView<'a, P, Ix2>;

impl<'a, P> Image2D

    where P: Pixel
{
    /// Create a new image of specified dimensions from a `Vec`.
    ///
    /// **Error**: `InvalidDimensions` if the dimensions do not match the length of `v`.
    pub fn from_vec(w: usize, h: usize, v: Vec
) -> Result<Image2D
> {
        let buf = try!(Array2::from_shape_vec((w, h), v));
        Ok(Image2D{ buffer: buf })
    }

    /// Return the pixel at the specified coordinates.
    ///
    /// **Panics** if the index is out of bounds.
    pub fn get_pixel(&self, x: usize, y: usize) -> P {
        self.buffer[[x, y]].clone()
    }

    /// Set the pixel at the specified coordinates to the specified value.
    ///
    /// **Panics** if the index is out of bounds.
    pub fn put_pixel(&mut self, x: usize, y: usize, pixel: P) {
        self.buffer[[x, y]] = pixel;
    }

    /// Return the width of the image.
    pub fn width(&self) -> usize { self.buffer.cols() }
    /// Return the height of the image.
    pub fn height(&self) -> usize { self.buffer.rows() }
    /// Return the dimensions of the image as a `(width, height)` tuple.
    pub fn dimensions(&self) -> (usize, usize) { self.buffer.dim() }

    /// Return a view to a subset of the image of specified dimensions starting at the specified
    /// coordinates.
    ///
    /// **Panics** if the specified region crosses image boundaries.
    pub fn sub_image(&'a self, x: usize, y: usize, w: usize, h: usize) -> Image2DView<'a, P> {
        let x = x as isize;
        let y = y as isize;
        let w = w as isize;
        let h = h as isize;
        self.buffer.slice(s![x..x + w, y..y + h])
    }
}

impl<'a, P> IntoIterator for &'a Image2D

    where P: Pixel + 'a
{
    type Item = &'a P;
    type IntoIter = ndarray::iter::Iter<'a, P, Ix2>;

    fn into_iter(self) -> Self::IntoIter {
        self.buffer.into_iter()
    }
}

impl<'a, P> IntoIterator for &'a mut Image2D

    where P: Pixel + 'a
{
    type Item = &'a mut P;
    type IntoIter = ndarray::iter::IterMut<'a, P, Ix2>;

    fn into_iter(self) -> Self::IntoIter {
        self.buffer.iter_mut()
    }
}

impl
 Image2D

    where P: Pixel + Zero
{
    /// Create a new image of specified dimensions filled with zeros.
    pub fn zeros(width: usize, height: usize) -> Image2D
 {
        Image2D { buffer: Array2::zeros((width, height)) }
    }
}

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

    use std::iter::FromIterator;
    use std::fmt::Debug;

    #[test]
    fn test_from_vec() {
        let v1 = Vec::from_iter((1u8..10u8).map(|n| Luma::new([n])));
        let v2 = Vec::from_iter((1u8..7u8).map(|n| Luma::new([n])));

        assert!(Image2D::from_vec(3, 3, v1.clone()).is_ok());
        assert!(Image2D::from_vec(2, 3, v2.clone()).is_ok());
        assert!(Image2D::from_vec(3, 2, v2.clone()).is_ok());

        assert!(Image2D::from_vec(3, 3, v2.clone()).is_err());
        assert!(Image2D::from_vec(4, 2, v2.clone()).is_err());
    }

    #[test]
    fn test_zeros() {
        fn test_zeros_helper
(w: usize, h: usize)
            where P: Pixel + Zero + Debug
        {
            let img = Image2D::
::zeros(w, h);
            for pixel in &img {
                assert!(pixel.is_zero());
            }
        };
        test_zeros_helper::<Luma<u8>>(100, 100);
        test_zeros_helper::<Luma<f32>>(100, 100);
    }

    #[test]
    fn test_into_iter() {
        let v: Vec<usize> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];

        for (i, p) in v.into_iter().enumerate() {
            assert!(i + 1 == p);
        }
    }

    #[test]
    fn test_sub_image() {
        let v: Vec<Luma<usize>> = (1..10).map(|n| Luma::new([n])).collect();
        let img = Image2D::from_vec(3, 3, v).unwrap();
        let subimg1 = img.sub_image(1, 1, 2, 2);

        fn subimg_vec_eq<'a>(subimg: Image2DView<'a, Luma<usize>>, v: &Vec<usize>) -> bool {
            let img_iter = subimg.into_iter();
            let v_iter   = v.into_iter();
            match img_iter.len() == v_iter.len() {
                true => !img_iter.zip(v_iter).any(|(p, i)| p.data[0] != *i),
                false => false
            }
        }

        let subimg1_vec: Vec<usize> = vec![5, 6, 8, 9];

        assert!(subimg_vec_eq(subimg1, &subimg1_vec));
    }
}
<commit_msg>Fix unit test<commit_after>//! Defines a generic 2D image type.

use ndarray;
use ndarray::prelude::*;
use num_traits::{Zero};

use std::iter::{IntoIterator};

use errors::*;
use traits::Pixel;

/// 2-dimensional image type.
pub struct Image2D

    where P: Pixel
{
    buffer: Array2

}

/// Type of immutable `Image2D` views.
pub type Image2DView<'a, P> = ndarray::ArrayView<'a, P, Ix2>;

impl<'a, P> Image2D

    where P: Pixel
{
    /// Create a new image of specified dimensions from a `Vec`.
    ///
    /// **Error**: `InvalidDimensions` if the dimensions do not match the length of `v`.
    pub fn from_vec(w: usize, h: usize, v: Vec
) -> Result<Image2D
> {
        let buf = try!(Array2::from_shape_vec((w, h), v));
        Ok(Image2D{ buffer: buf })
    }

    /// Return the pixel at the specified coordinates.
    ///
    /// **Panics** if the index is out of bounds.
    pub fn get_pixel(&self, x: usize, y: usize) -> P {
        self.buffer[[x, y]].clone()
    }

    /// Set the pixel at the specified coordinates to the specified value.
    ///
    /// **Panics** if the index is out of bounds.
    pub fn put_pixel(&mut self, x: usize, y: usize, pixel: P) {
        self.buffer[[x, y]] = pixel;
    }

    /// Return the width of the image.
    pub fn width(&self) -> usize { self.buffer.cols() }
    /// Return the height of the image.
    pub fn height(&self) -> usize { self.buffer.rows() }
    /// Return the dimensions of the image as a `(width, height)` tuple.
    pub fn dimensions(&self) -> (usize, usize) { self.buffer.dim() }

    /// Return a view to a subset of the image of specified dimensions starting at the specified
    /// coordinates.
    ///
    /// **Panics** if the specified region crosses image boundaries.
    pub fn sub_image(&'a self, x: usize, y: usize, w: usize, h: usize) -> Image2DView<'a, P> {
        let x = x as isize;
        let y = y as isize;
        let w = w as isize;
        let h = h as isize;
        self.buffer.slice(s![x..x + w, y..y + h])
    }
}

impl<'a, P> IntoIterator for &'a Image2D

    where P: Pixel + 'a
{
    type Item = &'a P;
    type IntoIter = ndarray::iter::Iter<'a, P, Ix2>;

    fn into_iter(self) -> Self::IntoIter {
        self.buffer.into_iter()
    }
}

impl<'a, P> IntoIterator for &'a mut Image2D

    where P: Pixel + 'a
{
    type Item = &'a mut P;
    type IntoIter = ndarray::iter::IterMut<'a, P, Ix2>;

    fn into_iter(self) -> Self::IntoIter {
        self.buffer.iter_mut()
    }
}

impl
 Image2D

    where P: Pixel + Zero
{
    /// Create a new image of specified dimensions filled with zeros.
    pub fn zeros(width: usize, height: usize) -> Image2D
 {
        Image2D { buffer: Array2::zeros((width, height)) }
    }
}

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

    use std::iter::FromIterator;
    use std::fmt::Debug;

    #[test]
    fn test_from_vec() {
        let v1 = Vec::from_iter((1u8..10u8).map(|n| Luma::new([n])));
        let v2 = Vec::from_iter((1u8..7u8).map(|n| Luma::new([n])));

        assert!(Image2D::from_vec(3, 3, v1.clone()).is_ok());
        assert!(Image2D::from_vec(2, 3, v2.clone()).is_ok());
        assert!(Image2D::from_vec(3, 2, v2.clone()).is_ok());

        assert!(Image2D::from_vec(3, 3, v2.clone()).is_err());
        assert!(Image2D::from_vec(4, 2, v2.clone()).is_err());
    }

    #[test]
    fn test_zeros() {
        fn test_zeros_helper
(w: usize, h: usize)
            where P: Pixel + Zero + Debug
        {
            let img = Image2D::
::zeros(w, h);
            for pixel in &img {
                assert!(pixel.is_zero());
            }
        };
        test_zeros_helper::<Luma<u8>>(100, 100);
        test_zeros_helper::<Luma<f32>>(100, 100);
    }

    #[test]
    fn test_into_iter() {
        let v: Vec<Luma<u8>> = (1..10).map(|i| Luma::from(i)).collect();
        let img = Image2D::from_vec(3, 3, v.clone()).unwrap();

        for (p, i) in img.into_iter().zip(v.into_iter()) {
            assert!(&i == p);
        }
    }

    #[test]
    fn test_sub_image() {
        let v: Vec<Luma<usize>> = (1..10).map(|n| Luma::new([n])).collect();
        let img = Image2D::from_vec(3, 3, v).unwrap();
        let subimg1 = img.sub_image(1, 1, 2, 2);

        fn subimg_vec_eq<'a>(subimg: Image2DView<'a, Luma<usize>>, v: &Vec<usize>) -> bool {
            let img_iter = subimg.into_iter();
            let v_iter   = v.into_iter();
            match img_iter.len() == v_iter.len() {
                true => !img_iter.zip(v_iter).any(|(p, i)| p.data[0] != *i),
                false => false
            }
        }

        let subimg1_vec: Vec<usize> = vec![5, 6, 8, 9];

        assert!(subimg_vec_eq(subimg1, &subimg1_vec));
    }
}
<|endoftext|>


<commit_before>use super::Wasmbin;

macro_rules! newtype_idx {
    ($name:ident) => {
        #[derive(Debug, PartialEq, Eq, Clone, Copy, Wasmbin)]
        pub struct $name(u32);
    };
}

newtype_idx!(TypeIdx);
newtype_idx!(FuncIdx);
newtype_idx!(TableIdx);
newtype_idx!(MemIdx);
newtype_idx!(GlobalIdx);
newtype_idx!(LocalIdx);
newtype_idx!(LabelIdx);
<commit_msg>Allow access to index value<commit_after>use super::Wasmbin;

macro_rules! newtype_idx {
    ($name:ident) => {
        #[derive(Debug, PartialEq, Eq, Clone, Copy, Wasmbin)]
        #[repr(transparent)]
        pub struct $name {
            pub index: u32,
        }
    };
}

newtype_idx!(TypeIdx);
newtype_idx!(FuncIdx);
newtype_idx!(TableIdx);
newtype_idx!(MemIdx);
newtype_idx!(GlobalIdx);
newtype_idx!(LocalIdx);
newtype_idx!(LabelIdx);
<|endoftext|>


<commit_before>use std::mem;

use futures::{Future, Poll};

enum State<R, T> {
    Pending {
        rd: R,
        buf: T,
    },
    Empty,
}

/// Tries to read some bytes directly into the given `buf` in asynchronous
/// manner, returning a future type.
///
/// The returned future will resolve to both the I/O stream as well as the
/// buffer once the read operation is completed.
pub fn read<R, T>(rd: R, buf: T) -> Read<R, T>
    where R: ::std::io::Read,
          T: AsMut<[u8]>
{
    Read { state: State::Pending { rd: rd, buf: buf } }
}

/// A future which can be used to easily read available number of bytes to fill
/// a buffer.
///
/// Created by the [`read`] function.
pub struct Read<R, T> {
    state: State<R, T>,
}

impl<R, T> Future for Read<R, T>
    where R: ::std::io::Read,
          T: AsMut<[u8]>
{
    type Item = (R, T, usize);
    type Error = ::std::io::Error;

    fn poll(&mut self) -> Poll<(R, T, usize), ::std::io::Error> {
        let nread = match self.state {
            State::Pending { ref mut rd, ref mut buf } => try_nb!(rd.read(&mut buf.as_mut()[..])),
            State::Empty => panic!("poll a ReadSome after it's done"),
        };

        match mem::replace(&mut self.state, State::Empty) {
            State::Pending { rd, buf } => Ok((rd, buf, nread).into()),
            State::Empty => panic!("invalid internal state"),
        }
    }
}
<commit_msg>chore: fix panic string<commit_after>use std::mem;

use futures::{Future, Poll};

enum State<R, T> {
    Pending {
        rd: R,
        buf: T,
    },
    Empty,
}

/// Tries to read some bytes directly into the given `buf` in asynchronous
/// manner, returning a future type.
///
/// The returned future will resolve to both the I/O stream as well as the
/// buffer once the read operation is completed.
pub fn read<R, T>(rd: R, buf: T) -> Read<R, T>
    where R: ::std::io::Read,
          T: AsMut<[u8]>
{
    Read { state: State::Pending { rd: rd, buf: buf } }
}

/// A future which can be used to easily read available number of bytes to fill
/// a buffer.
///
/// Created by the [`read`] function.
pub struct Read<R, T> {
    state: State<R, T>,
}

impl<R, T> Future for Read<R, T>
    where R: ::std::io::Read,
          T: AsMut<[u8]>
{
    type Item = (R, T, usize);
    type Error = ::std::io::Error;

    fn poll(&mut self) -> Poll<(R, T, usize), ::std::io::Error> {
        let nread = match self.state {
            State::Pending { ref mut rd, ref mut buf } => try_nb!(rd.read(&mut buf.as_mut()[..])),
            State::Empty => panic!("poll a Read after it's done"),
        };

        match mem::replace(&mut self.state, State::Empty) {
            State::Pending { rd, buf } => Ok((rd, buf, nread).into()),
            State::Empty => panic!("invalid internal state"),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015-2017 Intecture Developers.
//
// Licensed under the Mozilla Public License 2.0 <LICENSE or
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
// modified, or distributed except according to those terms.

use erased_serde::Serialize;
use errors::*;
use ExecutableProvider;
use host::*;
use pnet::datalink::interfaces;
use std::{env, process, str};
use target::{default, unix};
use telemetry::{Cpu, Os, Telemetry, TelemetryProvider, serializable};

pub struct Macos;

#[derive(Serialize, Deserialize)]
pub enum RemoteProvider {
    Available,
    Load,
}

impl <'de>ExecutableProvider<'de> for RemoteProvider {
    fn exec(&self, host: &Host) -> Result<Box<Serialize>> {
        match *self {
            RemoteProvider::Available => Ok(Box::new(Macos::available(host))),
            RemoteProvider::Load => {
                let t: serializable::Telemetry = Macos::load(host)?.into();
                Ok(Box::new(t))
            },
        }
    }
}

impl TelemetryProvider for Macos {
    fn available(host: &Host) -> bool {
        if host.is_local() {
            cfg!(macos)
        } else {
            unimplemented!();
            // let r = RemoteProvider::Available;
            // self.host.send(r).chain_err(|| ErrorKind::RemoteProvider("Telemetry", "available"))?;
            // let t: Telemetry = self.host.recv()?;
            // Ok(t)
        }
    }

    fn load(host: &Host) -> Result<Telemetry> {
        if host.is_local() {
            let cpu_vendor = try!(unix::get_sysctl_item("machdep\\.cpu\\.vendor"));
            let cpu_brand = try!(unix::get_sysctl_item("machdep\\.cpu\\.brand_string"));
            let hostname = try!(default::hostname());
            let (version_str, version_maj, version_min, version_patch) = try!(version());

            Ok(Telemetry {
                cpu: Cpu {
                    vendor: cpu_vendor,
                    brand_string: cpu_brand,
                    cores: unix::get_sysctl_item("hw\\.physicalcpu")
                                .chain_err(|| "could not resolve telemetry data")?
                                .parse::<u32>()
                                .chain_err(|| "could not resolve telemetry data")?
                },
                fs: try!(default::parse_fs(&[
                    default::FsFieldOrder::Filesystem,
                    default::FsFieldOrder::Size,
                    default::FsFieldOrder::Used,
                    default::FsFieldOrder::Available,
                    default::FsFieldOrder::Capacity,
                    default::FsFieldOrder::Blank,
                    default::FsFieldOrder::Blank,
                    default::FsFieldOrder::Blank,
                    default::FsFieldOrder::Mount,
                ])),
                hostname: hostname,
                memory: unix::get_sysctl_item("hw\\.memsize")
                             .chain_err(|| "could not resolve telemetry data")?
                             .parse::<u64>()
                             .chain_err(|| "could not resolve telemetry data")?,
                net: interfaces(),
                os: Os {
                    arch: env::consts::ARCH.into(),
                    family: "darwin".into(),
                    platform: "macos".into(),
                    version_str: version_str,
                    version_maj: version_maj,
                    version_min: version_min,
                    version_patch: version_patch
                },
            })
        } else {
            unimplemented!();
            // let r = RemoteProvider::Load;
            // self.host.send(r).chain_err(|| ErrorKind::RemoteProvider("Telemetry", "load"))?;
            // let t: Telemetry = self.host.recv()?;
            // Ok(t)
        }
    }
}

fn version() -> Result<(String, u32, u32, u32)> {
    let out = process::Command::new("sw_vers")
                               .arg("-productVersion")
                               .output()
                               .chain_err(|| ErrorKind::SystemCommand("sw_vers"))?;
    let version_str = str::from_utf8(&out.stdout)
                          .chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?
                          .trim()
                          .to_owned();
    let (maj, min, patch) = {
        let mut parts = version_str.split('.');
        let errstr = format!("Expected OS version format `u32.u32.u32`, got: '{}'", version_str);
        (
            parts.next().ok_or(&*errstr)?.parse().chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?,
            parts.next().ok_or(&*errstr)?.parse().chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?,
            parts.next().ok_or(&*errstr)?.parse().chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?
        )
    };
    Ok((version_str, maj, min, patch))
}
<commit_msg>Fix bugs in macOS provider<commit_after>// Copyright 2015-2017 Intecture Developers.
//
// Licensed under the Mozilla Public License 2.0 <LICENSE or
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
// modified, or distributed except according to those terms.

use erased_serde::Serialize;
use errors::*;
use ExecutableProvider;
use host::*;
use pnet::datalink::interfaces;
use std::{env, process, str};
use target::{default, unix};
use telemetry::{Cpu, Os, Telemetry, TelemetryProvider, serializable};

pub struct Macos;

#[derive(Serialize, Deserialize)]
pub enum RemoteProvider {
    Available,
    Load,
}

impl <'de>ExecutableProvider<'de> for RemoteProvider {
    fn exec(&self, host: &Host) -> Result<Box<Serialize>> {
        match *self {
            RemoteProvider::Available => Ok(Box::new(Macos::available(host))),
            RemoteProvider::Load => {
                let t: serializable::Telemetry = Macos::load(host)?.into();
                Ok(Box::new(t))
            },
        }
    }
}

impl TelemetryProvider for Macos {
    fn available(host: &Host) -> bool {
        if host.is_local() {
            cfg!(target_os="macos")
        } else {
            unimplemented!();
            // let r = RemoteProvider::Available;
            // self.host.send(r).chain_err(|| ErrorKind::RemoteProvider("Telemetry", "available"))?;
            // let t: Telemetry = self.host.recv()?;
            // Ok(t)
        }
    }

    fn load(host: &Host) -> Result<Telemetry> {
        if host.is_local() {
            let cpu_vendor = try!(unix::get_sysctl_item("machdep\\.cpu\\.vendor"));
            let cpu_brand = try!(unix::get_sysctl_item("machdep\\.cpu\\.brand_string"));
            let hostname = try!(default::hostname());
            let (version_str, version_maj, version_min, version_patch) = try!(version());

            Ok(Telemetry {
                cpu: Cpu {
                    vendor: cpu_vendor,
                    brand_string: cpu_brand,
                    cores: unix::get_sysctl_item("hw\\.physicalcpu")
                                .chain_err(|| "could not resolve telemetry data")?
                                .parse::<u32>()
                                .chain_err(|| "could not resolve telemetry data")?
                },
                fs: try!(default::parse_fs(&[
                    default::FsFieldOrder::Filesystem,
                    default::FsFieldOrder::Size,
                    default::FsFieldOrder::Used,
                    default::FsFieldOrder::Available,
                    default::FsFieldOrder::Capacity,
                    default::FsFieldOrder::Blank,
                    default::FsFieldOrder::Blank,
                    default::FsFieldOrder::Blank,
                    default::FsFieldOrder::Mount,
                ])),
                hostname: hostname,
                memory: unix::get_sysctl_item("hw\\.memsize")
                             .chain_err(|| "could not resolve telemetry data")?
                             .parse::<u64>()
                             .chain_err(|| "could not resolve telemetry data")?,
                net: interfaces(),
                os: Os {
                    arch: env::consts::ARCH.into(),
                    family: "darwin".into(),
                    platform: "macos".into(),
                    version_str: version_str,
                    version_maj: version_maj,
                    version_min: version_min,
                    version_patch: version_patch
                },
            })
        } else {
            unimplemented!();
            // let r = RemoteProvider::Load;
            // self.host.send(r).chain_err(|| ErrorKind::RemoteProvider("Telemetry", "load"))?;
            // let t: Telemetry = self.host.recv()?;
            // Ok(t)
        }
    }
}

fn version() -> Result<(String, u32, u32, u32)> {
    let out = process::Command::new("sw_vers")
                               .arg("-productVersion")
                               .output()
                               .chain_err(|| ErrorKind::SystemCommand("sw_vers"))?;
    let version_str = str::from_utf8(&out.stdout)
                          .chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?
                          .trim()
                          .to_owned();
    let (maj, min, patch) = {
        let mut parts = version_str.split('.');
        let errstr = format!("Expected OS version format `u32.u32[.u32]`, got: '{}'", version_str);
        (
            parts.next().ok_or(&*errstr)?.parse().chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?,
            parts.next().ok_or(&*errstr)?.parse().chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?,
            parts.next().unwrap_or("0").parse().chain_err(|| ErrorKind::SystemCommandOutput("sw_vers"))?
        )
    };
    Ok((version_str, maj, min, patch))
}
<|endoftext|>


<commit_before>use crate::{prelude::*, render::Image, utils::*};

/// Used to render an image.
pub struct ImageRenderObject;

impl Into<Box<dyn RenderObject>> for ImageRenderObject {
    fn into(self) -> Box<dyn RenderObject> {
        Box::new(self)
    }
}

impl RenderObject for ImageRenderObject {
    fn render_self(&self, ctx: &mut Context, global_position: &Point) {
        let (_, mut image) = {
            let widget = ctx.widget();
            (
                widget.clone::<Rectangle>("bounds"),
                widget.try_clone::<Image>("image"),
            )
        };

        if let Some(image) = &mut image {
            ctx.render_context_2_d()
                .draw_image(image, global_position.x, global_position.y);
        }
    }
}
<commit_msg>Fix image position.<commit_after>use crate::{prelude::*, render::Image, utils::*};

/// Used to render an image.
pub struct ImageRenderObject;

impl Into<Box<dyn RenderObject>> for ImageRenderObject {
    fn into(self) -> Box<dyn RenderObject> {
        Box::new(self)
    }
}

impl RenderObject for ImageRenderObject {
    fn render_self(&self, ctx: &mut Context, global_position: &Point) {
        let (bounds, mut image) = {
            let widget = ctx.widget();
            (
                widget.clone::<Rectangle>("bounds"),
                widget.try_clone::<Image>("image"),
            )
        };

        if let Some(image) = &mut image {
            ctx.render_context_2_d()
                .draw_image(image, bounds.x + global_position.x, bounds.y + global_position.y);
        }
    }
}
<|endoftext|>


<commit_before>use crate::simd::intrinsics;
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
use core::marker::PhantomData;

/// A mask where each lane is represented by a single bit.
#[repr(transparent)]
pub struct Mask<T, const LANES: usize>(
    <LaneCount<LANES> as SupportedLaneCount>::BitMask,
    PhantomData<T>,
)
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount;

impl<T, const LANES: usize> Copy for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
}

impl<T, const LANES: usize> Clone for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn clone(&self) -> Self {
        *self
    }
}

impl<T, const LANES: usize> PartialEq for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn eq(&self, other: &Self) -> bool {
        self.0.as_ref() == other.0.as_ref()
    }
}

impl<T, const LANES: usize> PartialOrd for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        self.0.as_ref().partial_cmp(other.0.as_ref())
    }
}

impl<T, const LANES: usize> Eq for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
}

impl<T, const LANES: usize> Ord for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        self.0.as_ref().cmp(other.0.as_ref())
    }
}

impl<T, const LANES: usize> Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    #[inline]
    pub fn splat(value: bool) -> Self {
        let mut mask = <LaneCount<LANES> as SupportedLaneCount>::BitMask::default();
        if value {
            mask.as_mut().fill(u8::MAX)
        } else {
            mask.as_mut().fill(u8::MIN)
        }
        if LANES % 8 > 0 {
            *mask.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - LANES % 8);
        }
        Self(mask, PhantomData)
    }

    #[inline]
    pub unsafe fn test_unchecked(&self, lane: usize) -> bool {
        (self.0.as_ref()[lane / 8] >> (lane % 8)) & 0x1 > 0
    }

    #[inline]
    pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
        self.0.as_mut()[lane / 8] ^= ((value ^ self.test_unchecked(lane)) as u8) << (lane % 8)
    }

    #[inline]
    pub fn to_int(self) -> Simd<T, LANES> {
        unsafe {
            let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
                core::mem::transmute_copy(&self);
            intrinsics::simd_select_bitmask(mask, Simd::splat(T::TRUE), Simd::splat(T::FALSE))
        }
    }

    #[inline]
    pub unsafe fn from_int_unchecked(value: Simd<T, LANES>) -> Self {
        // TODO remove the transmute when rustc is more flexible
        assert_eq!(
            core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::BitMask>(),
            core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::IntBitMask>(),
        );
        let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
            intrinsics::simd_bitmask(value);
        Self(core::mem::transmute_copy(&mask), PhantomData)
    }

    #[cfg(feature = "generic_const_exprs")]
    #[inline]
    pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
        // Safety: these are the same type and we are laundering the generic
        unsafe { core::mem::transmute_copy(&self.0) }
    }

    #[cfg(feature = "generic_const_exprs")]
    #[inline]
    pub fn from_bitmask(bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN]) -> Self {
        // Safety: these are the same type and we are laundering the generic
        Self(unsafe { core::mem::transmute_copy(&bitmask) }, PhantomData)
    }

    #[inline]
    pub fn convert<U>(self) -> Mask<U, LANES>
    where
        U: MaskElement,
    {
        unsafe { core::mem::transmute_copy(&self) }
    }

    #[inline]
    pub fn any(self) -> bool {
        self != Self::splat(false)
    }

    #[inline]
    pub fn all(self) -> bool {
        self == Self::splat(true)
    }
}

impl<T, const LANES: usize> core::ops::BitAnd for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
    <LaneCount<LANES> as SupportedLaneCount>::BitMask: AsRef<[u8]> + AsMut<[u8]>,
{
    type Output = Self;
    #[inline]
    fn bitand(mut self, rhs: Self) -> Self {
        for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) {
            *l &= r;
        }
        self
    }
}

impl<T, const LANES: usize> core::ops::BitOr for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
    <LaneCount<LANES> as SupportedLaneCount>::BitMask: AsRef<[u8]> + AsMut<[u8]>,
{
    type Output = Self;
    #[inline]
    fn bitor(mut self, rhs: Self) -> Self {
        for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) {
            *l |= r;
        }
        self
    }
}

impl<T, const LANES: usize> core::ops::BitXor for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    type Output = Self;
    #[inline]
    fn bitxor(mut self, rhs: Self) -> Self::Output {
        for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) {
            *l ^= r;
        }
        self
    }
}

impl<T, const LANES: usize> core::ops::Not for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    type Output = Self;
    #[inline]
    fn not(mut self) -> Self::Output {
        for x in self.0.as_mut() {
            *x = !*x;
        }
        if LANES % 8 > 0 {
            *self.0.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - LANES % 8);
        }
        self
    }
}
<commit_msg>Make sure MaskElement is in bitmasks.rs<commit_after>use super::MaskElement;
use crate::simd::intrinsics;
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
use core::marker::PhantomData;

/// A mask where each lane is represented by a single bit.
#[repr(transparent)]
pub struct Mask<T, const LANES: usize>(
    <LaneCount<LANES> as SupportedLaneCount>::BitMask,
    PhantomData<T>,
)
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount;

impl<T, const LANES: usize> Copy for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
}

impl<T, const LANES: usize> Clone for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn clone(&self) -> Self {
        *self
    }
}

impl<T, const LANES: usize> PartialEq for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn eq(&self, other: &Self) -> bool {
        self.0.as_ref() == other.0.as_ref()
    }
}

impl<T, const LANES: usize> PartialOrd for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        self.0.as_ref().partial_cmp(other.0.as_ref())
    }
}

impl<T, const LANES: usize> Eq for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
}

impl<T, const LANES: usize> Ord for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        self.0.as_ref().cmp(other.0.as_ref())
    }
}

impl<T, const LANES: usize> Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    #[inline]
    pub fn splat(value: bool) -> Self {
        let mut mask = <LaneCount<LANES> as SupportedLaneCount>::BitMask::default();
        if value {
            mask.as_mut().fill(u8::MAX)
        } else {
            mask.as_mut().fill(u8::MIN)
        }
        if LANES % 8 > 0 {
            *mask.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - LANES % 8);
        }
        Self(mask, PhantomData)
    }

    #[inline]
    pub unsafe fn test_unchecked(&self, lane: usize) -> bool {
        (self.0.as_ref()[lane / 8] >> (lane % 8)) & 0x1 > 0
    }

    #[inline]
    pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
        self.0.as_mut()[lane / 8] ^= ((value ^ self.test_unchecked(lane)) as u8) << (lane % 8)
    }

    #[inline]
    pub fn to_int(self) -> Simd<T, LANES> {
        unsafe {
            let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
                core::mem::transmute_copy(&self);
            intrinsics::simd_select_bitmask(mask, Simd::splat(T::TRUE), Simd::splat(T::FALSE))
        }
    }

    #[inline]
    pub unsafe fn from_int_unchecked(value: Simd<T, LANES>) -> Self {
        // TODO remove the transmute when rustc is more flexible
        assert_eq!(
            core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::BitMask>(),
            core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::IntBitMask>(),
        );
        let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
            intrinsics::simd_bitmask(value);
        Self(core::mem::transmute_copy(&mask), PhantomData)
    }

    #[cfg(feature = "generic_const_exprs")]
    #[inline]
    pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
        // Safety: these are the same type and we are laundering the generic
        unsafe { core::mem::transmute_copy(&self.0) }
    }

    #[cfg(feature = "generic_const_exprs")]
    #[inline]
    pub fn from_bitmask(bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN]) -> Self {
        // Safety: these are the same type and we are laundering the generic
        Self(unsafe { core::mem::transmute_copy(&bitmask) }, PhantomData)
    }

    #[inline]
    pub fn convert<U>(self) -> Mask<U, LANES>
    where
        U: MaskElement,
    {
        unsafe { core::mem::transmute_copy(&self) }
    }

    #[inline]
    pub fn any(self) -> bool {
        self != Self::splat(false)
    }

    #[inline]
    pub fn all(self) -> bool {
        self == Self::splat(true)
    }
}

impl<T, const LANES: usize> core::ops::BitAnd for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
    <LaneCount<LANES> as SupportedLaneCount>::BitMask: AsRef<[u8]> + AsMut<[u8]>,
{
    type Output = Self;
    #[inline]
    fn bitand(mut self, rhs: Self) -> Self {
        for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) {
            *l &= r;
        }
        self
    }
}

impl<T, const LANES: usize> core::ops::BitOr for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
    <LaneCount<LANES> as SupportedLaneCount>::BitMask: AsRef<[u8]> + AsMut<[u8]>,
{
    type Output = Self;
    #[inline]
    fn bitor(mut self, rhs: Self) -> Self {
        for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) {
            *l |= r;
        }
        self
    }
}

impl<T, const LANES: usize> core::ops::BitXor for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    type Output = Self;
    #[inline]
    fn bitxor(mut self, rhs: Self) -> Self::Output {
        for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) {
            *l ^= r;
        }
        self
    }
}

impl<T, const LANES: usize> core::ops::Not for Mask<T, LANES>
where
    T: MaskElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    type Output = Self;
    #[inline]
    fn not(mut self) -> Self::Output {
        for x in self.0.as_mut() {
            *x = !*x;
        }
        if LANES % 8 > 0 {
            *self.0.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - LANES % 8);
        }
        self
    }
}
<|endoftext|>