<commit_before>#![allow(
    clippy::diverging_sub_expression,
    clippy::let_and_return,
    clippy::let_underscore_drop,
    clippy::never_loop,
    clippy::unit_arg
)]

use anyhow::{anyhow, ensure, Chain, Error, Result};
use std::fmt::Debug;
use std::iter;
use std::marker::PhantomData;
use std::ops::Add;

struct S;

impl<T> Add<T> for S {
    type Output = bool;
    fn add(self, rhs: T) -> Self::Output {
        let _ = rhs;
        false
    }
}

trait Trait: Sized {
    fn t(self, i: i32) -> i32 {
        i
    }
}

impl<T> Trait for T {}

#[track_caller]
fn assert_err<T: Debug>(result: impl FnOnce() -> Result<T>, expected: &'static str) {
    let actual = result().unwrap_err().to_string();

    let mut accepted_alternatives = expected.split('\n');
    let expected = accepted_alternatives.next_back().unwrap();
    if accepted_alternatives.any(|alternative| actual == alternative) {
        return;
    }

    assert_eq!(actual, expected);
}

#[test]
fn test_recursion() {
    // Must not blow the default #[recursion_limit], which is 128.
    #[rustfmt::skip]
    let test = || Ok(ensure!(
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false
    ));

    test().unwrap_err();
}

#[test]
fn test_low_precedence_control_flow() {
    #[allow(unreachable_code)]
    let test = || {
        let val = loop {
            // Break has lower precedence than the comparison operators so the
            // expression here is `S + (break (1 == 1))`. It would be bad if the
            // ensure macro partitioned this input into `(S + break 1) == (1)`
            // because that means a different thing than what was written.
            ensure!(S + break 1 == 1);
        };
        Ok(val)
    };

    assert!(test().unwrap());
}

#[test]
fn test_low_precedence_binary_operator() {
    // Must not partition as `false == (true && false)`.
    let test = || Ok(ensure!(false == true && false));
    assert_err(test, "Condition failed: `false == true && false`");

    // But outside the root level, it is fine.
    let test = || Ok(ensure!(while false == true && false {} < ()));
    assert_err(
        test,
        "Condition failed: `while false == true && false { } < ()` (() vs ())",
    );
}

#[test]
fn test_closure() {
    // Must not partition as `(S + move) || (1 == 1)` by treating move as an
    // identifier, nor as `(S + move || 1) == (1)` by misinterpreting the
    // closure precedence.
    let test = || Ok(ensure!(S + move || 1 == 1));
    assert_err(test, "Condition failed: `S + (move || 1 == 1)`");

    let test = || Ok(ensure!(S + || 1 == 1));
    assert_err(test, "Condition failed: `S + (|| 1 == 1)`");

    // Must not partition as `S + ((move | ()) | 1) == 1` by treating those
    // pipes as bitwise-or.
    let test = || Ok(ensure!(S + move |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (move |()| 1 == 1)`");

    let test = || Ok(ensure!(S + |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (|()| 1 == 1)`");
}

#[test]
fn test_unary() {
    let mut x = &1;
    let test = || Ok(ensure!(*x == 2));
    assert_err(test, "Condition failed: `*x == 2` (1 vs 2)");

    let test = || Ok(ensure!(!x == 1));
    assert_err(test, "Condition failed: `!x == 1` (-2 vs 1)");

    let test = || Ok(ensure!(-x == 1));
    assert_err(test, "Condition failed: `-x == 1` (-1 vs 1)");

    let test = || Ok(ensure!(&x == &&2));
    assert_err(test, "Condition failed: `&x == &&2` (1 vs 2)");

    let test = || Ok(ensure!(&mut x == *&&mut &2));
    assert_err(test, "Condition failed: `&mut x == *&&mut &2` (1 vs 2)");
}

#[test]
fn test_if() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {}.t(1) == 2));
    assert_err(test, "Condition failed: `if false { }.t(1) == 2` (1 vs 2)");

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else if false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else if false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let | 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_loop() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + loop { break 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + loop  { break 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + loop { break 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + 'a: loop { break 'a 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + 'a: loop  { break 'a 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + 'a: loop { break 'a 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while let None = Some(1) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while let None = Some(1) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for | _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for true | false in iter::empty() {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for true | false in iter::empty() { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_match() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(match 1 == 1 { true => 1, false => 0 } == 2));
    assert_err(
        test,
        "Condition failed: `match 1 == 1 { true => 1, false => 0, } == 2` (1 vs 2)",
    );
}

#[test]
fn test_atom() {
    let test = || Ok(ensure!([false, false].len() > 3));
    assert_err(
        test,
        "Condition failed: `[false, false].len() > 3` (2 vs 3)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!({ let x = 1; x } >= 3));
    assert_err(test, "Condition failed: `{ let x = 1; x } >= 3` (1 vs 3)");

    let test = || Ok(ensure!(S + async { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + async move { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async move  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + unsafe { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + unsafe { 1 } == true` (false vs true)",
    );
}

#[test]
fn test_path() {
    let test = || Ok(ensure!(crate::S.t(1) == 2));
    assert_err(test, "Condition failed: `crate::S.t(1) == 2` (1 vs 2)");

    let test = || Ok(ensure!(::anyhow::Error::root_cause.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `::anyhow::Error::root_cause.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<&str>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Error::msg::<&str,>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<<str as ToOwned>::Owned>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<<str as ToOwned>::Owned>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Chain::<'static>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Chain::<'static,>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_macro() {
    let test = || Ok(ensure!(anyhow!("...").to_string().len() <= 1));
    assert_err(
        test,
        "Condition failed: `anyhow!(\"...\").to_string().len() <= 1` (3 vs 1)",
    );

    let test = || Ok(ensure!(vec![1].len() < 1));
    assert_err(test, "Condition failed: `vec![1].len() < 1` (1 vs 1)");

    let test = || Ok(ensure!(stringify! {} != ""));
    assert_err(
        test,
        "Condition failed: `stringify! { } != \"\"` (\"\" vs \"\")",
    );
}

#[test]
fn test_trailer() {
    let test = || Ok(ensure!((|| 1)() == 2));
    assert_err(test, "Condition failed: `(|| 1)() == 2` (1 vs 2)");

    let test = || Ok(ensure!(b"hmm"[1] == b'c'));
    assert_err(test, "Condition failed: `b\"hmm\"[1] == b'c'` (109 vs 99)");

    let test = || Ok(ensure!(PhantomData::<u8> {} != PhantomData));
    assert_err(
        test,
        "Condition failed: `PhantomData::<u8>{} != PhantomData` (PhantomData vs PhantomData)",
    );

    let result = Ok::<_, Error>(1);
    let test = || Ok(ensure!(result? == 2));
    assert_err(test, "Condition failed: `result? == 2` (1 vs 2)");

    let test = || Ok(ensure!((2, 3).1 == 2));
    assert_err(test, "Condition failed: `(2, 3).1 == 2` (3 vs 2)");

    let err = anyhow!("");
    let test = || Ok(ensure!(err.is::<&str>() == false));
    assert_err(
        test,
        "Condition failed: `err.is::<&str>() == false` (true vs false)",
    );

    let test = || Ok(ensure!(err.is::<<str as ToOwned>::Owned>() == true));
    assert_err(
        test,
        "Condition failed: `err.is::<<str as ToOwned>::Owned>() == true` (false vs true)",
    );
}

#[test]
fn test_whitespace() {
    #[derive(Debug)]
    pub struct Point {
        pub x: i32,
        pub y: i32,
    }

    let point = Point { x: 0, y: 0 };
    let test = || Ok(ensure!("" == format!("{:#?}", point)));
    assert_err(test, "Condition failed: `\"\" == format!(\"{:#?}\", point)`");
}

#[test]
fn test_too_long() {
    let test = || Ok(ensure!("" == "x".repeat(10)));
    assert_err(
        test,
        "Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")",
    );

    let test = || Ok(ensure!("" == "x".repeat(80)));
    assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`");
}
<commit_msg>Format with rustfmt 1.4.38<commit_after>#![allow(
    clippy::diverging_sub_expression,
    clippy::let_and_return,
    clippy::let_underscore_drop,
    clippy::never_loop,
    clippy::unit_arg
)]

use anyhow::{anyhow, ensure, Chain, Error, Result};
use std::fmt::Debug;
use std::iter;
use std::marker::PhantomData;
use std::ops::Add;

struct S;

impl<T> Add<T> for S {
    type Output = bool;
    fn add(self, rhs: T) -> Self::Output {
        let _ = rhs;
        false
    }
}

trait Trait: Sized {
    fn t(self, i: i32) -> i32 {
        i
    }
}

impl<T> Trait for T {}

#[track_caller]
fn assert_err<T: Debug>(result: impl FnOnce() -> Result<T>, expected: &'static str) {
    let actual = result().unwrap_err().to_string();

    let mut accepted_alternatives = expected.split('\n');
    let expected = accepted_alternatives.next_back().unwrap();
    if accepted_alternatives.any(|alternative| actual == alternative) {
        return;
    }

    assert_eq!(actual, expected);
}

#[test]
fn test_recursion() {
    // Must not blow the default #[recursion_limit], which is 128.
    #[rustfmt::skip]
    let test = || Ok(ensure!(
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false
    ));

    test().unwrap_err();
}

#[test]
fn test_low_precedence_control_flow() {
    #[allow(unreachable_code)]
    let test = || {
        let val = loop {
            // Break has lower precedence than the comparison operators so the
            // expression here is `S + (break (1 == 1))`. It would be bad if the
            // ensure macro partitioned this input into `(S + break 1) == (1)`
            // because that means a different thing than what was written.
            ensure!(S + break 1 == 1);
        };
        Ok(val)
    };

    assert!(test().unwrap());
}

#[test]
fn test_low_precedence_binary_operator() {
    // Must not partition as `false == (true && false)`.
    let test = || Ok(ensure!(false == true && false));
    assert_err(test, "Condition failed: `false == true && false`");

    // But outside the root level, it is fine.
    let test = || Ok(ensure!(while false == true && false {} < ()));
    assert_err(
        test,
        "Condition failed: `while false == true && false { } < ()` (() vs ())",
    );
}

#[test]
fn test_closure() {
    // Must not partition as `(S + move) || (1 == 1)` by treating move as an
    // identifier, nor as `(S + move || 1) == (1)` by misinterpreting the
    // closure precedence.
    let test = || Ok(ensure!(S + move || 1 == 1));
    assert_err(test, "Condition failed: `S + (move || 1 == 1)`");

    let test = || Ok(ensure!(S + || 1 == 1));
    assert_err(test, "Condition failed: `S + (|| 1 == 1)`");

    // Must not partition as `S + ((move | ()) | 1) == 1` by treating those
    // pipes as bitwise-or.
    let test = || Ok(ensure!(S + move |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (move |()| 1 == 1)`");

    let test = || Ok(ensure!(S + |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (|()| 1 == 1)`");
}

#[test]
fn test_unary() {
    let mut x = &1;
    let test = || Ok(ensure!(*x == 2));
    assert_err(test, "Condition failed: `*x == 2` (1 vs 2)");

    let test = || Ok(ensure!(!x == 1));
    assert_err(test, "Condition failed: `!x == 1` (-2 vs 1)");

    let test = || Ok(ensure!(-x == 1));
    assert_err(test, "Condition failed: `-x == 1` (-1 vs 1)");

    let test = || Ok(ensure!(&x == &&2));
    assert_err(test, "Condition failed: `&x == &&2` (1 vs 2)");

    let test = || Ok(ensure!(&mut x == *&&mut &2));
    assert_err(test, "Condition failed: `&mut x == *&&mut &2` (1 vs 2)");
}

#[test]
fn test_if() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {}.t(1) == 2));
    assert_err(test, "Condition failed: `if false { }.t(1) == 2` (1 vs 2)");

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else if false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else if false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let | 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_loop() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + loop { break 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + loop  { break 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + loop { break 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + 'a: loop { break 'a 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + 'a: loop  { break 'a 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + 'a: loop { break 'a 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while let None = Some(1) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while let None = Some(1) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for | _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for true | false in iter::empty() {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for true | false in iter::empty() { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_match() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(match 1 == 1 { true => 1, false => 0 } == 2));
    assert_err(
        test,
        "Condition failed: `match 1 == 1 { true => 1, false => 0, } == 2` (1 vs 2)",
    );
}

#[test]
fn test_atom() {
    let test = || Ok(ensure!([false, false].len() > 3));
    assert_err(
        test,
        "Condition failed: `[false, false].len() > 3` (2 vs 3)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!({ let x = 1; x } >= 3));
    assert_err(test, "Condition failed: `{ let x = 1; x } >= 3` (1 vs 3)");

    let test = || Ok(ensure!(S + async { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + async move { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async move  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + unsafe { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + unsafe { 1 } == true` (false vs true)",
    );
}

#[test]
fn test_path() {
    let test = || Ok(ensure!(crate::S.t(1) == 2));
    assert_err(test, "Condition failed: `crate::S.t(1) == 2` (1 vs 2)");

    let test = || Ok(ensure!(::anyhow::Error::root_cause.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `::anyhow::Error::root_cause.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<&str>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Error::msg::<&str,>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<<str as ToOwned>::Owned>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<<str as ToOwned>::Owned>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Chain::<'static>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Chain::<'static,>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_macro() {
    let test = || Ok(ensure!(anyhow!("...").to_string().len() <= 1));
    assert_err(
        test,
        "Condition failed: `anyhow!(\"...\").to_string().len() <= 1` (3 vs 1)",
    );

    let test = || Ok(ensure!(vec![1].len() < 1));
    assert_err(test, "Condition failed: `vec![1].len() < 1` (1 vs 1)");

    let test = || Ok(ensure!(stringify! {} != ""));
    assert_err(
        test,
        "Condition failed: `stringify! { } != \"\"` (\"\" vs \"\")",
    );
}

#[test]
fn test_trailer() {
    let test = || Ok(ensure!((|| 1)() == 2));
    assert_err(test, "Condition failed: `(|| 1)() == 2` (1 vs 2)");

    let test = || Ok(ensure!(b"hmm"[1] == b'c'));
    assert_err(test, "Condition failed: `b\"hmm\"[1] == b'c'` (109 vs 99)");

    let test = || Ok(ensure!(PhantomData::<u8> {} != PhantomData));
    assert_err(
        test,
        "Condition failed: `PhantomData::<u8>{} != PhantomData` (PhantomData vs PhantomData)",
    );

    let result = Ok::<_, Error>(1);
    let test = || Ok(ensure!(result? == 2));
    assert_err(test, "Condition failed: `result? == 2` (1 vs 2)");

    let test = || Ok(ensure!((2, 3).1 == 2));
    assert_err(test, "Condition failed: `(2, 3).1 == 2` (3 vs 2)");

    let err = anyhow!("");
    let test = || Ok(ensure!(err.is::<&str>() == false));
    assert_err(
        test,
        "Condition failed: `err.is::<&str>() == false` (true vs false)",
    );

    let test = || Ok(ensure!(err.is::<<str as ToOwned>::Owned>() == true));
    assert_err(
        test,
        "Condition failed: `err.is::<<str as ToOwned>::Owned>() == true` (false vs true)",
    );
}

#[test]
fn test_whitespace() {
    #[derive(Debug)]
    pub struct Point {
        pub x: i32,
        pub y: i32,
    }

    let point = Point { x: 0, y: 0 };
    let test = || Ok(ensure!("" == format!("{:#?}", point)));
    assert_err(
        test,
        "Condition failed: `\"\" == format!(\"{:#?}\", point)`",
    );
}

#[test]
fn test_too_long() {
    let test = || Ok(ensure!("" == "x".repeat(10)));
    assert_err(
        test,
        "Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")",
    );

    let test = || Ok(ensure!("" == "x".repeat(80)));
    assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`");
}
<|endoftext|>


<commit_before>extern crate parity_wasm;

use std::env;
use parity_wasm::elements::Section;

fn main() {
    let args = env::args().collect::<Vec<_>>();
    if args.len() != 2 {
        println!("Usage: {} somefile.wasm", args[0]);
        return;
    }

    let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module");

    println!("Module sections: {}", module.sections().len());

    for section in module.sections() {
        match section {
            &Section::Import(ref import_section) => {
                println!("  Imports: {}", import_section.entries().len());
            },
            &Section::Export(ref exports_section) => {
                println!("  Exports: {}", exports_section.entries().len());
            },
            &Section::Function(ref function_section) => {
                println!("  Functions: {}", function_section.entries().len());
            },
            &Section::Global(ref globals_section) => {
                println!("  Globals: {}", globals_section.entries().len());
            },
            &Section::Data(ref data_section) if data_section.entries().len() > 0 => {
                let data = &data_section.entries()[0];
                println!("  Data size: {}", data.value().len());
            },
            _ => {},
        }
    }
}<commit_msg>type section added in info example<commit_after>extern crate parity_wasm;

use std::env;
use parity_wasm::elements::Section;

fn main() {
    let args = env::args().collect::<Vec<_>>();
    if args.len() != 2 {
        println!("Usage: {} somefile.wasm", args[0]);
        return;
    }

    let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module");

    println!("Module sections: {}", module.sections().len());

    for section in module.sections() {
        match section {
            &Section::Import(ref import_section) => {
                println!("  Imports: {}", import_section.entries().len());
            },
            &Section::Export(ref exports_section) => {
                println!("  Exports: {}", exports_section.entries().len());
            },
            &Section::Function(ref function_section) => {
                println!("  Functions: {}", function_section.entries().len());
            },
            &Section::Type(ref type_section) => {
                println!("  Types: {}", type_section.types().len());
            },
            &Section::Global(ref globals_section) => {
                println!("  Globals: {}", globals_section.entries().len());
            },
            &Section::Data(ref data_section) if data_section.entries().len() > 0 => {
                let data = &data_section.entries()[0];
                println!("  Data size: {}", data.value().len());
            },
            _ => {},
        }
    }
}<|endoftext|>


<commit_before>extern crate hound;

use std::env;

fn main() {
    let fname = env::args().nth(1).expect("no file given");
    let mut reader = hound::WavReader::open(&fname).unwrap();
    let samples: Vec<i16> = reader.samples().map(|s| s.unwrap()).collect();

    let (ts, tu, n) = samples.iter().fold((0.0, 0.0, 0.0), |(ts, tu, n), &s| {
        let signed = s as f64;
        let unsigned = (s as u16) as f64;
        (ts + signed, tu + unsigned, n + 1.0)
    });
    let ms = ts / n;
    let mu = tu / n;
    println!("mean signed:   {} (should be 0, deviation is {})", ms, ms.abs());
    println!("mean unsigned: {} (should be 2^16 - 1, deviation is {})", mu, (mu - 32767.0).abs());

    let (ts, tu) = samples.iter().fold((0.0, 0.0), |(ts, tu), &s| {
        let ds = s as f64 - ms;
        let du = (s as u16) as f64 - mu;
        (ts + ds * ds, tu + du * du)
    });
    let rmss = (ts / n).sqrt();
    let rmsu = (tu / n).sqrt();
    println!("rms signed:    {}", rmss);
    println!("rms unsigned:  {}", rmsu);
}
<commit_msg>document that the mean example is just a dirty test for now<commit_after>// Hound -- A WAV encoding and decoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// This example computes the mean value and rms of a file, where samples are
// first interpreted as 16-bit signed integer, and then as a 16-bit unsigned
// integer. This should allow us to determine whether the samples stored are
// signed or unsigned: for signed the average value is expected to be 0, and
// for unsigned the value is expected to be 2^16 - 1.
//   Note that this example is not a particularly good example of proper coding
// style; it does not handle failure properly, and it assumes that the provided
// file has 16 bits per sample.

// TODO: This example should probably be removed, it is just here for verifying
// and assumption at this point.

extern crate hound;

use std::env;

fn main() {
    let fname = env::args().nth(1).expect("no file given");
    let mut reader = hound::WavReader::open(&fname).unwrap();
    let samples: Vec<i16> = reader.samples().map(|s| s.unwrap()).collect();

    let (ts, tu, n) = samples.iter().fold((0.0, 0.0, 0.0), |(ts, tu, n), &s| {
        let signed = s as f64;
        let unsigned = (s as u16) as f64;
        (ts + signed, tu + unsigned, n + 1.0)
    });
    let ms = ts / n;
    let mu = tu / n;
    println!("mean signed:   {} (should be 0, deviation is {})", ms, ms.abs());
    println!("mean unsigned: {} (should be 2^16 - 1, deviation is {})", mu, (mu - 32767.0).abs());

    let (ts, tu) = samples.iter().fold((0.0, 0.0), |(ts, tu), &s| {
        let ds = s as f64 - ms;
        let du = (s as u16) as f64 - mu;
        (ts + ds * ds, tu + du * du)
    });
    let rmss = (ts / n).sqrt();
    let rmsu = (tu / n).sqrt();
    println!("rms signed:    {}", rmss);
    println!("rms unsigned:  {}", rmsu);
}
<|endoftext|>


<commit_before>use rust_embed::RustEmbed;
use warp::{http::header::HeaderValue, path::Tail, reply::Response, Filter, Rejection, Reply};

#[derive(RustEmbed)]
#[folder = "examples/public/"]
struct Asset;

#[tokio::main]
async fn main() {
  let index_html = warp::path::end().and_then(serve_index);
  let dist = warp::path!("dist").and(warp::path::tail()).and_then(serve);

  let routes = index_html.or(dist);
  warp::serve(routes).run(([127, 0, 0, 1], 8080)).await;
}

async fn serve_index() -> Result<impl Reply, Rejection> {
  serve_impl("index.html")
}

async fn serve(path: Tail) -> Result<impl Reply, Rejection> {
  serve_impl(path.as_str())
}

fn serve_impl(path: &str) -> Result<impl Reply, Rejection> {
  let asset = Asset::get(path).ok_or_else(warp::reject::not_found)?;
  let mime = mime_guess::from_path(path).first_or_octet_stream();

  let mut res = Response::new(asset.into());
  res.headers_mut().insert("content-type", HeaderValue::from_str(mime.as_ref()).unwrap());
  Ok(res)
}
<commit_msg>Fix warp example<commit_after>use rust_embed::RustEmbed;
use warp::{http::header::HeaderValue, path::Tail, reply::Response, Filter, Rejection, Reply};

#[derive(RustEmbed)]
#[folder = "examples/public/"]
struct Asset;

#[tokio::main]
async fn main() {
  let index_html = warp::path::end().and_then(serve_index);
  let dist = warp::path("dist").and(warp::path::tail()).and_then(serve);

  let routes = index_html.or(dist);
  warp::serve(routes).run(([127, 0, 0, 1], 8080)).await;
}

async fn serve_index() -> Result<impl Reply, Rejection> {
  serve_impl("index.html")
}

async fn serve(path: Tail) -> Result<impl Reply, Rejection> {
  serve_impl(path.as_str())
}

fn serve_impl(path: &str) -> Result<impl Reply, Rejection> {
  let asset = Asset::get(path).ok_or_else(warp::reject::not_found)?;
  let mime = mime_guess::from_path(path).first_or_octet_stream();

  let mut res = Response::new(asset.into());
  res.headers_mut().insert("content-type", HeaderValue::from_str(mime.as_ref()).unwrap());
  Ok(res)
}
<|endoftext|>


<commit_before>use zerocopy::{FromBytes, Unaligned, BE, I16, I32, I64, U16, U32};

pub type Int8 = i8;
pub type Uint8 = u8;
pub type Int16 = I16<BE>;
pub type Uint16 = U16<BE>;
pub type Uint24 = [u8; 3];
pub type Int32 = I32<BE>;
pub type Uint32 = U32<BE>;

pub type Fixed = Int32;
pub type F2dot14 = Int16;
pub type LongDateTime = I64<BE>;

pub type Offset16 = Uint16;
pub type Offset24 = Uint24;
pub type Offset32 = Uint32;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Unaligned, FromBytes)]
#[repr(C)]
pub struct Tag([u8; 4]);
pub type Version16Dot16 = Uint32;
<commit_msg>fixup raw<commit_after>use zerocopy::{FromBytes, Unaligned, BE, I16, I32, I64, U16, U32};

pub type Int8 = i8;
pub type Uint8 = u8;
pub type Int16 = I16<BE>;
pub type Uint16 = U16<BE>;
pub type Uint24 = [u8; 3];
pub type Int32 = I32<BE>;
pub type Uint32 = U32<BE>;

pub type Fixed = Int32;
pub type F2Dot14 = Int16;
pub type LongDateTime = I64<BE>;

pub type Offset16 = Uint16;
pub type Offset24 = Uint24;
pub type Offset32 = Uint32;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Unaligned, FromBytes)]
#[repr(C)]
pub struct Tag([u8; 4]);
pub type Version16Dot16 = Uint32;
<|endoftext|>


<commit_before>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;
use std::io::BufRead;

use task_hookrs::import::{import_task, import_tasks};

use libimagrt::runtime::Runtime;
use libimagtodo::task::IntoTask;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {

    let name = "imag-todo";
    let version = &version!()[..];
    let about = "Interface with taskwarrior";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));

    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.unwrap_err());
            exit(1);
        }
    };

    let scmd = rt.cli().subcommand_name();
    match scmd {
        Some("tw-hook") => {
            let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
            if subcmd.is_present("add") {
                let stdin = stdin();
                let mut stdin = stdin.lock();
                let mut line = String::new();
                match stdin.read_line(&mut line) {
                    Ok(_) => { }
                    Err(e) => {
                        error!("{}", e);
                        return;
                    }
                };
                if let Ok(ttask) = import_task(&line.as_str()) {
                    let uuid = *ttask.uuid();
                    println!("{}", match serde_json::ser::to_string(&ttask) {
                        Ok(val) => val,
                        Err(e) => {
                            error!("{}", e);
                            return;
                        }
                    });
                    match ttask.into_filelockentry(rt.store()) {
                        Ok(val) => {
                            println!("Task {} stored in imag", uuid);
                            val
                        },
                        Err(e) => {
                            trace_error(&e);
                            error!("{}", e);
                            return;
                        }
                    };
                }
                else {
                    error!("No usable input");
                    return;
                }
            }
            else if subcmd.is_present("delete") {
                // The used hook is "on-modify". This hook gives two json-objects
                // per usage und wants one (the second one) back.
                let mut counter = 0;
                let stdin = stdin();
                let stdin = stdin.lock();
                if let Ok(ttasks) = import_tasks(stdin) {
                    for ttask in ttasks {
                        if counter % 2 == 1 {
                            // Only every second task is needed, the first one is the
                            // task before the change, and the second one after
                            // the change. The (maybe modified) second one is
                            // expected by taskwarrior.
                            println!("{}", match serde_json::ser::to_string(&ttask) {
                                Ok(val) => val,
                                Err(e) => {
                                    error!("{}", e);
                                    return;
                                }
                            });
                            match ttask.status() {
                                &task_hookrs::status::TaskStatus::Deleted => {
                                    match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) {
                                        Ok(_) => {
                                            println!("Deleted task {}", *ttask.uuid());
                                        }
                                        Err(e) => {
                                            trace_error(&e);
                                            error!("{}", e);
                                            return;
                                        }
                                    }
                                }
                                _ => {
                                }
                            } // end match ttask.status()
                        } // end if c % 2
                        counter += 1;
                    } // end for
                } // end if let
                else {
                    error!("No usable input");
                }
            }
            else {
                // Should not be possible, as one argument is required via
                // ArgGroup
                unreachable!();
            }
        },
        Some("exec") => {
            let subcmd = rt.cli().subcommand_matches("exec").unwrap();
            let mut args = Vec::new();
            if let Some(exec_string) = subcmd.values_of("command") {
                for e in exec_string {
                    args.push(e);
                }
                let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| {
                    panic!("failed to execute taskwarrior: {}", e);
                });

                let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                    panic!("failed to unwrap output: {}", e);
                });
                let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                    panic!("failed to ececute: {}", e);
                });
                println!("{}", outstring);
            } else {
                panic!("faild to execute: You need to exec --command");
            }
        }
        Some("list") => {
            let subcmd = rt.cli().subcommand_matches("list").unwrap();
            let mut args = Vec::new();
            let verbose = subcmd.is_present("verbose");
            let iter = match libimagtodo::read::get_todo_iterator(rt.store()) {
                //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") {
                Err(e) => {
                    error!("{}", e);
                    return;
                }
                Ok(val) => val,
            };
            for task in iter {
                match task {
                    Ok(val) => {
                        //let val = libimagtodo::task::Task::new(fle);
                        //println!("{:#?}", val.flentry);
                        let uuid = match val.flentry.get_header().read("todo.uuid") {
                            Ok(Some(u)) => u,
                            Ok(None) => continue,
                            Err(e) => {
                                error!("{}", e);
                                continue;
                            }
                        };
                        if verbose {
                            args.clear();
                            args.push(format!("uuid:{}", uuid));
                            args.push(format!("{}", "information"));
                            let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn()
                                .unwrap_or_else(|e| {
                                    error!("{}", e);
                                    panic!("failed");
                                });
                            let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                                panic!("failed to unwrap output: {}", e);
                            });
                            let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                                panic!("failed to ececute: {}", e);
                            });
                            println!("{}", outstring);
                        }
                        else {
                            println!("{}", match uuid {
                                toml::Value::String(s) => s,
                                _ => {
                                    error!("Unexpected type for todo.uuid: {}", uuid);
                                    continue;
                                },
                            });
                        }
                    }
                    Err(e) => {
                        error!("{}", e);
                        continue;
                    }
                } // end match task
            } // end for
        }
        _ => unimplemented!(),
    } // end match scmd
} // end main

<commit_msg>Remove unnecessary whitespace<commit_after>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;
use std::io::BufRead;

use task_hookrs::import::{import_task, import_tasks};

use libimagrt::runtime::Runtime;
use libimagtodo::task::IntoTask;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {
    let name = "imag-todo";
    let version = &version!()[..];
    let about = "Interface with taskwarrior";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));

    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.unwrap_err());
            exit(1);
        }
    };

    let scmd = rt.cli().subcommand_name();
    match scmd {
        Some("tw-hook") => {
            let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
            if subcmd.is_present("add") {
                let stdin = stdin();
                let mut stdin = stdin.lock();
                let mut line = String::new();
                match stdin.read_line(&mut line) {
                    Ok(_) => { }
                    Err(e) => {
                        error!("{}", e);
                        return;
                    }
                };
                if let Ok(ttask) = import_task(&line.as_str()) {
                    let uuid = *ttask.uuid();
                    println!("{}", match serde_json::ser::to_string(&ttask) {
                        Ok(val) => val,
                        Err(e) => {
                            error!("{}", e);
                            return;
                        }
                    });
                    match ttask.into_filelockentry(rt.store()) {
                        Ok(val) => {
                            println!("Task {} stored in imag", uuid);
                            val
                        },
                        Err(e) => {
                            trace_error(&e);
                            error!("{}", e);
                            return;
                        }
                    };
                }
                else {
                    error!("No usable input");
                    return;
                }
            }
            else if subcmd.is_present("delete") {
                // The used hook is "on-modify". This hook gives two json-objects
                // per usage und wants one (the second one) back.
                let mut counter = 0;
                let stdin = stdin();
                let stdin = stdin.lock();
                if let Ok(ttasks) = import_tasks(stdin) {
                    for ttask in ttasks {
                        if counter % 2 == 1 {
                            // Only every second task is needed, the first one is the
                            // task before the change, and the second one after
                            // the change. The (maybe modified) second one is
                            // expected by taskwarrior.
                            println!("{}", match serde_json::ser::to_string(&ttask) {
                                Ok(val) => val,
                                Err(e) => {
                                    error!("{}", e);
                                    return;
                                }
                            });
                            match ttask.status() {
                                &task_hookrs::status::TaskStatus::Deleted => {
                                    match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) {
                                        Ok(_) => {
                                            println!("Deleted task {}", *ttask.uuid());
                                        }
                                        Err(e) => {
                                            trace_error(&e);
                                            error!("{}", e);
                                            return;
                                        }
                                    }
                                }
                                _ => {
                                }
                            } // end match ttask.status()
                        } // end if c % 2
                        counter += 1;
                    } // end for
                } // end if let
                else {
                    error!("No usable input");
                }
            }
            else {
                // Should not be possible, as one argument is required via
                // ArgGroup
                unreachable!();
            }
        },
        Some("exec") => {
            let subcmd = rt.cli().subcommand_matches("exec").unwrap();
            let mut args = Vec::new();
            if let Some(exec_string) = subcmd.values_of("command") {
                for e in exec_string {
                    args.push(e);
                }
                let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| {
                    panic!("failed to execute taskwarrior: {}", e);
                });

                let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                    panic!("failed to unwrap output: {}", e);
                });
                let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                    panic!("failed to ececute: {}", e);
                });
                println!("{}", outstring);
            } else {
                panic!("faild to execute: You need to exec --command");
            }
        }
        Some("list") => {
            let subcmd = rt.cli().subcommand_matches("list").unwrap();
            let mut args = Vec::new();
            let verbose = subcmd.is_present("verbose");
            let iter = match libimagtodo::read::get_todo_iterator(rt.store()) {
                //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") {
                Err(e) => {
                    error!("{}", e);
                    return;
                }
                Ok(val) => val,
            };
            for task in iter {
                match task {
                    Ok(val) => {
                        //let val = libimagtodo::task::Task::new(fle);
                        //println!("{:#?}", val.flentry);
                        let uuid = match val.flentry.get_header().read("todo.uuid") {
                            Ok(Some(u)) => u,
                            Ok(None) => continue,
                            Err(e) => {
                                error!("{}", e);
                                continue;
                            }
                        };
                        if verbose {
                            args.clear();
                            args.push(format!("uuid:{}", uuid));
                            args.push(format!("{}", "information"));
                            let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn()
                                .unwrap_or_else(|e| {
                                    error!("{}", e);
                                    panic!("failed");
                                });
                            let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                                panic!("failed to unwrap output: {}", e);
                            });
                            let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                                panic!("failed to ececute: {}", e);
                            });
                            println!("{}", outstring);
                        }
                        else {
                            println!("{}", match uuid {
                                toml::Value::String(s) => s,
                                _ => {
                                    error!("Unexpected type for todo.uuid: {}", uuid);
                                    continue;
                                },
                            });
                        }
                    }
                    Err(e) => {
                        error!("{}", e);
                        continue;
                    }
                } // end match task
            } // end for
        }
        _ => unimplemented!(),
    } // end match scmd
} // end main

<|endoftext|>


<commit_before>extern crate ransid;

use alloc::boxed::Box;

use collections::String;

use common::debug::SerialConsole;
use common::event::{self, Event, EventOption};

use core::mem;

use graphics::color::Color;
use graphics::display::Display;

use sync::WaitQueue;

pub struct Console {
    pub display: Option<Box<Display>>,
    pub inner: Option<ransid::Console>,
    pub draw: bool,
    pub command: String,
    pub commands: WaitQueue<String>
}

impl Console {
    pub fn new() -> Console {
        let display_option = Display::root();
        let inner_option = if let Some(ref display) = display_option {
            Some(ransid::Console::new(display.width/8, display.height/16))
        } else {
            None
        };
        Console {
            display: display_option,
            inner: inner_option,
            draw: false,
            command: String::new(),
            commands: WaitQueue::new()
        }
    }

    pub fn event(&mut self, event: Event) {
        match event.to_option() {
            EventOption::Key(key_event) => {
                if key_event.pressed {
                    let raw_mode = if let Some(ref inner) = self.inner {
                        inner.raw_mode
                    } else {
                        false
                    };

                    if raw_mode {
                        match key_event.scancode {
                            event::K_BKSP => self.command.push_str("\x7F"),
                            event::K_UP => self.command.push_str("\x1B[A"),
                            event::K_DOWN => self.command.push_str("\x1B[B"),
                            event::K_RIGHT => self.command.push_str("\x1B[C"),
                            event::K_LEFT => self.command.push_str("\x1B[D"),
                            event::K_HOME => self.command.push_str("\x1B[H"),
                            event::K_END => self.command.push_str("\x1B[F"),
                            event::K_DEL => self.command.push_str("\x1B[3~"),
                            event::K_PGUP => self.command.push_str("\x1B[5~"),
                            event::K_PGDN => self.command.push_str("\x1B[6~"),
                            _ => match key_event.character {
                                '\0' => {},
                                c => {
                                    self.command.push(c);
                                }
                            },
                        }

                        if ! self.command.is_empty() {
                            let mut command = String::new();
                            mem::swap(&mut self.command, &mut command);
                            self.commands.send(command, "Console::event command (raw)");
                        }
                    } else {
                        match key_event.scancode {
                            event::K_BKSP => if ! self.command.is_empty() {
                                if let Some(ref mut inner) = self.inner {
                                    inner.redraw = true;
                                }

                                self.write(&[8]);
                                self.command.pop();
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                c => {
                                    if let Some(ref mut inner) = self.inner {
                                        inner.redraw = true;
                                    }

                                    self.write(&[c as u8]);
                                    self.command.push(c);

                                    if c == '\n' {
                                        let mut command = String::new();
                                        mem::swap(&mut self.command, &mut command);
                                        self.commands.send(command, "Console::event command (not raw)");
                                    }
                                }
                            },
                        }
                    }
                }
            }
            _ => (),
        }
    }

    pub fn write(&mut self, bytes: &[u8]) {
        if self.draw && self.inner.is_some() {
            if let Some(ref mut inner) = self.inner {
                inner.write(bytes);
                if inner.redraw {
                    inner.redraw = false;
                    if let Some(ref mut display) = self.display {
                        let mut min = inner.h;
                        let mut max = 0;

                        for y in 0..inner.h {
                            if inner.changed[y] {
                                inner.changed[y] = false;

                                if y < min {
                                    min = y;
                                }
                                if y > max {
                                    max = y;
                                }

                                for x in 0..inner.w {
                                    let block = inner.display[y * inner.w + x];
                                    let (bg, fg) = if inner.cursor && inner.y == y && inner.x == x {
                                        (block.fg.data, block.bg.data)
                                    }else{
                                        (block.bg.data, block.fg.data)
                                    };
                                    display.rect(x * 8, y * 16, 8, 16, Color {
                                        data: bg
                                    });
                                    if block.c != ' ' {
                                        display.char(x * 8, y * 16, block.c, Color {
                                            data: fg
                                        });
                                    }
                                    if block.underlined {
                                        display.rect(x * 8, y * 16 + 14, 8, 1, Color {
                                            data: fg
                                        });
                                    }
                                }
                            }
                        }

                        if min <= max {
                            //display.flip_rows(min * 16, (max + 1 - min) * 16);
                            display.flip();
                        }
                    }
                }
            }
        } else {
            SerialConsole::new().write(bytes);
        }
    }
}
<commit_msg>Back to partial redraw<commit_after>extern crate ransid;

use alloc::boxed::Box;

use collections::String;

use common::debug::SerialConsole;
use common::event::{self, Event, EventOption};

use core::mem;

use graphics::color::Color;
use graphics::display::Display;

use sync::WaitQueue;

pub struct Console {
    pub display: Option<Box<Display>>,
    pub inner: Option<ransid::Console>,
    pub draw: bool,
    pub command: String,
    pub commands: WaitQueue<String>
}

impl Console {
    pub fn new() -> Console {
        let display_option = Display::root();
        let inner_option = if let Some(ref display) = display_option {
            Some(ransid::Console::new(display.width/8, display.height/16))
        } else {
            None
        };
        Console {
            display: display_option,
            inner: inner_option,
            draw: false,
            command: String::new(),
            commands: WaitQueue::new()
        }
    }

    pub fn event(&mut self, event: Event) {
        match event.to_option() {
            EventOption::Key(key_event) => {
                if key_event.pressed {
                    let raw_mode = if let Some(ref inner) = self.inner {
                        inner.raw_mode
                    } else {
                        false
                    };

                    if raw_mode {
                        match key_event.scancode {
                            event::K_BKSP => self.command.push_str("\x7F"),
                            event::K_UP => self.command.push_str("\x1B[A"),
                            event::K_DOWN => self.command.push_str("\x1B[B"),
                            event::K_RIGHT => self.command.push_str("\x1B[C"),
                            event::K_LEFT => self.command.push_str("\x1B[D"),
                            event::K_HOME => self.command.push_str("\x1B[H"),
                            event::K_END => self.command.push_str("\x1B[F"),
                            event::K_DEL => self.command.push_str("\x1B[3~"),
                            event::K_PGUP => self.command.push_str("\x1B[5~"),
                            event::K_PGDN => self.command.push_str("\x1B[6~"),
                            _ => match key_event.character {
                                '\0' => {},
                                c => {
                                    self.command.push(c);
                                }
                            },
                        }

                        if ! self.command.is_empty() {
                            let mut command = String::new();
                            mem::swap(&mut self.command, &mut command);
                            self.commands.send(command, "Console::event command (raw)");
                        }
                    } else {
                        match key_event.scancode {
                            event::K_BKSP => if ! self.command.is_empty() {
                                if let Some(ref mut inner) = self.inner {
                                    inner.redraw = true;
                                }

                                self.write(&[8]);
                                self.command.pop();
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                c => {
                                    if let Some(ref mut inner) = self.inner {
                                        inner.redraw = true;
                                    }

                                    self.write(&[c as u8]);
                                    self.command.push(c);

                                    if c == '\n' {
                                        let mut command = String::new();
                                        mem::swap(&mut self.command, &mut command);
                                        self.commands.send(command, "Console::event command (not raw)");
                                    }
                                }
                            },
                        }
                    }
                }
            }
            _ => (),
        }
    }

    pub fn write(&mut self, bytes: &[u8]) {
        if self.draw && self.inner.is_some() {
            if let Some(ref mut inner) = self.inner {
                inner.write(bytes);
                if inner.redraw {
                    inner.redraw = false;
                    if let Some(ref mut display) = self.display {
                        let mut min = inner.h;
                        let mut max = 0;

                        for y in 0..inner.h {
                            if inner.changed[y] {
                                inner.changed[y] = false;

                                if y < min {
                                    min = y;
                                }
                                if y > max {
                                    max = y;
                                }

                                for x in 0..inner.w {
                                    let block = inner.display[y * inner.w + x];
                                    let (bg, fg) = if inner.cursor && inner.y == y && inner.x == x {
                                        (block.fg.data, block.bg.data)
                                    }else{
                                        (block.bg.data, block.fg.data)
                                    };
                                    display.rect(x * 8, y * 16, 8, 16, Color {
                                        data: bg
                                    });
                                    if block.c != ' ' {
                                        display.char(x * 8, y * 16, block.c, Color {
                                            data: fg
                                        });
                                    }
                                    if block.underlined {
                                        display.rect(x * 8, y * 16 + 14, 8, 1, Color {
                                            data: fg
                                        });
                                    }
                                }
                            }
                        }

                        if min <= max {
                            display.flip_rows(min * 16, (max + 1 - min) * 16);
                        }
                    }
                }
            }
        } else {
            SerialConsole::new().write(bytes);
        }
    }
}
<|endoftext|>


<commit_before>use std::slice::Iter;
use std::vec::Vec;

use analysis::imports::Imports;
use analysis::ref_mode::RefMode;
use config;
use env::Env;
use library::*;
use super::conversion_type::ConversionType;
use super::rust_type::parameter_rust_type;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mode {
    None,
    Normal,
    Optional,
    Combined,
    //<use function return>
    Throws(bool),
}

impl Default for Mode {
    fn default() -> Mode {
        Mode::None
    }
}

#[derive(Debug, Default)]
pub struct Info {
    pub mode: Mode,
    pub params: Vec<Parameter>,
}

impl Info {
    pub fn is_empty(&self) -> bool {
        self.mode == Mode::None
    }

    pub fn iter(&self) -> Iter<Parameter> {
        self.params.iter()
    }

    pub fn len(&self) -> usize {
        self.params.len()
    }
}

pub fn analyze(env: &Env, func: &Function,
               configured_functions: &[&config::functions::Function]) -> (Info, bool) {
    let mut info: Info = Default::default();
    let mut unsupported_outs = false;

    let nullable_override = configured_functions.iter()
        .filter_map(|f| f.ret.nullable)
        .next();
    if func.throws {
        let use_ret = use_function_return_for_result(env, &func.ret);
        info.mode = Mode::Throws(use_ret);
    } else if func.ret.typ == TypeId::tid_none() {
        info.mode = Mode::Normal;
    } else if func.ret.typ == TypeId::tid_bool() {
        if nullable_override == Some(Nullable(false)) {
            info.mode = Mode::Combined;
        } else {
            info.mode = Mode::Optional;
        }
    } else {
        info.mode = Mode::Combined;
    }

    for par in &func.parameters {
        if par.direction != ParameterDirection::Out { continue; }
        if can_as_return(env, par) {
            info.params.push(par.clone());
        } else {
            unsupported_outs = true;
        }
    }

    if info.params.is_empty() {
        info.mode = Mode::None;
    }
    if info.mode == Mode::Combined || info.mode == Mode::Throws(true) {
        let mut ret = func.ret.clone();
        //TODO: switch to use analyzed returns (it add too many Return<Option<>>)
        if let Some(val) = nullable_override {
            ret.nullable = val;
        }
        info.params.insert(0, ret);
    }

    (info, unsupported_outs)
}

pub fn analyze_imports(env: &Env, func: &Function, imports: &mut Imports) {
    for par in &func.parameters {
        if par.direction == ParameterDirection::Out && !par.caller_allocates {
            match *env.library.type_(par.typ) {
                Type::Fundamental(..) |
                    Type::Bitfield(..) |
                    Type::Enumeration(..) => imports.add("std::mem", func.version),
                _ => imports.add("std::ptr".into(), func.version),
            }
        }
    }
}

fn can_as_return(env: &Env, par: &Parameter) -> bool {
    use super::conversion_type::ConversionType::*;
    match ConversionType::of(&env.library, par.typ) {
        Direct => true,
        Scalar => true,
        Pointer => parameter_rust_type(env, par.typ, ParameterDirection::Out, Nullable(false),
                                       RefMode::None).is_ok(),
        Borrow => false,
        Unknown => false,
    }
}

fn use_function_return_for_result(env: &Env, ret: &Parameter) -> bool {
    if ret.typ == Default::default() { return false; }
    if ret.typ.ns_id != INTERNAL_NAMESPACE { return true; }
    let type_ = env.type_(ret.typ);
    match &*type_.get_name() {
        "UInt" => false,
        "Boolean" => false,
        _ => true,
    }
}
<commit_msg>Add std::mem import always for Fundamental/Bitfield/Enum out parameters<commit_after>use std::slice::Iter;
use std::vec::Vec;

use analysis::imports::Imports;
use analysis::ref_mode::RefMode;
use config;
use env::Env;
use library::*;
use super::conversion_type::ConversionType;
use super::rust_type::parameter_rust_type;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mode {
    None,
    Normal,
    Optional,
    Combined,
    //<use function return>
    Throws(bool),
}

impl Default for Mode {
    fn default() -> Mode {
        Mode::None
    }
}

#[derive(Debug, Default)]
pub struct Info {
    pub mode: Mode,
    pub params: Vec<Parameter>,
}

impl Info {
    pub fn is_empty(&self) -> bool {
        self.mode == Mode::None
    }

    pub fn iter(&self) -> Iter<Parameter> {
        self.params.iter()
    }

    pub fn len(&self) -> usize {
        self.params.len()
    }
}

pub fn analyze(env: &Env, func: &Function,
               configured_functions: &[&config::functions::Function]) -> (Info, bool) {
    let mut info: Info = Default::default();
    let mut unsupported_outs = false;

    let nullable_override = configured_functions.iter()
        .filter_map(|f| f.ret.nullable)
        .next();
    if func.throws {
        let use_ret = use_function_return_for_result(env, &func.ret);
        info.mode = Mode::Throws(use_ret);
    } else if func.ret.typ == TypeId::tid_none() {
        info.mode = Mode::Normal;
    } else if func.ret.typ == TypeId::tid_bool() {
        if nullable_override == Some(Nullable(false)) {
            info.mode = Mode::Combined;
        } else {
            info.mode = Mode::Optional;
        }
    } else {
        info.mode = Mode::Combined;
    }

    for par in &func.parameters {
        if par.direction != ParameterDirection::Out { continue; }
        if can_as_return(env, par) {
            info.params.push(par.clone());
        } else {
            unsupported_outs = true;
        }
    }

    if info.params.is_empty() {
        info.mode = Mode::None;
    }
    if info.mode == Mode::Combined || info.mode == Mode::Throws(true) {
        let mut ret = func.ret.clone();
        //TODO: switch to use analyzed returns (it add too many Return<Option<>>)
        if let Some(val) = nullable_override {
            ret.nullable = val;
        }
        info.params.insert(0, ret);
    }

    (info, unsupported_outs)
}

pub fn analyze_imports(env: &Env, func: &Function, imports: &mut Imports) {
    for par in &func.parameters {
        if par.direction == ParameterDirection::Out {
            match *env.library.type_(par.typ) {
                Type::Fundamental(..) |
                    Type::Bitfield(..) |
                    Type::Enumeration(..) => imports.add("std::mem", func.version),
                _ if !par.caller_allocates => imports.add("std::ptr".into(), func.version),
                _ => (),
            }
        }
    }
}

fn can_as_return(env: &Env, par: &Parameter) -> bool {
    use super::conversion_type::ConversionType::*;
    match ConversionType::of(&env.library, par.typ) {
        Direct => true,
        Scalar => true,
        Pointer => parameter_rust_type(env, par.typ, ParameterDirection::Out, Nullable(false),
                                       RefMode::None).is_ok(),
        Borrow => false,
        Unknown => false,
    }
}

fn use_function_return_for_result(env: &Env, ret: &Parameter) -> bool {
    if ret.typ == Default::default() { return false; }
    if ret.typ.ns_id != INTERNAL_NAMESPACE { return true; }
    let type_ = env.type_(ret.typ);
    match &*type_.get_name() {
        "UInt" => false,
        "Boolean" => false,
        _ => true,
    }
}
<|endoftext|>