<commit_before>use {Discard, Logger};

// Separate module to test lack of imports
mod no_imports {
    use {Discard, Logger};
    /// ensure o! macro expands without error inside a module
    #[test]
    fn test_o_macro_expansion() {
        let _ = Logger::root(Discard, o!("a" => "aa"));
    }
    /// ensure o! macro expands without error inside a module
    #[test]
    fn test_slog_o_macro_expansion() {
        let _ = Logger::root(Discard, slog_o!("a" => "aa"));
    }
}

#[cfg(feature = "std")]
mod std_only {
    use super::super::*;
    use std;

    #[test]
    fn logger_fmt_debug_sanity() {
        let root = Logger::root(Discard, o!("a" => "aa"));
        let log = root.new(o!("b" => "bb", "c" => "cc"));

        assert_eq!(format!("{:?}", log), "Logger(c, b, a)");
    }

    #[test]
    fn multichain() {
        #[derive(Clone)]
        struct CheckOwned;

        impl Drain for CheckOwned {
            type Ok = ();
            type Err = Never;
            fn log(
                &self,
                record: &Record,
                values: &OwnedKVList,
            ) -> std::result::Result<Self::Ok, Self::Err> {
                assert_eq!(
                    format!("{}", record.msg()),
                    format!("{:?}", values)
                );
                Ok(())
            }
        }

        let root = Logger::root(CheckOwned, o!("a" => "aa"));
        let log = root.new(o!("b1" => "bb", "b2" => "bb"));

        info!(log, "(b2, b1, a)");

        let log = Logger::root(log, o!("c" => "cc"));
        info!(log, "(c, b2, b1, a)");
        let log = Logger::root(log, o!("d1" => "dd", "d2" => "dd"));
        info!(log, "(d2, d1, c, b2, b1, a)");
    }
}

#[test]
fn expressions() {
    use super::{Record, Result, Serializer, KV};

    struct Foo;

    impl Foo {
        fn bar(&self) -> u32 {
            1
        }
    }

    struct X {
        foo: Foo,
    }

    let log = Logger::root(Discard, o!("version" => env!("CARGO_PKG_VERSION")));

    let foo = Foo;
    let r = X { foo: foo };

    warn!(log, "logging message");
    slog_warn!(log, "logging message");

    info!(log, #"with tag", "logging message");
    slog_info!(log, #"with tag", "logging message");

    warn!(log, "logging message"; "a" => "b");
    slog_warn!(log, "logging message"; "a" => "b");

    warn!(log, "logging message bar={}", r.foo.bar());
    slog_warn!(log, "logging message bar={}", r.foo.bar());

    warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar()
    );
    slog_warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar()
    );

    // trailing comma check
    warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar(),
    );
    slog_warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar(),
    );

    warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1);
    slog_warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1);

    // trailing comma check
    warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1,);
    slog_warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1,);

    warn!(log,
          "logging message bar={}", r.foo.bar(); "x" => 1, "y" => r.foo.bar());
    slog_warn!(log,
               "logging message bar={}", r.foo.bar();
               "x" => 1, "y" => r.foo.bar());

    warn!(log, "logging message bar={}", r.foo.bar(); "x" => r.foo.bar());
    slog_warn!(log, "logging message bar={}", r.foo.bar(); "x" => r.foo.bar());

    warn!(log, "logging message bar={}", r.foo.bar();
          "x" => r.foo.bar(), "y" => r.foo.bar());
    slog_warn!(log,
               "logging message bar={}", r.foo.bar();
               "x" => r.foo.bar(), "y" => r.foo.bar());

    // trailing comma check
    warn!(log,
          "logging message bar={}", r.foo.bar();
          "x" => r.foo.bar(), "y" => r.foo.bar(),);
    slog_warn!(log,
               "logging message bar={}", r.foo.bar();
               "x" => r.foo.bar(), "y" => r.foo.bar(),);

    {
        #[derive(Clone)]
        struct K;

        impl KV for K {
            fn serialize(
                &self,
                _record: &Record,
                _serializer: &mut Serializer,
            ) -> Result {
                Ok(())
            }
        }

        let x = K;

        let _log = log.new(o!(x.clone()));
        let _log = log.new(o!("foo" => "bar", x.clone()));
        let _log = log.new(o!("foo" => "bar", x.clone(), x.clone()));
        let _log = log.new(
            slog_o!("foo" => "bar", x.clone(), x.clone(), "aaa" => "bbb"),
        );

        info!(log, "message"; "foo" => "bar", &x, &x, "aaa" => "bbb");
    }

    info!(
        log,
        "message {}",
          { 3 + 3; 2};
          "foo" => "bar",
          "foo" => { 3 + 3; 2},
          "aaa" => "bbb");
}

#[cfg(integer128)]
#[test]
fn integer_128_types() {
    let log = Logger::root(Discard, o!("version" => env!("CARGO_PKG_VERSION")));

    info!(log, "i128 = {}", 42i128; "foo" => 7i128);
    info!(log, "u128 = {}", 42u128; "foo" => 7u128);
}

#[test]
fn expressions_fmt() {
    let log = Logger::root(Discard, o!("version" => env!("CARGO_PKG_VERSION")));

    let f = "f";
    let d = (1, 2);

    info!(log, "message"; "f" => %f, "d" => ?d);
}

#[test]
fn makers() {
    use ::*;
    let drain = Duplicate(
        Discard.filter(|r| r.level().is_at_least(Level::Info)),
        Discard.filter_level(Level::Warning),
    ).map(Fuse);
    let _log = Logger::root(
        Arc::new(drain),
        o!("version" => env!("CARGO_PKG_VERSION")),
    );
}

#[test]
fn simple_logger_erased() {
    use ::*;

    fn takes_arced_drain(_l: Logger) {}

    let drain = Discard.filter_level(Level::Warning).map(Fuse);
    let log =
        Logger::root_typed(drain, o!("version" => env!("CARGO_PKG_VERSION")));

    takes_arced_drain(log.to_erased());
}

#[test]
fn logger_to_erased() {
    use ::*;

    fn takes_arced_drain(_l: Logger) {}

    let drain = Duplicate(
        Discard.filter(|r| r.level().is_at_least(Level::Info)),
        Discard.filter_level(Level::Warning),
    ).map(Fuse);
    let log =
        Logger::root_typed(drain, o!("version" => env!("CARGO_PKG_VERSION")));

    takes_arced_drain(log.into_erased());
}

#[test]
fn logger_by_ref() {
    use ::*;
    let drain = Discard.filter_level(Level::Warning).map(Fuse);
    let log = Logger::root_typed(drain, o!("version" => env!("CARGO_PKG_VERSION")));
    let f = "f";
    let d = (1, 2);
    info!(&log, "message"; "f" => %f, "d" => ?d);
}

<commit_msg>Add test for Clone derive on Never<commit_after>use {Discard, Logger};
use Never;

// Separate module to test lack of imports
mod no_imports {
    use {Discard, Logger};
    /// ensure o! macro expands without error inside a module
    #[test]
    fn test_o_macro_expansion() {
        let _ = Logger::root(Discard, o!("a" => "aa"));
    }
    /// ensure o! macro expands without error inside a module
    #[test]
    fn test_slog_o_macro_expansion() {
        let _ = Logger::root(Discard, slog_o!("a" => "aa"));
    }
}

#[cfg(feature = "std")]
mod std_only {
    use super::super::*;
    use std;

    #[test]
    fn logger_fmt_debug_sanity() {
        let root = Logger::root(Discard, o!("a" => "aa"));
        let log = root.new(o!("b" => "bb", "c" => "cc"));

        assert_eq!(format!("{:?}", log), "Logger(c, b, a)");
    }

    #[test]
    fn multichain() {
        #[derive(Clone)]
        struct CheckOwned;

        impl Drain for CheckOwned {
            type Ok = ();
            type Err = Never;
            fn log(
                &self,
                record: &Record,
                values: &OwnedKVList,
            ) -> std::result::Result<Self::Ok, Self::Err> {
                assert_eq!(
                    format!("{}", record.msg()),
                    format!("{:?}", values)
                );
                Ok(())
            }
        }

        let root = Logger::root(CheckOwned, o!("a" => "aa"));
        let log = root.new(o!("b1" => "bb", "b2" => "bb"));

        info!(log, "(b2, b1, a)");

        let log = Logger::root(log, o!("c" => "cc"));
        info!(log, "(c, b2, b1, a)");
        let log = Logger::root(log, o!("d1" => "dd", "d2" => "dd"));
        info!(log, "(d2, d1, c, b2, b1, a)");
    }
}

#[test]
fn expressions() {
    use super::{Record, Result, Serializer, KV};

    struct Foo;

    impl Foo {
        fn bar(&self) -> u32 {
            1
        }
    }

    struct X {
        foo: Foo,
    }

    let log = Logger::root(Discard, o!("version" => env!("CARGO_PKG_VERSION")));

    let foo = Foo;
    let r = X { foo: foo };

    warn!(log, "logging message");
    slog_warn!(log, "logging message");

    info!(log, #"with tag", "logging message");
    slog_info!(log, #"with tag", "logging message");

    warn!(log, "logging message"; "a" => "b");
    slog_warn!(log, "logging message"; "a" => "b");

    warn!(log, "logging message bar={}", r.foo.bar());
    slog_warn!(log, "logging message bar={}", r.foo.bar());

    warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar()
    );
    slog_warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar()
    );

    // trailing comma check
    warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar(),
    );
    slog_warn!(
        log,
        "logging message bar={} foo={}",
        r.foo.bar(),
        r.foo.bar(),
    );

    warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1);
    slog_warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1);

    // trailing comma check
    warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1,);
    slog_warn!(log, "logging message bar={}", r.foo.bar(); "x" => 1,);

    warn!(log,
          "logging message bar={}", r.foo.bar(); "x" => 1, "y" => r.foo.bar());
    slog_warn!(log,
               "logging message bar={}", r.foo.bar();
               "x" => 1, "y" => r.foo.bar());

    warn!(log, "logging message bar={}", r.foo.bar(); "x" => r.foo.bar());
    slog_warn!(log, "logging message bar={}", r.foo.bar(); "x" => r.foo.bar());

    warn!(log, "logging message bar={}", r.foo.bar();
          "x" => r.foo.bar(), "y" => r.foo.bar());
    slog_warn!(log,
               "logging message bar={}", r.foo.bar();
               "x" => r.foo.bar(), "y" => r.foo.bar());

    // trailing comma check
    warn!(log,
          "logging message bar={}", r.foo.bar();
          "x" => r.foo.bar(), "y" => r.foo.bar(),);
    slog_warn!(log,
               "logging message bar={}", r.foo.bar();
               "x" => r.foo.bar(), "y" => r.foo.bar(),);

    {
        #[derive(Clone)]
        struct K;

        impl KV for K {
            fn serialize(
                &self,
                _record: &Record,
                _serializer: &mut Serializer,
            ) -> Result {
                Ok(())
            }
        }

        let x = K;

        let _log = log.new(o!(x.clone()));
        let _log = log.new(o!("foo" => "bar", x.clone()));
        let _log = log.new(o!("foo" => "bar", x.clone(), x.clone()));
        let _log = log.new(
            slog_o!("foo" => "bar", x.clone(), x.clone(), "aaa" => "bbb"),
        );

        info!(log, "message"; "foo" => "bar", &x, &x, "aaa" => "bbb");
    }

    info!(
        log,
        "message {}",
          { 3 + 3; 2};
          "foo" => "bar",
          "foo" => { 3 + 3; 2},
          "aaa" => "bbb");
}

#[cfg(integer128)]
#[test]
fn integer_128_types() {
    let log = Logger::root(Discard, o!("version" => env!("CARGO_PKG_VERSION")));

    info!(log, "i128 = {}", 42i128; "foo" => 7i128);
    info!(log, "u128 = {}", 42u128; "foo" => 7u128);
}

#[test]
fn expressions_fmt() {
    let log = Logger::root(Discard, o!("version" => env!("CARGO_PKG_VERSION")));

    let f = "f";
    let d = (1, 2);

    info!(log, "message"; "f" => %f, "d" => ?d);
}

#[test]
fn makers() {
    use ::*;
    let drain = Duplicate(
        Discard.filter(|r| r.level().is_at_least(Level::Info)),
        Discard.filter_level(Level::Warning),
    ).map(Fuse);
    let _log = Logger::root(
        Arc::new(drain),
        o!("version" => env!("CARGO_PKG_VERSION")),
    );
}

#[test]
fn simple_logger_erased() {
    use ::*;

    fn takes_arced_drain(_l: Logger) {}

    let drain = Discard.filter_level(Level::Warning).map(Fuse);
    let log =
        Logger::root_typed(drain, o!("version" => env!("CARGO_PKG_VERSION")));

    takes_arced_drain(log.to_erased());
}

#[test]
fn logger_to_erased() {
    use ::*;

    fn takes_arced_drain(_l: Logger) {}

    let drain = Duplicate(
        Discard.filter(|r| r.level().is_at_least(Level::Info)),
        Discard.filter_level(Level::Warning),
    ).map(Fuse);
    let log =
        Logger::root_typed(drain, o!("version" => env!("CARGO_PKG_VERSION")));

    takes_arced_drain(log.into_erased());
}

#[test]
fn logger_by_ref() {
    use ::*;
    let drain = Discard.filter_level(Level::Warning).map(Fuse);
    let log = Logger::root_typed(drain, o!("version" => env!("CARGO_PKG_VERSION")));
    let f = "f";
    let d = (1, 2);
    info!(&log, "message"; "f" => %f, "d" => ?d);
}

#[test]
fn test_never_type_clone() {
    // We just want to make sure that this compiles
    fn _do_not_run() {
        let x: Never = panic!("Can't actually construct a Never type here!");
        let y = x.clone();
    }
    // Always pass if we compiled
}
<|endoftext|>


<commit_before>use variables::*;
use variables::LpExpression::*;
use std::rc::Rc;
use operations::LpOperations;
use problem::LpFileFormat;

#[test]
fn expressions_creation() {
    let ref a = LpInteger::new("a")
        .lower_bound(10.0)
        .upper_bound(20.0);
    let ref b = LpInteger::new("b");

    assert_eq!(a + b, AddExpr(Rc::new(ConsInt(a.clone())), Rc::new(ConsInt(b.clone()))));
}

#[test]
fn distributivity() {

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    let test = a * (2 + b) * 3;
    let test2 = test.clone();
    assert_eq!( (2 * (2 + a)).to_lp_file_format(), "2 a + 4");
    assert_eq!( ((2+a) * (2+b)).to_lp_file_format(), "2 a + 2 b + b a + 4" );
    assert_eq!( test.to_lp_file_format(), "6 a + 3 a b" );
    assert_eq!( (10 * test).to_lp_file_format(), "60 a + 30 a b" );
    assert_eq!( ((c + 10) * test2).to_lp_file_format(), "6 c a + 3 c a b + 60 a + 30 a b" );

}

#[test]
fn associativity() {

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!( (a + (b + 2)).to_lp_file_format(), "a + b + 2" );
    assert_eq!( ((a + b) + 2).to_lp_file_format(), "a + b + 2" );

    assert_eq!( (a + (b - 2)).to_lp_file_format(), "a + b - 2" );
    assert_eq!( ((a + b) - 2).to_lp_file_format(), "a + b - 2" );

    assert_eq!( (a - (b + 2)).to_lp_file_format(), "a - b - 2" );
    assert_eq!( ((a - b) + 2).to_lp_file_format(), "a - b + 2" );

    assert_eq!( (a - (b - 2)).to_lp_file_format(), "a - b + 2" );
    assert_eq!( ((a - b) - 2).to_lp_file_format(), "a - b - 2" );

    assert_eq!( (a - (b - 2) + c).to_lp_file_format(), "a - b + c + 2" );
    assert_eq!( ((a - b) - 2 + c).to_lp_file_format(), "a - b + c - 2" );
}

#[test]
fn literal_first_with_accumulation() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!( (a + 1 + b + 2 + c + 3 + a + 4).to_lp_file_format(), "a + b + c + a + 10");
    assert_eq!( (a - 1 + b - 2 - c + 3 + a - 4).to_lp_file_format(), "a + b - c + a - 4");
    assert_eq!( (a + b + 1 - c - a - 3).to_lp_file_format(), "a + b - c - a - 2");
    assert_eq!( (a + b + (c - 1) * 2 - a - 3).to_lp_file_format(), "a + b + 2 c - a - 5");
    assert_eq!( (a + b + (1 - c) * 2 - a - 3).to_lp_file_format(), "a + b - 2 c - a - 1");
    assert_eq!( (2*(a + 5)).to_lp_file_format(), "2 a + 10");
    assert_eq!( ((2+b)*(a + 5)).to_lp_file_format(), "2 a + a b + 5 b + 10");
    assert_eq!( (2 + (a+b) + 3).to_lp_file_format(), "a + b + 5");

}

#[test]
fn trivial_rules() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");

    assert_eq!( ((a+b) * 0).to_lp_file_format(), "0");
    assert_eq!( ( 0 * (a+b)).to_lp_file_format(), "0");
    assert_eq!( ((a+b) + 0).to_lp_file_format(), "a + b");
    assert_eq!( (0 + (a+b) + 0).to_lp_file_format(), "a + b");
    assert_eq!( (0 + (a+b)).to_lp_file_format(), "a + b");
    assert_eq!( ((a+b) - 0).to_lp_file_format(), "a + b");
    assert_eq!( (0 - (a+b)).to_lp_file_format(), "-a - b");
    assert_eq!( (0 + (a+b)).to_lp_file_format(), "a + b");

}

#[test]
fn expressions_to_lp_file_format() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    // Expressions
    assert_eq!((a + 2*b + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + 3 * 2 * c).to_lp_file_format(), "a + 2 b + 6 c");
    assert_eq!((a + 2).to_lp_file_format(), "a + 2");
    assert_eq!((2*a + 2*b -4*c).to_lp_file_format(), "2 a + 2 b - 4 c");
    assert_eq!((-2*a).to_lp_file_format(), "-2 a");

    // Constraints
    assert_eq!((a+b).equal(10).to_lp_file_format(), "a + b = 10");
    assert_eq!((2*a + b).ge(10).to_lp_file_format(), "2 a + b >= 10");
    assert_eq!((2*a + b + 20).ge(c).to_lp_file_format(), "2 a + b - c >= -20");
    assert_eq!((-a).ge(10).to_lp_file_format(), "-a >= 10");
    assert_eq!((2*a - 20 + b).ge(-c).to_lp_file_format(), "2 a + b + c >= 20");
}

#[test]
fn test_readme_example() {
    use problem::{LpObjective, LpProblem};
    use operations::{LpOperations};
    use variables::LpInteger;
    use solvers::{SolverTrait, CbcSolver};

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    let mut problem = LpProblem::new("One Problem", LpObjective::Maximize);
    problem += 10.0 * a + 20.0 * b;

    problem += (500*a + 1200*b + 1500*c).le(10000);
    problem += (a).le(b);

    let solver = CbcSolver::new();

    match solver.run(&problem) {
        Ok((status, res)) => {
            println!("Status {:?}", status);
            for (name, value) in res.iter() {
                println!("value of {} = {}", name, value);
            }
        },
        Err(msg) => println!("{}", msg),
    }

    let output1 = "\\ One Problem

Maximize
  obj: 10 a + 20 b

Subject To
  c1: 500 a + 1200 b + 1500 c <= 10000
  c2: a - b <= 0

".to_string();
    let output2 = problem.to_lp_file_format();
    let output2 = output2.split("Generals").collect::<Vec<&str>>();
    let output2 = output2[0];
    assert_eq!(output1, output2);
}
<commit_msg>Add new tests for the const case<commit_after>use variables::*;
use variables::LpExpression::*;
use std::rc::Rc;
use operations::LpOperations;
use problem::LpFileFormat;

#[test]
fn expressions_creation() {
    let ref a = LpInteger::new("a")
        .lower_bound(10.0)
        .upper_bound(20.0);
    let ref b = LpInteger::new("b");

    assert_eq!(a + b, AddExpr(Rc::new(ConsInt(a.clone())), Rc::new(ConsInt(b.clone()))));
}

#[test]
fn distributivity() {

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    let test = a * (2 + b) * 3;
    let test2 = test.clone();
    assert_eq!( (2 * (2 + a)).to_lp_file_format(), "2 a + 4");
    assert_eq!( ((2+a) * (2+b)).to_lp_file_format(), "2 a + 2 b + b a + 4" );
    assert_eq!( test.to_lp_file_format(), "6 a + 3 a b" );
    assert_eq!( (10 * test).to_lp_file_format(), "60 a + 30 a b" );
    assert_eq!( ((c + 10) * test2).to_lp_file_format(), "6 c a + 3 c a b + 60 a + 30 a b" );

}

#[test]
fn associativity() {

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!( (a + (b + 2)).to_lp_file_format(), "a + b + 2" );
    assert_eq!( ((a + b) + 2).to_lp_file_format(), "a + b + 2" );

    assert_eq!( (a + (b - 2)).to_lp_file_format(), "a + b - 2" );
    assert_eq!( ((a + b) - 2).to_lp_file_format(), "a + b - 2" );

    assert_eq!( (a - (b + 2)).to_lp_file_format(), "a - b - 2" );
    assert_eq!( ((a - b) + 2).to_lp_file_format(), "a - b + 2" );

    assert_eq!( (a - (b - 2)).to_lp_file_format(), "a - b + 2" );
    assert_eq!( ((a - b) - 2).to_lp_file_format(), "a - b - 2" );

    assert_eq!( (a - (b - 2) + c).to_lp_file_format(), "a - b + c + 2" );
    assert_eq!( ((a - b) - 2 + c).to_lp_file_format(), "a - b + c - 2" );
}

#[test]
fn literal_first_with_accumulation() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    assert_eq!( (a + 1 + b + 2 + c + 3 + a + 4).to_lp_file_format(), "a + b + c + a + 10");
    assert_eq!( (a - 1 + b - 2 - c + 3 + a - 4).to_lp_file_format(), "a + b - c + a - 4");
    assert_eq!( (a + b + 1 - c - a - 3).to_lp_file_format(), "a + b - c - a - 2");
    assert_eq!( (a + b + (c - 1) * 2 - a - 3).to_lp_file_format(), "a + b + 2 c - a - 5");
    assert_eq!( (a + b + (1 - c) * 2 - a - 3).to_lp_file_format(), "a + b - 2 c - a - 1");
    assert_eq!( (2*(a + 5)).to_lp_file_format(), "2 a + 10");
    assert_eq!( ((2+b)*(a + 5)).to_lp_file_format(), "2 a + a b + 5 b + 10");
    assert_eq!( (2 + (a+b) + 3).to_lp_file_format(), "a + b + 5");

}

#[test]
fn trivial_rules() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");

    assert_eq!( ((a+b) * 0).to_lp_file_format(), "0");
    assert_eq!( ( 0 * (a+b)).to_lp_file_format(), "0");
    assert_eq!( (0 * a * b * 3).to_lp_file_format(), "0");
    assert_eq!( ((a+b) + 0).to_lp_file_format(), "a + b");
    assert_eq!( (0 + (a+b) + 0).to_lp_file_format(), "a + b");
    assert_eq!( (0 + (a+b)).to_lp_file_format(), "a + b");
    assert_eq!( ((a+b) - 0).to_lp_file_format(), "a + b");
    assert_eq!( (0 - (a+b)).to_lp_file_format(), "-a - b");
    assert_eq!( (0 + (a+b)).to_lp_file_format(), "a + b");

}

#[test]
fn expressions_to_lp_file_format() {
    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    // Expressions
    assert_eq!((a + 2*b + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + c).to_lp_file_format(), "a + 2 b + c");
    assert_eq!((a + b*2 + 3 * 2 * c).to_lp_file_format(), "a + 2 b + 6 c");
    assert_eq!((a + 2).to_lp_file_format(), "a + 2");
    assert_eq!((2*a + 2*b -4*c).to_lp_file_format(), "2 a + 2 b - 4 c");
    assert_eq!((-2*a).to_lp_file_format(), "-2 a");

    // Constraints
    assert_eq!((a+b).equal(10).to_lp_file_format(), "a + b = 10");
    assert_eq!((2*a + b).ge(10).to_lp_file_format(), "2 a + b >= 10");
    assert_eq!((2*a + b + 20).ge(c).to_lp_file_format(), "2 a + b - c >= -20");
    assert_eq!((-a).ge(10).to_lp_file_format(), "-a >= 10");
    assert_eq!((2*a - 20 + b).ge(-c).to_lp_file_format(), "2 a + b + c >= 20");
    assert_eq!((a + b + 10).ge(0).to_lp_file_format(), "a + b >= -10");
    assert_eq!( (3*(a+b+10)).le(0).to_lp_file_format(), "3 a + 3 b <= -30");
    assert_eq!( (3*(a+b+10)).le(a+b).to_lp_file_format(), "3 a + 3 b - a - b <= -30");
}

#[test]
fn test_readme_example() {
    use problem::{LpObjective, LpProblem};
    use operations::{LpOperations};
    use variables::LpInteger;
    use solvers::{SolverTrait, CbcSolver};

    let ref a = LpInteger::new("a");
    let ref b = LpInteger::new("b");
    let ref c = LpInteger::new("c");

    let mut problem = LpProblem::new("One Problem", LpObjective::Maximize);
    problem += 10.0 * a + 20.0 * b;

    problem += (500*a + 1200*b + 1500*c).le(10000);
    problem += (a).le(b);

    let solver = CbcSolver::new();

    match solver.run(&problem) {
        Ok((status, res)) => {
            println!("Status {:?}", status);
            for (name, value) in res.iter() {
                println!("value of {} = {}", name, value);
            }
        },
        Err(msg) => println!("{}", msg),
    }

    let output1 = "\\ One Problem

Maximize
  obj: 10 a + 20 b

Subject To
  c1: 500 a + 1200 b + 1500 c <= 10000
  c2: a - b <= 0

".to_string();
    let output2 = problem.to_lp_file_format();
    let output2 = output2.split("Generals").collect::<Vec<&str>>();
    let output2 = output2[0];
    assert_eq!(output1, output2);
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::num::Zero;
use std::io;
use std::fmt;
use std::error::Error;

use serde;
use serde_json;
use nix;
use term;

pub type FroyoResult<T> = Result<T, FroyoError>;

//
// Use distinct 'newtype' types for sectors and sector offsets for type safety.
// When needed, these can still be derefed to u64.
// Derive a bunch of stuff so we can do ops on them.
//
custom_derive! {
    #[derive(NewtypeFrom, NewtypeAdd, NewtypeSub, NewtypeDeref,
             NewtypeBitAnd, NewtypeNot, NewtypeDiv, NewtypeRem,
             NewtypeMul,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct Sectors(u64);
}

impl Sectors {
    pub const fn new(val: u64) -> Sectors {
        Sectors(val)
    }
}

impl Zero for Sectors {
    fn zero() -> Self {
        Sectors(0)
    }
}

impl serde::Serialize for Sectors {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for Sectors {
    fn deserialize<D>(deserializer: &mut D) -> Result<Sectors, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(Sectors(val))
    }
}

custom_derive! {
    #[derive(NewtypeFrom, NewtypeAdd, NewtypeSub, NewtypeDeref,
             NewtypeBitAnd, NewtypeNot, NewtypeDiv, NewtypeRem,
             NewtypeMul,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct SectorOffset(u64);
}

impl SectorOffset {
    pub const fn new(val: u64) -> SectorOffset {
        SectorOffset(val)
    }
}

impl Zero for SectorOffset {
    fn zero() -> Self {
        SectorOffset(0)
    }
}

impl serde::Serialize for SectorOffset {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for SectorOffset {
    fn deserialize<D>(deserializer: &mut D) -> Result<SectorOffset, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(SectorOffset(val))
    }
}

// A type for Data Blocks as used by the thin pool.
custom_derive! {
    #[derive(NewtypeFrom, NewtypeAdd, NewtypeSub, NewtypeDeref,
             NewtypeBitAnd, NewtypeNot, NewtypeDiv, NewtypeRem,
             NewtypeMul,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct DataBlocks(u64);
}

impl DataBlocks {
    pub const fn new(val: u64) -> DataBlocks {
        DataBlocks(val)
    }
}

impl Zero for DataBlocks {
    fn zero() -> Self {
        DataBlocks(0)
    }
}

impl serde::Serialize for DataBlocks {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for DataBlocks {
    fn deserialize<D>(deserializer: &mut D) -> Result<DataBlocks, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(DataBlocks(val))
    }
}

// Define a common error enum.
// See http://blog.burntsushi.net/rust-error-handling/
#[derive(Debug)]
pub enum FroyoError {
    Io(io::Error),
    Serde(serde_json::error::Error),
    Nix(nix::Error),
    Dbus(()),
    Term(term::Error),
}

impl fmt::Display for FroyoError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FroyoError::Io(ref err) => write!(f, "IO error: {}", err),
            FroyoError::Serde(ref err) => write!(f, "Serde error: {}", err),
            FroyoError::Nix(ref err) => write!(f, "Nix error: {}", err.errno().desc()),
            FroyoError::Dbus(()) => write!(f, "Dbus error"),
            FroyoError::Term(ref err) => write!(f, "Term error: {}", err),
        }
    }
}

impl Error for FroyoError {
    fn description(&self) -> &str {
        match *self {
            FroyoError::Io(ref err) => err.description(),
            FroyoError::Serde(ref err) => Error::description(err),
            FroyoError::Nix(ref err) => err.errno().desc(),
            FroyoError::Dbus(()) => "Dbus error",
            FroyoError::Term(ref err) => Error::description(err),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            FroyoError::Io(ref err) => Some(err),
            FroyoError::Serde(ref err) => Some(err),
            FroyoError::Nix(_) => None,
            FroyoError::Dbus(()) => None,
            FroyoError::Term(ref err) => Some(err),
        }
    }
}

impl From<io::Error> for FroyoError {
    fn from(err: io::Error) -> FroyoError {
        FroyoError::Io(err)
    }
}

impl From<serde_json::error::Error> for FroyoError {
    fn from(err: serde_json::error::Error) -> FroyoError {
        FroyoError::Serde(err)
    }
}

impl From<nix::Error> for FroyoError {
    fn from(err: nix::Error) -> FroyoError {
        FroyoError::Nix(err)
    }
}

impl From<()> for FroyoError {
    fn from(err: ()) -> FroyoError {
        FroyoError::Dbus(err)
    }
}

impl From<term::Error> for FroyoError {
    fn from(err: term::Error) -> FroyoError {
        FroyoError::Term(err)
    }
}
<commit_msg>Fix cause for FroyoError::Nix<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::num::Zero;
use std::io;
use std::fmt;
use std::error::Error;

use serde;
use serde_json;
use nix;
use term;

pub type FroyoResult<T> = Result<T, FroyoError>;

//
// Use distinct 'newtype' types for sectors and sector offsets for type safety.
// When needed, these can still be derefed to u64.
// Derive a bunch of stuff so we can do ops on them.
//
custom_derive! {
    #[derive(NewtypeFrom, NewtypeAdd, NewtypeSub, NewtypeDeref,
             NewtypeBitAnd, NewtypeNot, NewtypeDiv, NewtypeRem,
             NewtypeMul,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct Sectors(u64);
}

impl Sectors {
    pub const fn new(val: u64) -> Sectors {
        Sectors(val)
    }
}

impl Zero for Sectors {
    fn zero() -> Self {
        Sectors(0)
    }
}

impl serde::Serialize for Sectors {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for Sectors {
    fn deserialize<D>(deserializer: &mut D) -> Result<Sectors, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(Sectors(val))
    }
}

custom_derive! {
    #[derive(NewtypeFrom, NewtypeAdd, NewtypeSub, NewtypeDeref,
             NewtypeBitAnd, NewtypeNot, NewtypeDiv, NewtypeRem,
             NewtypeMul,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct SectorOffset(u64);
}

impl SectorOffset {
    pub const fn new(val: u64) -> SectorOffset {
        SectorOffset(val)
    }
}

impl Zero for SectorOffset {
    fn zero() -> Self {
        SectorOffset(0)
    }
}

impl serde::Serialize for SectorOffset {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for SectorOffset {
    fn deserialize<D>(deserializer: &mut D) -> Result<SectorOffset, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(SectorOffset(val))
    }
}

// A type for Data Blocks as used by the thin pool.
custom_derive! {
    #[derive(NewtypeFrom, NewtypeAdd, NewtypeSub, NewtypeDeref,
             NewtypeBitAnd, NewtypeNot, NewtypeDiv, NewtypeRem,
             NewtypeMul,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct DataBlocks(u64);
}

impl DataBlocks {
    pub const fn new(val: u64) -> DataBlocks {
        DataBlocks(val)
    }
}

impl Zero for DataBlocks {
    fn zero() -> Self {
        DataBlocks(0)
    }
}

impl serde::Serialize for DataBlocks {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for DataBlocks {
    fn deserialize<D>(deserializer: &mut D) -> Result<DataBlocks, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(DataBlocks(val))
    }
}

// Define a common error enum.
// See http://blog.burntsushi.net/rust-error-handling/
#[derive(Debug)]
pub enum FroyoError {
    Io(io::Error),
    Serde(serde_json::error::Error),
    Nix(nix::Error),
    Dbus(()),
    Term(term::Error),
}

impl fmt::Display for FroyoError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FroyoError::Io(ref err) => write!(f, "IO error: {}", err),
            FroyoError::Serde(ref err) => write!(f, "Serde error: {}", err),
            FroyoError::Nix(ref err) => write!(f, "Nix error: {}", err.errno().desc()),
            FroyoError::Dbus(()) => write!(f, "Dbus error"),
            FroyoError::Term(ref err) => write!(f, "Term error: {}", err),
        }
    }
}

impl Error for FroyoError {
    fn description(&self) -> &str {
        match *self {
            FroyoError::Io(ref err) => err.description(),
            FroyoError::Serde(ref err) => Error::description(err),
            FroyoError::Nix(ref err) => err.errno().desc(),
            FroyoError::Dbus(()) => "Dbus error",
            FroyoError::Term(ref err) => Error::description(err),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            FroyoError::Io(ref err) => Some(err),
            FroyoError::Serde(ref err) => Some(err),
            FroyoError::Nix(ref err) => Some(err),
            FroyoError::Dbus(()) => None,
            FroyoError::Term(ref err) => Some(err),
        }
    }
}

impl From<io::Error> for FroyoError {
    fn from(err: io::Error) -> FroyoError {
        FroyoError::Io(err)
    }
}

impl From<serde_json::error::Error> for FroyoError {
    fn from(err: serde_json::error::Error) -> FroyoError {
        FroyoError::Serde(err)
    }
}

impl From<nix::Error> for FroyoError {
    fn from(err: nix::Error) -> FroyoError {
        FroyoError::Nix(err)
    }
}

impl From<()> for FroyoError {
    fn from(err: ()) -> FroyoError {
        FroyoError::Dbus(err)
    }
}

impl From<term::Error> for FroyoError {
    fn from(err: term::Error) -> FroyoError {
        FroyoError::Term(err)
    }
}
<|endoftext|>


<commit_before>//! Types that specify what is contained in a ZIP.

use time;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum System
{
    Dos = 0,
    Unix = 3,
    Unknown,
    #[doc(hidden)]
    __Nonexhaustive,
}

impl System {
    pub fn from_u8(system: u8) -> System
    {
        use self::System::*;

        match system {
            0 => Dos,
            3 => Unix,
            _ => Unknown,
        }
    }
}

pub const DEFAULT_VERSION: u8 = 20;

/// Structure representing a ZIP file.
#[derive(Debug)]
pub struct ZipFileData
{
    /// Compatibility of the file attribute information
    pub system: System,
    /// Specification version
    pub version_made_by: u8,
    /// True if the file is encrypted.
    pub encrypted: bool,
    /// Compression method used to store the file
    pub compression_method: ::compression::CompressionMethod,
    /// Last modified time. This will only have a 2 second precision.
    pub last_modified_time: time::Tm,
    /// CRC32 checksum
    pub crc32: u32,
    /// Size of the file in the ZIP
    pub compressed_size: u64,
    /// Size of the file when extracted
    pub uncompressed_size: u64,
    /// Name of the file
    pub file_name: String,
    /// Raw file name. To be used when file_name was incorrectly decoded.
    pub file_name_raw: Vec<u8>,
    /// File comment
    pub file_comment: String,
    /// Specifies where the local header of the file starts
    pub header_start: u64,
    /// Specifies where the compressed data of the file starts
    pub data_start: u64,
    /// External file attributes
    pub external_attributes: u32,
}

impl ZipFileData {
    pub fn file_name_sanitized(&self) -> ::std::path::PathBuf {
        let no_null_filename = match self.file_name.find('\0') {
            Some(index) => &self.file_name[0..index],
            None => &self.file_name,
        };

        ::std::path::Path::new(no_null_filename)
            .components()
            .filter(|component| match *component {
                ::std::path::Component::Normal(..) => true,
                _ => false,
            })
            .fold(::std::path::PathBuf::new(), |mut path, ref cur| {
                path.push(cur.as_os_str());
                path
            })
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn system() {
        use super::System;
        assert_eq!(System::Dos as u16, 0u16);
        assert_eq!(System::Unix as u16, 3u16);
        assert_eq!(System::from_u8(0), System::Dos);
        assert_eq!(System::from_u8(3), System::Unix);
    }

    #[test]
    fn sanitize() {
        use super::*;
        let file_name = "/path/../../../../etc/./passwd\0/etc/shadow".to_string();
        let data = ZipFileData {
            system: System::Dos,
            version_made_by: 0,
            encrypted: false,
            compression_method: ::compression::CompressionMethod::Stored,
            last_modified_time: time::empty_tm(),
            crc32: 0,
            compressed_size: 0,
            uncompressed_size: 0,
            file_name: file_name.clone(),
            file_name_raw: file_name.into_bytes(),
            file_comment: String::new(),
            header_start: 0,
            data_start: 0,
            external_attributes: 0,
        };
        assert_eq!(data.file_name_sanitized().to_str().unwrap(), "path/etc/passwd");
    }
}
<commit_msg>Fix sanitized_name test for Windows<commit_after>//! Types that specify what is contained in a ZIP.

use time;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum System
{
    Dos = 0,
    Unix = 3,
    Unknown,
    #[doc(hidden)]
    __Nonexhaustive,
}

impl System {
    pub fn from_u8(system: u8) -> System
    {
        use self::System::*;

        match system {
            0 => Dos,
            3 => Unix,
            _ => Unknown,
        }
    }
}

pub const DEFAULT_VERSION: u8 = 20;

/// Structure representing a ZIP file.
#[derive(Debug)]
pub struct ZipFileData
{
    /// Compatibility of the file attribute information
    pub system: System,
    /// Specification version
    pub version_made_by: u8,
    /// True if the file is encrypted.
    pub encrypted: bool,
    /// Compression method used to store the file
    pub compression_method: ::compression::CompressionMethod,
    /// Last modified time. This will only have a 2 second precision.
    pub last_modified_time: time::Tm,
    /// CRC32 checksum
    pub crc32: u32,
    /// Size of the file in the ZIP
    pub compressed_size: u64,
    /// Size of the file when extracted
    pub uncompressed_size: u64,
    /// Name of the file
    pub file_name: String,
    /// Raw file name. To be used when file_name was incorrectly decoded.
    pub file_name_raw: Vec<u8>,
    /// File comment
    pub file_comment: String,
    /// Specifies where the local header of the file starts
    pub header_start: u64,
    /// Specifies where the compressed data of the file starts
    pub data_start: u64,
    /// External file attributes
    pub external_attributes: u32,
}

impl ZipFileData {
    pub fn file_name_sanitized(&self) -> ::std::path::PathBuf {
        let no_null_filename = match self.file_name.find('\0') {
            Some(index) => &self.file_name[0..index],
            None => &self.file_name,
        };

        ::std::path::Path::new(no_null_filename)
            .components()
            .filter(|component| match *component {
                ::std::path::Component::Normal(..) => true,
                _ => false,
            })
            .fold(::std::path::PathBuf::new(), |mut path, ref cur| {
                path.push(cur.as_os_str());
                path
            })
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn system() {
        use super::System;
        assert_eq!(System::Dos as u16, 0u16);
        assert_eq!(System::Unix as u16, 3u16);
        assert_eq!(System::from_u8(0), System::Dos);
        assert_eq!(System::from_u8(3), System::Unix);
    }

    #[test]
    fn sanitize() {
        use super::*;
        let file_name = "/path/../../../../etc/./passwd\0/etc/shadow".to_string();
        let data = ZipFileData {
            system: System::Dos,
            version_made_by: 0,
            encrypted: false,
            compression_method: ::compression::CompressionMethod::Stored,
            last_modified_time: time::empty_tm(),
            crc32: 0,
            compressed_size: 0,
            uncompressed_size: 0,
            file_name: file_name.clone(),
            file_name_raw: file_name.into_bytes(),
            file_comment: String::new(),
            header_start: 0,
            data_start: 0,
            external_attributes: 0,
        };
        assert_eq!(data.file_name_sanitized(), ::std::path::PathBuf::from("path/etc/passwd"));
    }
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#![deny(
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_must_use,
    unused_mut,
    unused_qualifications,
    while_true,
)]

extern crate clap;
#[macro_use]
extern crate log;
#[macro_use]
extern crate version;

extern crate libimagentryannotation;
extern crate libimagentryedit;
extern crate libimagerror;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;

use std::path::PathBuf;

use libimagentryannotation::annotateable::*;
use libimagentryannotation::annotation_fetcher::*;
use libimagentryannotation::error::AnnotationError as AE;
use libimagentryedit::edit::*;
use libimagerror::trace::MapErrTrace;
use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::IntoStoreId;
use libimagutil::warn_exit::warn_exit;

mod ui;

fn main() {
    let rt = generate_runtime_setup("imag-annotation",
                                    &version!()[..],
                                    "Add annotations to entries",
                                    ui::build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            match name {
                "add"    => add(&rt),
                "remove" => remove(&rt),
                "list"   => list(&rt),
                _        => warn_exit("No commandline call", 1)
            }
        });
}

fn add(rt: &Runtime) {
    let scmd            = rt.cli().subcommand_matches("add").unwrap(); // safed by main()
    let annotation_name = scmd.value_of("annotation_name").unwrap(); // safed by clap
    let entry_name      = scmd
        .value_of("entry")
        .map(PathBuf::from)
        .map(|pb| pb.into_storeid().map_err_trace_exit(1).unwrap())
        .unwrap(); // safed by clap

    let _ = rt.store()
        .get(entry_name)
        .map_err_trace_exit(1)
        .unwrap()
        .ok_or(AE::from("Entry does not exist".to_owned()))
        .map_err_trace_exit(1)
        .unwrap()
        .annotate(rt.store(), annotation_name)
        .map_err_trace_exit(1)
        .unwrap()
        .edit_content(&rt)
        .map_err_trace_exit(1)
        .unwrap();

    info!("Ok");
}

fn remove(rt: &Runtime) {
    let scmd            = rt.cli().subcommand_matches("remove").unwrap(); // safed by main()
    let entry_name      = scmd.value_of("entry").unwrap(); // safed by clap
    let annotation_name = scmd.value_of("annotation_name").unwrap(); // safed by clap
    let delete          = scmd.is_present("delete-annotation");

    let mut entry = rt.store()
        .get(PathBuf::from(entry_name).into_storeid().map_err_trace_exit(1).unwrap())
        .map_err_trace_exit(1)
        .unwrap()
        .ok_or(AE::from("Entry does not exist".to_owned()))
        .map_err_trace_exit(1)
        .unwrap();

    let annotation = entry
        .denotate(rt.store(), annotation_name)
        .map_err_trace_exit(1)
        .unwrap();

    if delete {
        if let Some(an) = annotation {
            let loc = an.get_location().clone();
            drop(an);

            let _ = rt
                .store()
                .delete(loc)
                .map_err_trace_exit(1)
                .unwrap();
        }
    }

    info!("Ok");
}

fn list(rt: &Runtime) {
    let scmd        = rt.cli().subcommand_matches("list").unwrap(); // safed by clap
    let with_text   = scmd.is_present("list-with-text");
    match scmd.value_of("entry").map(PathBuf::from) {
        Some(pb) => {
            let _ = rt
                .store()
                .get(pb.into_storeid().map_err_trace_exit(1).unwrap())
                .map_err_trace_exit(1)
                .unwrap()
                .ok_or(AE::from("Entry does not exist".to_owned()))
                .map_err_trace_exit(1)
                .unwrap()
                .annotations(rt.store())
                .map_err_trace_exit(1)
                .unwrap()
                .enumerate()
                .map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text))
                .collect::<Vec<_>>();
        }

        None => {
            // show them all
            let _ = rt
                .store()
                .all_annotations()
                .map_err_trace_exit(1)
                .unwrap()
                .enumerate()
                .map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text))
                .collect::<Vec<_>>();
        }
    }

    info!("Ok");
}

fn list_annotation<'a>(i: usize, a: FileLockEntry<'a>, with_text: bool) {
    if with_text {
        println!("--- {i: >5} | {id}\n{text}\n\n",
                 i = i,
                 id = a.get_location(),
                 text = a.get_content());
    } else {
        println!("{: >5} | {}", i, a.get_location());
    }
}

<commit_msg>Add debug output<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#![deny(
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_must_use,
    unused_mut,
    unused_qualifications,
    while_true,
)]

extern crate clap;
#[macro_use]
extern crate log;
#[macro_use]
extern crate version;

extern crate libimagentryannotation;
extern crate libimagentryedit;
extern crate libimagerror;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;

use std::path::PathBuf;

use libimagentryannotation::annotateable::*;
use libimagentryannotation::annotation_fetcher::*;
use libimagentryannotation::error::AnnotationError as AE;
use libimagentryedit::edit::*;
use libimagerror::trace::MapErrTrace;
use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::IntoStoreId;
use libimagutil::warn_exit::warn_exit;

mod ui;

fn main() {
    let rt = generate_runtime_setup("imag-annotation",
                                    &version!()[..],
                                    "Add annotations to entries",
                                    ui::build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            match name {
                "add"    => add(&rt),
                "remove" => remove(&rt),
                "list"   => list(&rt),
                _        => warn_exit("No commandline call", 1)
            }
        });
}

fn add(rt: &Runtime) {
    let scmd            = rt.cli().subcommand_matches("add").unwrap(); // safed by main()
    let annotation_name = scmd.value_of("annotation_name").unwrap(); // safed by clap
    let entry_name      = scmd
        .value_of("entry")
        .map(PathBuf::from)
        .map(|pb| pb.into_storeid().map_err_trace_exit(1).unwrap())
        .unwrap(); // safed by clap

    let _ = rt.store()
        .get(entry_name)
        .map_err_trace_exit(1)
        .unwrap()
        .ok_or(AE::from("Entry does not exist".to_owned()))
        .map_err_trace_exit(1)
        .unwrap()
        .annotate(rt.store(), annotation_name)
        .map_err_trace_exit(1)
        .unwrap()
        .edit_content(&rt)
        .map_err_trace_exit(1)
        .unwrap();

    info!("Ok");
}

fn remove(rt: &Runtime) {
    let scmd            = rt.cli().subcommand_matches("remove").unwrap(); // safed by main()
    let entry_name      = scmd.value_of("entry").unwrap(); // safed by clap
    let annotation_name = scmd.value_of("annotation_name").unwrap(); // safed by clap
    let delete          = scmd.is_present("delete-annotation");

    let mut entry = rt.store()
        .get(PathBuf::from(entry_name).into_storeid().map_err_trace_exit(1).unwrap())
        .map_err_trace_exit(1)
        .unwrap()
        .ok_or(AE::from("Entry does not exist".to_owned()))
        .map_err_trace_exit(1)
        .unwrap();

    let annotation = entry
        .denotate(rt.store(), annotation_name)
        .map_err_trace_exit(1)
        .unwrap();

    if delete {
        debug!("Deleting annotation object");
        if let Some(an) = annotation {
            let loc = an.get_location().clone();
            drop(an);

            let _ = rt
                .store()
                .delete(loc)
                .map_err_trace_exit(1)
                .unwrap();
        } else {
            warn!("Not having annotation object, cannot delete!");
        }
    } else {
        debug!("Not deleting annotation object");
    }

    info!("Ok");
}

fn list(rt: &Runtime) {
    let scmd        = rt.cli().subcommand_matches("list").unwrap(); // safed by clap
    let with_text   = scmd.is_present("list-with-text");
    match scmd.value_of("entry").map(PathBuf::from) {
        Some(pb) => {
            let _ = rt
                .store()
                .get(pb.into_storeid().map_err_trace_exit(1).unwrap())
                .map_err_trace_exit(1)
                .unwrap()
                .ok_or(AE::from("Entry does not exist".to_owned()))
                .map_err_trace_exit(1)
                .unwrap()
                .annotations(rt.store())
                .map_err_trace_exit(1)
                .unwrap()
                .enumerate()
                .map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text))
                .collect::<Vec<_>>();
        }

        None => {
            // show them all
            let _ = rt
                .store()
                .all_annotations()
                .map_err_trace_exit(1)
                .unwrap()
                .enumerate()
                .map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text))
                .collect::<Vec<_>>();
        }
    }

    info!("Ok");
}

fn list_annotation<'a>(i: usize, a: FileLockEntry<'a>, with_text: bool) {
    if with_text {
        println!("--- {i: >5} | {id}\n{text}\n\n",
                 i = i,
                 id = a.get_location(),
                 text = a.get_content());
    } else {
        println!("{: >5} | {}", i, a.get_location());
    }
}

<|endoftext|>


<commit_before>extern crate bindgen;
#[cfg(feature = "static")]
extern crate cmake;

static LIBRARIES: &'static [&'static str] =
    &["wlr-common", "wlr-wayland", "wlr-backend", "wlr-session"];

fn main() {
    let generated = bindgen::builder()
        .header("src/wlroots.h")
        .whitelisted_type(r"^wlr_.*$")
        .whitelisted_function(r"^wlr_.*$")
        .no_unstable_rust()
        .ctypes_prefix("libc")
        .clang_arg("-I")
        .clang_arg("wlroots/include")
        .generate().unwrap();

    if cfg!(feature = "static") {
        println!("cargo:rustc-link-lib=dylib=wayland-server");
        println!("cargo:rustc-link-lib=dylib=EGL");
        println!("cargo:rustc-link-lib=dylib=GL");
        println!("cargo:rustc-link-lib=dylib=drm");
        println!("cargo:rustc-link-lib=dylib=input");
        println!("cargo:rustc-link-lib=dylib=udev");
        println!("cargo:rustc-link-lib=dylib=systemd");
        println!("cargo:rustc-link-lib=dylib=dbus-1");
    } else {
        for library in LIBRARIES {
            println!("cargo:rustc-link-lib=dylib={}", library);
        }
    }

    // generate the bindings
    generated.write_to_file("src/gen.rs").unwrap();

    cmake();
}

#[cfg(not(feature = "static"))]
fn cmake() {}

#[cfg(feature = "static")]
fn cmake() {
    use cmake::Config;

    let dst = Config::new("wlroots")
                // TODO Eventually change to Release, once the warnings stop
                .define("CMAKE_BUILD_TYPE", "Debug")
                // TODO Remove "all" once "install" is valid
                .build_target("all")
                .build();

    println!("cargo:rustc-link-search=native={}/lib", dst.display());
    println!("cargo:rustc-link-search=native={}/lib64", dst.display());
    println!("cargo:rustc-link-search=native={}/build/", dst.display());
    // TODO May not be needed to specify the directiories directly,
    // wait until the library output stabilizes and look into it later
    println!("cargo:rustc-link-search=native={}/build/session", dst.display());
    println!("cargo:rustc-link-search=native={}/build/common", dst.display());
    println!("cargo:rustc-link-search=native={}/build/wayland", dst.display());
    println!("cargo:rustc-link-search=native={}/build/backend", dst.display());

    for library in LIBRARIES {
        println!("cargo:rustc-link-lib=static={}", library);
    }
}
<commit_msg>Added wlr-types to build<commit_after>extern crate bindgen;
#[cfg(feature = "static")]
extern crate cmake;

static LIBRARIES: &'static [&'static str] =
    &["wlr-common", "wlr-wayland", "wlr-backend", "wlr-session", "wlr-types"];

fn main() {
    let generated = bindgen::builder()
        .header("src/wlroots.h")
        .whitelisted_type(r"^wlr_.*$")
        .whitelisted_function(r"^wlr_.*$")
        .no_unstable_rust()
        .ctypes_prefix("libc")
        .clang_arg("-I")
        .clang_arg("wlroots/include")
        .generate().unwrap();

    if cfg!(feature = "static") {
        println!("cargo:rustc-link-lib=dylib=wayland-server");
        println!("cargo:rustc-link-lib=dylib=EGL");
        println!("cargo:rustc-link-lib=dylib=GL");
        println!("cargo:rustc-link-lib=dylib=gbm");
        println!("cargo:rustc-link-lib=dylib=drm");
        println!("cargo:rustc-link-lib=dylib=input");
        println!("cargo:rustc-link-lib=dylib=udev");
        println!("cargo:rustc-link-lib=dylib=systemd");
        println!("cargo:rustc-link-lib=dylib=dbus-1");
    } else {
        for library in LIBRARIES {
            println!("cargo:rustc-link-lib=dylib={}", library);
        }
    }

    // generate the bindings
    generated.write_to_file("src/gen.rs").unwrap();

    cmake();
}

#[cfg(not(feature = "static"))]
fn cmake() {}

#[cfg(feature = "static")]
fn cmake() {
    use cmake::Config;

    let dst = Config::new("wlroots")
                // TODO Eventually change to Release, once the warnings stop
                .define("CMAKE_BUILD_TYPE", "Debug")
                // TODO Remove "all" once "install" is valid
                .build_target("all")
                .build();

    println!("cargo:rustc-link-search=native={}/lib", dst.display());
    println!("cargo:rustc-link-search=native={}/lib64", dst.display());
    println!("cargo:rustc-link-search=native={}/build/", dst.display());
    // TODO May not be needed to specify the directiories directly,
    // wait until the library output stabilizes and look into it later
    println!("cargo:rustc-link-search=native={}/build/types", dst.display());
    println!("cargo:rustc-link-search=native={}/build/session", dst.display());
    println!("cargo:rustc-link-search=native={}/build/common", dst.display());
    println!("cargo:rustc-link-search=native={}/build/wayland", dst.display());
    println!("cargo:rustc-link-search=native={}/build/backend", dst.display());

    for library in LIBRARIES {
        println!("cargo:rustc-link-lib=static={}", library);
    }
}
<|endoftext|>


<commit_before>use super::VulkanoRenderer;

use game_state::winit;
use game_state::input::events::{
    InputEvent,
    MouseButton,
};

use game_state::input::screen::{
    ScreenPoint,
    ScreenRect,
    DeltaVector,
};

use std::collections::VecDeque;
use game_state::input::InputSource;

// TODO: probably extract this to game_state

impl InputSource for VulkanoRenderer {
    fn get_input_events(&mut self) -> VecDeque<InputEvent> {

        //println!("get_input_events");
        let mut events = VecDeque::new();
        {
            let event_loop = &mut self.events_loop.lock().unwrap();
            event_loop.poll_events(|e| events.push_back(e.clone()));
        }

        let this_window_id = self.id as u64;
        //test chg

        let mut converted_events = VecDeque::with_capacity(events.len());

        for e in events {

            match e {
                winit::Event::DeviceEvent{device_id, ref event} => {
                    match event {
                        &winit::DeviceEvent::Added => {
                            println!("device added");
                        },
                        &winit::DeviceEvent::Removed => {
                            println!("device removed")
                        },
                        &winit::DeviceEvent::MouseMotion { delta } => { },
                        &winit::DeviceEvent::MouseWheel {delta} => {},
                        &winit::DeviceEvent::Motion { axis, value } => {
                        },
                        &winit::DeviceEvent::Button { button, state } => {},
                        &winit::DeviceEvent::Key(input) => {},
                        &winit::DeviceEvent::Text{codepoint} => {}
                    }
                },
                winit::Event::WindowEvent{ window_id, ref event } => {
                    let maybe_converted_event = match event {
                        // Keyboard Events
                        &winit::WindowEvent::KeyboardInput{device_id, input} => {
                            let e = match input.state {
                                winit::ElementState::Pressed => InputEvent::KeyDown(self.id, input.scancode),
                                winit::ElementState::Released => InputEvent::KeyUp(self.id, input.scancode)
                            };

                            // within the renderer itself we want to listen for input events
                            // directly, so we read what's been copied
                            if let &InputEvent::KeyDown(ref id, ref scan) = &e {
                                let c = *scan as u8;
                                match c {
                                    33 => {
                                        self.fullscreen = !self.fullscreen;
                                        // TODO: monitor parameter
                                        if self.fullscreen {
                                            println!("going into fullscreen");
                                            self.window.set_fullscreen(Some(self.window.get_current_monitor()));
                                            self.fullscreen = true;
                                            self.window.hide_cursor(true);
                                            self.cursor_hidden = true;
                                            match self.window.grab_cursor(true) {
                                               Ok(_) => {
                                                   println!("grabbed cursor");
                                                   self.cursor_grabbed = true;
                                               },
                                               Err(e) => println!("unable to grab cursor {:?}", e)
                                            }
                                        } else {
                                            println!("leaving fullscreen");
                                            self.window.set_fullscreen(None);
                                            self.fullscreen = false;
                                            self.window.hide_cursor(false);
                                            self.cursor_hidden = false;
                                            match self.window.grab_cursor(false) {
                                                Ok(_) => {
                                                    println!("grabbed cursor");
                                                    self.cursor_grabbed = false;
                                                },
                                                Err(e) => println!("unable to grab cursor {:?}", e)
                                            }
                                        }
                                    }
                                    _ => {}
                                }
                            }

                            Some(e)
                        }

                        // Mouse Events
                        &winit::WindowEvent::CursorMoved{device_id, position, modifiers} => {
                            let winit::dpi::LogicalPosition{x,y} = position;
                            let old_pos: ScreenPoint = self.get_mouse_pos().clone();
                            // TODO: resolve f64 truncation to i32 here
                            let new_pos = ScreenPoint::new(x as i32, y as i32);
                            let moved =
                                InputEvent::MouseMove(self.id, new_pos.clone(), DeltaVector::from_points(&old_pos, &new_pos));
                            self.set_mouse_pos(new_pos);
                            Some(moved)
                        },
                        &winit::WindowEvent::MouseInput{device_id, state, button, modifiers} => {
                            let b = match button {
                                winit::MouseButton::Left => MouseButton::Left,
                                winit::MouseButton::Right => MouseButton::Right,
                                winit::MouseButton::Middle => MouseButton::Middle,
                                winit::MouseButton::Other(n) => MouseButton::Other(n)
                            };
                            let e = match state {
                                winit::ElementState::Pressed => InputEvent::MouseDown(self.id, b, self.get_mouse_pos().clone()),
                                winit::ElementState::Released => InputEvent::MouseUp(self.id, b, self.get_mouse_pos().clone())
                            };
                            Some(e)
                        },

                        &winit::WindowEvent::MouseWheel{device_id, delta, phase, modifiers} => {
                            let e = match delta {
                                winit::MouseScrollDelta::LineDelta(x,y) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                },
                                winit::MouseScrollDelta::PixelDelta(winit::dpi::LogicalPosition{x,y}) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                }
                            };

                            Some(e)
                        },

                        // Window Manager events
                        &winit::WindowEvent::CloseRequested => Some(InputEvent::CloseRequested(self.id)),
                        &winit::WindowEvent::Destroyed => Some(InputEvent::Destroyed(self.id)),
                        &winit::WindowEvent::Focused(f) => Some(if f { InputEvent::GainedFocus(self.id) } else { InputEvent::LostFocus(self.id) }),
                        &winit::WindowEvent::Moved(winit::dpi::LogicalPosition{x,y}) => {
                            let new_rect = ScreenRect::new(x as i32, y as i32, self.rect.w, self.rect.h);
                            let e = InputEvent::Moved(self.id, ScreenPoint::new(x as i32, y as i32));
                            self.set_rect(new_rect);
                            Some(e)
                        }
                        &winit::WindowEvent::Resized(winit::dpi::LogicalSize{width, height}) => {
                            let new_rect = ScreenRect::new(self.rect.x, self.rect.y, width as i32, height as i32);
                            let e = InputEvent::Resized(self.id, new_rect.clone());
                            self.set_rect(new_rect);
                            Some(e)
                        },
                        _ => None

                    };
                    if maybe_converted_event.is_some() {
                        converted_events.push_back(maybe_converted_event.unwrap());
                    }

                }
                _ => {}
            };
        }
        converted_events
    }
    // FIXME Ruby
}

<commit_msg>remove comment<commit_after>use super::VulkanoRenderer;

use game_state::winit;
use game_state::input::events::{
    InputEvent,
    MouseButton,
};

use game_state::input::screen::{
    ScreenPoint,
    ScreenRect,
    DeltaVector,
};

use std::collections::VecDeque;
use game_state::input::InputSource;

// TODO: probably extract this to game_state

impl InputSource for VulkanoRenderer {
    fn get_input_events(&mut self) -> VecDeque<InputEvent> {

        //println!("get_input_events");
        let mut events = VecDeque::new();
        {
            let event_loop = &mut self.events_loop.lock().unwrap();
            event_loop.poll_events(|e| events.push_back(e.clone()));
        }

        let this_window_id = self.id as u64;
        //test chg

        let mut converted_events = VecDeque::with_capacity(events.len());

        for e in events {

            match e {
                winit::Event::DeviceEvent{device_id, ref event} => {
                    match event {
                        &winit::DeviceEvent::Added => {
                            println!("device added");
                        },
                        &winit::DeviceEvent::Removed => {
                            println!("device removed")
                        },
                        &winit::DeviceEvent::MouseMotion { delta } => { },
                        &winit::DeviceEvent::MouseWheel {delta} => {},
                        &winit::DeviceEvent::Motion { axis, value } => {
                        },
                        &winit::DeviceEvent::Button { button, state } => {},
                        &winit::DeviceEvent::Key(input) => {},
                        &winit::DeviceEvent::Text{codepoint} => {}
                    }
                },
                winit::Event::WindowEvent{ window_id, ref event } => {
                    let maybe_converted_event = match event {
                        // Keyboard Events
                        &winit::WindowEvent::KeyboardInput{device_id, input} => {
                            let e = match input.state {
                                winit::ElementState::Pressed => InputEvent::KeyDown(self.id, input.scancode),
                                winit::ElementState::Released => InputEvent::KeyUp(self.id, input.scancode)
                            };

                            // within the renderer itself we want to listen for input events
                            // directly, so we read what's been copied
                            if let &InputEvent::KeyDown(ref id, ref scan) = &e {
                                let c = *scan as u8;
                                match c {
                                    33 => {
                                        self.fullscreen = !self.fullscreen;
                                        if self.fullscreen {
                                            println!("going into fullscreen");
                                            self.window.set_fullscreen(Some(self.window.get_current_monitor()));
                                            self.fullscreen = true;
                                            self.window.hide_cursor(true);
                                            self.cursor_hidden = true;
                                            match self.window.grab_cursor(true) {
                                               Ok(_) => {
                                                   println!("grabbed cursor");
                                                   self.cursor_grabbed = true;
                                               },
                                               Err(e) => println!("unable to grab cursor {:?}", e)
                                            }
                                        } else {
                                            println!("leaving fullscreen");
                                            self.window.set_fullscreen(None);
                                            self.fullscreen = false;
                                            self.window.hide_cursor(false);
                                            self.cursor_hidden = false;
                                            match self.window.grab_cursor(false) {
                                                Ok(_) => {
                                                    println!("grabbed cursor");
                                                    self.cursor_grabbed = false;
                                                },
                                                Err(e) => println!("unable to grab cursor {:?}", e)
                                            }
                                        }
                                    }
                                    _ => {}
                                }
                            }

                            Some(e)
                        }

                        // Mouse Events
                        &winit::WindowEvent::CursorMoved{device_id, position, modifiers} => {
                            let winit::dpi::LogicalPosition{x,y} = position;
                            let old_pos: ScreenPoint = self.get_mouse_pos().clone();
                            // TODO: resolve f64 truncation to i32 here
                            let new_pos = ScreenPoint::new(x as i32, y as i32);
                            let moved =
                                InputEvent::MouseMove(self.id, new_pos.clone(), DeltaVector::from_points(&old_pos, &new_pos));
                            self.set_mouse_pos(new_pos);
                            Some(moved)
                        },
                        &winit::WindowEvent::MouseInput{device_id, state, button, modifiers} => {
                            let b = match button {
                                winit::MouseButton::Left => MouseButton::Left,
                                winit::MouseButton::Right => MouseButton::Right,
                                winit::MouseButton::Middle => MouseButton::Middle,
                                winit::MouseButton::Other(n) => MouseButton::Other(n)
                            };
                            let e = match state {
                                winit::ElementState::Pressed => InputEvent::MouseDown(self.id, b, self.get_mouse_pos().clone()),
                                winit::ElementState::Released => InputEvent::MouseUp(self.id, b, self.get_mouse_pos().clone())
                            };
                            Some(e)
                        },

                        &winit::WindowEvent::MouseWheel{device_id, delta, phase, modifiers} => {
                            let e = match delta {
                                winit::MouseScrollDelta::LineDelta(x,y) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                },
                                winit::MouseScrollDelta::PixelDelta(winit::dpi::LogicalPosition{x,y}) => {
                                    InputEvent::MouseWheel(
                                        self.id, self.get_mouse_pos().clone(),
                                        DeltaVector::new(x as i32, y as i32)
                                    )
                                }
                            };

                            Some(e)
                        },

                        // Window Manager events
                        &winit::WindowEvent::CloseRequested => Some(InputEvent::CloseRequested(self.id)),
                        &winit::WindowEvent::Destroyed => Some(InputEvent::Destroyed(self.id)),
                        &winit::WindowEvent::Focused(f) => Some(if f { InputEvent::GainedFocus(self.id) } else { InputEvent::LostFocus(self.id) }),
                        &winit::WindowEvent::Moved(winit::dpi::LogicalPosition{x,y}) => {
                            let new_rect = ScreenRect::new(x as i32, y as i32, self.rect.w, self.rect.h);
                            let e = InputEvent::Moved(self.id, ScreenPoint::new(x as i32, y as i32));
                            self.set_rect(new_rect);
                            Some(e)
                        }
                        &winit::WindowEvent::Resized(winit::dpi::LogicalSize{width, height}) => {
                            let new_rect = ScreenRect::new(self.rect.x, self.rect.y, width as i32, height as i32);
                            let e = InputEvent::Resized(self.id, new_rect.clone());
                            self.set_rect(new_rect);
                            Some(e)
                        },
                        _ => None

                    };
                    if maybe_converted_event.is_some() {
                        converted_events.push_back(maybe_converted_event.unwrap());
                    }

                }
                _ => {}
            };
        }
        converted_events
    }
    // FIXME Ruby
}

<|endoftext|>


<commit_before>extern crate time;
extern crate mio;
extern crate httparse;

use std::env;
use std::fmt::Write;
use std::net::SocketAddr;

use mio::{Handler, EventLoop, Token, EventSet, PollOpt, TryRead, TryWrite};
use mio::tcp::*;
use mio::util::Slab;

const LISTENER: mio::Token = mio::Token(0);

struct Server {
    count: u64,
    listener: TcpListener,
    connections: Slab<Connection>,
}

impl Server {
    fn new(listener: TcpListener) -> Server {
        Server {
            count: 0,
            listener: listener,
            connections: Slab::new_starting_at(mio::Token(1), 1024),
        }
    }
}

impl Handler for Server {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Server>, token: Token, events: EventSet) {
        println!("token {:?}", token);

        if token == LISTENER {
            if let Ok(Some(socket)) = self.listener.accept() {
                self.count += 1;
                println!("...connection {}", self.count);

                let token = self.connections
                    .insert_with(move |token| Connection::new(token, socket.0))
                    .unwrap();

                event_loop.register(
                    &self.connections[token].socket,
                    token,
                    EventSet::readable(),
                    PollOpt::edge() | PollOpt::oneshot()).unwrap();
            }
        } else {
            self.connections[token].ready(event_loop, token, events);

            if self.connections[token].is_closed() {
                println!("...closing");
                self.connections.remove(token);
            }
        }
    }
}

struct Connection {
    socket: TcpStream,
    token: Token,
    state: State,
}

type Input = Vec<u8>;

struct Output {
    buf: Vec<u8>,
    pos: usize,
}

enum State {
    Request(Input),
    Response(Output),
    Closed,
}

impl Connection {
    fn new(token: Token, socket: TcpStream) -> Connection {
        Connection {
            token: token,
            socket: socket,
            state: State::Request(Input::new()),
        }
    }

    fn ready(&mut self, event_loop: &mut EventLoop<Server>, token: Token, events: EventSet) {
        let move_forward = match self.state {
            State::Request(ref mut input) => read(&mut self.socket, input, event_loop),
            State::Response(ref mut output) => write(&mut self.socket, output, event_loop),
            State::Closed => unreachable!(),
        };
        if move_forward {
            self.move_forward();
        }
        self.reregister(event_loop, token);
    }

    fn move_forward(&mut self) {
        println!("state change");

        self.state = match self.state {
            State::Request(_) => {
                let mut r = Response::new();
                r.header("Content-Type", "text/plain")
                    .header("Content-Lenth", "15")
                    .header("Server", "wut")
                    .header("Date", &time::now().rfc822().to_string())
                    .body("Hello, World!");
                State::Response(Output { buf: r.to_bytes(), pos: 0 })
            }
            State::Response(_) => State::Closed,
            State::Closed => unreachable!(),
        };
    }

    fn is_closed(&self) -> bool {
        match self.state {
            State::Closed => true,
            _ => false,
        }
    }

    fn reregister(&mut self, event_loop: &mut EventLoop<Server>, token: Token) {
        match self.state {
            State::Request(_) => {
                event_loop.reregister(
                    &self.socket,
                    token,
                    EventSet::readable(),
                    PollOpt::edge() | PollOpt::oneshot()).unwrap()
            }
            State::Response(_) => {
                event_loop.reregister(
                    &self.socket,
                    token,
                    EventSet::writable(),
                    PollOpt::edge() | PollOpt::oneshot()).unwrap()
            }
            State::Closed => {}
        }
    }
}

impl Drop for Connection {
    fn drop(&mut self) {
        println!("...dropping connection");
    }
}

struct Request {
    method: String,
    path: String,
    version: u8,
    headers: Vec<(String, Vec<u8>)>,
}

fn parse(buf: &[u8]) -> Option<Request> {
    let mut headers = [httparse::EMPTY_HEADER; 16];
    let mut r = httparse::Request::new(&mut headers);
    let status = match r.parse(&buf) {
        Ok(status) => status,
        Err(e) => {
            return None
        }
    };
    match status {
        httparse::Status::Complete(amt) => {
            assert_eq!(amt, buf.len());
            Some(Request {
                method: r.method.unwrap().to_string(),
                path: r.path.unwrap().to_string(),
                version: r.version.unwrap(),
                headers: r.headers.iter().map(|h| {
                    (h.name.to_string(), h.value.to_owned())
                }).collect(),
            })
        }
        httparse::Status::Partial => None
    }
}

pub struct Response {
    headers: Vec<(String, String)>,
    response: String,
}

impl Response {
    pub fn new() -> Response {
        Response {
            headers: Vec::new(),
            response: String::new(),
        }
    }

    pub fn header(&mut self, name: &str, val: &str) -> &mut Response {
        self.headers.push((name.to_string(), val.to_string()));
        self
    }

    pub fn body(&mut self, s: &str) -> &mut Response {
        self.response = s.to_string();
        self
    }

    // first, inefficient stab: just build a single buffer big enough to hold entire response
    fn to_bytes(&self) -> Vec<u8> {
        let mut bytes = String::new();
        write!(bytes, "HTTP/1.1 200 OK\r\n");
        for &(ref k, ref v) in &self.headers {
            write!(bytes, "{}: {}\r\n", k, v).unwrap();
        }
        write!(bytes, "\r\n").unwrap();
        write!(bytes, "{}", self.response).unwrap();
        bytes.into_bytes()
    }
}

fn read(socket: &mut TcpStream, input: &mut Input, event_loop: &mut EventLoop<Server>) -> bool {
    match socket.try_read_buf(input).unwrap() {
        // spurious notification
        None => {
            false
        }

        // read `n`, attempt parse
        Some(n) => {
            parse(input).is_some()
        }
    }
}

fn write(socket: &mut TcpStream, output: &mut Output, event_loop: &mut EventLoop<Server>) -> bool {
    match socket.try_write(&output.buf[output.pos..]).unwrap() {
        // spurious
        None => {
            false
        }

        Some(n) => {
            output.pos += n;
            output.pos == output.buf.len()
        }
    }
}

// ab -c 8 -n 10000 localhost:8080/plaintext
fn main() {
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
    let addr = addr.parse::<SocketAddr>().unwrap();
    let listener = TcpListener::bind(&addr).unwrap();
    let mut event_loop = mio::EventLoop::new().unwrap();
    event_loop.register(&listener,
                        LISTENER,
                        EventSet::readable(),
                        PollOpt::level())
        .unwrap();
    let mut server = Server::new(listener);
    event_loop.run(&mut server).unwrap();
}
<commit_msg>Move forward to a next state in case of early EOF.<commit_after>extern crate time;
extern crate mio;
extern crate httparse;

use std::env;
use std::fmt::Write;
use std::net::SocketAddr;

use mio::{Handler, EventLoop, Token, EventSet, PollOpt, TryRead, TryWrite};
use mio::tcp::*;
use mio::util::Slab;

const LISTENER: mio::Token = mio::Token(0);

struct Server {
    count: u64,
    listener: TcpListener,
    connections: Slab<Connection>,
}

impl Server {
    fn new(listener: TcpListener) -> Server {
        Server {
            count: 0,
            listener: listener,
            connections: Slab::new_starting_at(mio::Token(1), 1024),
        }
    }
}

impl Handler for Server {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Server>, token: Token, events: EventSet) {
        println!("token {:?}", token);

        if token == LISTENER {
            if let Ok(Some(socket)) = self.listener.accept() {
                self.count += 1;
                println!("...connection {}", self.count);

                let token = self.connections
                    .insert_with(move |token| Connection::new(token, socket.0))
                    .unwrap();

                event_loop.register(
                    &self.connections[token].socket,
                    token,
                    EventSet::readable(),
                    PollOpt::edge() | PollOpt::oneshot()).unwrap();
            }
        } else {
            self.connections[token].ready(event_loop, token, events);

            if self.connections[token].is_closed() {
                println!("...closing");
                self.connections.remove(token);
            }
        }
    }
}

struct Connection {
    socket: TcpStream,
    token: Token,
    state: State,
}

type Input = Vec<u8>;

struct Output {
    buf: Vec<u8>,
    pos: usize,
}

enum State {
    Request(Input),
    Response(Output),
    Closed,
}

impl Connection {
    fn new(token: Token, socket: TcpStream) -> Connection {
        Connection {
            token: token,
            socket: socket,
            state: State::Request(Input::new()),
        }
    }

    fn ready(&mut self, event_loop: &mut EventLoop<Server>, token: Token, events: EventSet) {
        let move_forward = match self.state {
            State::Request(ref mut input) => read(&mut self.socket, input, event_loop),
            State::Response(ref mut output) => write(&mut self.socket, output, event_loop),
            State::Closed => unreachable!(),
        };
        if move_forward {
            self.move_forward();
        }
        self.reregister(event_loop, token);
    }

    fn move_forward(&mut self) {
        println!("state change");

        self.state = match self.state {
            State::Request(_) => {
                let mut r = Response::new();
                r.header("Content-Type", "text/plain")
                    .header("Content-Lenth", "15")
                    .header("Server", "wut")
                    .header("Date", &time::now().rfc822().to_string())
                    .body("Hello, World!");
                State::Response(Output { buf: r.to_bytes(), pos: 0 })
            }
            State::Response(_) => State::Closed,
            State::Closed => unreachable!(),
        };
    }

    fn is_closed(&self) -> bool {
        match self.state {
            State::Closed => true,
            _ => false,
        }
    }

    fn reregister(&mut self, event_loop: &mut EventLoop<Server>, token: Token) {
        match self.state {
            State::Request(_) => {
                event_loop.reregister(
                    &self.socket,
                    token,
                    EventSet::readable(),
                    PollOpt::edge() | PollOpt::oneshot()).unwrap()
            }
            State::Response(_) => {
                event_loop.reregister(
                    &self.socket,
                    token,
                    EventSet::writable(),
                    PollOpt::edge() | PollOpt::oneshot()).unwrap()
            }
            State::Closed => {}
        }
    }
}

impl Drop for Connection {
    fn drop(&mut self) {
        println!("...dropping connection");
    }
}

struct Request {
    method: String,
    path: String,
    version: u8,
    headers: Vec<(String, Vec<u8>)>,
}

fn parse(buf: &[u8]) -> Option<Request> {
    let mut headers = [httparse::EMPTY_HEADER; 16];
    let mut r = httparse::Request::new(&mut headers);
    let status = match r.parse(&buf) {
        Ok(status) => status,
        Err(e) => {
            return None
        }
    };
    match status {
        httparse::Status::Complete(amt) => {
            assert_eq!(amt, buf.len());
            Some(Request {
                method: r.method.unwrap().to_string(),
                path: r.path.unwrap().to_string(),
                version: r.version.unwrap(),
                headers: r.headers.iter().map(|h| {
                    (h.name.to_string(), h.value.to_owned())
                }).collect(),
            })
        }
        httparse::Status::Partial => None
    }
}

pub struct Response {
    headers: Vec<(String, String)>,
    response: String,
}

impl Response {
    pub fn new() -> Response {
        Response {
            headers: Vec::new(),
            response: String::new(),
        }
    }

    pub fn header(&mut self, name: &str, val: &str) -> &mut Response {
        self.headers.push((name.to_string(), val.to_string()));
        self
    }

    pub fn body(&mut self, s: &str) -> &mut Response {
        self.response = s.to_string();
        self
    }

    // first, inefficient stab: just build a single buffer big enough to hold entire response
    fn to_bytes(&self) -> Vec<u8> {
        let mut bytes = String::new();
        write!(bytes, "HTTP/1.1 200 OK\r\n");
        for &(ref k, ref v) in &self.headers {
            write!(bytes, "{}: {}\r\n", k, v).unwrap();
        }
        write!(bytes, "\r\n").unwrap();
        write!(bytes, "{}", self.response).unwrap();
        bytes.into_bytes()
    }
}

fn read(socket: &mut TcpStream, input: &mut Input, event_loop: &mut EventLoop<Server>) -> bool {
    match socket.try_read_buf(input).unwrap() {
        // spurious notification
        None => {
            false
        }

        // move forward in case of unexpected eof
        Some(0) => {
            true
        }

        // read `n`, attempt parse
        Some(n) => {
            parse(input).is_some()
        }
    }
}

fn write(socket: &mut TcpStream, output: &mut Output, event_loop: &mut EventLoop<Server>) -> bool {
    match socket.try_write(&output.buf[output.pos..]).unwrap() {
        // spurious
        None => {
            false
        }

        Some(n) => {
            output.pos += n;
            output.pos == output.buf.len()
        }
    }
}

// ab -c 8 -n 10000 localhost:8080/plaintext
fn main() {
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
    let addr = addr.parse::<SocketAddr>().unwrap();
    let listener = TcpListener::bind(&addr).unwrap();
    let mut event_loop = mio::EventLoop::new().unwrap();
    event_loop.register(&listener,
                        LISTENER,
                        EventSet::readable(),
                        PollOpt::level())
        .unwrap();
    let mut server = Server::new(listener);
    event_loop.run(&mut server).unwrap();
}
<|endoftext|>