<commit_before>extern crate difflib;

use difflib::differ::Differ;
use difflib::sequencematcher::{Match, Opcode, SequenceMatcher};

#[test]
fn test_longest_match() {
    let matcher = SequenceMatcher::new(" abcd", "abcd abcd");
    let m = matcher.find_longest_match(0, 5, 0, 9);
    assert_eq!(m.first_start, 0);
    assert_eq!(m.second_start, 4);
    assert_eq!(m.size, 5);
}

#[test]
fn test_all_matches() {
    let mut matcher = SequenceMatcher::new("abxcd", "abcd");
    let result = matcher.get_matching_blocks();
    let mut expected_result = Vec::new();
    expected_result.push(Match {
        first_start: 0,
        second_start: 0,
        size: 2,
    });
    expected_result.push(Match {
        first_start: 3,
        second_start: 2,
        size: 2,
    });
    expected_result.push(Match {
        first_start: 5,
        second_start: 4,
        size: 0,
    });
    assert_eq!(result, expected_result);
}

#[test]
fn test_get_opcodes() {
    let mut matcher = SequenceMatcher::new("qabxcd", "abycdf");
    let result = matcher.get_opcodes();
    let mut expected_result = Vec::new();
    expected_result.push(Opcode {
        tag: "delete".to_string(),
        first_start: 0,
        first_end: 1,
        second_start: 0,
        second_end: 0,
    });
    expected_result.push(Opcode {
        tag: "equal".to_string(),
        first_start: 1,
        first_end: 3,
        second_start: 0,
        second_end: 2,
    });
    expected_result.push(Opcode {
        tag: "replace".to_string(),
        first_start: 3,
        first_end: 4,
        second_start: 2,
        second_end: 3,
    });
    expected_result.push(Opcode {
        tag: "equal".to_string(),
        first_start: 4,
        first_end: 6,
        second_start: 3,
        second_end: 5,
    });
    expected_result.push(Opcode {
        tag: "insert".to_string(),
        first_start: 6,
        first_end: 6,
        second_start: 5,
        second_end: 6,
    });
    assert_eq!(result, expected_result);
}

#[test]
fn test_ratio() {
    let mut matcher = SequenceMatcher::new("abcd", "bcde");
    assert_eq!(matcher.ratio(), 0.75);
}

#[test]
fn test_get_close_matches() {
    let words = vec!["ape", "apple", "peach", "puppy"];
    let result = difflib::get_close_matches("appel", words, 3, 0.6);
    assert_eq!(result, vec!["apple", "ape"]);
}

#[test]
fn test_differ_compare() {
    let first_text = vec!["one\n", "two\n", "three\n"];
    let second_text = vec!["ore\n", "tree\n", "emu\n"];
    let differ = Differ::new();
    let result = differ.compare(&first_text, &second_text).join("");
    assert_eq!(
        result,
        "- one\n?  ^\n+ ore\n?  ^\n- two\n- three\n?  -\n+ tree\n+ emu\n"
    );
}

fn is_junk_char(ch: &char) -> bool {
    if *ch == ' ' || *ch == '\t' {
        return true;
    }
    false
}

#[test]
fn test_differ_compare_with_func() {
    let first_text = vec!["one\n", "two\n", "three\n"];
    let second_text = vec!["ore\n", "tree\n", "emu\n"];
    let mut differ = Differ::new();
    differ.char_junk = Some(is_junk_char);
    let result = differ.compare(&first_text, &second_text).join("");
    assert_eq!(
        result,
        "- one\n?  ^\n+ ore\n?  ^\n- two\n- three\n?  -\n+ tree\n+ emu\n"
    );
}

#[test]
fn test_differ_restore() {
    let first_text = vec!["one\n", "  two\n", "three\n"];
    let second_text = vec!["ore\n", "tree\n", "emu\n"];
    let differ = Differ::new();
    let diff = differ.compare(&first_text, &second_text);
    assert_eq!(first_text, Differ::restore(&diff, 1));
    assert_eq!(second_text, Differ::restore(&diff, 2));
}

#[test]
fn test_unified_diff() {
    let first_text = "one two three four".split(" ").collect::<Vec<&str>>();
    let second_text = "zero one tree four".split(" ").collect::<Vec<&str>>();
    let result = difflib::unified_diff(
        &first_text,
        &second_text,
        "Original",
        "Current",
        "2005-01-26 23:30:50",
        "2010-04-02 10:20:52",
        3,
    ).join("");
    assert_eq!(
        result,
        "--- Original\t2005-01-26 23:30:50\n+++ Current\t2010-04-02 10:20:52\n@@ -1,4 \
         +1,4 @@\n+zero one-two-three+tree four"
    );
}

#[test]
fn test_context_diff() {
    let first_text = "one two three four".split(" ").collect::<Vec<&str>>();
    let second_text = "zero one tree four".split(" ").collect::<Vec<&str>>();
    let result = difflib::context_diff(
        &first_text,
        &second_text,
        "Original",
        "Current",
        "2005-01-26 23:30:50",
        "2010-04-02 10:20:52",
        3,
    ).join("");
    assert_eq!(
        result,
        "*** Original\t2005-01-26 23:30:50\n--- Current\t2010-04-02 \
         10:20:52\n***************\n*** 1,4 ****\n  one! two! three  four--- 1,4 ----\n+ \
         zero  one! tree  four"
    );
}
<commit_msg>Test SequenceMatcher with integer slices<commit_after>extern crate difflib;

use difflib::differ::Differ;
use difflib::sequencematcher::{Match, Opcode, SequenceMatcher};

#[test]
fn test_longest_match() {
    let matcher = SequenceMatcher::new(" abcd", "abcd abcd");
    let m = matcher.find_longest_match(0, 5, 0, 9);
    assert_eq!(m.first_start, 0);
    assert_eq!(m.second_start, 4);
    assert_eq!(m.size, 5);
}

#[test]
fn test_all_matches() {
    let mut matcher = SequenceMatcher::new("abxcd", "abcd");
    let result = matcher.get_matching_blocks();
    let mut expected_result = Vec::new();
    expected_result.push(Match {
        first_start: 0,
        second_start: 0,
        size: 2,
    });
    expected_result.push(Match {
        first_start: 3,
        second_start: 2,
        size: 2,
    });
    expected_result.push(Match {
        first_start: 5,
        second_start: 4,
        size: 0,
    });
    assert_eq!(result, expected_result);
}

#[test]
fn test_get_opcodes() {
    let mut matcher = SequenceMatcher::new("qabxcd", "abycdf");
    let result = matcher.get_opcodes();
    let mut expected_result = Vec::new();
    expected_result.push(Opcode {
        tag: "delete".to_string(),
        first_start: 0,
        first_end: 1,
        second_start: 0,
        second_end: 0,
    });
    expected_result.push(Opcode {
        tag: "equal".to_string(),
        first_start: 1,
        first_end: 3,
        second_start: 0,
        second_end: 2,
    });
    expected_result.push(Opcode {
        tag: "replace".to_string(),
        first_start: 3,
        first_end: 4,
        second_start: 2,
        second_end: 3,
    });
    expected_result.push(Opcode {
        tag: "equal".to_string(),
        first_start: 4,
        first_end: 6,
        second_start: 3,
        second_end: 5,
    });
    expected_result.push(Opcode {
        tag: "insert".to_string(),
        first_start: 6,
        first_end: 6,
        second_start: 5,
        second_end: 6,
    });
    assert_eq!(result, expected_result);
}

#[test]
fn test_ratio() {
    let mut matcher = SequenceMatcher::new("abcd", "bcde");
    assert_eq!(matcher.ratio(), 0.75);
}

#[test]
fn test_get_close_matches() {
    let words = vec!["ape", "apple", "peach", "puppy"];
    let result = difflib::get_close_matches("appel", words, 3, 0.6);
    assert_eq!(result, vec!["apple", "ape"]);
}

#[test]
fn test_differ_compare() {
    let first_text = vec!["one\n", "two\n", "three\n"];
    let second_text = vec!["ore\n", "tree\n", "emu\n"];
    let differ = Differ::new();
    let result = differ.compare(&first_text, &second_text).join("");
    assert_eq!(
        result,
        "- one\n?  ^\n+ ore\n?  ^\n- two\n- three\n?  -\n+ tree\n+ emu\n"
    );
}

fn is_junk_char(ch: &char) -> bool {
    if *ch == ' ' || *ch == '\t' {
        return true;
    }
    false
}

#[test]
fn test_differ_compare_with_func() {
    let first_text = vec!["one\n", "two\n", "three\n"];
    let second_text = vec!["ore\n", "tree\n", "emu\n"];
    let mut differ = Differ::new();
    differ.char_junk = Some(is_junk_char);
    let result = differ.compare(&first_text, &second_text).join("");
    assert_eq!(
        result,
        "- one\n?  ^\n+ ore\n?  ^\n- two\n- three\n?  -\n+ tree\n+ emu\n"
    );
}

#[test]
fn test_differ_restore() {
    let first_text = vec!["one\n", "  two\n", "three\n"];
    let second_text = vec!["ore\n", "tree\n", "emu\n"];
    let differ = Differ::new();
    let diff = differ.compare(&first_text, &second_text);
    assert_eq!(first_text, Differ::restore(&diff, 1));
    assert_eq!(second_text, Differ::restore(&diff, 2));
}

#[test]
fn test_unified_diff() {
    let first_text = "one two three four".split(" ").collect::<Vec<&str>>();
    let second_text = "zero one tree four".split(" ").collect::<Vec<&str>>();
    let result = difflib::unified_diff(
        &first_text,
        &second_text,
        "Original",
        "Current",
        "2005-01-26 23:30:50",
        "2010-04-02 10:20:52",
        3,
    ).join("");
    assert_eq!(
        result,
        "--- Original\t2005-01-26 23:30:50\n+++ Current\t2010-04-02 10:20:52\n@@ -1,4 \
         +1,4 @@\n+zero one-two-three+tree four"
    );
}

#[test]
fn test_context_diff() {
    let first_text = "one two three four".split(" ").collect::<Vec<&str>>();
    let second_text = "zero one tree four".split(" ").collect::<Vec<&str>>();
    let result = difflib::context_diff(
        &first_text,
        &second_text,
        "Original",
        "Current",
        "2005-01-26 23:30:50",
        "2010-04-02 10:20:52",
        3,
    ).join("");
    assert_eq!(
        result,
        "*** Original\t2005-01-26 23:30:50\n--- Current\t2010-04-02 \
         10:20:52\n***************\n*** 1,4 ****\n  one! two! three  four--- 1,4 ----\n+ \
         zero  one! tree  four"
    );
}

#[test]
fn test_integer_slice() {
    let s1 = vec![1, 2, 3, 4, 5];
    let s2 = vec![5, 4, 3, 2, 1];
    let result = SequenceMatcher::new(&s1, &s2).get_matching_blocks();
    let mut expected_result = Vec::new();
    expected_result.push(Match {
        first_start: 0,
        second_start: 4,
        size: 1,
    });
    expected_result.push(Match {
        first_start: 5,
        second_start: 5,
        size: 0,
    });
    assert_eq!(result, expected_result);
}
<|endoftext|>


<commit_before>/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

#[macro_use]
extern crate autograd;
use autograd::Context;
use std::num::Float;
use std::ops::Neg;

macro_rules! unary_operation_test {
    ($name:ident, $x:expr, $y:expr, $dx:expr) => (
        #[test]
        fn $name() {
            let context = new_autograd_context!(f32, 1000);
            let x = context.new_variable($x);

            let y = x.$name();
            assert_eq!(y.value, $y);

            context.differentiate(y);
            assert_eq!(context.get_derivative(x), $dx);
            assert_eq!(context.get_derivative(y), 1.);
        }
    )
}

unary_operation_test!(cos, 0., 1., 0.);
unary_operation_test!(neg, 1.5, -1.5, -1.);

#[test]
fn addition() {
    let context = new_autograd_context!(f32, 1000);
    let x1 = context.new_variable(1.5);
    let x2 = context.new_variable(2.5);

    let y = x1 + x2;
    assert_eq!(y.value, 4.);

    context.differentiate(y);
    assert_eq!(context.get_derivative(x1), 1.);
    assert_eq!(context.get_derivative(x2), 1.);
    assert_eq!(context.get_derivative(y), 1.);
}

#[test]
fn multiplication() {
    let context = new_autograd_context!(f32, 1000);
    let x1 = context.new_variable(1.5);
    let x2 = context.new_variable(2.5);

    let y = x1 * x2;
    assert_eq!(y.value, 3.75);

    context.differentiate(y);
    assert_eq!(context.get_derivative(x1), 2.5);
    assert_eq!(context.get_derivative(x2), 1.5);
    assert_eq!(context.get_derivative(y), 1.);
}

#[test]
fn single_thread_multiple_run() {
    for _ in 0..10 {
        addition();
    }
}

#[test]
fn multi_thread_multiple_run() {
    // TODO Insert purposeful sleep for each task?
    let task_pool = std::sync::TaskPool::new(10);
    let semaphore = std::sync::Arc::new(std::sync::Semaphore::new(-999));
    for _ in 0..1000 {
        let semaphore_task = semaphore.clone();
        task_pool.execute(move || {
            single_thread_multiple_run();
            semaphore_task.release();
        });
    }
    semaphore.access();
}

#[test]
#[should_fail(expected = "This Context instance is in use now. Note that a Context instance is allowed per construction location and per thread. Consequently, it cannot be recursively constructed unless it is destructed. This is a limitation caused by the thread local static variables usages in the current implementation.")]
fn context_lock() {
    fn recursive_context(n: usize) {
        if n > 0 {
            let context = new_autograd_context!(f32, 10);
            recursive_context(n - 1);
        }
    }
    recursive_context(2);
}

#[test]
fn context_capacity_expression_argument() {
    let a = 200;
    let b = 10;
    let context = new_autograd_context!(f32, a/b);
}
<commit_msg>Add binary_operation_test macro.<commit_after>/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

#[macro_use]
extern crate autograd;
use autograd::Context;
use std::num::Float;
use std::ops::Add;
use std::ops::Mul;
use std::ops::Neg;

macro_rules! unary_operation_test {
    ($name:ident, $x:expr, $y:expr, $dx:expr) => (
        #[test]
        fn $name() {
            let context = new_autograd_context!(f32, 1000);
            let x = context.new_variable($x);

            let y = x.$name();
            assert_eq!(y.value, $y);

            context.differentiate(y);
            assert_eq!(context.get_derivative(x), $dx);
            assert_eq!(context.get_derivative(y), 1.);
        }
    )
}

unary_operation_test!(cos, 0., 1., 0.);
unary_operation_test!(neg, 1.5, -1.5, -1.);

macro_rules! binary_operation_test {
    ($name:ident, $x1:expr, $x2:expr, $y:expr, $dx1:expr, $dx2:expr) => (
        #[test]
        fn $name() {
            let context = new_autograd_context!(f32, 1000);
            let x1 = context.new_variable($x1);
            let x2 = context.new_variable($x2);

            let y = x1.$name(x2);
            assert_eq!(y.value, $y);

            context.differentiate(y);
            assert_eq!(context.get_derivative(x1), $dx1);
            assert_eq!(context.get_derivative(x2), $dx2);
            assert_eq!(context.get_derivative(y), 1.);
        }
    )
}

binary_operation_test!(add, 1.5, 2.5, 4., 1., 1.);
binary_operation_test!(mul, 1.5, 2.5, 3.75, 2.5, 1.5);

#[test]
fn single_thread_multiple_run() {
    for _ in 0..10 {
        add();
    }
}

#[test]
fn multi_thread_multiple_run() {
    // TODO Insert purposeful sleep for each task?
    let task_pool = std::sync::TaskPool::new(10);
    let semaphore = std::sync::Arc::new(std::sync::Semaphore::new(-999));
    for _ in 0..1000 {
        let semaphore_task = semaphore.clone();
        task_pool.execute(move || {
            single_thread_multiple_run();
            semaphore_task.release();
        });
    }
    semaphore.access();
}

#[test]
#[should_fail(expected = "This Context instance is in use now. Note that a Context instance is allowed per construction location and per thread. Consequently, it cannot be recursively constructed unless it is destructed. This is a limitation caused by the thread local static variables usages in the current implementation.")]
fn context_lock() {
    fn recursive_context(n: usize) {
        if n > 0 {
            let context = new_autograd_context!(f32, 10);
            recursive_context(n - 1);
        }
    }
    recursive_context(2);
}

#[test]
fn context_capacity_expression_argument() {
    let a = 200;
    let b = 10;
    let context = new_autograd_context!(f32, a/b);
}
<|endoftext|>


<commit_before>#[feature(globs)];
#[feature(macro_rules)];
#[feature(managed_boxes)];

#[link_args="-lwxc"];

extern mod native;
extern mod wx;

use std::libc::c_void;

use wx::_unsafe::*;
use wx::defs::*;
use wx::base::*;
use wx::core::*;

mod macros;

wxApp!(wx_main)

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

extern "C"
fn MyButton_clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
    println("hello!");
    let parent = wxWindow::from(data);
    let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", wxOK);
    msgDlg.showModal();
}

struct MyButton(@wxButton);
impl MyButton {
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton_clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
}
<commit_msg>Handle button press event only when appropriate.<commit_after>#[feature(globs)];
#[feature(macro_rules)];
#[feature(managed_boxes)];

#[link_args="-lwxc"];

extern mod native;
extern mod wx;

use std::libc::c_void;

use wx::_unsafe::*;
use wx::defs::*;
use wx::base::*;
use wx::core::*;

mod macros;

wxApp!(wx_main)

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

extern "C"
fn MyButton_clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
    if (evt == 0 as *mut c_void) {
        // Comes here when the target widget is destroyed.
        return;
    }

    println("hello!");
    let parent = wxWindow::from(data);
    let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", wxOK);
    msgDlg.showModal();
}

struct MyButton(@wxButton);
impl MyButton {
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton_clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]

use std::borrow::Cow;

extern crate proc_macro2;
#[macro_use]
extern crate quote;

use proc_macro2::{Ident, Span, TokenStream};
use quote::TokenStreamExt;

mod conditional {
    #[cfg(integer128)]
    mod integer128;
}

struct X;

impl quote::ToTokens for X {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.append(Ident::new("X", Span::call_site()));
    }
}

#[test]
fn test_quote_impl() {
    let tokens = quote! {
        impl<'a, T: ToTokens> ToTokens for &'a T {
            fn to_tokens(&self, tokens: &mut TokenStream) {
                (**self).to_tokens(tokens)
            }
        }
    };

    let expected = concat!(
        "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
        "fn to_tokens ( & self , tokens : & mut TokenStream ) { ",
        "( * * self ) . to_tokens ( tokens ) ",
        "} ",
        "}"
    );

    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_substitution() {
    let x = X;
    let tokens = quote!(#x <#x> (#x) [#x] {#x});

    let expected = "X < X > ( X ) [ X ] { X }";

    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_iter() {
    let primes = &[X, X, X, X];

    assert_eq!("X X X X", quote!(#(#primes)*).to_string());

    assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string());

    assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string());
}

#[test]
fn test_advanced() {
    let generics = quote!( <'a, T> );

    let where_clause = quote!( where T: Serialize );

    let field_ty = quote!(String);

    let item_ty = quote!(Cow<'a, str>);

    let path = quote!(SomeTrait::serialize_with);

    let value = quote!(self.x);

    let tokens = quote! {
        struct SerializeWith #generics #where_clause {
            value: &'a #field_ty,
            phantom: ::std::marker::PhantomData<#item_ty>,
        }

        impl #generics ::serde::Serialize for SerializeWith #generics #where_clause {
            fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
                where S: ::serde::Serializer
            {
                #path(self.value, s)
            }
        }

        SerializeWith {
            value: #value,
            phantom: ::std::marker::PhantomData::<#item_ty>,
        }
    };

    let expected = concat!(
        "struct SerializeWith < 'a , T > where T : Serialize { ",
        "value : & 'a String , ",
        "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ",
        "} ",
        "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ",
        "fn serialize < S > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > ",
        "where S : :: serde :: Serializer ",
        "{ ",
        "SomeTrait :: serialize_with ( self . value , s ) ",
        "} ",
        "} ",
        "SerializeWith { ",
        "value : self . x , ",
        "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ",
        "}"
    );

    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_integer() {
    let ii8 = -1i8;
    let ii16 = -1i16;
    let ii32 = -1i32;
    let ii64 = -1i64;
    let iisize = -1isize;
    let uu8 = 1u8;
    let uu16 = 1u16;
    let uu32 = 1u32;
    let uu64 = 1u64;
    let uusize = 1usize;

    let tokens = quote! {
        #ii8 #ii16 #ii32 #ii64 #iisize
        #uu8 #uu16 #uu32 #uu64 #uusize
    };
    let expected = "-1i8 -1i16 -1i32 -1i64 -1isize 1u8 1u16 1u32 1u64 1usize";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_floating() {
    let e32 = 2.345f32;

    let e64 = 2.345f64;

    let tokens = quote! {
        #e32
        #e64
    };
    let expected = concat!("2.345f32 2.345f64");
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_char() {
    let zero = '\0';
    let pound = '#';
    let quote = '"';
    let apost = '\'';
    let newline = '\n';
    let heart = '\u{2764}';

    let tokens = quote! {
        #zero #pound #quote #apost #newline #heart
    };
    let expected = "'\\u{0}' '#' '\"' '\\'' '\\n' '\\u{2764}'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_str() {
    let s = "\0 a 'b \" c";
    let tokens = quote!(#s);
    let expected = "\"\\u{0} a 'b \\\" c\"";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_string() {
    let s = "\0 a 'b \" c".to_string();
    let tokens = quote!(#s);
    let expected = "\"\\u{0} a 'b \\\" c\"";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_ident() {
    let foo = Ident::new("Foo", Span::call_site());
    let bar = Ident::new(&format!("Bar{}", 7), Span::call_site());
    let tokens = quote!(struct #foo; enum #bar {});
    let expected = "struct Foo ; enum Bar7 { }";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_duplicate() {
    let ch = 'x';

    let tokens = quote!(#ch #ch);

    let expected = "'x' 'x'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_fancy_repetition() {
    let foo = vec!["a", "b"];
    let bar = vec![true, false];

    let tokens = quote! {
        #(#foo: #bar),*
    };

    let expected = r#""a" : true , "b" : false"#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_nested_fancy_repetition() {
    let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']];

    let tokens = quote! {
        #(
            #(#nested)*
        ),*
    };

    let expected = "'a' 'b' 'c' , 'x' 'y' 'z'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_duplicate_name_repetition() {
    let foo = &["a", "b"];

    let tokens = quote! {
        #(#foo: #foo),*
        #(#foo: #foo),*
    };

    let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_duplicate_name_repetition_no_copy() {
    let foo = vec!["a".to_owned(), "b".to_owned()];

    let tokens = quote! {
        #(#foo: #foo),*
    };

    let expected = r#""a" : "a" , "b" : "b""#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_variable_name_conflict() {
    // The implementation of `#(...),*` uses the variable `_i` but it should be
    // fine, if a little confusing when debugging.
    let _i = vec!['a', 'b'];
    let tokens = quote! { #(#_i),* };
    let expected = "'a' , 'b'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_nonrep_in_repetition() {
    let rep = vec!["a", "b"];
    let nonrep = "c";

    let tokens = quote! {
        #(#rep #rep : #nonrep #nonrep),*
    };

    let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_empty_quote() {
    let tokens = quote!();
    assert_eq!("", tokens.to_string());
}

#[test]
fn test_box_str() {
    let b = "str".to_owned().into_boxed_str();
    let tokens = quote! { #b };
    assert_eq!("\"str\"", tokens.to_string());
}

#[test]
fn test_cow() {
    let owned: Cow<Ident> = Cow::Owned(Ident::new("owned", Span::call_site()));

    let ident = Ident::new("borrowed", Span::call_site());
    let borrowed = Cow::Borrowed(&ident);

    let tokens = quote! { #owned #borrowed };
    assert_eq!("owned borrowed", tokens.to_string());
}

#[test]
fn test_closure() {
    fn field_i(i: usize) -> Ident {
        format_ident!("__field{}", i)
    }

    let fields = (0usize..3)
        .map(field_i as fn(_) -> _)
        .map(|var| quote! { #var });

    let tokens = quote! { #(#fields)* };
    assert_eq!("__field0 __field1 __field2", tokens.to_string());
}

#[test]
fn test_append_tokens() {
    let mut a = quote!(a);
    let b = quote!(b);
    a.append_all(b);
    assert_eq!("a b", a.to_string());
}

#[test]
fn test_format_ident() {
    let id0 = format_ident!("Aa");
    let id1 = format_ident!("Hello{x}", x = id0);
    let id2 = format_ident!("Hello{x}", x = 5usize);
    let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize);
    let id4 = format_ident!("Aa", span = Span::call_site());

    assert_eq!(id0, "Aa");
    assert_eq!(id1, "HelloAa");
    assert_eq!(id2, "Hello5");
    assert_eq!(id3, "HelloAa_10");
    assert_eq!(id4, "Aa");

    // XXX: No way to test spans are set correctly?
}

#[test]
fn test_format_ident_strip_raw() {
    let id = format_ident!("r#struct");
    let my_id = format_ident!("MyId{}", id);
    let raw_my_id = format_ident!("r#MyId{}", id);

    assert_eq!(id, "r#struct");
    assert_eq!(my_id, "MyIdstruct");
    assert_eq!(raw_my_id, "r#MyIdstruct");

    // XXX: No way to test spans are set correctly?
}
<commit_msg>Add tests for doc comments and attributes<commit_after>#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]

use std::borrow::Cow;

extern crate proc_macro2;
#[macro_use]
extern crate quote;

use proc_macro2::{Ident, Span, TokenStream};
use quote::TokenStreamExt;

mod conditional {
    #[cfg(integer128)]
    mod integer128;
}

struct X;

impl quote::ToTokens for X {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.append(Ident::new("X", Span::call_site()));
    }
}

#[test]
fn test_quote_impl() {
    let tokens = quote! {
        impl<'a, T: ToTokens> ToTokens for &'a T {
            fn to_tokens(&self, tokens: &mut TokenStream) {
                (**self).to_tokens(tokens)
            }
        }
    };

    let expected = concat!(
        "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
        "fn to_tokens ( & self , tokens : & mut TokenStream ) { ",
        "( * * self ) . to_tokens ( tokens ) ",
        "} ",
        "}"
    );

    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_substitution() {
    let x = X;
    let tokens = quote!(#x <#x> (#x) [#x] {#x});

    let expected = "X < X > ( X ) [ X ] { X }";

    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_iter() {
    let primes = &[X, X, X, X];

    assert_eq!("X X X X", quote!(#(#primes)*).to_string());

    assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string());

    assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string());
}

#[test]
fn test_advanced() {
    let generics = quote!( <'a, T> );

    let where_clause = quote!( where T: Serialize );

    let field_ty = quote!(String);

    let item_ty = quote!(Cow<'a, str>);

    let path = quote!(SomeTrait::serialize_with);

    let value = quote!(self.x);

    let tokens = quote! {
        struct SerializeWith #generics #where_clause {
            value: &'a #field_ty,
            phantom: ::std::marker::PhantomData<#item_ty>,
        }

        impl #generics ::serde::Serialize for SerializeWith #generics #where_clause {
            fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
                where S: ::serde::Serializer
            {
                #path(self.value, s)
            }
        }

        SerializeWith {
            value: #value,
            phantom: ::std::marker::PhantomData::<#item_ty>,
        }
    };

    let expected = concat!(
        "struct SerializeWith < 'a , T > where T : Serialize { ",
        "value : & 'a String , ",
        "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ",
        "} ",
        "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ",
        "fn serialize < S > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > ",
        "where S : :: serde :: Serializer ",
        "{ ",
        "SomeTrait :: serialize_with ( self . value , s ) ",
        "} ",
        "} ",
        "SerializeWith { ",
        "value : self . x , ",
        "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ",
        "}"
    );

    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_integer() {
    let ii8 = -1i8;
    let ii16 = -1i16;
    let ii32 = -1i32;
    let ii64 = -1i64;
    let iisize = -1isize;
    let uu8 = 1u8;
    let uu16 = 1u16;
    let uu32 = 1u32;
    let uu64 = 1u64;
    let uusize = 1usize;

    let tokens = quote! {
        #ii8 #ii16 #ii32 #ii64 #iisize
        #uu8 #uu16 #uu32 #uu64 #uusize
    };
    let expected = "-1i8 -1i16 -1i32 -1i64 -1isize 1u8 1u16 1u32 1u64 1usize";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_floating() {
    let e32 = 2.345f32;

    let e64 = 2.345f64;

    let tokens = quote! {
        #e32
        #e64
    };
    let expected = concat!("2.345f32 2.345f64");
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_char() {
    let zero = '\0';
    let pound = '#';
    let quote = '"';
    let apost = '\'';
    let newline = '\n';
    let heart = '\u{2764}';

    let tokens = quote! {
        #zero #pound #quote #apost #newline #heart
    };
    let expected = "'\\u{0}' '#' '\"' '\\'' '\\n' '\\u{2764}'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_str() {
    let s = "\0 a 'b \" c";
    let tokens = quote!(#s);
    let expected = "\"\\u{0} a 'b \\\" c\"";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_string() {
    let s = "\0 a 'b \" c".to_string();
    let tokens = quote!(#s);
    let expected = "\"\\u{0} a 'b \\\" c\"";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_ident() {
    let foo = Ident::new("Foo", Span::call_site());
    let bar = Ident::new(&format!("Bar{}", 7), Span::call_site());
    let tokens = quote!(struct #foo; enum #bar {});
    let expected = "struct Foo ; enum Bar7 { }";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_duplicate() {
    let ch = 'x';

    let tokens = quote!(#ch #ch);

    let expected = "'x' 'x'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_fancy_repetition() {
    let foo = vec!["a", "b"];
    let bar = vec![true, false];

    let tokens = quote! {
        #(#foo: #bar),*
    };

    let expected = r#""a" : true , "b" : false"#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_nested_fancy_repetition() {
    let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']];

    let tokens = quote! {
        #(
            #(#nested)*
        ),*
    };

    let expected = "'a' 'b' 'c' , 'x' 'y' 'z'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_duplicate_name_repetition() {
    let foo = &["a", "b"];

    let tokens = quote! {
        #(#foo: #foo),*
        #(#foo: #foo),*
    };

    let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_duplicate_name_repetition_no_copy() {
    let foo = vec!["a".to_owned(), "b".to_owned()];

    let tokens = quote! {
        #(#foo: #foo),*
    };

    let expected = r#""a" : "a" , "b" : "b""#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_variable_name_conflict() {
    // The implementation of `#(...),*` uses the variable `_i` but it should be
    // fine, if a little confusing when debugging.
    let _i = vec!['a', 'b'];
    let tokens = quote! { #(#_i),* };
    let expected = "'a' , 'b'";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_nonrep_in_repetition() {
    let rep = vec!["a", "b"];
    let nonrep = "c";

    let tokens = quote! {
        #(#rep #rep : #nonrep #nonrep),*
    };

    let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#;
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_empty_quote() {
    let tokens = quote!();
    assert_eq!("", tokens.to_string());
}

#[test]
fn test_box_str() {
    let b = "str".to_owned().into_boxed_str();
    let tokens = quote! { #b };
    assert_eq!("\"str\"", tokens.to_string());
}

#[test]
fn test_cow() {
    let owned: Cow<Ident> = Cow::Owned(Ident::new("owned", Span::call_site()));

    let ident = Ident::new("borrowed", Span::call_site());
    let borrowed = Cow::Borrowed(&ident);

    let tokens = quote! { #owned #borrowed };
    assert_eq!("owned borrowed", tokens.to_string());
}

#[test]
fn test_closure() {
    fn field_i(i: usize) -> Ident {
        format_ident!("__field{}", i)
    }

    let fields = (0usize..3)
        .map(field_i as fn(_) -> _)
        .map(|var| quote! { #var });

    let tokens = quote! { #(#fields)* };
    assert_eq!("__field0 __field1 __field2", tokens.to_string());
}

#[test]
fn test_append_tokens() {
    let mut a = quote!(a);
    let b = quote!(b);
    a.append_all(b);
    assert_eq!("a b", a.to_string());
}

#[test]
fn test_format_ident() {
    let id0 = format_ident!("Aa");
    let id1 = format_ident!("Hello{x}", x = id0);
    let id2 = format_ident!("Hello{x}", x = 5usize);
    let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize);
    let id4 = format_ident!("Aa", span = Span::call_site());

    assert_eq!(id0, "Aa");
    assert_eq!(id1, "HelloAa");
    assert_eq!(id2, "Hello5");
    assert_eq!(id3, "HelloAa_10");
    assert_eq!(id4, "Aa");

    // XXX: No way to test spans are set correctly?
}

#[test]
fn test_format_ident_strip_raw() {
    let id = format_ident!("r#struct");
    let my_id = format_ident!("MyId{}", id);
    let raw_my_id = format_ident!("r#MyId{}", id);

    assert_eq!(id, "r#struct");
    assert_eq!(my_id, "MyIdstruct");
    assert_eq!(raw_my_id, "r#MyIdstruct");

    // XXX: No way to test spans are set correctly?
}

#[test]
fn test_outer_line_comment() {
    let tokens = quote! {
        /// doc
    };
    let expected = "# [ doc = r\" doc\" ]";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_inner_line_comment() {
    let tokens = quote! {
        //! doc
    };
    let expected = "# ! [ doc = r\" doc\" ]";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_outer_block_comment() {
    let tokens = quote! {
        /** doc */
    };
    let expected = "# [ doc = r\" doc \" ]";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_inner_block_comment() {
    let tokens = quote! {
        /*! doc */
    };
    let expected = "# ! [ doc = r\" doc \" ]";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_outer_attr() {
    let tokens = quote! {
        #[inline]
    };
    let expected = "# [ inline ]";
    assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_inner_attr() {
    let tokens = quote! {
        #![no_std]
    };
    let expected = "# ! [ no_std ]";
    assert_eq!(expected, tokens.to_string());
}
<|endoftext|>


<commit_before>extern crate handlebars;
#[macro_use]
extern crate serde_json;

use handlebars::Handlebars;
use std::error::Error;

// wait RFC1937 in
fn main() -> Result<(), Box<dyn Error>> {
    let mut reg = Handlebars::new();
    // render without register
    println!(
        "{}",
        reg.render_template("Hello {{name}}", &json!({"name": "foo"}))?
    );

    // register template using given name
    reg.register_template_string("tpl_1", "Good afternoon, {{name}}")?;
    println!("{}", reg.render("tpl_1", &json!({"name": "foo"}))?);
    Ok(())
}
<commit_msg>(test) refresh quick start example<commit_after>use std::error::Error;

use handlebars::Handlebars;
use serde_json::json;

fn main() -> Result<(), Box<dyn Error>> {
    let mut reg = Handlebars::new();
    // render without register
    println!(
        "{}",
        reg.render_template("Hello {{name}}", &json!({"name": "foo"}))?
    );

    // register template using given name
    reg.register_template_string("tpl_1", "Good afternoon, {{name}}")?;
    println!("{}", reg.render("tpl_1", &json!({"name": "foo"}))?);
    Ok(())
}
<|endoftext|>


<commit_before>#[derive(serde::Serialize)]
struct HyphenResult {
    hyphenated: String,
    error: String,
}

pub fn app(_request: &rouille::Request) -> rouille::Response {
    let response = rouille::Response::json(&HyphenResult {
        hyphenated: "asz=szony=nyal".to_owned(),
        error: "".to_owned(),
    });
    response
}
<commit_msg>connect hyphen to rouille<commit_after>#[derive(serde::Serialize)]
struct HyphenResult {
    hyphenated: String,
    error: String,
}

pub fn app(request: &rouille::Request) -> rouille::Response {
    let word = match request.get_param("word") {
        Some(value) => value,
        None => {
            return rouille::Response::json(&HyphenResult {
                hyphenated: "".to_owned(),
                error: "missing GET param: word".to_owned(),
            });
        }
    };
    let dict = match hyphen::HyphenDict::new("/usr/share/hyphen/hyph_hu_HU.dic") {
        Ok(value) => value,
        Err(err) => {
            return rouille::Response::json(&HyphenResult {
                hyphenated: "".to_owned(),
                error: format!("failed to load the dict: {:?}", err),
            });
        }
    };
    let hyphenated = match dict.hyphenate(&word) {
        Ok(value) => value,
        Err(err) => {
            return rouille::Response::json(&HyphenResult {
                hyphenated: "".to_owned(),
                error: format!("failed to hyphenate the word: {:?}", err),
            });
        }
    };
    let response = rouille::Response::json(&HyphenResult {
        hyphenated,
        error: "".to_owned(),
    });
    response
}
<|endoftext|>


<commit_before>use byteorder::{BigEndian, ByteOrder};
use std::io;
use std::ptr;
use super::ipv4_header::IPv4Header;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};

struct IPv4PacketBuffer {
    buf: [u8; MAX_PACKET_LENGTH],
    head: usize,
}

impl IPv4PacketBuffer {
    fn new() -> IPv4PacketBuffer {
        IPv4PacketBuffer {
            buf: [0; MAX_PACKET_LENGTH],
            head: 0,
        }
    }

    fn read_from<R: io::Read>(&mut self, source: &mut R) -> io::Result<()> {
        let r = source.read(&mut self.buf[self.head..])?;
        self.head += r;
        Ok(())
    }

    fn get_available_packet_length(&self) -> Option<u16> {
        let length = IPv4Header::read_length(&self.buf);
        match length {
            // no packet
            None => None,
            // no full packet available
            Some(len) if len > self.head as u16 => None,
            // full packet available
            length => length
        }
    }

    pub fn as_ipv4_packet<'a>(&'a mut self) -> Option<IPv4Packet<'a>> {
        let length = self.get_available_packet_length();
        if let Some(len) = length {
            Some(IPv4Packet::new(&mut self.buf[..len as usize]))
        } else {
            None
        }
    }

    pub fn next(&mut self) {
        // remove the packet in front of the buffer
        let length = self.get_available_packet_length()
                .expect("next() called while there was no packet") as usize;
        self.head -= length;
        unsafe {
            let buf_ptr = self.buf.as_mut_ptr();
            // semantically equivalent to memmove()
            ptr::copy(buf_ptr.offset(length as isize), buf_ptr, length);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;
    use byteorder::{BigEndian, WriteBytesExt};
    use ::relay::ipv4_header::Protocol;
    use ::relay::transport_header::TransportHeader;

    fn create_packet() -> Vec<u8> {
        let mut raw: Vec<u8> = vec![];
        raw.reserve(32);
        raw.write_u8(4u8 << 4 | 5).unwrap();
        raw.write_u8(0).unwrap(); // ToS
        raw.write_u16::<BigEndian>(32); // total length 20 + 8 + 4
        raw.write_u32::<BigEndian>(0); // id_flags_fragment_offset
        raw.write_u8(0).unwrap(); // TTL
        raw.write_u8(17).unwrap(); // protocol (UDP)
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum
        raw.write_u32::<BigEndian>(0x12345678).unwrap(); // source address
        raw.write_u32::<BigEndian>(0x42424242).unwrap(); // destination address

        raw.write_u16::<BigEndian>(1234).unwrap(); // source port
        raw.write_u16::<BigEndian>(5678).unwrap(); // destination port
        raw.write_u16::<BigEndian>(12).unwrap(); // length
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum

        raw.write_u32::<BigEndian>(0x11223344).unwrap(); // payload

        raw
    }

    fn check_packet_headers(ipv4_packet: &IPv4Packet) {
        let ipv4_header = &ipv4_packet.ipv4_header;
        assert_eq!(20, ipv4_header.header_length);
        assert_eq!(32, ipv4_header.total_length);
        assert_eq!(Protocol::UDP, ipv4_header.protocol);
        assert_eq!(0x12345678, ipv4_header.source);
        assert_eq!(0x42424242, ipv4_header.destination);

        if let Some(TransportHeader::UDP(ref udp_header)) = ipv4_packet.transport_header {
            assert_eq!(1234, udp_header.source_port);
            assert_eq!(5678, udp_header.destination_port);
        } else {
            panic!("No UDP transport header");
        }
    }

    #[test]
    fn parse_ipv4_packet_buffer() {
        let raw = &create_packet()[..];
        let mut packet_buffer = IPv4PacketBuffer::new();
        let mut cursor = io::Cursor::new(raw);

        packet_buffer.read_from(&mut cursor).unwrap();

        let packet = packet_buffer.as_ipv4_packet().unwrap();
        check_packet_headers(&packet);
    }
}
<commit_msg>Add test for fragmented packet in IPv4PacketBuffer<commit_after>use byteorder::{BigEndian, ByteOrder};
use std::io;
use std::ptr;
use super::ipv4_header::IPv4Header;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};

struct IPv4PacketBuffer {
    buf: [u8; MAX_PACKET_LENGTH],
    head: usize,
}

impl IPv4PacketBuffer {
    fn new() -> IPv4PacketBuffer {
        IPv4PacketBuffer {
            buf: [0; MAX_PACKET_LENGTH],
            head: 0,
        }
    }

    fn read_from<R: io::Read>(&mut self, source: &mut R) -> io::Result<()> {
        let r = source.read(&mut self.buf[self.head..])?;
        self.head += r;
        Ok(())
    }

    fn get_available_packet_length(&self) -> Option<u16> {
        let length = IPv4Header::read_length(&self.buf);
        match length {
            // no packet
            None => None,
            // no full packet available
            Some(len) if len > self.head as u16 => None,
            // full packet available
            length => length
        }
    }

    pub fn as_ipv4_packet<'a>(&'a mut self) -> Option<IPv4Packet<'a>> {
        let length = self.get_available_packet_length();
        if let Some(len) = length {
            Some(IPv4Packet::new(&mut self.buf[..len as usize]))
        } else {
            None
        }
    }

    pub fn next(&mut self) {
        // remove the packet in front of the buffer
        let length = self.get_available_packet_length()
                .expect("next() called while there was no packet") as usize;
        self.head -= length;
        unsafe {
            let buf_ptr = self.buf.as_mut_ptr();
            // semantically equivalent to memmove()
            ptr::copy(buf_ptr.offset(length as isize), buf_ptr, length);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;
    use byteorder::{BigEndian, WriteBytesExt};
    use ::relay::ipv4_header::Protocol;
    use ::relay::transport_header::TransportHeader;

    fn create_packet() -> Vec<u8> {
        let mut raw: Vec<u8> = vec![];
        raw.reserve(32);
        raw.write_u8(4u8 << 4 | 5).unwrap();
        raw.write_u8(0).unwrap(); // ToS
        raw.write_u16::<BigEndian>(32); // total length 20 + 8 + 4
        raw.write_u32::<BigEndian>(0); // id_flags_fragment_offset
        raw.write_u8(0).unwrap(); // TTL
        raw.write_u8(17).unwrap(); // protocol (UDP)
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum
        raw.write_u32::<BigEndian>(0x12345678).unwrap(); // source address
        raw.write_u32::<BigEndian>(0x42424242).unwrap(); // destination address

        raw.write_u16::<BigEndian>(1234).unwrap(); // source port
        raw.write_u16::<BigEndian>(5678).unwrap(); // destination port
        raw.write_u16::<BigEndian>(12).unwrap(); // length
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum

        raw.write_u32::<BigEndian>(0x11223344).unwrap(); // payload

        raw
    }

    fn check_packet_headers(ipv4_packet: &IPv4Packet) {
        let ipv4_header = &ipv4_packet.ipv4_header;
        assert_eq!(20, ipv4_header.header_length);
        assert_eq!(32, ipv4_header.total_length);
        assert_eq!(Protocol::UDP, ipv4_header.protocol);
        assert_eq!(0x12345678, ipv4_header.source);
        assert_eq!(0x42424242, ipv4_header.destination);

        if let Some(TransportHeader::UDP(ref udp_header)) = ipv4_packet.transport_header {
            assert_eq!(1234, udp_header.source_port);
            assert_eq!(5678, udp_header.destination_port);
        } else {
            panic!("No UDP transport header");
        }
    }

    #[test]
    fn parse_ipv4_packet_buffer() {
        let raw = create_packet();
        let mut packet_buffer = IPv4PacketBuffer::new();
        let mut cursor = io::Cursor::new(raw);

        packet_buffer.read_from(&mut cursor).unwrap();

        let packet = packet_buffer.as_ipv4_packet().unwrap();
        check_packet_headers(&packet);
    }

    #[test]
    fn parse_fragmented_ipv4_packet_buffer() {
        let raw = create_packet();
        let mut packet_buffer = IPv4PacketBuffer::new();

        let mut cursor = io::Cursor::new(&raw[..14]);
        packet_buffer.read_from(&mut cursor).unwrap();

        assert!(packet_buffer.as_ipv4_packet().is_none());

        let mut cursor = io::Cursor::new(&raw[14..]);
        packet_buffer.read_from(&mut cursor).unwrap();

        let packet = packet_buffer.as_ipv4_packet().unwrap();
        check_packet_headers(&packet);
    }
}
<|endoftext|>


<commit_before>// Rust TNetStrings serialization library.

use std;
import option::{some, none};
import std::io;
import std::map;
import std::rand;

export t;
export to_writer;
export to_bytes;
export to_str;
export from_reader;
export from_bytes;
export from_str;
export string;
export integer;
export floating;
export boolean;
export null;
export map;
export list;

/*
Tag: t

Represents a tnetstring value.
*/
tag t {
    /* Variant: string */
    string([u8]);
    /* Variant: integer */
    integer(int);
    /* Variant: floating */
    floating(float);
    /* Variant: boolean */
    boolean(bool);
    /* Variant: null */
    null;
    /* Variant: map */
    map(map::hashmap<[u8], t>);
    /* Variant: list */
    list(@[t]);
}

/*
Function: to_writer

Serializes a tnetstring value into a io::writer.
*/
fn to_writer(writer: io::writer, t: t) {
    alt t {
        string(s) {
            writer.write_str(#fmt("%u:", vec::len(s)));
            writer.write_bytes(s);
            writer.write_char(',');
        }
        integer(i) {
            let s = int::str(i);
            writer.write_str(#fmt("%u:%s#", str::byte_len(s), s));
        }
        floating(f) {
            let s = float::to_str(f, 6u);
            writer.write_str(#fmt("%u:%s^", str::byte_len(s), s));
        }
        boolean(b) {
            let s = bool::to_str(b);
            writer.write_str(#fmt("%u:%s!", str::byte_len(s), s));
        }
        map(m) {
            let wr = io::bytes_writer();
            m.items({ |key, value|
                to_writer(wr.get_writer(), string(key));
                to_writer(wr.get_writer(), value);
            });
            let payload = wr.get_bytes();
            writer.write_str(#fmt("%u:", vec::len(payload)));
            writer.write_bytes(payload);
            writer.write_char('}');
        }
        list(@l) {
            let wr = io::bytes_writer();
            vec::iter(l, {|e| to_writer(wr.get_writer(), e) });
            let payload = wr.get_bytes();
            writer.write_str(#fmt("%u:", vec::len(payload)));
            writer.write_bytes(payload);
            writer.write_char(']');
        }
        null {
            writer.write_str("0:~");
        }
    }
}

/*
Function: to_bytes

Serializes a tnetstring value into a byte string.
*/
fn to_bytes(t: t) -> [const u8] {
    let writer = io::bytes_writer();
    to_writer(writer.get_writer(), t);
    writer.get_bytes()
}

/*
Function: to_str

Serializes a tnetstring value into a string.
*/
fn to_str(t: t) -> str {
    let writer = io::string_writer();
    to_writer(writer.get_writer(), t);
    writer.get_str()
}

/*
Function: from_reader

Deserializes a tnetstring value from an io::reader.
*/
fn from_reader(reader: io::reader) -> option::t<t> {
    assert !reader.eof();

    let c = reader.read_byte();
    let len = 0u;

    // Note that netstring spec explicitly forbids padding zeros.
    // If the first char is zero, it must be the only char.
    if c < '0' as int || c > '9' as int {
        fail "Not a tnetstring: invalid or missing length prefix";
    } else if c == '0' as int {
        c = reader.read_byte();
    } else {
        do {
            len = (10u * len) + ((c as uint) - ('0' as uint));

            if reader.eof() {
                fail "Not a tnetstring: invalid or missing length prefix";
            }
            c = reader.read_byte();
        } while c >= '0' as int && c <= '9' as int;
    }

    // Validate end-of-length-prefix marker.
    if c != ':' as int {
        fail "Not a tnetstring: missing length prefix";
    }

    // Read the data plus terminating type tag.
    let payload = reader.read_bytes(len);

    if vec::len(payload) != len {
        fail "Not a tnetstring: invalid length prefix";
    }

    if reader.eof() {
        fail "Not a tnetstring: missing type tag";
    }

    alt reader.read_byte() as char {
        '#' {
            let v = int::from_str(str::unsafe_from_bytes(payload));
            some(integer(v))
        }
        '}' { some(map(parse_map(payload))) }
        ']' { some(list(parse_list(payload))) }
        '!' {
            let v = bool::from_str(str::unsafe_from_bytes(payload));
            some(boolean(v))
        }
        '^' {
            let v = float::from_str(str::unsafe_from_bytes(payload));
            some(floating(v))
        }
        '~' {
            assert vec::len(payload) == 0u;
            some(null)
        }
        ',' { some(string(payload)) }
        c {
            let s = str::from_char(c);
            fail #fmt("Invalid payload type: %s", str::escape(s))
        }
    }
}

fn parse_list(data: [u8]) -> @[t] {
    if vec::len(data) == 0u { ret @[]; }

    let reader = io::bytes_reader(data);

    let value = from_reader(reader);
    assert option::is_some(value);
    let result = [option::get(value)];

    while !reader.eof() {
        let value = from_reader(reader);
        assert option::is_some(value);
        vec::push(result, option::get(value));
    }

    ret @result;
}

fn parse_pair(reader: io::reader) -> ([u8], t) {
    let key = from_reader(reader);
    assert option::is_some(key);
    assert !reader.eof();

    let key = alt option::get(key) {
        string(key) { key }
        _ { fail "Keys can only be strings." }
    };

    let value = from_reader(reader);
    assert option::is_some(value);

    ret (key, option::get(value));
}

fn parse_map(data: [u8]) -> map::hashmap<[u8], t> {
    if vec::len(data) == 0u { ret map::new_bytes_hash(); }

    let reader = io::bytes_reader(data);
    let (key, value) = parse_pair(reader);

    let result = map::new_bytes_hash();
    result.insert(key, value);

    while !reader.eof() {
        let (key, value) = parse_pair(reader);
        result.insert(key, value);
    }

    ret result;
}

/*
Function: from_bytes

Deserializes a tnetstring value from a byte string.
*/
fn from_bytes(data: [u8]) -> (option::t<t>, [u8]) {
    let reader = io::bytes_reader(data);
    let tnetstring = from_reader(reader);
    (tnetstring, reader.read_whole_stream())
}

/*
Function: from_str

Deserializes a tnetstring value from a string.
*/
fn from_str(data: str) -> (option::t<t>, str) {
    let reader = io::string_reader(data);
    let tnetstring = from_reader(reader);
    (tnetstring, str::unsafe_from_bytes(reader.read_whole_stream()))
}

fn eq(t0: t, t1: t) -> bool {
    alt (t0, t1) {
        (string(s0), string(s1)) { s0 == s1 }
        (integer(i0), integer(i1)) { i0 == i1 }
        (floating(f0), floating(f1)) { f0 == f1 }
        (boolean(b0), boolean(b1)) { b0 == b1 }
        (null., null.) { true }
        (map(d0), map(d1)) {
            if d0.size() == d1.size() {
                let equal = true;
                d0.items() { |k, v|
                    if !d1.contains_key(k) || !eq(d1.get(k), v) {
                        equal = false;
                    }
                };
                equal
            } else {
                false
            }
        }
        (list(l0), list(l1)) {
            vec::all2(*l0, *l1, eq)
        }
        _ { false }
    }
}

#[cfg(test)]
mod tests {
    // Tests inspired by https://github.com/rfk/tnetstring.

    fn test(string: str, expected: t) {
        let (actual, rest) = from_str(string);
        assert option::is_some(actual);
        assert rest == "";

        let actual = option::get(actual);
        assert eq(actual, expected);
        assert to_str(expected) == string;
    }

    #[test]
    fn test_format() {
        test("11:hello world,", string(str::bytes("hello world")));
        test("0:}", map(map::new_bytes_hash()));
        test("0:]", list(@[]));

        let d = map::new_bytes_hash();
        d.insert(str::bytes("hello"),
                list(@[
                    integer(12345678901),
                    string(str::bytes("this")),
                    boolean(true),
                    null,
                    string(str::bytes("\x00\x00\x00\x00"))]));

        test("51:5:hello,39:11:12345678901#4:this,4:true!0:~4:\x00\x00\x00" +
            "\x00,]}", map(d));

        test("5:12345#", integer(12345));
        test("12:this is cool,", string(str::bytes("this is cool")));
        test("0:,", string(str::bytes("")));
        test("0:~", null);
        test("4:true!", boolean(true));
        test("5:false!", boolean(false));
        test("10:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
            string(str::bytes("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")));
        test("24:5:12345#5:67890#5:xxxxx,]",
            list(
                @[integer(12345),
                integer(67890),
                string(str::bytes("xxxxx"))]));
        test("18:3:0.1^3:0.2^3:0.4^]",
           list(@[floating(0.1), floating(0.2), floating(0.4)]));
        test("243:238:233:228:223:218:213:208:203:198:193:188:183:178:173:" +
            "168:163:158:153:148:143:138:133:128:123:118:113:108:103:99:95:" +
            "91:87:83:79:75:71:67:63:59:55:51:47:43:39:35:31:27:23:19:15:" +
            "11:hello-there,]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" +
            "]]]]",
            list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[
                    string(str::bytes("hello-there"))
                ])])])])])])])])])])])])])])])])])])])])])])])])])])])])
                ])])])])])])])])])])])])])])])])])])])])])])]));
    }

    #[test]
    fn test_random() {
        fn randint(rng: rand::rng, a: u32, b: u32) -> u32 {
            (rng.next() % (b - a + 1u32)) + a
        }

        fn get_random_object(rng: rand::rng, depth: u32) -> t {
            if randint(rng, depth, 10u32) <= 4u32 {
                if randint(rng, 0u32, 1u32) == 0u32 {
                    let n = randint(rng, 0u32, 10u32);
                    list(@vec::init_fn(
                        { |_i| get_random_object(rng, depth + 1u32) },
                        n as uint))
                } else {
                    let d = map::new_bytes_hash();

                    let i = randint(rng, 0u32, 10u32);
                    while i != 0u32 {
                        let s = rng.gen_bytes(randint(rng, 0u32, 100u32) as uint);
                        d.insert(s, get_random_object(rng, depth + 1u32));
                        i -= 1u32;
                    }
                    map(d)
                }
            } else {
                alt randint(rng, 0u32, 5u32) {
                    0u32 { null }
                    1u32 { boolean(true) }
                    2u32 { boolean(false) }
                    3u32 {
                        if randint(rng, 0u32, 1u32) == 0u32 {
                            integer(rng.next() as int)
                        } else {
                            integer(-rng.next() as int)
                        }
                    }
                    4u32 {
                        let f = rng.next_float();

                        // Generate a float that can be exactly converted to
                        // and from a string.
                        while true {
                            let f1 = float::from_str(float::to_str(f, 6u));
                            if f == f1 { break; }
                            f = f1;
                        }

                        if randint(rng, 0u32, 1u32) == 0u32 {
                            floating(f)
                        } else {
                            floating(-f)
                        }
                    }
                    5u32 {
                        string(rng.gen_bytes(randint(rng, 0u32, 100u32) as uint))
                    }
                    _ { fail }
                }
            }
        }

        let rng = rand::mk_rng();

        let i = 500u;
        while i != 0u {
            let v0 = get_random_object(rng, 0u32);

            alt from_str(to_str(v0)) {
                (some(v1), "") { assert eq(v0, v1); }
                _ { fail; }
            }
            i -= 1u;
        }
    }
}
<commit_msg>Sync with rust io changes.<commit_after>// Rust TNetStrings serialization library.

use std;
import option::{some, none};
import std::io;
import std::map;
import std::rand;

import io::writer_util;
import io::reader_util;

export t;
export to_writer;
export to_bytes;
export to_str;
export from_reader;
export from_bytes;
export from_str;
export string;
export integer;
export floating;
export boolean;
export null;
export map;
export list;

/*
Tag: t

Represents a tnetstring value.
*/
tag t {
    /* Variant: string */
    string([u8]);
    /* Variant: integer */
    integer(int);
    /* Variant: floating */
    floating(float);
    /* Variant: boolean */
    boolean(bool);
    /* Variant: null */
    null;
    /* Variant: map */
    map(map::hashmap<[u8], t>);
    /* Variant: list */
    list(@[t]);
}

/*
Function: to_writer

Serializes a tnetstring value into a io::writer.
*/
fn to_writer(writer: io::writer, t: t) {
    alt t {
        string(s) {
            writer.write_str(#fmt("%u:", vec::len(s)));
            writer.write(s);
            writer.write_char(',');
        }
        integer(i) {
            let s = int::str(i);
            writer.write_str(#fmt("%u:%s#", str::byte_len(s), s));
        }
        floating(f) {
            let s = float::to_str(f, 6u);
            writer.write_str(#fmt("%u:%s^", str::byte_len(s), s));
        }
        boolean(b) {
            let s = bool::to_str(b);
            writer.write_str(#fmt("%u:%s!", str::byte_len(s), s));
        }
        map(m) {
            let buf = io::mk_mem_buffer();
            let wr = io::mem_buffer_writer(buf);
            m.items({ |key, value|
                to_writer(wr, string(key));
                to_writer(wr, value);
            });
            let payload = io::mem_buffer_buf(buf);
            writer.write_str(#fmt("%u:", vec::len(payload)));
            writer.write(payload);
            writer.write_char('}');
        }
        list(@l) {
            let buf = io::mk_mem_buffer();
            let wr = io::mem_buffer_writer(buf);
            vec::iter(l, {|e| to_writer(wr, e) });
            let payload = io::mem_buffer_buf(buf);
            writer.write_str(#fmt("%u:", vec::len(payload)));
            writer.write(payload);
            writer.write_char(']');
        }
        null {
            writer.write_str("0:~");
        }
    }
}

/*
Function: to_bytes

Serializes a tnetstring value into a byte string.
*/
fn to_bytes(t: t) -> [const u8] {
    let buf = io::mk_mem_buffer();
    let wr = io::mem_buffer_writer(buf);
    to_writer(wr, t);
    io::mem_buffer_buf(buf)
}

/*
Function: to_str

Serializes a tnetstring value into a string.
*/
fn to_str(t: t) -> str {
    let buf = io::mk_mem_buffer();
    let wr = io::mem_buffer_writer(buf);
    to_writer(wr, t);
    io::mem_buffer_str(buf)
}

/*
Function: from_reader

Deserializes a tnetstring value from an io::reader.
*/
fn from_reader(reader: io::reader) -> option::t<t> {
    assert !reader.eof();

    let c = reader.read_byte();
    let len = 0u;

    // Note that netstring spec explicitly forbids padding zeros.
    // If the first char is zero, it must be the only char.
    if c < '0' as int || c > '9' as int {
        fail "Not a tnetstring: invalid or missing length prefix";
    } else if c == '0' as int {
        c = reader.read_byte();
    } else {
        do {
            len = (10u * len) + ((c as uint) - ('0' as uint));

            if reader.eof() {
                fail "Not a tnetstring: invalid or missing length prefix";
            }
            c = reader.read_byte();
        } while c >= '0' as int && c <= '9' as int;
    }

    // Validate end-of-length-prefix marker.
    if c != ':' as int {
        fail "Not a tnetstring: missing length prefix";
    }

    // Read the data plus terminating type tag.
    let payload = reader.read_bytes(len);

    if vec::len(payload) != len {
        fail "Not a tnetstring: invalid length prefix";
    }

    if reader.eof() {
        fail "Not a tnetstring: missing type tag";
    }

    alt reader.read_byte() as char {
        '#' {
            let v = int::from_str(str::unsafe_from_bytes(payload));
            some(integer(v))
        }
        '}' { some(map(parse_map(payload))) }
        ']' { some(list(parse_list(payload))) }
        '!' {
            let v = bool::from_str(str::unsafe_from_bytes(payload));
            some(boolean(v))
        }
        '^' {
            let v = float::from_str(str::unsafe_from_bytes(payload));
            some(floating(v))
        }
        '~' {
            assert vec::len(payload) == 0u;
            some(null)
        }
        ',' { some(string(payload)) }
        c {
            let s = str::from_char(c);
            fail #fmt("Invalid payload type: %s", str::escape(s))
        }
    }
}

fn parse_list(data: [u8]) -> @[t] {
    if vec::len(data) == 0u { ret @[]; }

    let reader = io::bytes_reader(data);

    let value = from_reader(reader);
    assert option::is_some(value);
    let result = [option::get(value)];

    while !reader.eof() {
        let value = from_reader(reader);
        assert option::is_some(value);
        vec::push(result, option::get(value));
    }

    ret @result;
}

fn parse_pair(reader: io::reader) -> ([u8], t) {
    let key = from_reader(reader);
    assert option::is_some(key);
    assert !reader.eof();

    let key = alt option::get(key) {
        string(key) { key }
        _ { fail "Keys can only be strings." }
    };

    let value = from_reader(reader);
    assert option::is_some(value);

    ret (key, option::get(value));
}

fn parse_map(data: [u8]) -> map::hashmap<[u8], t> {
    if vec::len(data) == 0u { ret map::new_bytes_hash(); }

    let reader = io::bytes_reader(data);
    let (key, value) = parse_pair(reader);

    let result = map::new_bytes_hash();
    result.insert(key, value);

    while !reader.eof() {
        let (key, value) = parse_pair(reader);
        result.insert(key, value);
    }

    ret result;
}

/*
Function: from_bytes

Deserializes a tnetstring value from a byte string.
*/
fn from_bytes(data: [u8]) -> (option::t<t>, [u8]) {
    let reader = io::bytes_reader(data);
    let tnetstring = from_reader(reader);
    (tnetstring, reader.read_whole_stream())
}

/*
Function: from_str

Deserializes a tnetstring value from a string.
*/
fn from_str(data: str) -> (option::t<t>, str) {
    let reader = io::string_reader(data);
    let tnetstring = from_reader(reader);
    (tnetstring, str::unsafe_from_bytes(reader.read_whole_stream()))
}

fn eq(t0: t, t1: t) -> bool {
    alt (t0, t1) {
        (string(s0), string(s1)) { s0 == s1 }
        (integer(i0), integer(i1)) { i0 == i1 }
        (floating(f0), floating(f1)) { f0 == f1 }
        (boolean(b0), boolean(b1)) { b0 == b1 }
        (null., null.) { true }
        (map(d0), map(d1)) {
            if d0.size() == d1.size() {
                let equal = true;
                d0.items() { |k, v|
                    if !d1.contains_key(k) || !eq(d1.get(k), v) {
                        equal = false;
                    }
                };
                equal
            } else {
                false
            }
        }
        (list(l0), list(l1)) {
            vec::all2(*l0, *l1, eq)
        }
        _ { false }
    }
}

#[cfg(test)]
mod tests {
    // Tests inspired by https://github.com/rfk/tnetstring.

    fn test(string: str, expected: t) {
        let (actual, rest) = from_str(string);
        assert option::is_some(actual);
        assert rest == "";

        let actual = option::get(actual);
        assert eq(actual, expected);
        assert to_str(expected) == string;
    }

    #[test]
    fn test_format() {
        test("11:hello world,", string(str::bytes("hello world")));
        test("0:}", map(map::new_bytes_hash()));
        test("0:]", list(@[]));

        let d = map::new_bytes_hash();
        d.insert(str::bytes("hello"),
                list(@[
                    integer(12345678901),
                    string(str::bytes("this")),
                    boolean(true),
                    null,
                    string(str::bytes("\x00\x00\x00\x00"))]));

        test("51:5:hello,39:11:12345678901#4:this,4:true!0:~4:\x00\x00\x00" +
            "\x00,]}", map(d));

        test("5:12345#", integer(12345));
        test("12:this is cool,", string(str::bytes("this is cool")));
        test("0:,", string(str::bytes("")));
        test("0:~", null);
        test("4:true!", boolean(true));
        test("5:false!", boolean(false));
        test("10:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,",
            string(str::bytes("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")));
        test("24:5:12345#5:67890#5:xxxxx,]",
            list(
                @[integer(12345),
                integer(67890),
                string(str::bytes("xxxxx"))]));
        test("18:3:0.1^3:0.2^3:0.4^]",
           list(@[floating(0.1), floating(0.2), floating(0.4)]));
        test("243:238:233:228:223:218:213:208:203:198:193:188:183:178:173:" +
            "168:163:158:153:148:143:138:133:128:123:118:113:108:103:99:95:" +
            "91:87:83:79:75:71:67:63:59:55:51:47:43:39:35:31:27:23:19:15:" +
            "11:hello-there,]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" +
            "]]]]",
            list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[list(@[list(@[list(@[list(@[list(@[list(
                @[list(@[list(@[
                    string(str::bytes("hello-there"))
                ])])])])])])])])])])])])])])])])])])])])])])])])])])])])
                ])])])])])])])])])])])])])])])])])])])])])])]));
    }

    #[test]
    fn test_random() {
        fn randint(rng: rand::rng, a: u32, b: u32) -> u32 {
            (rng.next() % (b - a + 1u32)) + a
        }

        fn get_random_object(rng: rand::rng, depth: u32) -> t {
            if randint(rng, depth, 10u32) <= 4u32 {
                if randint(rng, 0u32, 1u32) == 0u32 {
                    let n = randint(rng, 0u32, 10u32);
                    list(@vec::init_fn(
                        { |_i| get_random_object(rng, depth + 1u32) },
                        n as uint))
                } else {
                    let d = map::new_bytes_hash();

                    let i = randint(rng, 0u32, 10u32);
                    while i != 0u32 {
                        let s = rng.gen_bytes(randint(rng, 0u32, 100u32) as uint);
                        d.insert(s, get_random_object(rng, depth + 1u32));
                        i -= 1u32;
                    }
                    map(d)
                }
            } else {
                alt randint(rng, 0u32, 5u32) {
                    0u32 { null }
                    1u32 { boolean(true) }
                    2u32 { boolean(false) }
                    3u32 {
                        if randint(rng, 0u32, 1u32) == 0u32 {
                            integer(rng.next() as int)
                        } else {
                            integer(-rng.next() as int)
                        }
                    }
                    4u32 {
                        let f = rng.next_float();

                        // Generate a float that can be exactly converted to
                        // and from a string.
                        while true {
                            let f1 = float::from_str(float::to_str(f, 6u));
                            if f == f1 { break; }
                            f = f1;
                        }

                        if randint(rng, 0u32, 1u32) == 0u32 {
                            floating(f)
                        } else {
                            floating(-f)
                        }
                    }
                    5u32 {
                        string(rng.gen_bytes(randint(rng, 0u32, 100u32) as uint))
                    }
                    _ { fail }
                }
            }
        }

        let rng = rand::mk_rng();

        let i = 500u;
        while i != 0u {
            let v0 = get_random_object(rng, 0u32);

            alt from_str(to_str(v0)) {
                (some(v1), "") { assert eq(v0, v1); }
                _ { fail; }
            }
            i -= 1u;
        }
    }
}
<|endoftext|>


<commit_before>//! JSON-RPC client implementation primitives.
//!
//! By default this crate does not implement any transports,
//! use corresponding features (`tls`, `http` or `ws`) to opt-in for them.
//!
//! See documentation of [`jsonrpc-client-transports`](../jsonrpc_client_transports/) for more details.

#![deny(missing_docs)]

pub use futures;
pub use jsonrpc_client_transports::*;
<commit_msg>Fix link to documentation (#620)<commit_after>//! JSON-RPC client implementation primitives.
//!
//! By default this crate does not implement any transports,
//! use corresponding features (`tls`, `http` or `ws`) to opt-in for them.
//!
//! See documentation of [`jsonrpc-client-transports`](https://docs.rs/jsonrpc-client-transports) for more details.

#![deny(missing_docs)]

pub use futures;
pub use jsonrpc_client_transports::*;
<|endoftext|>


<commit_before>use crate::{
    compiler::hir::{self, HirDb},
    discover::{run::Discover, value::Value},
    input::InputReference,
    language_server::utils::LspPositionConversion,
};

#[salsa::query_group(AnalyzeStorage)]
pub trait Analyze: Discover + HirDb + LspPositionConversion {
    fn analyze(&self, input_reference: InputReference) -> Vec<AnalyzerReport>;
}

fn analyze(db: &dyn Analyze, input_reference: InputReference) -> Vec<AnalyzerReport> {
    db.run_all(input_reference.to_owned())
        .into_iter()
        .filter_map(move |(id, value)| match value {
            Some(Ok(value)) => Some(AnalyzerReport::ValueOfExpression {
                id: id.to_owned(),
                value,
            }),
            Some(Err(value)) => Some(AnalyzerReport::ExpressionPanics {
                id: id.to_owned(),
                value,
            }),
            None => None,
        })
        .collect()
}

#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum AnalyzerReport {
    ValueOfExpression {
        id: hir::Id,
        value: Value,
    },
    ExpressionPanics {
        id: hir::Id,
        value: Value,
    },
    FunctionHasError {
        function: hir::Id,
        error_inducing_inputs: Vec<Value>,
    },
}
<commit_msg>change(compiler): reduce value hints<commit_after>use crate::{
    compiler::hir::{self, Body, Expression, HirDb, Lambda},
    discover::{run::Discover, value::Value},
    input::InputReference,
    language_server::utils::LspPositionConversion,
};

#[salsa::query_group(AnalyzeStorage)]
pub trait Analyze: Discover + HirDb + LspPositionConversion {
    fn analyze(&self, input_reference: InputReference) -> Vec<AnalyzerReport>;
}

fn analyze(db: &dyn Analyze, input_reference: InputReference) -> Vec<AnalyzerReport> {
    hir_ids_for_value_hints(db, input_reference.clone())
        .into_iter()
        .map(move |id| (id.clone(), db.run(input_reference.clone(), id)))
        .into_iter()
        .filter_map(move |(id, value)| match value {
            Some(Ok(value)) => Some(AnalyzerReport::ValueOfExpression {
                id: id.to_owned(),
                value,
            }),
            Some(Err(value)) => Some(AnalyzerReport::ExpressionPanics {
                id: id.to_owned(),
                value,
            }),
            None => None,
        })
        .collect()
}

fn hir_ids_for_value_hints(db: &dyn Analyze, input_reference: InputReference) -> Vec<hir::Id> {
    let (hir, _) = db.hir(input_reference).unwrap();
    let mut ids = vec![];
    hir.collect_hir_ids_for_value_hints(&mut ids);
    ids
}

impl Expression {
    fn collect_hir_ids_for_value_hints(&self, ids: &mut Vec<hir::Id>) {
        match self {
            Expression::Int(_) => {}
            Expression::Text(_) => {}
            Expression::Reference(_) => {}
            Expression::Symbol(_) => {}
            Expression::Lambda(Lambda { body, .. }) => {
                body.collect_hir_ids_for_value_hints(ids);
            }
            Expression::Body(body) => body.collect_hir_ids_for_value_hints(ids),
            Expression::Call { arguments, .. } => {
                ids.extend(arguments.iter().cloned());
            }
            Expression::Error => {}
        }
    }
}
impl Body {
    fn collect_hir_ids_for_value_hints(&self, ids: &mut Vec<hir::Id>) {
        for (id, expression) in &self.expressions {
            // We don't show the value if it's literally right there.
            let should_show_hints = match expression {
                Expression::Int(_) => false,
                Expression::Text(_) => false,
                Expression::Reference(_) => true,
                Expression::Symbol(_) => false,
                Expression::Lambda(_) => false,
                Expression::Body(_) => true,
                Expression::Call { .. } => true,
                Expression::Error => true,
            };
            if !should_show_hints {
                return;
            }

            ids.push(id.to_owned());
            expression.collect_hir_ids_for_value_hints(ids);
        }
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum AnalyzerReport {
    ValueOfExpression {
        id: hir::Id,
        value: Value,
    },
    ExpressionPanics {
        id: hir::Id,
        value: Value,
    },
    FunctionHasError {
        function: hir::Id,
        error_inducing_inputs: Vec<Value>,
    },
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use extra::json;
use std::hashmap::HashMap;
use serialize::Decodable;
use glfw;
use gl;
use gl::types::{
  GLfloat,
  GLint,
  GLuint,
};
use cgmath::vector::{
  Vec3,
  Vec2,
};
use glh = gl_helpers;
use camera::Camera;
use map::TileIterator;
use geom::Geom;
use tile_picker::TilePicker;
use obj;
use mesh::Mesh;
use misc::read_file;

fn build_hex_mesh(&geom: &Geom) -> ~[Vec3<GLfloat>] {
  let mut vertex_data = ~[];
  for tile_pos in TileIterator::new() {
    let pos3d = geom.map_pos_to_world_pos(tile_pos);
    for num in range(0, 6) {
      let vertex = geom.index_to_hex_vertex(num);
      let next_vertex = geom.index_to_hex_vertex(num + 1);
      vertex_data.push(pos3d + vertex);
      vertex_data.push(pos3d + next_vertex);
      vertex_data.push(pos3d + Vec3::zero());
    }
  }
  vertex_data
}

fn build_hex_tex_coord() -> ~[Vec2<GLfloat>] {
  let mut vertex_data = ~[];
  for _ in TileIterator::new() {
    for _ in range(0, 6) {
      vertex_data.push(Vec2{x: 0.0, y: 0.0});
      vertex_data.push(Vec2{x: 1.0, y: 0.0});
      vertex_data.push(Vec2{x: 0.5, y: 0.5});
    }
  }
  vertex_data
}

pub struct SceneNode {
  pos: Vec3<f32>,
}

#[deriving(Decodable)]
struct Size2<T> {
  x: T,
  y: T,
}

fn read_win_size(config_path: &str) -> Vec2<int> {
  let path = Path::new(config_path);
  let json = json::from_str(read_file(&path)).unwrap();
  let mut decoder = json::Decoder::new(json);
  let size: Size2<int> = Decodable::decode(&mut decoder);
  Vec2{x: size.x, y: size.y}
}

fn init_win(win_size: Vec2<int>) -> glfw::Window {
  glfw::set_error_callback(~glfw::LogErrorHandler);
  let init_status = glfw::init();
  if !init_status.is_ok() {
    fail!("Failed to initialize GLFW");
  }
  let win = glfw::Window::create(
    win_size.x as u32,
    win_size.y as u32,
    "Marauder",
    glfw::Windowed,
  ).unwrap();
  win.make_context_current();
  win.set_all_polling(true);
  win
}

pub struct Visualizer {
  program: GLuint,
  map_mesh: Mesh,
  unit_mesh: Mesh,
  mat_id: GLint,
  win: Option<glfw::Window>,
  mouse_pos: Vec2<f32>,
  camera: Camera,
  picker: TilePicker,
  selected_tile_pos: Option<Vec2<i32>>,
  geom: Geom,
  scene_nodes: HashMap<i32, SceneNode>,
}

impl Visualizer {
  pub fn new() -> ~Visualizer {
    let win_size = read_win_size("config.json");
    let win = init_win(win_size);
    let geom = Geom::new();
    let mut vis = ~Visualizer {
      program: 0,
      map_mesh: Mesh::new(),
      unit_mesh: Mesh::new(),
      mat_id: 0,
      win: Some(win),
      mouse_pos: Vec2::zero(),
      camera: Camera::new(),
      picker: TilePicker::new(),
      selected_tile_pos: None,
      geom: geom,
      scene_nodes: HashMap::new(),
    };
    vis.init_opengl();
    vis.picker.init(&geom);
    vis.init_models();
    vis.init_textures();
    vis.init_units();
    vis
  }

  fn init_textures(&mut self) {
  }

  fn win<'a>(&'a self) -> &'a glfw::Window {
    self.win.get_ref()
  }

  fn init_models(&mut self) {
    self.program = glh::compile_program(
      read_file(&Path::new("normal.vs.glsl")),
      read_file(&Path::new("normal.fs.glsl")),
    );
    gl::UseProgram(self.program);
    self.mat_id = glh::get_uniform(self.program, "mvp_mat");
    let position_attr = glh::get_attr(self.program, "in_vertex_coordinates");
    gl::EnableVertexAttribArray(position_attr);
    glh::vertex_attrib_pointer(position_attr, 3);
    let vt_attr = glh::get_attr(self.program, "in_texture_coordinates");
    gl::EnableVertexAttribArray(vt_attr);
    glh::vertex_attrib_pointer(vt_attr, 3);
    let map_vertex_data = build_hex_mesh(&self.geom);
    self.map_mesh.set_vertex_coords(map_vertex_data);
    self.map_mesh.set_texture_coords(build_hex_tex_coord());
    self.map_mesh.set_texture(glh::load_texture(~"data/floor.png"));
    let unit_obj = obj::Model::new("data/tank.obj");
    self.unit_mesh.set_vertex_coords(unit_obj.build());
    self.unit_mesh.set_texture_coords(unit_obj.build_tex_coord());
    self.unit_mesh.set_texture(glh::load_texture(~"data/tank.png"));
  }

  fn add_unit(&mut self, id: i32, pos: Vec2<i32>) {
    let world_pos = self.geom.map_pos_to_world_pos(pos);
    self.scene_nodes.insert(id, SceneNode{pos: world_pos});
  }

  fn init_units(&mut self) {
    self.add_unit(0, Vec2{x: 0, y: 0});
    self.add_unit(1, Vec2{x: 0, y: 1});
    self.add_unit(2, Vec2{x: 1, y: 0});
    self.add_unit(2, Vec2{x: 1, y: 1});
  }

  fn init_opengl(&mut self) {
    gl::load_with(glfw::get_proc_address);
    gl::Enable(gl::DEPTH_TEST);
  }

  fn cleanup_opengl(&self) {
    gl::DeleteProgram(self.program);
  }

  fn draw_units(&self) {
    gl::UseProgram(self.program);
    for (_, unit) in self.scene_nodes.iter() {
      let m = glh::tr(self.camera.mat(), unit.pos);
      glh::uniform_mat4f(self.mat_id, &m);
      self.unit_mesh.draw(self.program);
    }
  }

  fn draw_map(&self) {
    glh::uniform_mat4f(self.mat_id, &self.camera.mat());
    self.map_mesh.draw(self.program);
  }

  fn draw(&self) {
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
    gl::UseProgram(self.program);
    self.draw_units();
    self.draw_map();
    self.win().swap_buffers();
  }

  pub fn is_running(&self) -> bool {
    return !self.win().should_close()
  }

  fn handle_key_event(&mut self, key: glfw::Key) {
    match key {
      glfw::KeyEscape | glfw::KeyQ => {
        self.win().set_should_close(true);
      },
      glfw::KeySpace => println!("space"),
      glfw::KeyUp => self.camera.move(270.0),
      glfw::KeyDown => self.camera.move(90.0),
      glfw::KeyRight => self.camera.move(0.0),
      glfw::KeyLeft => self.camera.move(180.0),
      glfw::KeyMinus => self.camera.zoom += 1.0,
      glfw::KeyEqual => self.camera.zoom -= 1.0,
      _ => {},
    }
  }

  fn handle_cursor_pos_event(&mut self, pos: Vec2<f32>) {
    let button = self.win().get_mouse_button(glfw::MouseButtonRight);
    if button == glfw::Press {
      self.camera.z_angle += (self.mouse_pos.x - pos.x) / 2.0;
      self.camera.x_angle += (self.mouse_pos.y - pos.y) / 2.0;
    }
    self.mouse_pos = pos;
  }

  fn get_events(&mut self) -> ~[glfw::WindowEvent] {
    glfw::poll_events();
    let mut events = ~[];
    for (_, event) in self.win().flush_events() {
      events.push(event);
    }
    events
  }

  fn handle_event(&mut self, event: glfw::WindowEvent) {
    match event {
      glfw::KeyEvent(key, _, glfw::Press, _) => {
        self.handle_key_event(key);
      },
      glfw::CursorPosEvent(x, y) => {
        let p = Vec2{x: x as f32, y: y as f32};
        self.handle_cursor_pos_event(p);
      },
      glfw::SizeEvent(w, h) => {
        gl::Viewport(0, 0, w, h);
      },
      _ => {},
    }
  }

  fn handle_events(&mut self) {
    for event in self.get_events().iter() {
      self.handle_event(*event);
    }
  }

  fn pick_tile(&mut self) {
    let mouse_pos = Vec2 {
      x: self.mouse_pos.x as i32,
      y: self.mouse_pos.y as i32,
    };
    let win_size = self.win().get_size();
    self.selected_tile_pos = self.picker.pick_tile(
      win_size, &self.camera, mouse_pos);
    if !self.selected_tile_pos.is_none() {
      let map_pos = self.selected_tile_pos.unwrap();
      let pos = self.geom.map_pos_to_world_pos(map_pos);
      let unit_id = 0;
      self.scene_nodes.get_mut(&unit_id).pos = pos;
    }
  }

  pub fn tick(&mut self) {
    self.handle_events();
    self.pick_tile();
    self.draw();
  }
}

impl Drop for Visualizer {
  fn drop(&mut self) {
    self.cleanup_opengl();
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<commit_msg>Visualizer: Handle mouse button event<commit_after>// See LICENSE file for copyright and license details.

use extra::json;
use std::hashmap::HashMap;
use serialize::Decodable;
use glfw;
use gl;
use gl::types::{
  GLfloat,
  GLint,
  GLuint,
};
use cgmath::vector::{
  Vec3,
  Vec2,
};
use glh = gl_helpers;
use camera::Camera;
use map::TileIterator;
use geom::Geom;
use tile_picker::TilePicker;
use obj;
use mesh::Mesh;
use misc::read_file;

fn build_hex_mesh(&geom: &Geom) -> ~[Vec3<GLfloat>] {
  let mut vertex_data = ~[];
  for tile_pos in TileIterator::new() {
    let pos3d = geom.map_pos_to_world_pos(tile_pos);
    for num in range(0, 6) {
      let vertex = geom.index_to_hex_vertex(num);
      let next_vertex = geom.index_to_hex_vertex(num + 1);
      vertex_data.push(pos3d + vertex);
      vertex_data.push(pos3d + next_vertex);
      vertex_data.push(pos3d + Vec3::zero());
    }
  }
  vertex_data
}

fn build_hex_tex_coord() -> ~[Vec2<GLfloat>] {
  let mut vertex_data = ~[];
  for _ in TileIterator::new() {
    for _ in range(0, 6) {
      vertex_data.push(Vec2{x: 0.0, y: 0.0});
      vertex_data.push(Vec2{x: 1.0, y: 0.0});
      vertex_data.push(Vec2{x: 0.5, y: 0.5});
    }
  }
  vertex_data
}

pub struct SceneNode {
  pos: Vec3<f32>,
}

#[deriving(Decodable)]
struct Size2<T> {
  x: T,
  y: T,
}

fn read_win_size(config_path: &str) -> Vec2<int> {
  let path = Path::new(config_path);
  let json = json::from_str(read_file(&path)).unwrap();
  let mut decoder = json::Decoder::new(json);
  let size: Size2<int> = Decodable::decode(&mut decoder);
  Vec2{x: size.x, y: size.y}
}

fn init_win(win_size: Vec2<int>) -> glfw::Window {
  glfw::set_error_callback(~glfw::LogErrorHandler);
  let init_status = glfw::init();
  if !init_status.is_ok() {
    fail!("Failed to initialize GLFW");
  }
  let win = glfw::Window::create(
    win_size.x as u32,
    win_size.y as u32,
    "Marauder",
    glfw::Windowed,
  ).unwrap();
  win.make_context_current();
  win.set_all_polling(true);
  win
}

pub struct Visualizer {
  program: GLuint,
  map_mesh: Mesh,
  unit_mesh: Mesh,
  mat_id: GLint,
  win: Option<glfw::Window>,
  mouse_pos: Vec2<f32>,
  camera: Camera,
  picker: TilePicker,
  selected_tile_pos: Option<Vec2<i32>>,
  geom: Geom,
  scene_nodes: HashMap<i32, SceneNode>,
}

impl Visualizer {
  pub fn new() -> ~Visualizer {
    let win_size = read_win_size("config.json");
    let win = init_win(win_size);
    let geom = Geom::new();
    let mut vis = ~Visualizer {
      program: 0,
      map_mesh: Mesh::new(),
      unit_mesh: Mesh::new(),
      mat_id: 0,
      win: Some(win),
      mouse_pos: Vec2::zero(),
      camera: Camera::new(),
      picker: TilePicker::new(),
      selected_tile_pos: None,
      geom: geom,
      scene_nodes: HashMap::new(),
    };
    vis.init_opengl();
    vis.picker.init(&geom);
    vis.init_models();
    vis.init_textures();
    vis.init_units();
    vis
  }

  fn init_textures(&mut self) {
  }

  fn win<'a>(&'a self) -> &'a glfw::Window {
    self.win.get_ref()
  }

  fn init_models(&mut self) {
    self.program = glh::compile_program(
      read_file(&Path::new("normal.vs.glsl")),
      read_file(&Path::new("normal.fs.glsl")),
    );
    gl::UseProgram(self.program);
    self.mat_id = glh::get_uniform(self.program, "mvp_mat");
    let position_attr = glh::get_attr(self.program, "in_vertex_coordinates");
    gl::EnableVertexAttribArray(position_attr);
    glh::vertex_attrib_pointer(position_attr, 3);
    let vt_attr = glh::get_attr(self.program, "in_texture_coordinates");
    gl::EnableVertexAttribArray(vt_attr);
    glh::vertex_attrib_pointer(vt_attr, 3);
    let map_vertex_data = build_hex_mesh(&self.geom);
    self.map_mesh.set_vertex_coords(map_vertex_data);
    self.map_mesh.set_texture_coords(build_hex_tex_coord());
    self.map_mesh.set_texture(glh::load_texture(~"data/floor.png"));
    let unit_obj = obj::Model::new("data/tank.obj");
    self.unit_mesh.set_vertex_coords(unit_obj.build());
    self.unit_mesh.set_texture_coords(unit_obj.build_tex_coord());
    self.unit_mesh.set_texture(glh::load_texture(~"data/tank.png"));
  }

  fn add_unit(&mut self, id: i32, pos: Vec2<i32>) {
    let world_pos = self.geom.map_pos_to_world_pos(pos);
    self.scene_nodes.insert(id, SceneNode{pos: world_pos});
  }

  fn init_units(&mut self) {
    self.add_unit(0, Vec2{x: 0, y: 0});
    self.add_unit(1, Vec2{x: 0, y: 1});
    self.add_unit(2, Vec2{x: 1, y: 0});
    self.add_unit(2, Vec2{x: 1, y: 1});
  }

  fn init_opengl(&mut self) {
    gl::load_with(glfw::get_proc_address);
    gl::Enable(gl::DEPTH_TEST);
  }

  fn cleanup_opengl(&self) {
    gl::DeleteProgram(self.program);
  }

  fn draw_units(&self) {
    gl::UseProgram(self.program);
    for (_, unit) in self.scene_nodes.iter() {
      let m = glh::tr(self.camera.mat(), unit.pos);
      glh::uniform_mat4f(self.mat_id, &m);
      self.unit_mesh.draw(self.program);
    }
  }

  fn draw_map(&self) {
    glh::uniform_mat4f(self.mat_id, &self.camera.mat());
    self.map_mesh.draw(self.program);
  }

  fn draw(&self) {
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
    gl::UseProgram(self.program);
    self.draw_units();
    self.draw_map();
    self.win().swap_buffers();
  }

  pub fn is_running(&self) -> bool {
    return !self.win().should_close()
  }

  fn handle_key_event(&mut self, key: glfw::Key) {
    match key {
      glfw::KeyEscape | glfw::KeyQ => {
        self.win().set_should_close(true);
      },
      glfw::KeySpace => println!("space"),
      glfw::KeyUp => self.camera.move(270.0),
      glfw::KeyDown => self.camera.move(90.0),
      glfw::KeyRight => self.camera.move(0.0),
      glfw::KeyLeft => self.camera.move(180.0),
      glfw::KeyMinus => self.camera.zoom += 1.0,
      glfw::KeyEqual => self.camera.zoom -= 1.0,
      _ => {},
    }
  }

  fn handle_cursor_pos_event(&mut self, pos: Vec2<f32>) {
    let button = self.win().get_mouse_button(glfw::MouseButtonRight);
    if button == glfw::Press {
      self.camera.z_angle += (self.mouse_pos.x - pos.x) / 2.0;
      self.camera.x_angle += (self.mouse_pos.y - pos.y) / 2.0;
    }
    self.mouse_pos = pos;
  }

  fn handle_mouse_button_event(&mut self) {
    if !self.selected_tile_pos.is_none() {
      let map_pos = self.selected_tile_pos.unwrap();
      let pos = self.geom.map_pos_to_world_pos(map_pos);
      let unit_id = 0;
      self.scene_nodes.get_mut(&unit_id).pos = pos;
    }
  }

  fn get_events(&mut self) -> ~[glfw::WindowEvent] {
    glfw::poll_events();
    let mut events = ~[];
    for (_, event) in self.win().flush_events() {
      events.push(event);
    }
    events
  }

  fn handle_event(&mut self, event: glfw::WindowEvent) {
    match event {
      glfw::KeyEvent(key, _, glfw::Press, _) => {
        self.handle_key_event(key);
      },
      glfw::CursorPosEvent(x, y) => {
        let p = Vec2{x: x as f32, y: y as f32};
        self.handle_cursor_pos_event(p);
      },
      glfw::MouseButtonEvent(glfw::MouseButtonLeft, glfw::Press, _) => {
        self.handle_mouse_button_event();
      },
      glfw::SizeEvent(w, h) => {
        gl::Viewport(0, 0, w, h);
      },
      _ => {},
    }
  }

  fn handle_events(&mut self) {
    for event in self.get_events().iter() {
      self.handle_event(*event);
    }
  }

  fn pick_tile(&mut self) {
    let mouse_pos = Vec2 {
      x: self.mouse_pos.x as i32,
      y: self.mouse_pos.y as i32,
    };
    let win_size = self.win().get_size();
    self.selected_tile_pos = self.picker.pick_tile(
      win_size, &self.camera, mouse_pos);
  }

  pub fn tick(&mut self) {
    self.handle_events();
    self.pick_tile();
    self.draw();
  }
}

impl Drop for Visualizer {
  fn drop(&mut self) {
    self.cleanup_opengl();
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<|endoftext|>


<commit_before>type Callback = fn (i32, i32) -> bool;

#[no_mangle]
extern "C" fn root(x: fn(),
                   y: Callback)
{ }
<commit_msg>Remove the fn-ptr compile-test<commit_after><|endoftext|>


<commit_before>// Ensures that unicode characters are handled in the JSON output.

fn main() {
    let foo = "❤";
//      ^^^WARN unused variable
//      ^^^NOTE(>=1.17.0) #[warn(unused_variables)]
//      ^^^NOTE(>=1.21.0,<1.22.0) to disable this warning
//      ^^^NOTE(>=1.22.0,<1.25.0-beta) to avoid this warning
//      ^^^HELP(>=1.25.0-beta) consider using `_foo` instead
//      ^^^HELP(>=1.25.0-beta) /Accept Replacement:.*_foo/
}
<commit_msg>Tests: Update minor wording change 1.34<commit_after>// Ensures that unicode characters are handled in the JSON output.

fn main() {
    let foo = "❤";
//      ^^^WARN unused variable
//      ^^^NOTE(>=1.17.0) #[warn(unused_variables)]
//      ^^^NOTE(>=1.21.0,<1.22.0) to disable this warning
//      ^^^NOTE(>=1.22.0,<1.25.0-beta) to avoid this warning
//      ^^^HELP(>=1.25.0-beta) consider
//      ^^^HELP(>=1.25.0-beta) /Accept Replacement:.*_foo/
}
<|endoftext|>


<commit_before>

use xml::reader::{EventReader, XmlEvent};

use model::{ComponentDiagram};
use io::component_diagram_parser::{ComponentDiagramParser};

pub struct ComponentDiagramXmlRsParser {

}

impl ComponentDiagramXmlRsParser {
    pub fn new() -> ComponentDiagramXmlRsParser {
        return ComponentDiagramXmlRsParser {};
    }
}

impl ComponentDiagramParser for ComponentDiagramXmlRsParser {

    fn parse_bytes(&self, spec: &[u8]) -> Result<ComponentDiagram, String> {
        let parser = EventReader::new(spec);

        let mut components_name: &str;

        for e in parser {
            match e {
                Ok(XmlEvent::StartElement { name, .. }) => {
                    println!("{}", name);
                }
                Ok(XmlEvent::EndElement { name }) => {
                    println!("{}", name);
                }
                Err(e) => {
                    println!("Error: {}", e);
                    break;
                }
                _ => {}
            }
        }

        return Ok(ComponentDiagram::new("hello"));
    }

}

<commit_msg>prepared parsing<commit_after>

use xml::reader::{EventReader, XmlEvent};

use model::{ComponentDiagram};
use io::component_diagram_parser::{ComponentDiagramParser};

pub struct ComponentDiagramXmlRsParser {

}

impl ComponentDiagramXmlRsParser {
    pub fn new() -> ComponentDiagramXmlRsParser {
        return ComponentDiagramXmlRsParser {};
    }
/*
    fn parse_component_diagram<I>(&self, reader: I) -> Result<ComponentDiagram, String>
        where I: Iterator<Item=Result<XmlEvent>>  {

        //reader.next();

    }*/
}

impl ComponentDiagramParser for ComponentDiagramXmlRsParser {

    fn parse_bytes(&self, spec: &[u8]) -> Result<ComponentDiagram, String> {
        let parser = EventReader::new(spec);

        //self.hi(&(parser.into_iter()));

        let mut components_name: &str;

        for e in parser {
            match e {
                Ok(XmlEvent::StartElement { name, attributes, .. }) => {
                    println!("{} {:?}", name, attributes);
                }
                Ok(XmlEvent::EndElement { name }) => {
                    println!("{}", name);
                }
                Err(e) => {
                    println!("Error: {}", e);
                    break;
                }
                _ => {}
            }
        }

        return Ok(ComponentDiagram::new("hello"));
    }

}

<|endoftext|>