<commit_before>use parser;
use typechecker::check_program;
use typechecker::{TypeCheckerIssue, TypeCheckerIssueWithPosition};
use runtime::RuntimeError;
use typechecker::{Type, ConstraintType};
use ast::*;

fn check_and_get_result(code: &str) -> Result<(), Vec<TypeCheckerIssueWithPosition>> {
    let ast = parser::program(code);
    match ast {
        Ok(ast) => {
            let result = check_program(&ast);
            result
        }
        Err(_) => panic!("{:?}", ast),
    }
}

#[test]
fn check_no_reference_error() {
    let result = check_and_get_result("var x = 5; x;");
    assert!(result.is_ok());
}

#[test]
fn check_reference_error() {
    let result = check_and_get_result("var x = 5; y;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::ReferenceError("y".to_owned())),
                 (11, 12))]);
}

#[test]
fn check_no_undeclared_assignment() {
    let result = check_and_get_result("var x = 5;");
    assert!(result.is_ok());
}

#[test]
fn check_undeclared_assignment_error() {
    let result = check_and_get_result("x = 5;");
    assert_eq!(result.unwrap_err(), [
        (TypeCheckerIssue::RuntimeError(RuntimeError::UndeclaredAssignment("x".to_owned())), (0, 2))
    ]);
}

#[test]
fn check_no_binary_type_error() {
    let result = check_and_get_result("5 + 5.5 < 10 - 2 and 5;");
    assert!(result.is_ok());
}

#[test]
fn check_binary_type_error_add() {
    let result = check_and_get_result("1 + true;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Number,
                                                                              Type::Bool)),
                 (0, 8))]);

    let result = check_and_get_result("true + 1;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Bool,
                                                                              Type::Number)),
                 (0, 8))]);

    let result = check_and_get_result("false + true;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Bool,
                                                                              Type::Bool)),
                 (0, 12))]);
}

#[test]
fn check_no_unary_minus_error() {
    let result = check_and_get_result("-10.9;");
    assert!(result.is_ok());
}

#[test]
fn check_unary_minus_error() {
    let result = check_and_get_result("-false;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::UnaryTypeError(UnaryOp::Minus,
                                                                             Type::Bool)),
                 (1, 6))]);
}

#[test]
fn check_multiple_types_from_branch() {
    let result = check_and_get_result("var x = 5; if true { x = true; } else { x = 10; } ");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::MultipleTypesFromBranchWarning("x".to_owned()), (11, 50))]);
}

#[test]
fn check_none_error_for_builtin() {
    let result = check_and_get_result("-println(10);");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::NoneError(Some("println"
                     .to_owned()))),
                 (1, 12))]);
}

#[test]
fn check_arg_mismatch_fail() {
    let result = check_and_get_result("fn f(x) {} f(1);");
    assert!(result.is_ok());
}

#[test]
fn check_arg_mismatch_pass() {
    let result = check_and_get_result("fn f(x) {} f();");
    assert_eq!(result.unwrap_err(),
               [((TypeCheckerIssue::RuntimeError(RuntimeError::ArgumentLength(None))), (11, 14))]);
}

#[test]
fn check_type_error_in_fn() {
    let result = check_and_get_result("fn f() { true + 1; }");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Bool,
                                                                              Type::Number)),
                 (9, 17))]);
}

#[test]
fn check_no_reference_error_in_fn() {
    let result = check_and_get_result("var x = 1; fn f() { x; }");
    assert!(result.is_ok());
}

#[test]
fn check_reference_error_in_fn() {
    let result = check_and_get_result("fn f() { x; }");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::ReferenceError("x".to_owned())),
                 (9, 10))]);
}

#[test]
fn check_nested_multiple_types_error() {
    let result = check_and_get_result("var x = 1;
if 1 {
    if 2 {
        x = true;
    } else {
        x = 1;
    }
} else {
    x = 5;
}");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::MultipleTypesFromBranchWarning("x".to_owned()), (22, 81))]);
}

#[test]
fn check_non_integral_subscript() {
    assert_eq!(check_and_get_result("(1, 2, 3)[true];").unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::NonIntegralSubscript(Type::Bool)),
                 (10, 14))]);
}

#[test]
fn check_function_body_on_call() {
    let code = "fn add(a, b) {
    return a + b;
}

add(true, true);
add(1, 1);
add(true, 1);
add(false, false);";
    assert_eq!(check_and_get_result(code).unwrap_err(), [
        (
            TypeCheckerIssue::InsideFunctionCall(
                Box::new(
                    (
                        TypeCheckerIssue::RuntimeError(
                            RuntimeError::BinaryTypeError(BinaryOp::Add, Type::Bool, Type::Bool)
                        ),
                        (26, 31)
                    )
                )
            ),
            (36, 51)
        ),
        (
            TypeCheckerIssue::InsideFunctionCall(
                Box::new(
                    (
                        TypeCheckerIssue::RuntimeError(
                            RuntimeError::BinaryTypeError(BinaryOp::Add, Type::Bool, Type::Number)
                        ),
                        (26, 31)
                    )
                )
            ),
            (64, 76)
        ),
    ]);
}

#[test]
fn check_return_type() {
    let code = "fn add(a, b): Number {
    return true;
}";
    assert_eq!(check_and_get_result(code).unwrap_err(),
               [(TypeCheckerIssue::ReturnTypeMismatch(Some(ConstraintType::Number),
                                                      Some(ConstraintType::Bool)),
                 (27, 40))]);
}

#[test]
fn check_inferred_return_type() {
    let code = "fn bool_id(a): Bool {
    return a;
}

bool_id(1);";
    assert_eq!(check_and_get_result(code).unwrap_err(),
        [(TypeCheckerIssue::InsideFunctionCall(
            Box::new((TypeCheckerIssue::ReturnTypeMismatch(Some(ConstraintType::Bool), Some(ConstraintType::Number)), (26, 44)))
        ), (47, 57))]
    );
}
<commit_msg>Fix offset error in failing typechecker test<commit_after>use parser;
use typechecker::check_program;
use typechecker::{TypeCheckerIssue, TypeCheckerIssueWithPosition};
use runtime::RuntimeError;
use typechecker::{Type, ConstraintType};
use ast::*;

fn check_and_get_result(code: &str) -> Result<(), Vec<TypeCheckerIssueWithPosition>> {
    let ast = parser::program(code);
    match ast {
        Ok(ast) => {
            let result = check_program(&ast);
            result
        }
        Err(_) => panic!("{:?}", ast),
    }
}

#[test]
fn check_no_reference_error() {
    let result = check_and_get_result("var x = 5; x;");
    assert!(result.is_ok());
}

#[test]
fn check_reference_error() {
    let result = check_and_get_result("var x = 5; y;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::ReferenceError("y".to_owned())),
                 (11, 12))]);
}

#[test]
fn check_no_undeclared_assignment() {
    let result = check_and_get_result("var x = 5;");
    assert!(result.is_ok());
}

#[test]
fn check_undeclared_assignment_error() {
    let result = check_and_get_result("x = 5;");
    assert_eq!(result.unwrap_err(), [
        (TypeCheckerIssue::RuntimeError(RuntimeError::UndeclaredAssignment("x".to_owned())), (0, 2))
    ]);
}

#[test]
fn check_no_binary_type_error() {
    let result = check_and_get_result("5 + 5.5 < 10 - 2 and 5;");
    assert!(result.is_ok());
}

#[test]
fn check_binary_type_error_add() {
    let result = check_and_get_result("1 + true;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Number,
                                                                              Type::Bool)),
                 (0, 8))]);

    let result = check_and_get_result("true + 1;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Bool,
                                                                              Type::Number)),
                 (0, 8))]);

    let result = check_and_get_result("false + true;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Bool,
                                                                              Type::Bool)),
                 (0, 12))]);
}

#[test]
fn check_no_unary_minus_error() {
    let result = check_and_get_result("-10.9;");
    assert!(result.is_ok());
}

#[test]
fn check_unary_minus_error() {
    let result = check_and_get_result("-false;");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::UnaryTypeError(UnaryOp::Minus,
                                                                             Type::Bool)),
                 (1, 6))]);
}

#[test]
fn check_multiple_types_from_branch() {
    let result = check_and_get_result("var x = 5; if true { x = true; } else { x = 10; } ");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::MultipleTypesFromBranchWarning("x".to_owned()), (11, 50))]);
}

#[test]
fn check_none_error_for_builtin() {
    let result = check_and_get_result("-println(10);");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::NoneError(Some("println"
                     .to_owned()))),
                 (1, 12))]);
}

#[test]
fn check_arg_mismatch_fail() {
    let result = check_and_get_result("fn f(x) {} f(1);");
    assert!(result.is_ok());
}

#[test]
fn check_arg_mismatch_pass() {
    let result = check_and_get_result("fn f(x) {} f();");
    assert_eq!(result.unwrap_err(),
               [((TypeCheckerIssue::RuntimeError(RuntimeError::ArgumentLength(None))), (11, 14))]);
}

#[test]
fn check_type_error_in_fn() {
    let result = check_and_get_result("fn f() { true + 1; }");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::BinaryTypeError(BinaryOp::Add,
                                                                              Type::Bool,
                                                                              Type::Number)),
                 (9, 17))]);
}

#[test]
fn check_no_reference_error_in_fn() {
    let result = check_and_get_result("var x = 1; fn f() { x; }");
    assert!(result.is_ok());
}

#[test]
fn check_reference_error_in_fn() {
    let result = check_and_get_result("fn f() { x; }");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::ReferenceError("x".to_owned())),
                 (9, 10))]);
}

#[test]
fn check_nested_multiple_types_error() {
    let result = check_and_get_result("var x = 1;
if 1 {
    if 2 {
        x = true;
    } else {
        x = 1;
    }
} else {
    x = 5;
}");
    assert_eq!(result.unwrap_err(),
               [(TypeCheckerIssue::MultipleTypesFromBranchWarning("x".to_owned()), (22, 81))]);
}

#[test]
fn check_non_integral_subscript() {
    assert_eq!(check_and_get_result("(1, 2, 3)[true];").unwrap_err(),
               [(TypeCheckerIssue::RuntimeError(RuntimeError::NonIntegralSubscript(Type::Bool)),
                 (10, 14))]);
}

#[test]
fn check_function_body_on_call() {
    let code = "fn add(a, b) {
    return a + b;
}

add(true, true);
add(1, 1);
add(true, 1);
add(false, false);";
    assert_eq!(check_and_get_result(code).unwrap_err(), [
        (
            TypeCheckerIssue::InsideFunctionCall(
                Box::new(
                    (
                        TypeCheckerIssue::RuntimeError(
                            RuntimeError::BinaryTypeError(BinaryOp::Add, Type::Bool, Type::Bool)
                        ),
                        (26, 31)
                    )
                )
            ),
            (36, 51)
        ),
        (
            TypeCheckerIssue::InsideFunctionCall(
                Box::new(
                    (
                        TypeCheckerIssue::RuntimeError(
                            RuntimeError::BinaryTypeError(BinaryOp::Add, Type::Bool, Type::Number)
                        ),
                        (26, 31)
                    )
                )
            ),
            (64, 76)
        ),
    ]);
}

#[test]
fn check_return_type() {
    let code = "fn add(a, b): Number {
    return true;
}";
    assert_eq!(check_and_get_result(code).unwrap_err(),
               [(TypeCheckerIssue::ReturnTypeMismatch(Some(ConstraintType::Number),
                                                      Some(ConstraintType::Bool)),
                 (27, 40))]);
}

#[test]
fn check_inferred_return_type() {
    let code = "fn bool_id(a): Bool {
    return a;
}

bool_id(1);";
    assert_eq!(check_and_get_result(code).unwrap_err(),
        [(TypeCheckerIssue::InsideFunctionCall(
            Box::new((TypeCheckerIssue::ReturnTypeMismatch(Some(ConstraintType::Bool), Some(ConstraintType::Number)), (26, 36)))
        ), (39, 49))]
    );
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::path::Path;
use std::time::Instant;

use perftest_data::PerftestData;
use protobuf::Message;
use rand::Rng;
use rand::SeedableRng;
use rand::StdRng;

mod perftest_data;

fn measure_ns<R, F: FnMut() -> R>(mut f: F) -> (u64, R) {
    let start = Instant::now();
    let r = f();
    (start.elapsed().as_nanos() as u64, r)
}

fn measure_and_print<R, F: FnMut() -> R>(title: &str, iter: u64, f: F) -> R {
    let (ns, r) = measure_ns(f);
    let ns_per_iter = ns / iter;
    println!("{}: {} ns per iter", title, ns_per_iter);
    r
}

struct TestRunner {
    data_size: u32,
    selected: Option<String>,
    any_matched: bool,
}

impl TestRunner {
    fn run_test<M: Message + Clone + PartialEq>(&self, name: &str, data: &[M]) {
        assert!(data.len() > 0, "empty string for test: {}", name);

        let mut rng: StdRng = SeedableRng::from_seed([
            10, 20, 30, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0,
        ]);

        let mut random_data: Vec<M> = Vec::new();

        let mut total_size = 0;
        while total_size < self.data_size {
            let ref item = data[rng.gen_range(0, data.len())];
            random_data.push(item.clone());
            total_size += item.compute_size();
        }

        let mut buf = Vec::new();
        measure_and_print(
            &format!("{}: write", name),
            random_data.len() as u64,
            || {
                for m in &random_data {
                    m.write_length_delimited_to_vec(&mut buf).unwrap();
                }
            },
        );

        let read_data =
            measure_and_print(&format!("{}: read", name), random_data.len() as u64, || {
                let mut r = Vec::new();
                let mut coded_input_stream = protobuf::CodedInputStream::from_bytes(&buf);
                while !coded_input_stream.eof().unwrap() {
                    r.push(coded_input_stream.read_message().unwrap());
                }
                r
            });

        assert_eq!(random_data, read_data);

        let merged = measure_and_print(
            &format!("{}: read reuse", name),
            random_data.len() as u64,
            || {
                let mut coded_input_stream = protobuf::CodedInputStream::from_bytes(&buf);
                let mut msg: M = Message::new();
                let mut count = 0;
                while !coded_input_stream.eof().unwrap() {
                    msg.clear();
                    coded_input_stream.merge_message(&mut msg).unwrap();
                    count += 1;
                }
                count
            },
        );

        assert_eq!(random_data.len(), merged);
    }

    fn test<M: Message + Clone + PartialEq>(&mut self, name: &str, data: &[M]) {
        if self.selected.as_ref().map(|s| *s == name).unwrap_or(true) {
            self.run_test(name, data);
            self.any_matched = true;
        }
    }

    fn check(&self) {
        if !self.any_matched {
            let name = self.selected.as_ref().map(|s| &s[..]).unwrap_or("bug");
            panic!("no tests found with name {}", name);
        }
    }
}

fn main() {
    let args = std::env::args().collect::<Vec<_>>();
    if args.len() > 3 {
        panic!("usage: {} [data_size] [test]", args[0])
    }
    let data_size = args
        .iter()
        .nth(1)
        .map(|x| x.parse().unwrap())
        .unwrap_or(1000000);
    let selected = args.iter().nth(2).cloned();

    let mut runner = TestRunner {
        selected: selected,
        any_matched: false,
        data_size: data_size,
    };

    let mut is = File::open(&Path::new("perftest_data.pbbin")).unwrap();
    let test_data = PerftestData::parse_from_reader(&mut is).unwrap();

    runner.test("test1", &test_data.test1);
    runner.test("test_repeated_bool", &test_data.test_repeated_bool);
    runner.test(
        "test_repeated_packed_int32",
        &test_data.test_repeated_packed_int32,
    );
    runner.test("test_repeated_messages", &test_data.test_repeated_messages);
    runner.test("test_optional_messages", &test_data.test_optional_messages);
    runner.test("test_strings", &test_data.test_strings);
    runner.test("test_small_bytearrays", &test_data.test_small_bytearrays);
    runner.test("test_large_bytearrays", &test_data.test_large_bytearrays);
    runner.check();
}
<commit_msg>Fix compilation<commit_after>use std::fs::File;
use std::path::Path;
use std::time::Instant;

use perftest_data::PerftestData;
use protobuf::Message;
use rand::Rng;
use rand::SeedableRng;
use rand::StdRng;

mod perftest_data;

fn measure_ns<R, F: FnMut() -> R>(mut f: F) -> (u64, R) {
    let start = Instant::now();
    let r = f();
    (start.elapsed().as_nanos() as u64, r)
}

fn measure_and_print<R, F: FnMut() -> R>(title: &str, iter: u64, f: F) -> R {
    let (ns, r) = measure_ns(f);
    let ns_per_iter = ns / iter;
    println!("{}: {} ns per iter", title, ns_per_iter);
    r
}

struct TestRunner {
    data_size: u32,
    selected: Option<String>,
    any_matched: bool,
}

impl TestRunner {
    fn run_test<M: Message + Clone + PartialEq>(&self, name: &str, data: &[M]) {
        assert!(data.len() > 0, "empty string for test: {}", name);

        let mut rng: StdRng = SeedableRng::from_seed([
            10, 20, 30, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0,
        ]);

        let mut random_data: Vec<M> = Vec::new();

        let mut total_size = 0;
        while total_size < self.data_size {
            let ref item = data[rng.gen_range(0, data.len())];
            random_data.push(item.clone());
            total_size += item.compute_size() as u32;
        }

        let mut buf = Vec::new();
        measure_and_print(
            &format!("{}: write", name),
            random_data.len() as u64,
            || {
                for m in &random_data {
                    m.write_length_delimited_to_vec(&mut buf).unwrap();
                }
            },
        );

        let read_data =
            measure_and_print(&format!("{}: read", name), random_data.len() as u64, || {
                let mut r = Vec::new();
                let mut coded_input_stream = protobuf::CodedInputStream::from_bytes(&buf);
                while !coded_input_stream.eof().unwrap() {
                    r.push(coded_input_stream.read_message().unwrap());
                }
                r
            });

        assert_eq!(random_data, read_data);

        let merged = measure_and_print(
            &format!("{}: read reuse", name),
            random_data.len() as u64,
            || {
                let mut coded_input_stream = protobuf::CodedInputStream::from_bytes(&buf);
                let mut msg: M = Message::new();
                let mut count = 0;
                while !coded_input_stream.eof().unwrap() {
                    msg.clear();
                    coded_input_stream.merge_message(&mut msg).unwrap();
                    count += 1;
                }
                count
            },
        );

        assert_eq!(random_data.len(), merged);
    }

    fn test<M: Message + Clone + PartialEq>(&mut self, name: &str, data: &[M]) {
        if self.selected.as_ref().map(|s| *s == name).unwrap_or(true) {
            self.run_test(name, data);
            self.any_matched = true;
        }
    }

    fn check(&self) {
        if !self.any_matched {
            let name = self.selected.as_ref().map(|s| &s[..]).unwrap_or("bug");
            panic!("no tests found with name {}", name);
        }
    }
}

fn main() {
    let args = std::env::args().collect::<Vec<_>>();
    if args.len() > 3 {
        panic!("usage: {} [data_size] [test]", args[0])
    }
    let data_size = args
        .iter()
        .nth(1)
        .map(|x| x.parse().unwrap())
        .unwrap_or(1000000);
    let selected = args.iter().nth(2).cloned();

    let mut runner = TestRunner {
        selected: selected,
        any_matched: false,
        data_size: data_size,
    };

    let mut is = File::open(&Path::new("perftest_data.pbbin")).unwrap();
    let test_data = PerftestData::parse_from_reader(&mut is).unwrap();

    runner.test("test1", &test_data.test1);
    runner.test("test_repeated_bool", &test_data.test_repeated_bool);
    runner.test(
        "test_repeated_packed_int32",
        &test_data.test_repeated_packed_int32,
    );
    runner.test("test_repeated_messages", &test_data.test_repeated_messages);
    runner.test("test_optional_messages", &test_data.test_optional_messages);
    runner.test("test_strings", &test_data.test_strings);
    runner.test("test_small_bytearrays", &test_data.test_small_bytearrays);
    runner.test("test_large_bytearrays", &test_data.test_large_bytearrays);
    runner.check();
}
<|endoftext|>


<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk 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 rgtk.  If not, see <http://www.gnu.org/licenses/>.

use ffi;
use glib::to_bool;
use FFIWidget;
use cast::GTK_RECENT_INFO;
use std::ptr;
use glib::translate::{FromGlibPtr, FromGlibPtrNotNull, FromGlibPtrContainer, ToGlibPtr};
use libc::c_char;

struct_Widget!(RecentInfo);

impl RecentInfo {
    pub fn _ref(&self) -> Option<RecentInfo> {
        let tmp_pointer = unsafe { ffi::gtk_recent_info_ref(GTK_RECENT_INFO(self.unwrap_widget())) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(::FFIWidget::wrap_widget(tmp_pointer as *mut ffi::C_GtkWidget))
        }
    }

    pub fn unref(&self) {
        unsafe { ffi::gtk_recent_info_unref(GTK_RECENT_INFO(self.unwrap_widget())) }
    }

    pub fn get_uri(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_uri(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_display_name(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_display_name(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_description(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_description(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_mime_type(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_mime_type(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_added(&self) -> i64 {
        unsafe { ffi::gtk_recent_info_get_added(GTK_RECENT_INFO(self.unwrap_widget())) }
    }

    pub fn get_modified(&self) -> i64 {
        unsafe { ffi::gtk_recent_info_get_modified(GTK_RECENT_INFO(self.unwrap_widget())) }
    }

    pub fn get_visited(&self) -> i64 {
        unsafe { ffi::gtk_recent_info_get_visited(GTK_RECENT_INFO(self.unwrap_widget())) }
    }

    pub fn get_private_hint(&self) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_get_private_hint(GTK_RECENT_INFO(self.unwrap_widget()))) }
    }

    pub fn get_application_info(&self, app_name: &str) -> Option<(String, u32, i64)> {
        unsafe {
            let mut app_exec = ptr::null();
            let mut count = 0u32;
            let mut time_ = 0i64;

            let ret = to_bool(
                ffi::gtk_recent_info_get_application_info(
                    GTK_RECENT_INFO(self.unwrap_widget()),
                    app_name.borrow_to_glib().0,
                    &mut app_exec,
                    &mut count,
                    &mut time_));

            if ret {
                let app_exec = FromGlibPtrNotNull::borrow(app_exec);
                Some((app_exec, count, time_))
            }
            else {
                None
            }
        }
    }

    pub fn get_applications(&self) -> Vec<String> {
        unsafe {
            let mut length = 0;
            let ptr = ffi::gtk_recent_info_get_applications(
                GTK_RECENT_INFO(self.unwrap_widget()),
                &mut length) as *const *const c_char;
            FromGlibPtrContainer::take_num(ptr, length as usize)
        }
    }

    pub fn last_application(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_last_application(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn has_application(&self, app_name: &str) -> bool {
        unsafe {
            to_bool(ffi::gtk_recent_info_has_application(GTK_RECENT_INFO(self.unwrap_widget()), app_name.borrow_to_glib().0))
        }
    }

    pub fn get_groups(&self) -> Vec<String> {
        unsafe {
            let mut length = 0;
            let ptr = ffi::gtk_recent_info_get_groups(
                GTK_RECENT_INFO(self.unwrap_widget()),
                &mut length) as *const *const c_char;
            FromGlibPtrContainer::take_num(ptr, length as usize)
        }
    }

    pub fn has_group(&self, group_name: &str) -> bool {
        unsafe {
            to_bool(
                ffi::gtk_recent_info_has_group(GTK_RECENT_INFO(self.unwrap_widget()),
                                               group_name.borrow_to_glib().0))
        }
    }

    pub fn get_short_name(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_short_name(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_uri_display(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_uri_display(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_age(&self) -> i32 {
        unsafe { ffi::gtk_recent_info_get_age(GTK_RECENT_INFO(self.unwrap_widget())) }
    }

    pub fn is_local(&self) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_is_local(GTK_RECENT_INFO(self.unwrap_widget()))) }
    }

    pub fn exists(&self) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_exists(GTK_RECENT_INFO(self.unwrap_widget()))) }
    }

    pub fn _match(&self, other: &RecentInfo) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_match(GTK_RECENT_INFO(self.unwrap_widget()), GTK_RECENT_INFO(other.unwrap_widget()))) }
    }
}

impl_drop!(RecentInfo);
impl_TraitWidget!(RecentInfo);

impl_widget_events!(RecentInfo);
<commit_msg>GtkRecentInfo: implement error handling, and cast time_t to u64.<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk 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 rgtk.  If not, see <http://www.gnu.org/licenses/>.

use ffi;
use glib::to_bool;
use FFIWidget;
use cast::GTK_RECENT_INFO;
use std::ptr;
use glib::translate::{FromGlibPtr, FromGlibPtrNotNull, FromGlibPtrContainer, ToGlibPtr};
use libc::c_char;

struct_Widget!(RecentInfo);

impl RecentInfo {
    pub fn _ref(&self) -> Option<RecentInfo> {
        let tmp_pointer = unsafe { ffi::gtk_recent_info_ref(GTK_RECENT_INFO(self.unwrap_widget())) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(::FFIWidget::wrap_widget(tmp_pointer as *mut ffi::C_GtkWidget))
        }
    }

    pub fn unref(&self) {
        unsafe { ffi::gtk_recent_info_unref(GTK_RECENT_INFO(self.unwrap_widget())) }
    }

    pub fn get_uri(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_uri(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_display_name(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_display_name(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_description(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_description(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_mime_type(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_mime_type(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_added(&self) -> Option<u64> {
        match unsafe { ffi::gtk_recent_info_get_added(GTK_RECENT_INFO(self.unwrap_widget())) } {
            x if x >= 0 => Some(x as u64),
            _ => None
        }
    }

    pub fn get_modified(&self) -> Option<u64> {
        match unsafe { ffi::gtk_recent_info_get_modified(GTK_RECENT_INFO(self.unwrap_widget())) } {
            x if x >= 0 => Some(x as u64),
            _ => None
        }
    }

    pub fn get_visited(&self) -> Option<u64> {
        match unsafe { ffi::gtk_recent_info_get_visited(GTK_RECENT_INFO(self.unwrap_widget())) } {
            x if x >= 0 => Some(x as u64),
            _ => None
        }
    }

    pub fn get_private_hint(&self) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_get_private_hint(GTK_RECENT_INFO(self.unwrap_widget()))) }
    }

    pub fn get_application_info(&self, app_name: &str) -> Option<(String, u32, u64)> {
        unsafe {
            let mut app_exec = ptr::null();
            let mut count = 0;
            let mut time_ = 0;

            match to_bool(ffi::gtk_recent_info_get_application_info(
                    GTK_RECENT_INFO(self.unwrap_widget()), app_name.borrow_to_glib().0,
                    &mut app_exec, &mut count, &mut time_)) {
                true => Some((FromGlibPtrNotNull::borrow(app_exec), count, time_ as u64)),
                _ => None
            }
        }
    }

    pub fn get_applications(&self) -> Vec<String> {
        unsafe {
            let mut length = 0;
            let ptr = ffi::gtk_recent_info_get_applications(
                GTK_RECENT_INFO(self.unwrap_widget()),
                &mut length) as *const *const c_char;
            FromGlibPtrContainer::take_num(ptr, length as usize)
        }
    }

    pub fn last_application(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_last_application(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn has_application(&self, app_name: &str) -> bool {
        unsafe {
            to_bool(ffi::gtk_recent_info_has_application(GTK_RECENT_INFO(self.unwrap_widget()), app_name.borrow_to_glib().0))
        }
    }

    pub fn get_groups(&self) -> Vec<String> {
        unsafe {
            let mut length = 0;
            let ptr = ffi::gtk_recent_info_get_groups(
                GTK_RECENT_INFO(self.unwrap_widget()),
                &mut length) as *const *const c_char;
            FromGlibPtrContainer::take_num(ptr, length as usize)
        }
    }

    pub fn has_group(&self, group_name: &str) -> bool {
        unsafe {
            to_bool(
                ffi::gtk_recent_info_has_group(GTK_RECENT_INFO(self.unwrap_widget()),
                                               group_name.borrow_to_glib().0))
        }
    }

    pub fn get_short_name(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_short_name(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_uri_display(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gtk_recent_info_get_uri_display(GTK_RECENT_INFO(self.unwrap_widget())))
        }
    }

    pub fn get_age(&self) -> i32 {
        unsafe { ffi::gtk_recent_info_get_age(GTK_RECENT_INFO(self.unwrap_widget())) }
    }

    pub fn is_local(&self) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_is_local(GTK_RECENT_INFO(self.unwrap_widget()))) }
    }

    pub fn exists(&self) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_exists(GTK_RECENT_INFO(self.unwrap_widget()))) }
    }

    pub fn _match(&self, other: &RecentInfo) -> bool {
        unsafe { to_bool(ffi::gtk_recent_info_match(GTK_RECENT_INFO(self.unwrap_widget()), GTK_RECENT_INFO(other.unwrap_widget()))) }
    }
}

impl_drop!(RecentInfo);
impl_TraitWidget!(RecentInfo);

impl_widget_events!(RecentInfo);
<|endoftext|>


<commit_before>
use std::sync::Mutex;
use std::ptr;
use rand;
use rand::distributions::{IndependentSample, Range};
use std::f32::consts;

#[derive(Clone, Copy)]
struct Particle {
    px : f32,
    py : f32,
    vx : f32,
    vy : f32,
    m  : f32
}

lazy_static! {
    static ref PARTICLES: Mutex<Vec<Particle>> = {
        Mutex::new(Vec::new())
    };
}

#[no_mangle]
pub extern fn nb_random_disk(num_particles: i32) -> () {
    // Place particles with random position and velocity in a disk in the center of the viewport

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let mut rng = rand::thread_rng();
    let vel  = Range::new(-3.5, 3.5);
    let mass = Range::new( 0.1, 1.5);
    let u    = Range::new( 0.0, 1.0);

    for _ in 0..num_particles {
        let mut x : f32 = u.ind_sample(&mut rng);
        let mut y : f32 = u.ind_sample(&mut rng);
        uniform_sample_disk(&mut x, &mut y);
        x *= 20.0;
        y *= 20.0;

        particles.push(Particle { px: x,
                                  py: y,
                                  vx: vel.ind_sample(&mut rng),
                                  vy: vel.ind_sample(&mut rng),
                                  m:  mass.ind_sample(&mut rng) });
    }
}

fn uniform_sample_disk(x: &mut f32, y: &mut f32) {
    let r = x.sqrt();
    let theta = 2.0 * consts::PI * (* y);
    * x = r * theta.cos();
    * y = r * theta.sin();
}

#[no_mangle]
pub extern fn nb_stable_orbits(num_particles: i32, rmin: f32, rmax: f32) -> () {
    // Generate a bunch of 'planets' with a circular orbit around a 'sun'
    //
    // References:
    //
    // http://www.cs.cmu.edu/~./ph/859E/src/nbody/circ.p2
    // www.cs.cmu.edu/~./ph/859E/src/nbody/nbody.cc

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let sun_mass    = 1000.0;
    let planet_mass = 1.0;
    let g : f32     = 1.0;
    let speed       = (g * sun_mass).sqrt();

    let mut rng     = rand::thread_rng();
    let u           = Range::new(0.0, 1.0);

    particles.push( Particle { px: 0.0, py: 0.0, vx: 0.0, vy: 0.0, m: sun_mass } );

    for _ in 0..num_particles {
        let r     = (rmax - rmin) * u.ind_sample(&mut rng) + rmin;
        let theta = 2.0 * consts::PI * u.ind_sample(&mut rng);
        particles.push( Particle { px: r * theta.cos(),
                                   py: r * theta.sin(),
                                   vx: -speed * theta.sin(),
                                   vy:  speed * theta.cos(),
                                   m: planet_mass });
    }
}

#[no_mangle]
pub extern fn nb_step() -> () {
    let mut particles_mtx = PARTICLES.lock().unwrap();

    // Compute forces
    let forces;
    {
        let particles = &(* particles_mtx);

        #[derive(Clone)]
        struct Force {
            fx : f32,
            fy : f32
        }
        let mut mforces = Vec::new();
        mforces.resize(particles.len(), Force { fx: 0.0, fy: 0.0 });

        for i in 0..particles.len() {
            let a = &particles[i];

            for j in 0..particles.len() {
                if i == j { continue; }

                let b = &particles[j];

                let dx = b.px - a.px;
                let dy = b.py - a.py;
                let dist = (dx * dx + dy * dy).sqrt();

                let eps = 0.00001; // Softening factor, prevent singularities
                let f = a.m * b.m / (dist * dist + eps);

                mforces[i].fx += f * dx; // / dist;
                mforces[i].fy += f * dy; // / dist;
            }
        }

        forces = mforces;
    }

    // Update positions and velocities
    {
        let mut particles = &mut (* particles_mtx);

        let dt = 0.01;

        for i in 0..particles.len() {
            particles[i].vx += dt * forces[i].fx / particles[i].m;
            particles[i].vy += dt * forces[i].fy / particles[i].m;

            particles[i].px += dt * particles[i].vx;
            particles[i].py += dt * particles[i].vy;
        }
    }
}

// TODO: Don't write scattered points to write combined memory

#[no_mangle]
pub extern fn nb_draw(w: i32, h: i32, fb: *mut u32) -> () {
    // Clear background
    unsafe { ptr::write_bytes(fb, 0, (w * h) as usize); }

    // Specify viewport over simulation to be mapped to the framebuffer
    let vp_wdh   = 100.0;
    let vp_org_x = 0.0;
    let vp_org_y = 0.0;

    // Keep full width of the viewport visible, adjust height as needed
    let aspect = h as f32 / w as f32;

    // Framebuffer viewport in simulation dimensions
    let x1 =  vp_org_x - vp_wdh / 2.0;
    let y1 = (vp_org_y - vp_wdh / 2.0) * aspect;
    let x2 =  vp_org_x + vp_wdh / 2.0;
    let y2 = (vp_org_y + vp_wdh / 2.0) * aspect;

    // Scale factor for translating from simulation to framebuffer
    let vpw    = x2 - x1;
    let vph    = y2 - y1;
    let scalex = (1.0 / vpw) * w as f32;
    let scaley = (1.0 / vph) * h as f32;

    let particles = PARTICLES.lock().unwrap();
    for p in &(*particles) {
        // Translate from simulation to viewport coordinates
        let x = ((p.px - x1) * scalex) as i32;
        let y = ((p.py - y1) * scaley) as i32;

        // Bounds check
        if x < 0 || x >= w || y < 0 || y >= h { continue; }

        // Draw particle
        let idx = x + y * w;
        unsafe {
            * fb.offset(idx as isize) = 0x00FFFFFF;
        }
    }

    // Debug draw center cross
    unsafe {
        * fb.offset((w / 2 + 0 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * fb.offset((w / 2 + 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * fb.offset((w / 2 + 0 + (h / 2 + 1) * w) as isize) = 0x00FF00FF;
        * fb.offset((w / 2 - 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * fb.offset((w / 2 + 0 + (h / 2 - 1) * w) as isize) = 0x00FF00FF;
    }
}

<commit_msg>Optional buffering for writing N-body particles to write combined memory<commit_after>
use std::sync::Mutex;
use std::ptr;
use rand;
use rand::distributions::{IndependentSample, Range};
use std::f32::consts;

#[derive(Clone, Copy)]
struct Particle {
    px : f32,
    py : f32,
    vx : f32,
    vy : f32,
    m  : f32
}

lazy_static! {
    static ref PARTICLES: Mutex<Vec<Particle>> = {
        Mutex::new(Vec::new())
    };
}

#[no_mangle]
pub extern fn nb_random_disk(num_particles: i32) -> () {
    // Place particles with random position and velocity in a disk in the center of the viewport

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let mut rng = rand::thread_rng();
    let vel  = Range::new(-3.5, 3.5);
    let mass = Range::new( 0.1, 1.5);
    let u    = Range::new( 0.0, 1.0);

    for _ in 0..num_particles {
        let mut x : f32 = u.ind_sample(&mut rng);
        let mut y : f32 = u.ind_sample(&mut rng);
        uniform_sample_disk(&mut x, &mut y);
        x *= 20.0;
        y *= 20.0;

        particles.push(Particle { px: x,
                                  py: y,
                                  vx: vel.ind_sample(&mut rng),
                                  vy: vel.ind_sample(&mut rng),
                                  m:  mass.ind_sample(&mut rng) });
    }
}

fn uniform_sample_disk(x: &mut f32, y: &mut f32) {
    let r = x.sqrt();
    let theta = 2.0 * consts::PI * (* y);
    * x = r * theta.cos();
    * y = r * theta.sin();
}

#[no_mangle]
pub extern fn nb_stable_orbits(num_particles: i32, rmin: f32, rmax: f32) -> () {
    // Generate a bunch of 'planets' with a circular orbit around a 'sun'
    //
    // References:
    //
    // http://www.cs.cmu.edu/~./ph/859E/src/nbody/circ.p2
    // www.cs.cmu.edu/~./ph/859E/src/nbody/nbody.cc

    let mut particles = PARTICLES.lock().unwrap();
    particles.clear();

    let sun_mass    = 1000.0;
    let planet_mass = 1.0;
    let g : f32     = 1.0;
    let speed       = (g * sun_mass).sqrt();

    let mut rng     = rand::thread_rng();
    let u           = Range::new(0.0, 1.0);

    particles.push( Particle { px: 0.0, py: 0.0, vx: 0.0, vy: 0.0, m: sun_mass } );

    for _ in 0..num_particles {
        let r     = (rmax - rmin) * u.ind_sample(&mut rng) + rmin;
        let theta = 2.0 * consts::PI * u.ind_sample(&mut rng);
        particles.push( Particle { px: r * theta.cos(),
                                   py: r * theta.sin(),
                                   vx: -speed * theta.sin(),
                                   vy:  speed * theta.cos(),
                                   m: planet_mass });
    }
}

#[no_mangle]
pub extern fn nb_step() -> () {
    let mut particles_mtx = PARTICLES.lock().unwrap();

    // Compute forces
    let forces;
    {
        let particles = &(* particles_mtx);

        #[derive(Clone)]
        struct Force {
            fx : f32,
            fy : f32
        }
        let mut mforces = Vec::new();
        mforces.resize(particles.len(), Force { fx: 0.0, fy: 0.0 });

        for i in 0..particles.len() {
            let a = &particles[i];

            for j in 0..particles.len() {
                if i == j { continue; }

                let b = &particles[j];

                let dx = b.px - a.px;
                let dy = b.py - a.py;
                let dist = (dx * dx + dy * dy).sqrt();

                let eps = 0.00001; // Softening factor, prevent singularities
                let f = a.m * b.m / (dist * dist + eps);

                mforces[i].fx += f * dx; // / dist;
                mforces[i].fy += f * dy; // / dist;
            }
        }

        forces = mforces;
    }

    // Update positions and velocities
    {
        let mut particles = &mut (* particles_mtx);

        let dt = 0.01;

        for i in 0..particles.len() {
            particles[i].vx += dt * forces[i].fx / particles[i].m;
            particles[i].vy += dt * forces[i].fy / particles[i].m;

            particles[i].px += dt * particles[i].vx;
            particles[i].py += dt * particles[i].vy;
        }
    }
}

#[no_mangle]
pub extern fn nb_draw(w: i32, h: i32, fb: *mut u32) -> () {
    // If writing scattered points to write combined memory turns out to be a problem,
    // enabled buffering
    let buffer = false;

    if !buffer {
        // Clear background
        unsafe { ptr::write_bytes(fb, 0, (w * h) as usize); }
    }

    // Specify viewport over simulation to be mapped to the framebuffer
    let vp_wdh   = 100.0;
    let vp_org_x = 0.0;
    let vp_org_y = 0.0;

    // Keep full width of the viewport visible, adjust height as needed
    let aspect = h as f32 / w as f32;

    // Framebuffer viewport in simulation dimensions
    let x1 =  vp_org_x - vp_wdh / 2.0;
    let y1 = (vp_org_y - vp_wdh / 2.0) * aspect;
    let x2 =  vp_org_x + vp_wdh / 2.0;
    let y2 = (vp_org_y + vp_wdh / 2.0) * aspect;

    // Scale factor for translating from simulation to framebuffer
    let vpw    = x2 - x1;
    let vph    = y2 - y1;
    let scalex = (1.0 / vpw) * w as f32;
    let scaley = (1.0 / vph) * h as f32;

    // Optionally allocate buffer
    let buf_ptr;
    if buffer {
        let mut buf = Vec::new();
        buf.resize((w * h) as usize, 0u32);
        buf_ptr = buf.as_mut_ptr();
    } else {
        buf_ptr = fb;
    }

    let particles = PARTICLES.lock().unwrap();
    for p in &(*particles) {
        // Translate from simulation to viewport coordinates
        let x = ((p.px - x1) * scalex) as i32;
        let y = ((p.py - y1) * scaley) as i32;

        // Bounds check
        if x < 0 || x >= w || y < 0 || y >= h { continue; }

        // Draw particle
        let idx = x + y * w;
        unsafe {
            * buf_ptr.offset(idx as isize) = 0x00FFFFFF;
        }
    }

    // Debug draw center cross
    unsafe {
        * buf_ptr.offset((w / 2 + 0 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 0 + (h / 2 + 1) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 - 1 + (h / 2 + 0) * w) as isize) = 0x00FF00FF;
        * buf_ptr.offset((w / 2 + 0 + (h / 2 - 1) * w) as isize) = 0x00FF00FF;
    }

    // Output in one contiguous copy
    if buffer {
        unsafe { ptr::copy_nonoverlapping(buf_ptr, fb, (w * h) as usize); }
    }
}

<|endoftext|>


<commit_before>#[ path="../functional.rs"] mod functional;
#[ path="helpers.rs"]       mod helpers;
#[ path="shellprocess.rs"]  mod shellprocess;
#[ path="parser.rs"]        mod parser;

pub mod shell {
    use std::run::Process;
    use std::os;
    use std::io::{stdin, stdout, stdio};
    use std::io::buffered::BufferedReader;
    use std::io::signal::{Listener, Interrupt};
    use std::task::try;

    use std::libc::consts::os::posix88::{STDOUT_FILENO, STDIN_FILENO};
    use std::libc::types::os::arch::posix88::pid_t;
    use std::libc;

    use helpers::helpers::{split_words, input_redirect, output_redirect, pipe_redirect};
    use functional::borrowed_maybe;
    use shellprocess::fg::FgProcess;
    use shellprocess::bg::BgProcess;
    use parser::cmd::Cmd;
    use parser::pathtype::{Read, Write};

    extern {
        pub fn kill(pid: pid_t, sig: libc::c_int) -> libc::c_int;
    }

    pub struct Shell {
        cmd_prompt : ~str,
        history    : ~[~str],
        processes  : ~[~BgProcess],
        broken : bool,
    }

    impl Shell {
        pub fn new(prompt_str: &str) -> Shell {
            Shell {
                cmd_prompt: prompt_str.to_owned(),
                history: ~[],
                processes: ~[],
                broken: false,
            }
        }

        // Start the shell with an interrupt handler. Only needed when
        // an interactive shell is used.
        pub fn start(&mut self) {
            // Setup the interrupt handler. Has to happen here, or it won't
            // retain control over interrupts.
            let mut listener = Listener::new();
            listener.register(Interrupt);
            let port = listener.port;
            spawn(proc() {
                try(proc() {
                    loop {
                        match port.recv_opt() {
                            Some(Interrupt) => {
                            }
                            None => {
                                break;
                            }
                            _ => {
                            }
                        }
                    }
                    return 0
                });
                return ();
            });
            self.display_prompt();
        }

        // Show the prompt. If called by itself, without start(), no interrupt
        // handling will occur.
        fn display_prompt(&mut self) {
            // Standard input reader
            let mut stdin = BufferedReader::new(stdin());
            // Show the prompt
            print(self.cmd_prompt);
            stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");
            self.disown_dead();

            match program {
                "" =>  {
                    self.display_prompt();
                }
                "exit" =>  {
                    self.kill_all();
                }
                "history" => {
                    self.show_hist();
                    self.display_prompt();
                }
                "jobs" => {
                    self.push_hist(cmd_line);
                    self.jobs();
                    self.display_prompt();
                }
                "cd" =>  {
                    self.push_hist(cmd_line);
                    self.chdir(cmd_line);
                    self.display_prompt();
                }
                _ => {
                    self.push_hist(cmd_line);
                    self.run_cmdline(cmd_line);
                    self.display_prompt();
                }
            }
        }

        fn run(&mut self, elem : ~Cmd) -> Option<~Process> {
            if elem.pipe.is_some() {
                let left = self.parse_process(elem.clone(), None, None).expect("Couldn't spawn!");
                Some(elem.iter().fold(left, |left, right| {
                    let right = self.pipe_file(right).expect("Couldn't spawn!");
                    pipe_redirect(left,right)
                }))
            }
            else {
                self.pipe_file(elem)
            }
        }

        // "Pipe" output to or from a file. If no file is available, just return
        // the created process.
        fn pipe_file(&mut self, elem : ~Cmd) -> Option<~Process> {
            match elem.clone().file {
                Some(file) => {
                    match file.mode {
                        Read => {
                            let process = self.to_process(elem).expect("Couldn't spawn!");
                            Some(input_redirect(process, &file.path))
                        }
                        Write => {
                            let process = self.parse_process(elem, None, None).expect("Couldn't spawn!");
                            output_redirect(process, &file.path);
                            None
                        }
                    }
                }
                None => {
                    self.to_process(elem)
                }
            }
        }

        // Make a process from a Cmd. Sets the output to stdout if the "last"
        // field is true.
        fn to_process(&mut self, elem : ~Cmd) -> Option<~Process> {
                self.parse_process(elem.clone(),
                                None,
                                if elem.last { Some(STDOUT_FILENO) }
                                else { None })
        }

        // Determine the type of the current block, and send it to the right
        // parsing function.
        pub fn run_cmdline(&mut self, cmd_line: &str) {
            let cmd = Cmd::new(cmd_line);
            if cmd.pipe.is_none() && cmd.file.is_none() {
                self.parse_process(cmd, Some(STDIN_FILENO), Some(STDOUT_FILENO));
            }
            else {
                self.run(cmd);
            }
        }

        // Parse a new lone process. Background/foreground it appropriately.
        fn parse_process(&mut self,
                        cmd: ~Cmd,
                        stdin: Option<i32>,
                        stdout:Option<i32>)
                        -> Option<~Process> {
            if (cmd.argv.len() > 0 && cmd.argv.last() == &~"&") {
                let mut argv = cmd.argv.to_owned();
                argv.pop();
                self.make_bg_process(cmd);
                None
            }
            else {
                Some(~(FgProcess::new(cmd, stdin, stdout).run()))
            }
        }

        // background processes.
        fn make_bg_process(&mut self, cmd : ~Cmd) {
            let name = cmd.program.to_owned();
            let mut process = BgProcess::new(cmd);
            match process.run() {
                Some(pid) => {
                    println!("{:s} {:i}", name, pid);
                    self.processes.push(~process);
                }
                None => {
                }
            }
        }

        // Nice extra feature: list running jobs.
        fn jobs(&mut self) {
            for cmd in self.processes.iter() {
                print!("{:s}", cmd.command);
                match cmd.pid {
                    Some(pid) => {
                        println!(" {:i}", pid);
                    }
                    None => {
                        println("");
                    }
                }
            }
        }

        // Remove dead processes from the list of processes.
        fn disown_dead(&mut self) {
            let mut dead : ~[uint];
            dead = ~[];
            let mut i = 0;
            for cmd in self.processes.iter() {
                borrowed_maybe(&cmd.exit_port, |port| match port.try_recv() {
                    Some(_) => {dead.push(i); Some(i)},
                    _ => None,
                });
                i += 1;
            }
            for &p in dead.iter() {
                self.processes.remove(p);
            }
        }

        // Kill all the background jobs. Used when "exit" is called at the CLI.
        fn kill_all(&mut self) {
            for p in self.processes.iter() {
                match p.pid {
                    Some(pid) => {
                        unsafe {
                            // Kill perhaps isn't the best way to do this, but
                            // without it we have no way of killing our background
                            // processes with only the PID - we'd need the process
                            // object itself, and that can't be moved out of the
                            // spawn() that it's trapped inside.
                            kill(pid, 15);
                        }
                    }
                    None => {
                    }
                }
            }
        }

        // Push a new command onto history.
        fn push_hist(&mut self, cmd_line: &str) {
            &self.history.push(cmd_line.to_owned());
        }

        // Show the history.
        fn show_hist(&mut self) {
            let mut hist = ~"";
            for i in self.history.iter() {
                let s = i.to_owned();
                match hist {
                    ~"" => { hist = s; }
                    _   => { hist = hist + "\n" + s; }
                }
            }
            println!("{:s}", hist);
        }

        // Change directories.
        fn chdir(&mut self, cmd_line: &str) {
            let mut argv: ~[~str] = split_words(cmd_line);
            if argv.len() > 0 {
                argv.remove(0);
                let path = Path::new(argv[0]);
                os::change_dir(&path);
            }
        }
    }
}
<commit_msg>rearrange imports<commit_after>#[ path="../functional.rs"] mod functional;
#[ path="helpers.rs"]       mod helpers;
#[ path="shellprocess.rs"]  mod shellprocess;
#[ path="parser.rs"]        mod parser;

pub mod shell {
    use std::run::Process;
    use std::os;
    use std::io::{stdin, stdout, stdio};
    use std::io::buffered::BufferedReader;
    use std::io::signal::{Listener, Interrupt};
    use std::task::try;

    use helpers::helpers::{split_words, input_redirect, output_redirect, pipe_redirect};
    use functional::borrowed_maybe;
    use shellprocess::fg::FgProcess;
    use shellprocess::bg::BgProcess;
    use parser::cmd::Cmd;
    use parser::pathtype::{Read, Write};

    use std::libc::consts::os::posix88::{STDOUT_FILENO, STDIN_FILENO};
    use std::libc::types::os::arch::posix88::pid_t;
    use std::libc;

    extern {
        pub fn kill(pid: pid_t, sig: libc::c_int) -> libc::c_int;
    }

    pub struct Shell {
        cmd_prompt : ~str,
        history    : ~[~str],
        processes  : ~[~BgProcess],
        broken : bool,
    }

    impl Shell {
        pub fn new(prompt_str: &str) -> Shell {
            Shell {
                cmd_prompt: prompt_str.to_owned(),
                history: ~[],
                processes: ~[],
                broken: false,
            }
        }

        // Start the shell with an interrupt handler. Only needed when
        // an interactive shell is used.
        pub fn start(&mut self) {
            // Setup the interrupt handler. Has to happen here, or it won't
            // retain control over interrupts.
            let mut listener = Listener::new();
            listener.register(Interrupt);
            let port = listener.port;
            spawn(proc() {
                try(proc() {
                    loop {
                        match port.recv_opt() {
                            Some(Interrupt) => {
                            }
                            None => {
                                break;
                            }
                            _ => {
                            }
                        }
                    }
                    return 0
                });
                return ();
            });
            self.display_prompt();
        }

        // Show the prompt. If called by itself, without start(), no interrupt
        // handling will occur.
        fn display_prompt(&mut self) {
            // Standard input reader
            let mut stdin = BufferedReader::new(stdin());
            // Show the prompt
            print(self.cmd_prompt);
            stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");
            self.disown_dead();

            match program {
                "" =>  {
                    self.display_prompt();
                }
                "exit" =>  {
                    self.kill_all();
                }
                "history" => {
                    self.show_hist();
                    self.display_prompt();
                }
                "jobs" => {
                    self.push_hist(cmd_line);
                    self.jobs();
                    self.display_prompt();
                }
                "cd" =>  {
                    self.push_hist(cmd_line);
                    self.chdir(cmd_line);
                    self.display_prompt();
                }
                _ => {
                    self.push_hist(cmd_line);
                    self.run_cmdline(cmd_line);
                    self.display_prompt();
                }
            }
        }

        fn run(&mut self, elem : ~Cmd) -> Option<~Process> {
            if elem.pipe.is_some() {
                let left = self.parse_process(elem.clone(), None, None).expect("Couldn't spawn!");
                Some(elem.iter().fold(left, |left, right| {
                    let right = self.pipe_file(right).expect("Couldn't spawn!");
                    pipe_redirect(left,right)
                }))
            }
            else {
                self.pipe_file(elem)
            }
        }

        // "Pipe" output to or from a file. If no file is available, just return
        // the created process.
        fn pipe_file(&mut self, elem : ~Cmd) -> Option<~Process> {
            match elem.clone().file {
                Some(file) => {
                    match file.mode {
                        Read => {
                            let process = self.to_process(elem).expect("Couldn't spawn!");
                            Some(input_redirect(process, &file.path))
                        }
                        Write => {
                            let process = self.parse_process(elem, None, None).expect("Couldn't spawn!");
                            output_redirect(process, &file.path);
                            None
                        }
                    }
                }
                None => {
                    self.to_process(elem)
                }
            }
        }

        // Make a process from a Cmd. Sets the output to stdout if the "last"
        // field is true.
        fn to_process(&mut self, elem : ~Cmd) -> Option<~Process> {
                self.parse_process(elem.clone(),
                                None,
                                if elem.last { Some(STDOUT_FILENO) }
                                else { None })
        }

        // Determine the type of the current block, and send it to the right
        // parsing function.
        pub fn run_cmdline(&mut self, cmd_line: &str) {
            let cmd = Cmd::new(cmd_line);
            if cmd.pipe.is_none() && cmd.file.is_none() {
                self.parse_process(cmd, Some(STDIN_FILENO), Some(STDOUT_FILENO));
            }
            else {
                self.run(cmd);
            }
        }

        // Parse a new lone process. Background/foreground it appropriately.
        fn parse_process(&mut self,
                        cmd: ~Cmd,
                        stdin: Option<i32>,
                        stdout:Option<i32>)
                        -> Option<~Process> {
            if (cmd.argv.len() > 0 && cmd.argv.last() == &~"&") {
                let mut argv = cmd.argv.to_owned();
                argv.pop();
                self.make_bg_process(cmd);
                None
            }
            else {
                Some(~(FgProcess::new(cmd, stdin, stdout).run()))
            }
        }

        // background processes.
        fn make_bg_process(&mut self, cmd : ~Cmd) {
            let name = cmd.program.to_owned();
            let mut process = BgProcess::new(cmd);
            match process.run() {
                Some(pid) => {
                    println!("{:s} {:i}", name, pid);
                    self.processes.push(~process);
                }
                None => {
                }
            }
        }

        // Nice extra feature: list running jobs.
        fn jobs(&mut self) {
            for cmd in self.processes.iter() {
                print!("{:s}", cmd.command);
                match cmd.pid {
                    Some(pid) => {
                        println!(" {:i}", pid);
                    }
                    None => {
                        println("");
                    }
                }
            }
        }

        // Remove dead processes from the list of processes.
        fn disown_dead(&mut self) {
            let mut dead : ~[uint];
            dead = ~[];
            let mut i = 0;
            for cmd in self.processes.iter() {
                borrowed_maybe(&cmd.exit_port, |port| match port.try_recv() {
                    Some(_) => {dead.push(i); Some(i)},
                    _ => None,
                });
                i += 1;
            }
            for &p in dead.iter() {
                self.processes.remove(p);
            }
        }

        // Kill all the background jobs. Used when "exit" is called at the CLI.
        fn kill_all(&mut self) {
            for p in self.processes.iter() {
                match p.pid {
                    Some(pid) => {
                        unsafe {
                            // Kill perhaps isn't the best way to do this, but
                            // without it we have no way of killing our background
                            // processes with only the PID - we'd need the process
                            // object itself, and that can't be moved out of the
                            // spawn() that it's trapped inside.
                            kill(pid, 15);
                        }
                    }
                    None => {
                    }
                }
            }
        }

        // Push a new command onto history.
        fn push_hist(&mut self, cmd_line: &str) {
            &self.history.push(cmd_line.to_owned());
        }

        // Show the history.
        fn show_hist(&mut self) {
            let mut hist = ~"";
            for i in self.history.iter() {
                let s = i.to_owned();
                match hist {
                    ~"" => { hist = s; }
                    _   => { hist = hist + "\n" + s; }
                }
            }
            println!("{:s}", hist);
        }

        // Change directories.
        fn chdir(&mut self, cmd_line: &str) {
            let mut argv: ~[~str] = split_words(cmd_line);
            if argv.len() > 0 {
                argv.remove(0);
                let path = Path::new(argv[0]);
                os::change_dir(&path);
            }
        }
    }
}
<|endoftext|>


<commit_before>//! The integration suite for inspecting sessions.

extern crate libc;
extern crate rand;
extern crate regex;

mod helpers;

mod open {
    use rand::{random};
    use std::fs::File;
    use std::fs;
    use std::path::PathBuf;
    use std::io::prelude::*;
    use helpers::*;
    use std::thread::sleep;
    use std::time::Duration;

    fn setup(contents: &'static [u8]) -> (String, PathBuf) {
        let project_name = format!("muxed_int_test_{}", random::<u16>());
        let project_file = format!("/tmp/muxed_{}/{}.yml", random::<u16>(), project_name);
        let project_path = PathBuf::from(&project_file);

        let muxed_path = project_path.parent().unwrap();
        if !muxed_path.exists() { println!("{:?}", fs::create_dir(muxed_path)) };

        let mut buffer = File::create(&project_path).unwrap();
        let _ = buffer.write(contents);

        (project_name, project_path.clone())
    }

    fn cleanup(project_name: &String, config_path: &PathBuf) -> () {
        let _ = fs::remove_file(config_path);
        let _ = fs::remove_dir(config_path.parent().unwrap());
        kill_session(&project_name);
    }

    fn test_with_contents(contents: &'static [u8]) -> TmuxSession {
        let (project_name, config_path) = setup(contents);
        open_muxed(&project_name, config_path.parent().unwrap());
        // Needed as send-keys commands may not be finished executing when we go
        // to introspect. In the future make all test templates touch a named
        // .finished file in the last pane/window. Loop until the file exists.
        // Once it is found we know it's time for inspection. This is better
        // than sleeping as we may sleep longer than needed. Especially for
        // tests that don't require the wait time at all.
        sleep(Duration::from_millis(800));
        let session = TmuxSession::from_string(&list_windows(&project_name.to_string()));
        cleanup(&project_name, &config_path);
        session
    }

    #[test]
    fn opens_3_windows_from_array() {
        let contents = b"---
windows: ['vi', 'ls', 'git']
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn opens_2_windows() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
  - stuff: ''
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 2)
    }

    #[test]
    fn opens_3_windows_with_integer_names() {
        let contents = b"---
windows: [1, 'ls', 3]
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn single_window_has_2_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn multiple_windows_with_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
  - tests:
      layout: 'main-vertical'
      panes: ['vi', 'ls', 'ls']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        let num1 = session.windows.get("tests").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2);
        assert_eq!(num1, 3)
    }

    #[test]
    fn window_with_empty_command_is_valid() {
        let contents = b"---
windows:
  - editor:
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 1)
    }

    #[test]
    fn panes_with_empty_commands_are_valid() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes:
        -
        -
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn expect_to_open_in_directory_containing_spaces() {
        let dir = PathBuf::from("/tmp/Directory With Spaces/");
        if !dir.exists() { println!("{:?}", fs::create_dir(&dir)) };
        let contents = b"---
root: /tmp/Directory With Spaces/
windows:
  - editor: ''
";
        let session = test_with_contents(contents);
        let active_dir = session.active_dir;
        let _ = fs::remove_dir(dir);
        assert_eq!(active_dir, "/tmp/Directory With Spaces");
    }
}
<commit_msg>Timing issues in Travis.<commit_after>//! The integration suite for inspecting sessions.

extern crate libc;
extern crate rand;
extern crate regex;

mod helpers;

mod open {
    use rand::{random};
    use std::fs::File;
    use std::fs;
    use std::path::PathBuf;
    use std::io::prelude::*;
    use helpers::*;
    use std::thread::sleep;
    use std::time::Duration;

    fn setup(contents: &'static [u8]) -> (String, PathBuf) {
        let project_name = format!("muxed_int_test_{}", random::<u16>());
        let project_file = format!("/tmp/muxed_{}/{}.yml", random::<u16>(), project_name);
        let project_path = PathBuf::from(&project_file);

        let muxed_path = project_path.parent().unwrap();
        if !muxed_path.exists() { println!("{:?}", fs::create_dir(muxed_path)) };

        let mut buffer = File::create(&project_path).unwrap();
        let _ = buffer.write(contents);

        (project_name, project_path.clone())
    }

    fn cleanup(project_name: &String, config_path: &PathBuf) -> () {
        let _ = fs::remove_file(config_path);
        let _ = fs::remove_dir(config_path.parent().unwrap());
        kill_session(&project_name);
    }

    fn test_with_contents(contents: &'static [u8]) -> TmuxSession {
        let (project_name, config_path) = setup(contents);
        open_muxed(&project_name, config_path.parent().unwrap());
        // Needed as send-keys commands may not be finished executing when we go
        // to introspect. In the future make all test templates touch a named
        // .finished file in the last pane/window. Loop until the file exists.
        // Once it is found we know it's time for inspection. This is better
        // than sleeping as we may sleep longer than needed. Especially for
        // tests that don't require the wait time at all.
        sleep(Duration::new(1,0));
        let session = TmuxSession::from_string(&list_windows(&project_name.to_string()));
        cleanup(&project_name, &config_path);
        session
    }

    #[test]
    fn opens_3_windows_from_array() {
        let contents = b"---
windows: ['vi', 'ls', 'git']
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn opens_2_windows() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
  - stuff: ''
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 2)
    }

    #[test]
    fn opens_3_windows_with_integer_names() {
        let contents = b"---
windows: [1, 'ls', 3]
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn single_window_has_2_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn multiple_windows_with_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
  - tests:
      layout: 'main-vertical'
      panes: ['vi', 'ls', 'ls']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        let num1 = session.windows.get("tests").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2);
        assert_eq!(num1, 3)
    }

    #[test]
    fn window_with_empty_command_is_valid() {
        let contents = b"---
windows:
  - editor:
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 1)
    }

    #[test]
    fn panes_with_empty_commands_are_valid() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes:
        -
        -
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn expect_to_open_in_directory_containing_spaces() {
        let dir = PathBuf::from("/tmp/Directory With Spaces/");
        if !dir.exists() { println!("{:?}", fs::create_dir(&dir)) };
        let contents = b"---
root: /tmp/Directory With Spaces/
windows:
  - editor: ''
";
        let session = test_with_contents(contents);
        let active_dir = session.active_dir;
        let _ = fs::remove_dir(dir);
        assert_eq!(active_dir, "/tmp/Directory With Spaces");
    }
}
<|endoftext|>


<commit_before>#![allow(unstable)]

#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;

lazy_static! {
    static ref NUMBER: u32 = times_two(3);
    static ref ARRAY_BOXES: [Box<u32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];
    static ref STRING: String = "hello".to_string();
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "abc");
        m.insert(1, "def");
        m.insert(2, "ghi");
        m
    };
    // This *should* triggger warn(dead_code) by design.
    static ref UNUSED: () = ();
}

fn times_two(n: u32) -> u32 {
    n * 2
}

#[test]
fn test_basic() {
    assert_eq!(&STRING[..], "hello");
    assert_eq!(*NUMBER, 6);
    assert!(HASHMAP.get(&1).is_some());
    assert!(HASHMAP.get(&3).is_none());
    assert_eq!(&ARRAY_BOXES[..], &[Box::new(1), Box::new(2), Box::new(3)][..]);
}

#[test]
fn test_repeat() {
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
}

mod visibility {
    lazy_static! {
        pub static ref FOO: Box<u32> = Box::new(0);
    }
}

#[test]
fn test_visibility() {
    assert_eq!(*visibility::FOO, Box::new(0));
}

// This should not cause a warning about a missing Copy implementation
lazy_static! {
    pub static ref VAR: i32 = { 0 };
}
<commit_msg>This line appears unnecessary.  It was emitting the following warning:<commit_after>#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;

lazy_static! {
    static ref NUMBER: u32 = times_two(3);
    static ref ARRAY_BOXES: [Box<u32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];
    static ref STRING: String = "hello".to_string();
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "abc");
        m.insert(1, "def");
        m.insert(2, "ghi");
        m
    };
    // This *should* triggger warn(dead_code) by design.
    static ref UNUSED: () = ();
}

fn times_two(n: u32) -> u32 {
    n * 2
}

#[test]
fn test_basic() {
    assert_eq!(&STRING[..], "hello");
    assert_eq!(*NUMBER, 6);
    assert!(HASHMAP.get(&1).is_some());
    assert!(HASHMAP.get(&3).is_none());
    assert_eq!(&ARRAY_BOXES[..], &[Box::new(1), Box::new(2), Box::new(3)][..]);
}

#[test]
fn test_repeat() {
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
}

mod visibility {
    lazy_static! {
        pub static ref FOO: Box<u32> = Box::new(0);
    }
}

#[test]
fn test_visibility() {
    assert_eq!(*visibility::FOO, Box::new(0));
}

// This should not cause a warning about a missing Copy implementation
lazy_static! {
    pub static ref VAR: i32 = { 0 };
}
<|endoftext|>