<commit_before>extern crate nalgebra as na;
#[allow(unused_imports)]
use na::{Vector,Dim,Real,Vector4,Vector3,Vector2,U1,Matrix,DVector,Dynamic,VecStorage};
use na::storage::{Storage};
use std::cmp;

enum ConvolveMode{
    Full,
    Valid,
    Same
}

fn convolve_full<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector : Vector<R,D,S>,
    kernel : Vector<R,E,Q>
    ) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
    {

        let vec = vector.len();
        let ker = kernel.len();
        let len = vec + ker - 1;
        let v = vec as i8;
        let k = ker as i8;
        let l = len as i8;
        let mut conv = DVector::<R>::zeros(len);

        for i in 0..l{
            let u_i = cmp::max(0, i - k);
            let u_f = cmp::min(i, v - 1);

            if u_i == u_f{
                conv[i as usize] += vector[u_i as usize] * kernel[(i - u_i) as usize];
            }
            else{
                for u in u_i..(u_f+1){
                    if i - u < k{
                        conv[i as usize] += vector[u as usize] * kernel[(i - u ) as usize];
                    }
                }
            }
        }
        conv
    }

fn convolve_valid<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector : Vector<R,D,S>,
    kernel : Vector<R,E,Q>
    ) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
    {
        let vec = vector.len();
        let ker = kernel.len();
        let len = vec - ker + 1;
        let mut conv = DVector::<R>::zeros(len);

        for i in 0..len {
            for j in 0..ker {
                conv[i] += vector[i + j] * kernel[ker - j - 1];
            }
        }

        conv
    }

fn convolve_same<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector : Vector<R,D,S>,
    kernel : Vector<R,E,Q>
    ) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
    {

        let vec = vector.len();
        let ker = kernel.len();
        let len = vec + ker - 1;
        let v = vec as i8;
        let k = ker as i8;
        let l = len as i8;
        let mut conv = DVector::<R>::zeros(len);

        for i in 0..l {
            let u_i = cmp::max(0, i - k);
            let u_f = cmp::min(i, v - 1);

            if u_i == u_f {
                conv[i as usize] += vector[u_i as usize] * kernel[(i - u_i) as usize];
            }
            else{
                for u in u_i..(u_f+1){
                    if i - u < k{
                        conv[i as usize] += vector[u as usize] * kernel[(i - u ) as usize];
                    }
                }
            }
        }
        conv
    }

fn convolve<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector : Vector<R,D,S>,
    kernel : Vector<R,E,Q>,
    mode : Option<ConvolveMode>
    ) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
    {
        //
        // vector is the vector, Kervel is the kervel
        // C is the returv vector
        //
        if kernel.len() > vector.len(){
            return convolve(kernel, vector, mode);
        }

        match mode.unwrap_or(ConvolveMode::Full) {
            ConvolveMode::Full => return convolve_full(vector,kernel),
            ConvolveMode::Valid => return convolve_valid(vector,kernel),
            ConvolveMode::Same => return convolve_same(vector,kernel)
        }
    }

fn main() {
    let v1 = Vector2::new(3.0,1.0);
    let v2 = Vector4::new(1.0,2.0,5.0,9.0);
    let x = convolve(v1,v2,Some(ConvolveMode::Valid));
    println!("{:?}",x)
}<commit_msg>Cleaned up some labels and steps<commit_after>extern crate nalgebra as na;
use na::storage::Storage;
#[allow(unused_imports)]
use na::{
    DMatrix, DVector, Dim, Dynamic, Matrix, Matrix2x3, Real, VecStorage, Vector, Vector2, Vector3,
    Vector4, U1,
};
use std::cmp;

enum ConvolveMode {
    Full,
    Valid,
    Same,
}

fn convolve_full<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector: Vector<R, D, S>,
    kernel: Vector<R, E, Q>,
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>> {
    let vec = vector.len();
    let ker = kernel.len();
    let newlen = vec + ker - 1;

    let mut conv = DVector::<R>::zeros(newlen);

    for i in 0..newlen {
        let u_i = if i > ker {i - ker} else {0};
        let u_f = cmp::min(i, vec - 1);

        if u_i == u_f {
            conv[i] += vector[u_i] * kernel[(i - u_i)];
        } else {
            for u in u_i..(u_f + 1) {
                if i - u < ker {
                    conv[i] += vector[u] * kernel[(i - u)];
                }
            }
        }
    }
    conv
}

fn convolve_valid<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector: Vector<R, D, S>,
    kernel: Vector<R, E, Q>,
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>> {
    let vec = vector.len();
    let ker = kernel.len();
    let newlen = vec - ker + 1;
    let mut conv = DVector::<R>::zeros(newlen);

    for i in 0..newlen {
        for j in 0..ker {
            conv[i] += vector[i + j] * kernel[ker - j - 1];
        }
    }
    conv
}

fn convolve_same<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector: Vector<R, D, S>,
    kernel: Vector<R, E, Q>,
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>> {
    let vec = vector.len();
    let ker = kernel.len();
    let newlen = vec + ker - 1;

    let mut conv = DVector::<R>::zeros(newlen);

    for i in 0..newlen {
        // let u_i = cmp::max(0, i - k);
        // let u_f = cmp::min(i, v - 1);

        // if u_i == u_f {
        //     conv[i as usize] += vector[u_i as usize] * kernel[(i - u_i) as usize];
        // } else {
        //     for u in u_i..(u_f + 1) {
        //         if i - u < k {
        //             conv[i as usize] += vector[u as usize] * kernel[(i - u) as usize];
        //         }
        //     }
        // }
    }
    conv
}

fn convolve<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
    vector: Vector<R, D, S>,
    kernel: Vector<R, E, Q>,
    mode: Option<ConvolveMode>,
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>> {
    //
    // vector is the vector, Kervel is the kervel
    // C is the returv vector
    //
    if kernel.len() > vector.len() {
        return convolve(kernel, vector, mode);
    }

    match mode.unwrap_or(ConvolveMode::Full) {
        ConvolveMode::Full => return convolve_full(vector, kernel),
        ConvolveMode::Valid => return convolve_valid(vector, kernel),
        ConvolveMode::Same => return convolve_same(vector, kernel),
    }
}

fn main() {
    let v1 = Vector2::new(3.0,1.0);
    let v2 = Vector4::new(1.0,2.0,5.0,9.0);
    let x = convolve(v1,v2,Some(ConvolveMode::Valid));
    println!("{:?}",x)

    // let m = Matrix2x3::from_anti_diagonal_element(5.0);
    // The two additional arguments represent the matrix dimensions.
    // let dm = DMatrix::from_anti_diagonal_element(2, 3, 5.0);
    let mut m = Matrix2x3::new(1.1, 1.2, 1.3,
                                2.1, 2.2, 2.3);

    // assert!(m.m11 == 0.0 && m.m12 == 0.0 && m.m13 == 5.0 &&
    //         m.m21 == 0.0 && m.m22 == 5.0 && m.m23 == 0.0);
    // assert!(dm[(0, 0)] == 0.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 5.0 &&
    //         dm[(1, 0)] == 0.0 && dm[(1, 1)] == 5.0 && dm[(1, 2)] == 0.0);
    println!("m={:?}",m);
    for i in 0..std::cmp::min(m.nrows(),m.ncols()) {
        // for j in 0..3 {
            println!("m({:?},{:?})={:?}",i,3-i-1,m[(i,3-i-1)]);
unsafe { println!("m({:?},{:?})={:?}",i,3-i-1,*m.get_unchecked_mut((i, 3-i-1))) }
        // }
    }

}
<|endoftext|>


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

use autocxx::include_cpp;
use autocxx::subclass::{is_subclass, CppSubclass};
use cxx::CxxString;
use std::cell::RefCell;

include_cpp! {
    // C++ headers we want to include.
    #include "messages.h"
    // Safety policy. We are marking that this whole C++ inclusion is unsafe
    // which means the functions themselves do not need to be marked
    // as unsafe. Other policies are possible.
    safety!(unsafe)
    // What types and functions we want to generate
    generate!("run_demo")
    generate!("register_cpp_thingies")
    generate!("register_producer")
    generate!("register_displayer")
    // Declare some C++ classes have Rust subclasses.
    subclass!("MessageDisplayer",UwuDisplayer)
    subclass!("MessageDisplayer",BoxDisplayer)
    subclass!("MessageProducer",QuoteProducer)
}

static SHAKESPEARE_QUOTES: [&str; 10] = [
    "All that glitters is not gold",
    "Hell is empty and all the devils are here.",
    "Good night, good night! parting is such sweet sorrow, That I shall say good night till it be morrow.",
    "These violent delights have violent ends...",
    "Something is rotten in the state of Denmark.",
    "Love all, trust a few, do wrong to none.",
    "The lady doth protest too much, methinks.",
    "Brevity is the soul of wit.",
    "Uneasy lies the head that wears a crown.",
    "Now is the winter of our discontent.",
];

// The following lines define a subclass of MessageDisplayer,
// together with the "subclass!" directive above in the include_cpp!
// macro. See the main function at the bottom for how this subclass
// is instantiated.

#[is_subclass]
#[derive(Default)]
pub struct UwuDisplayer {}

impl ffi::MessageDisplayer_methods for UwuDisplayer {
    fn display_message(&self, msg: &CxxString) {
        let uwu = uwuifier::uwuify_str_sse(msg.to_str().unwrap());
        println!("{}", uwu);
    }
}

// And here's a different pure virtual class.
// This one is notable only in that the interface of the C++ class
// involves std::string, yet in Rust the subclass uses
// std::unique_ptr<std::string> (for all the normal reasons in autocxx -
// for now, at least, we can't hold non-trivial C++ objects on the Rust stack.)
// All the boxing and unboxing is done automatically by autocxx layers.

#[is_subclass]
#[derive(Default)]
pub struct QuoteProducer {}

impl ffi::MessageProducer_methods for QuoteProducer {
    fn get_message(&self) -> cxx::UniquePtr<CxxString> {
        use ffi::ToCppString;
        SHAKESPEARE_QUOTES[fastrand::usize(0..SHAKESPEARE_QUOTES.len())].into_cpp()
    }
}

// Here's another subclass of the same 'displayer' class.
// This one is more complex in two ways.
//
// First, we actually want to store some data here in our subclass.
// That means we can't just allocate ourselves with Default::default().
// And that means we need to be aware of the cpp_peer field which is
// added by the #[subclass] macro.
//
// Second, we're going to simulate the observer/listener type pattern
// in C++ where a const* is used to send messages around a codebase yet
// recipients need to react by mutating themselves or otherwise actively
// doing stuff. In C++ you'd probably need a const_cast. Here we use
// interior mutability.

#[is_subclass]
pub struct BoxDisplayer {
    message_count: RefCell<usize>,
}

impl BoxDisplayer {
    fn new() -> Self {
        Self {
            // As we're allocating this class ourselves instead of using [`Default`]
            // we need to initialize the `cpp_peer` member ourselves. This member is
            // inserted by the `#[is_subclass]` annotation. autocxx will
            // later use this to store a pointer back to the C++ peer.
            cpp_peer: Default::default(),
            message_count: RefCell::new(1usize),
        }
    }
}

impl ffi::MessageDisplayer_methods for BoxDisplayer {
    fn display_message(&self, msg: &CxxString) {
        let msg = textwrap::fill(msg.to_str().unwrap(), 70);
        let horz_line = std::iter::repeat("#").take(74).collect::<String>();
        println!("{}", horz_line);
        let msgmsg = format!("Message {}", self.message_count.borrow());
        self.message_count.replace_with(|old| *old + 1usize);
        println!("# {:^70} #", msgmsg);
        println!("{}", horz_line);
        for l in msg.lines() {
            println!("# {:^70} #", l);
        }
        println!("{}", horz_line);
    }
}

fn main() {
    // Register some C++ example classes.
    ffi::register_cpp_thingies();
    // Create a message displayer. We create and pass an instance of
    // the subclass on the Rust side - that's the first parameter -
    // and also a closure which calls an appropriate C++ constructor for
    // the C++ side peer object. Constructors exist for each superclass
    // constructor, so effectively this is a call to the C++ superclass
    // constructor.
    let uwu =
        UwuDisplayer::new_rust_owned(UwuDisplayer::default(), ffi::UwuDisplayerCpp::make_unique);
    // The next line casts the &UwuDisplayerCpp to a &MessageDisplayer.
    ffi::register_displayer(uwu.as_ref().borrow().as_ref());
    // Same again for the next message displayer object.
    // In each case, we could have said `new_cpp_owned` instead, which would
    // have given us a cxx::UniquePtr that we could have passed to C++.
    let boxd = BoxDisplayer::new_rust_owned(BoxDisplayer::new(), ffi::BoxDisplayerCpp::make_unique);
    ffi::register_displayer(boxd.as_ref().borrow().as_ref());
    // Let's register a producer too.
    let shakespeare =
        QuoteProducer::new_rust_owned(QuoteProducer::default(), ffi::QuoteProducerCpp::make_unique);
    ffi::register_producer(shakespeare.as_ref().borrow().as_ref());
    ffi::run_demo();
    ffi::run_demo();
}
<commit_msg>Allow example to build on non-Intel platforms<commit_after>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use autocxx::include_cpp;
use autocxx::subclass::{is_subclass, CppSubclass};
use cxx::CxxString;
use std::cell::RefCell;

include_cpp! {
    // C++ headers we want to include.
    #include "messages.h"
    // Safety policy. We are marking that this whole C++ inclusion is unsafe
    // which means the functions themselves do not need to be marked
    // as unsafe. Other policies are possible.
    safety!(unsafe)
    // What types and functions we want to generate
    generate!("run_demo")
    generate!("register_cpp_thingies")
    generate!("register_producer")
    generate!("register_displayer")
    // Declare some C++ classes have Rust subclasses.
    subclass!("MessageDisplayer",UwuDisplayer)
    subclass!("MessageDisplayer",BoxDisplayer)
    subclass!("MessageProducer",QuoteProducer)
}

static SHAKESPEARE_QUOTES: [&str; 10] = [
    "All that glitters is not gold",
    "Hell is empty and all the devils are here.",
    "Good night, good night! parting is such sweet sorrow, That I shall say good night till it be morrow.",
    "These violent delights have violent ends...",
    "Something is rotten in the state of Denmark.",
    "Love all, trust a few, do wrong to none.",
    "The lady doth protest too much, methinks.",
    "Brevity is the soul of wit.",
    "Uneasy lies the head that wears a crown.",
    "Now is the winter of our discontent.",
];

// The following lines define a subclass of MessageDisplayer,
// together with the "subclass!" directive above in the include_cpp!
// macro. See the main function at the bottom for how this subclass
// is instantiated.

#[is_subclass]
#[derive(Default)]
pub struct UwuDisplayer {}

impl ffi::MessageDisplayer_methods for UwuDisplayer {
    fn display_message(&self, _msg: &CxxString) {
        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
        let uwu = uwuifier::uwuify_str_sse(_msg.to_str().unwrap());
        #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
        let uwu = "uwuification is unavailable for this pwatform :(";
        println!("{}", uwu);
    }
}

// And here's a different pure virtual class.
// This one is notable only in that the interface of the C++ class
// involves std::string, yet in Rust the subclass uses
// std::unique_ptr<std::string> (for all the normal reasons in autocxx -
// for now, at least, we can't hold non-trivial C++ objects on the Rust stack.)
// All the boxing and unboxing is done automatically by autocxx layers.

#[is_subclass]
#[derive(Default)]
pub struct QuoteProducer {}

impl ffi::MessageProducer_methods for QuoteProducer {
    fn get_message(&self) -> cxx::UniquePtr<CxxString> {
        use ffi::ToCppString;
        SHAKESPEARE_QUOTES[fastrand::usize(0..SHAKESPEARE_QUOTES.len())].into_cpp()
    }
}

// Here's another subclass of the same 'displayer' class.
// This one is more complex in two ways.
//
// First, we actually want to store some data here in our subclass.
// That means we can't just allocate ourselves with Default::default().
// And that means we need to be aware of the cpp_peer field which is
// added by the #[subclass] macro.
//
// Second, we're going to simulate the observer/listener type pattern
// in C++ where a const* is used to send messages around a codebase yet
// recipients need to react by mutating themselves or otherwise actively
// doing stuff. In C++ you'd probably need a const_cast. Here we use
// interior mutability.

#[is_subclass]
pub struct BoxDisplayer {
    message_count: RefCell<usize>,
}

impl BoxDisplayer {
    fn new() -> Self {
        Self {
            // As we're allocating this class ourselves instead of using [`Default`]
            // we need to initialize the `cpp_peer` member ourselves. This member is
            // inserted by the `#[is_subclass]` annotation. autocxx will
            // later use this to store a pointer back to the C++ peer.
            cpp_peer: Default::default(),
            message_count: RefCell::new(1usize),
        }
    }
}

impl ffi::MessageDisplayer_methods for BoxDisplayer {
    fn display_message(&self, msg: &CxxString) {
        let msg = textwrap::fill(msg.to_str().unwrap(), 70);
        let horz_line = std::iter::repeat("#").take(74).collect::<String>();
        println!("{}", horz_line);
        let msgmsg = format!("Message {}", self.message_count.borrow());
        self.message_count.replace_with(|old| *old + 1usize);
        println!("# {:^70} #", msgmsg);
        println!("{}", horz_line);
        for l in msg.lines() {
            println!("# {:^70} #", l);
        }
        println!("{}", horz_line);
    }
}

fn main() {
    // Register some C++ example classes.
    ffi::register_cpp_thingies();
    // Create a message displayer. We create and pass an instance of
    // the subclass on the Rust side - that's the first parameter -
    // and also a closure which calls an appropriate C++ constructor for
    // the C++ side peer object. Constructors exist for each superclass
    // constructor, so effectively this is a call to the C++ superclass
    // constructor.
    let uwu =
        UwuDisplayer::new_rust_owned(UwuDisplayer::default(), ffi::UwuDisplayerCpp::make_unique);
    // The next line casts the &UwuDisplayerCpp to a &MessageDisplayer.
    ffi::register_displayer(uwu.as_ref().borrow().as_ref());
    // Same again for the next message displayer object.
    // In each case, we could have said `new_cpp_owned` instead, which would
    // have given us a cxx::UniquePtr that we could have passed to C++.
    let boxd = BoxDisplayer::new_rust_owned(BoxDisplayer::new(), ffi::BoxDisplayerCpp::make_unique);
    ffi::register_displayer(boxd.as_ref().borrow().as_ref());
    // Let's register a producer too.
    let shakespeare =
        QuoteProducer::new_rust_owned(QuoteProducer::default(), ffi::QuoteProducerCpp::make_unique);
    ffi::register_producer(shakespeare.as_ref().borrow().as_ref());
    ffi::run_demo();
    ffi::run_demo();
}
<|endoftext|>


<commit_before>//! https://arkada38.github.io/2018/01/14/creating-a-turtle/
//!
//! This is inspired by a child's drawing of a turtle.
//! We are going to draw the turtle using arcs and straight lines.
//! To draw arcs, we use multiple Rust for-loops to create different tilt angles and
//! lengths. The more sophisticated the figure is, the more loops we need to make it.
extern crate turtle;

use turtle::{Turtle, Color, color};

const SIZE: f64 = 1.0;
const SHELL_COLOR: Color = Color {red: 62.0, green: 114.0, blue: 29.0, alpha: 1.0};
const BODY_COLOR: Color = Color {red: 119.0, green: 178.0, blue: 85.0, alpha: 1.0};
const EYE_COLOR: Color = color::BLACK;

fn main() {
    let mut turtle = Turtle::new();
    turtle.set_speed(8);

    turtle.pen_up();
    turtle.set_x(-280.0);
    turtle.set_y(-90.0);

    draw_shell(&mut turtle);

    draw_tail(&mut turtle);

    turtle.pen_up();
    turtle.right(55.0);
    turtle.forward(SIZE * 10.0);
    turtle.right(55.0);

    // Back leg
    draw_leg(&mut turtle);

    turtle.right(86.5);
    turtle.forward(SIZE * 55.0);
    turtle.right(86.0);

    // Front leg
    draw_leg(&mut turtle);

    turtle.right(54.5);
    turtle.forward(SIZE * 8.0);

    draw_neck(&mut turtle);

    turtle.right(172.6);
    turtle.forward(SIZE * 40.0);
    turtle.right(110.0);

    draw_head(&mut turtle);

    turtle.left(128.0);
    turtle.forward(SIZE * 15.0);

    draw_eye(&mut turtle);

    turtle.set_fill_color(BODY_COLOR);

    turtle.left(175.0);
    turtle.forward(SIZE * 43.0);

    // Here we start to draw highlights on the shell.
    // We have 3 highlights: on the right, in the middle and on the left.

    draw_right_highlight(&mut turtle);

    turtle.right(18.0);
    turtle.forward(SIZE * 37.0);
    turtle.set_heading(180.0);

    draw_middle_highlight(&mut turtle);

    turtle.left(24.0);
    turtle.forward(SIZE * 36.0);
    turtle.set_heading(180.0);

    draw_left_highlight(&mut turtle);/**/
}

fn draw_shell(turtle: &mut Turtle) {
    turtle.set_fill_color(SHELL_COLOR);
    turtle.begin_fill();

    for _ in 0..180 {
        turtle.forward(SIZE);
        turtle.right(1.0);
    }

    for _ in 0..90 {
        turtle.forward(SIZE / 3.0);
        turtle.right(1.0);
    }

    turtle.set_speed(5);
    let d = SIZE * 360.0 / std::f64::consts::PI;
    turtle.forward(d - d / 3.0);
    turtle.set_speed(10);

    for _ in 0..90 {
        turtle.forward(SIZE / 3.0);
        turtle.right(1.0);
    }

    turtle.end_fill();
}

fn draw_tail(turtle: &mut Turtle) {
    turtle.set_fill_color(BODY_COLOR);
    turtle.begin_fill();

    turtle.left(90.0);
    turtle.forward(SIZE);

    for _ in 0..45 {
        turtle.forward(SIZE / 3.0);
        turtle.left(1.0);
    }

    turtle.forward(SIZE * 3.0);

    for _ in 0..25 {
        turtle.forward(SIZE / 3.0);
        turtle.left(6.0);
    }

    turtle.forward(SIZE * 9.0);
    turtle.right(6.0);
    turtle.forward(SIZE * 8.0);

    turtle.end_fill();
}

fn draw_leg(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..15 {
        turtle.forward(SIZE);
        turtle.left(0.5);
    }

    for _ in 0..90 {
        turtle.forward(SIZE / 6.0);
        turtle.left(1.0);
    }

    turtle.forward(SIZE * 3.0);

    for _ in 0..90 {
        turtle.forward(SIZE / 6.0);
        turtle.left(1.0);
    }

    turtle.forward(SIZE * 14.5);

    turtle.end_fill();
}

fn draw_neck(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..15 {
        turtle.forward(SIZE * 3.0);
        turtle.left(1.5);
    }

    turtle.end_fill();
    turtle.begin_fill();

    turtle.left(100.0);
    turtle.forward(SIZE * 20.0);
    turtle.left(80.0);

    for _ in 0..4 {
        turtle.forward(SIZE * 3.7);
        turtle.left(1.5);
    }

    turtle.left(30.0);

    for _ in 0..27 {
        turtle.forward(SIZE);
        turtle.right(1.0);
    }

    turtle.end_fill();
}

// In our case the most difficult part of the turtle is head. It requires six loops to draw.
// There was a way to draw it as one circle but
// I've decided to make it look a like a real turtle's head.
fn draw_head(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..20 {
        turtle.forward(SIZE * 1.2);
        turtle.left(1.0);
    }

    for _ in 0..10 {
        turtle.forward(SIZE * 1.2);
        turtle.left(4.0);
    }

    for _ in 0..10 {
        turtle.forward(SIZE / 1.5);
        turtle.left(7.0);
    }

    for _ in 0..10 {
        turtle.forward(SIZE);
        turtle.left(2.0);
    }

    for _ in 0..50 {
        turtle.forward(SIZE / 2.5);
        turtle.left(1.0);
    }

    for _ in 0..30 {
        turtle.forward(SIZE / 3.0);
        turtle.left(1.8);
    }

    for _ in 0..10 {
        turtle.forward(SIZE / 1.5);
        turtle.left(1.8);
    }

    turtle.end_fill();
}

fn draw_eye(turtle: &mut Turtle) {
    turtle.set_fill_color(EYE_COLOR);
    turtle.begin_fill();
    for _ in 0..90 {
        turtle.forward(SIZE / 3.0);
        turtle.right(4.0);
    }
    turtle.end_fill();
}

fn draw_right_highlight(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..39 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    turtle.forward(SIZE * 36.0);

    for _ in 0..90 {
        turtle.forward(SIZE / 2.5);
        turtle.left(2.0);
    }

    for _ in 0..42 {
        turtle.forward(SIZE);
        turtle.left(0.9);
    }

    for _ in 0..26 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    turtle.end_fill();
}

fn draw_middle_highlight(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..40 {
        turtle.forward(SIZE / 4.0);
        turtle.left(2.0);
    }

    turtle.forward(SIZE * 47.0);
    turtle.left(8.5);

    for _ in 0..90 {
        turtle.forward(SIZE / 2.0);
        turtle.left(2.0);
    }
    turtle.forward(SIZE / 2.0);

    turtle.left(8.5);
    turtle.forward(SIZE * 47.0);

    for _ in 0..40 {
        turtle.left(2.0);
        turtle.forward(SIZE / 4.0);
    }

    turtle.end_fill();
}

fn draw_left_highlight(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..26 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    for _ in 0..42 {
        turtle.forward(SIZE);
        turtle.left(0.9);
    }

    for _ in 0..90 {
        turtle.forward(SIZE / 2.5);
        turtle.left(2.0);
    }

    turtle.forward(SIZE * 36.0);

    for _ in 0..39 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    turtle.end_fill();
}
<commit_msg>Removing empty comment<commit_after>//! https://arkada38.github.io/2018/01/14/creating-a-turtle/
//!
//! This is inspired by a child's drawing of a turtle.
//! We are going to draw the turtle using arcs and straight lines.
//! To draw arcs, we use multiple Rust for-loops to create different tilt angles and
//! lengths. The more sophisticated the figure is, the more loops we need to make it.
extern crate turtle;

use turtle::{Turtle, Color, color};

const SIZE: f64 = 1.0;
const SHELL_COLOR: Color = Color {red: 62.0, green: 114.0, blue: 29.0, alpha: 1.0};
const BODY_COLOR: Color = Color {red: 119.0, green: 178.0, blue: 85.0, alpha: 1.0};
const EYE_COLOR: Color = color::BLACK;

fn main() {
    let mut turtle = Turtle::new();
    turtle.set_speed(8);

    turtle.pen_up();
    turtle.set_x(-280.0);
    turtle.set_y(-90.0);

    draw_shell(&mut turtle);

    draw_tail(&mut turtle);

    turtle.pen_up();
    turtle.right(55.0);
    turtle.forward(SIZE * 10.0);
    turtle.right(55.0);

    // Back leg
    draw_leg(&mut turtle);

    turtle.right(86.5);
    turtle.forward(SIZE * 55.0);
    turtle.right(86.0);

    // Front leg
    draw_leg(&mut turtle);

    turtle.right(54.5);
    turtle.forward(SIZE * 8.0);

    draw_neck(&mut turtle);

    turtle.right(172.6);
    turtle.forward(SIZE * 40.0);
    turtle.right(110.0);

    draw_head(&mut turtle);

    turtle.left(128.0);
    turtle.forward(SIZE * 15.0);

    draw_eye(&mut turtle);

    turtle.set_fill_color(BODY_COLOR);

    turtle.left(175.0);
    turtle.forward(SIZE * 43.0);

    // Here we start to draw highlights on the shell.
    // We have 3 highlights: on the right, in the middle and on the left.

    draw_right_highlight(&mut turtle);

    turtle.right(18.0);
    turtle.forward(SIZE * 37.0);
    turtle.set_heading(180.0);

    draw_middle_highlight(&mut turtle);

    turtle.left(24.0);
    turtle.forward(SIZE * 36.0);
    turtle.set_heading(180.0);

    draw_left_highlight(&mut turtle);
}

fn draw_shell(turtle: &mut Turtle) {
    turtle.set_fill_color(SHELL_COLOR);
    turtle.begin_fill();

    for _ in 0..180 {
        turtle.forward(SIZE);
        turtle.right(1.0);
    }

    for _ in 0..90 {
        turtle.forward(SIZE / 3.0);
        turtle.right(1.0);
    }

    turtle.set_speed(5);
    let d = SIZE * 360.0 / std::f64::consts::PI;
    turtle.forward(d - d / 3.0);
    turtle.set_speed(10);

    for _ in 0..90 {
        turtle.forward(SIZE / 3.0);
        turtle.right(1.0);
    }

    turtle.end_fill();
}

fn draw_tail(turtle: &mut Turtle) {
    turtle.set_fill_color(BODY_COLOR);
    turtle.begin_fill();

    turtle.left(90.0);
    turtle.forward(SIZE);

    for _ in 0..45 {
        turtle.forward(SIZE / 3.0);
        turtle.left(1.0);
    }

    turtle.forward(SIZE * 3.0);

    for _ in 0..25 {
        turtle.forward(SIZE / 3.0);
        turtle.left(6.0);
    }

    turtle.forward(SIZE * 9.0);
    turtle.right(6.0);
    turtle.forward(SIZE * 8.0);

    turtle.end_fill();
}

fn draw_leg(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..15 {
        turtle.forward(SIZE);
        turtle.left(0.5);
    }

    for _ in 0..90 {
        turtle.forward(SIZE / 6.0);
        turtle.left(1.0);
    }

    turtle.forward(SIZE * 3.0);

    for _ in 0..90 {
        turtle.forward(SIZE / 6.0);
        turtle.left(1.0);
    }

    turtle.forward(SIZE * 14.5);

    turtle.end_fill();
}

fn draw_neck(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..15 {
        turtle.forward(SIZE * 3.0);
        turtle.left(1.5);
    }

    turtle.end_fill();
    turtle.begin_fill();

    turtle.left(100.0);
    turtle.forward(SIZE * 20.0);
    turtle.left(80.0);

    for _ in 0..4 {
        turtle.forward(SIZE * 3.7);
        turtle.left(1.5);
    }

    turtle.left(30.0);

    for _ in 0..27 {
        turtle.forward(SIZE);
        turtle.right(1.0);
    }

    turtle.end_fill();
}

// In our case the most difficult part of the turtle is head. It requires six loops to draw.
// There was a way to draw it as one circle but
// I've decided to make it look a like a real turtle's head.
fn draw_head(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..20 {
        turtle.forward(SIZE * 1.2);
        turtle.left(1.0);
    }

    for _ in 0..10 {
        turtle.forward(SIZE * 1.2);
        turtle.left(4.0);
    }

    for _ in 0..10 {
        turtle.forward(SIZE / 1.5);
        turtle.left(7.0);
    }

    for _ in 0..10 {
        turtle.forward(SIZE);
        turtle.left(2.0);
    }

    for _ in 0..50 {
        turtle.forward(SIZE / 2.5);
        turtle.left(1.0);
    }

    for _ in 0..30 {
        turtle.forward(SIZE / 3.0);
        turtle.left(1.8);
    }

    for _ in 0..10 {
        turtle.forward(SIZE / 1.5);
        turtle.left(1.8);
    }

    turtle.end_fill();
}

fn draw_eye(turtle: &mut Turtle) {
    turtle.set_fill_color(EYE_COLOR);
    turtle.begin_fill();
    for _ in 0..90 {
        turtle.forward(SIZE / 3.0);
        turtle.right(4.0);
    }
    turtle.end_fill();
}

fn draw_right_highlight(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..39 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    turtle.forward(SIZE * 36.0);

    for _ in 0..90 {
        turtle.forward(SIZE / 2.5);
        turtle.left(2.0);
    }

    for _ in 0..42 {
        turtle.forward(SIZE);
        turtle.left(0.9);
    }

    for _ in 0..26 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    turtle.end_fill();
}

fn draw_middle_highlight(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..40 {
        turtle.forward(SIZE / 4.0);
        turtle.left(2.0);
    }

    turtle.forward(SIZE * 47.0);
    turtle.left(8.5);

    for _ in 0..90 {
        turtle.forward(SIZE / 2.0);
        turtle.left(2.0);
    }
    turtle.forward(SIZE / 2.0);

    turtle.left(8.5);
    turtle.forward(SIZE * 47.0);

    for _ in 0..40 {
        turtle.left(2.0);
        turtle.forward(SIZE / 4.0);
    }

    turtle.end_fill();
}

fn draw_left_highlight(turtle: &mut Turtle) {
    turtle.begin_fill();

    for _ in 0..26 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    for _ in 0..42 {
        turtle.forward(SIZE);
        turtle.left(0.9);
    }

    for _ in 0..90 {
        turtle.forward(SIZE / 2.5);
        turtle.left(2.0);
    }

    turtle.forward(SIZE * 36.0);

    for _ in 0..39 {
        turtle.forward(SIZE / 5.0);
        turtle.left(2.0);
    }

    turtle.end_fill();
}
<|endoftext|>


<commit_before>// Copyright (c) <2015> <lummax>
// Licensed under MIT (http://opensource.org/licenses/MIT)

extern crate wayland_client;
use wayland_client::client::{FromPrimitive, Display,
                             Registry, RegistryEventHandler,
                             Seat, SeatEventHandler, SeatCapability,
                             Shm, ShmEventHandler, ShmFormat,
                             Output, OutputEventHandler, OutputSubpixel,
                             OutputTransform, OutputMode};

use std::collections::HashMap;

#[derive(Default)]
struct SeatData {
    name: String,
    capabilities: Vec<String>,
}

#[derive(Default)]
struct ShmData {
    formats: Vec<String>,
}

#[derive(Default)]
struct OutputData {
    x: i32,
    y: i32,
    physical_width: i32,
    physical_height: i32,
    subpixel: String,
    make: String,
    model: String,
    transform: String,
    modes: Vec<OutputModeData>,
}

struct OutputModeData {
    width: i32,
    height: i32,
    refresh: i32,
    flags: String,
}

struct Info {
    registry: Registry,
    seat: Option<Seat>,
    shm: Option<Shm>,
    output: Option<Output>,
    pub roundtrip: bool,
    data: HashMap<String, String>,
    seat_data: SeatData,
    shm_data: ShmData,
    output_data: OutputData,
}

impl Info {
    fn new(registry: Registry) -> Info {
        return Info {
            registry: registry,
            seat: None,
            shm: None,
            output: None,
            roundtrip: true,
            data: HashMap::new(),
            seat_data: Default::default(),
            shm_data: Default::default(),
            output_data: Default::default(),
        };
    }
}

impl RegistryEventHandler for Info {
    fn get_registry(&mut self) -> &mut Registry {
        return &mut self.registry;
    }

    fn on_global(&mut self, name: u32, interface: String, version: u32) {
        self.data.insert(interface.clone(),
                         format!("interface: '{}', version: {}, name: {}",
                                 interface, version, name));

        if interface == "wl_seat" {
            self.roundtrip = true;
            self.seat = self.registry.bind(name, version).ok();
            SeatEventHandler::connect_dispatcher(self);
        } else if interface == "wl_shm" {
            self.roundtrip = true;
            self.shm = self.registry.bind(name, version).ok();
            ShmEventHandler::connect_dispatcher(self);
        } else if interface == "wl_output" {
            self.roundtrip = true;
            self.output = self.registry.bind(name, version).ok();
            OutputEventHandler::connect_dispatcher(self);
        }
    }
}

impl SeatEventHandler for Info {
    fn get_seat(&mut self) -> &mut Seat {
        return self.seat.as_mut().unwrap();
    }

    fn on_capabilities(&mut self, capabilities: u32) {
        if capabilities & (SeatCapability::Pointer as u32) != 0 {
            self.seat_data.capabilities.push("pointer".to_string());
        }
        if capabilities & (SeatCapability::Keyboard as u32) != 0 {
            self.seat_data.capabilities.push("keyboard".to_string());
        }
        if capabilities & (SeatCapability::Touch as u32) != 0 {
            self.seat_data.capabilities.push("touch".to_string());
        }
    }

    fn on_name(&mut self, name: String) {
        self.seat_data.name = name;
    }
}

impl ShmEventHandler for Info {
    fn get_shm(&mut self) -> &mut Shm {
        return self.shm.as_mut().unwrap();
    }

    fn on_format(&mut self, format: u32) {
        self.shm_data.formats.push(format!("{:?}", ShmFormat::from_u32(format).unwrap()));
    }
}

impl OutputEventHandler for Info {
    fn get_output(&mut self) -> &mut Output {
        return self.output.as_mut().unwrap();
    }

    fn on_geometry(&mut self, x: i32, y: i32, physical_width: i32,
                   physical_height: i32, subpixel: i32, make: String, model:
                   String, transform: i32) {
        println!("on_geometry({}, {}, {}, {}, {:?}, {}, {}, {:?})", x, y,
            physical_width, physical_height,
            OutputSubpixel::from_u32(subpixel as u32).unwrap(), make, model,
            OutputTransform::from_u32(transform as u32).unwrap());
    }

    fn on_mode(&mut self, flags: u32, width: i32, height: i32, refresh: i32) {
        println!("on_mode({}, {}, {}, {})", flags, width, height, refresh);
    }

    fn on_done(&mut self) {
        println!("on_done()");
    }

    fn on_scale(&mut self, factor: i32) {
        println!("on_scale({})", factor);
    }
}

fn main() {
    let mut display = Display::connect(None).unwrap();
    let mut info = Info::new(display.get_registry().unwrap());
    RegistryEventHandler::connect_dispatcher(&mut info);

    while info.roundtrip {
        info.roundtrip = false;
        display.roundtrip();
    }
}
<commit_msg>weston-info: gather output data<commit_after>// Copyright (c) <2015> <lummax>
// Licensed under MIT (http://opensource.org/licenses/MIT)

extern crate wayland_client;
use wayland_client::client::{FromPrimitive, Display,
                             Registry, RegistryEventHandler,
                             Seat, SeatEventHandler, SeatCapability,
                             Shm, ShmEventHandler, ShmFormat,
                             Output, OutputEventHandler, OutputSubpixel,
                             OutputTransform, OutputMode};

use std::collections::HashMap;

#[derive(Default)]
struct SeatData {
    name: String,
    capabilities: Vec<String>,
}

#[derive(Default)]
struct ShmData {
    formats: Vec<String>,
}

#[derive(Default)]
struct OutputData {
    x: i32,
    y: i32,
    physical_width: i32,
    physical_height: i32,
    subpixel: String,
    make: String,
    model: String,
    transform: String,
    modes: Vec<OutputModeData>,
}

struct OutputModeData {
    width: i32,
    height: i32,
    refresh: i32,
    flags: String,
}

struct Info {
    registry: Registry,
    seat: Option<Seat>,
    shm: Option<Shm>,
    output: Option<Output>,
    pub roundtrip: bool,
    data: HashMap<String, String>,
    seat_data: SeatData,
    shm_data: ShmData,
    output_data: OutputData,
}

impl Info {
    fn new(registry: Registry) -> Info {
        return Info {
            registry: registry,
            seat: None,
            shm: None,
            output: None,
            roundtrip: true,
            data: HashMap::new(),
            seat_data: Default::default(),
            shm_data: Default::default(),
            output_data: Default::default(),
        };
    }
}

impl RegistryEventHandler for Info {
    fn get_registry(&mut self) -> &mut Registry {
        return &mut self.registry;
    }

    fn on_global(&mut self, name: u32, interface: String, version: u32) {
        self.data.insert(interface.clone(),
                         format!("interface: '{}', version: {}, name: {}",
                                 interface, version, name));

        if interface == "wl_seat" {
            self.roundtrip = true;
            self.seat = self.registry.bind(name, version).ok();
            SeatEventHandler::connect_dispatcher(self);
        } else if interface == "wl_shm" {
            self.roundtrip = true;
            self.shm = self.registry.bind(name, version).ok();
            ShmEventHandler::connect_dispatcher(self);
        } else if interface == "wl_output" {
            self.roundtrip = true;
            self.output = self.registry.bind(name, version).ok();
            OutputEventHandler::connect_dispatcher(self);
        }
    }
}

impl SeatEventHandler for Info {
    fn get_seat(&mut self) -> &mut Seat {
        return self.seat.as_mut().unwrap();
    }

    fn on_capabilities(&mut self, capabilities: u32) {
        if capabilities & (SeatCapability::Pointer as u32) != 0 {
            self.seat_data.capabilities.push("pointer".to_string());
        }
        if capabilities & (SeatCapability::Keyboard as u32) != 0 {
            self.seat_data.capabilities.push("keyboard".to_string());
        }
        if capabilities & (SeatCapability::Touch as u32) != 0 {
            self.seat_data.capabilities.push("touch".to_string());
        }
    }

    fn on_name(&mut self, name: String) {
        self.seat_data.name = name;
    }
}

impl ShmEventHandler for Info {
    fn get_shm(&mut self) -> &mut Shm {
        return self.shm.as_mut().unwrap();
    }

    fn on_format(&mut self, format: u32) {
        self.shm_data.formats.push(format!("{:?}", ShmFormat::from_u32(format).unwrap()));
    }
}

impl OutputEventHandler for Info {
    fn get_output(&mut self) -> &mut Output {
        return self.output.as_mut().unwrap();
    }

    fn on_geometry(&mut self, x: i32, y: i32, physical_width: i32,
                   physical_height: i32, subpixel: i32, make: String, model:
                   String, transform: i32) {
        self.output_data.x = x;
        self.output_data.y = y;
        self.output_data.physical_width = physical_width;
        self.output_data.physical_height = physical_height;
        self.output_data.subpixel = format!("{:?}", OutputSubpixel::from_u32(subpixel as u32).unwrap());
        self.output_data.make = make;
        self.output_data.model = model;
        self.output_data.transform = format!("{:?}", OutputTransform::from_u32(transform as u32).unwrap());
    }

    fn on_mode(&mut self, flags: u32, width: i32, height: i32, refresh: i32) {
        let mut flags_ = Vec::new();
        if flags & (OutputMode::Current as u32) != 0 {
            flags_.push("current".to_string());
        }
        if flags & (OutputMode::Preferred as u32) != 0 {
            flags_.push("preferred".to_string());
        }
        self.output_data.modes.push(OutputModeData {
            width: width,
            height: height,
            refresh: refresh,
            flags: flags_.connect(" "),
        })
    }
}

fn main() {
    let mut display = Display::connect(None).unwrap();
    let mut info = Info::new(display.get_registry().unwrap());
    RegistryEventHandler::connect_dispatcher(&mut info);

    while info.roundtrip {
        info.roundtrip = false;
        display.roundtrip();
    }
}
<|endoftext|>


<commit_before>use std::io::Read;

use errors::{Result, ErrorKind};
use types::{Tag, WireType};
use message::Message;

use byteorder::ReadBytesExt;
use byteorder::LittleEndian as LE;

/// A struct to read protocol binary files
pub struct Reader<R> {
    inner: R,
    len: usize,
}

impl<R: Read> Reader<R> {

    /// Creates a new protocol buffer reader with the maximum len of bytes to read
    pub fn from_reader(r: R, len: usize) -> Reader<R> {
        Reader { inner: r, len: len }
    }

    /// Reads next tag, `None` if all bytes have been read
    pub fn next_tag(&mut self) -> Option<Result<Tag>> {
        if self.len == 0 {
            None
        } else {
            Some(self.read_varint().map(|i| (i as u32).into()))
        }
    }

    /// Reads next tag, `None` if all bytes have been read
    pub fn next_tag_value(&mut self) -> Option<Result<u32>> {
        if self.len == 0 {
            None
        } else {
            Some(self.read_varint().map(|i| (i as u32)))
        }
    }

    fn read_varint(&mut self) -> Result<u64> {
        let mut r: u64 = 0;
        let mut i = 0;
        for _ in 0..10 {
            self.len -= 1;
            let b = self.inner.read_u8()?;
            // TODO: may overflow if i == 9
            r |= ((b & 0x7f) as u64) << i;
            if b < 0x80 {
                return Ok(r);
            }
            i += 7;
        }
        if i == 70 {
            Err(ErrorKind::Varint.into())
        } else {
            Err(ErrorKind::Eof.into())
        }
    }

    pub fn read_int32(&mut self) -> Result<i32> {
        self.read_varint().map(|i| i as i32)
    }

    pub fn read_int64(&mut self) -> Result<i64> {
        self.read_varint().map(|i| i as i64)
    }

    pub fn read_uint32(&mut self) -> Result<u32> {
        self.read_varint().map(|i| i as u32)
    }

    pub fn read_uint64(&mut self) -> Result<u64> {
        self.read_varint()
    }

    pub fn read_sint32(&mut self) -> Result<i32> {
        unimplemented!()
    }

    pub fn read_sint64(&mut self) -> Result<i64> {
        unimplemented!()
    }

    pub fn read_fixed64(&mut self) -> Result<u64> {
        self.len -= 8;
        self.inner.read_u64::<LE>().map_err(|e| e.into())
    }

    pub fn read_fixed32(&mut self) -> Result<u32> {
        self.len -= 4;
        self.inner.read_u32::<LE>().map_err(|e| e.into())
    }

    pub fn read_sfixed64(&mut self) -> Result<i64> {
        self.len -= 8;
        self.inner.read_i64::<LE>().map_err(|e| e.into())
    }

    pub fn read_sfixed32(&mut self) -> Result<i32> {
        self.len -= 4;
        self.inner.read_i32::<LE>().map_err(|e| e.into())
    }

    pub fn read_float(&mut self) -> Result<f32> {
        self.len -= 4;
        self.inner.read_f32::<LE>().map_err(|e| e.into())
    }

    pub fn read_double(&mut self) -> Result<f64> {
        self.len -= 8;
        self.inner.read_f64::<LE>().map_err(|e| e.into())
    }

    pub fn read_bool(&mut self) -> Result<bool> {
        self.read_varint().map(|i| i != 0)
    }

    pub fn read_enum<E: From<u64>>(&mut self) -> Result<E> {
        self.read_varint().map(|i| i.into())
    }

    pub fn read_bytes(&mut self) -> Result<Vec<u8>> {
        let len = self.read_varint()? as usize;
        self.len -= len;
        let mut vec = Vec::with_capacity(len);
        unsafe { vec.set_len(len); }
        self.inner.read_exact(&mut vec[..])?;
        Ok(vec)
    }

    pub fn read_string(&mut self) -> Result<String> {
        let vec = self.read_bytes()?;
        String::from_utf8(vec).map_err(|e| e.into())
    }

    pub fn read_packed_repeated_field(&mut self) -> Result<()> {
        unimplemented!()
    }

    pub fn read_message<M: Message>(&mut self) -> Result<M> {
        let len = self.read_varint()? as usize;
        let cur_len = self.len;
        self.len = len;
        let msg = M::from_reader(self)?;
        self.len = cur_len - len;
        Ok(msg)
    }

    pub fn read_unknown(&mut self, wire_type: WireType) -> Result<()> {
        let len = match wire_type {
            WireType::Varint => return self.read_varint().map(|_| ()),
            WireType::Fixed64 => 8,
            WireType::LengthDelimited => {
                let len = self.read_varint()? as usize;
                if len == 0 { return Ok(()); }
                len
            },
            WireType::StartGroup |
                WireType::EndGroup => return Err(ErrorKind::Deprecated("group").into()),
            WireType::Fixed32 => 4,
            WireType::Unknown => return Err(ErrorKind::UnknownWireType.into()),
        };

        let mut buf = Vec::with_capacity(len);
        unsafe { buf.set_len(len); }
        self.inner.read_exact(&mut buf)?;
        self.len -= len;
        Ok(())
    }

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

#[test]
fn test_varint() {
    let data: &[u8] = &[0x96, 0x01];
    let mut r = Reader::from_reader(data, data.len());
    assert_eq!(150, r.read_varint().unwrap());
    assert!(r.next_tag().is_none());
}

#[test]
fn test_next_field() {
    let data: &[u8] = &[0x08, 0x96, 0x01];
    let mut r = Reader::from_reader(data, data.len());
    let tag = r.next_tag().unwrap().unwrap();
    assert_eq!((1, WireType::Varint), tag.unpack());
    assert_eq!(150, r.read_varint().unwrap());
    assert!(r.next_tag().is_none());
}
<commit_msg>require Read instead of BufRead<commit_after>use std::io::Read;

use errors::{Result, ErrorKind};
use types::{Tag, WireType};
use message::Message;

use byteorder::ReadBytesExt;
use byteorder::LittleEndian as LE;

/// A struct to read protocol binary files
pub struct Reader<R> {
    inner: R,
    len: usize,
}

impl<R: Read> Reader<R> {

    /// Creates a new protocol buffer reader with the maximum len of bytes to read
    pub fn from_reader(r: R, len: usize) -> Reader<R> {
        Reader { inner: r, len: len }
    }

    /// Reads next tag, `None` if all bytes have been read
    pub fn next_tag(&mut self) -> Option<Result<Tag>> {
        if self.len == 0 {
            None
        } else {
            Some(self.read_varint().map(|i| (i as u32).into()))
        }
    }

    /// Reads next tag, `None` if all bytes have been read
    pub fn next_tag_value(&mut self) -> Option<Result<u32>> {
        if self.len == 0 {
            None
        } else {
            Some(self.read_varint().map(|i| (i as u32)))
        }
    }

    fn read_varint(&mut self) -> Result<u64> {
        let mut r: u64 = 0;
        let mut i = 0;
        for _ in 0..10 {
            self.len -= 1;
            let b = self.inner.read_u8()?;
            // TODO: may overflow if i == 9
            r |= ((b & 0x7f) as u64) << i;
            if b < 0x80 {
                return Ok(r);
            }
            i += 7;
        }
        if i == 70 {
            Err(ErrorKind::Varint.into())
        } else {
            Err(ErrorKind::Eof.into())
        }
    }

    pub fn read_int32(&mut self) -> Result<i32> {
        self.read_varint().map(|i| i as i32)
    }

    pub fn read_int64(&mut self) -> Result<i64> {
        self.read_varint().map(|i| i as i64)
    }

    pub fn read_uint32(&mut self) -> Result<u32> {
        self.read_varint().map(|i| i as u32)
    }

    pub fn read_uint64(&mut self) -> Result<u64> {
        self.read_varint()
    }

    pub fn read_sint32(&mut self) -> Result<i32> {
        unimplemented!()
    }

    pub fn read_sint64(&mut self) -> Result<i64> {
        unimplemented!()
    }

    pub fn read_fixed64(&mut self) -> Result<u64> {
        self.len -= 8;
        self.inner.read_u64::<LE>().map_err(|e| e.into())
    }

    pub fn read_fixed32(&mut self) -> Result<u32> {
        self.len -= 4;
        self.inner.read_u32::<LE>().map_err(|e| e.into())
    }

    pub fn read_sfixed64(&mut self) -> Result<i64> {
        self.len -= 8;
        self.inner.read_i64::<LE>().map_err(|e| e.into())
    }

    pub fn read_sfixed32(&mut self) -> Result<i32> {
        self.len -= 4;
        self.inner.read_i32::<LE>().map_err(|e| e.into())
    }

    pub fn read_float(&mut self) -> Result<f32> {
        self.len -= 4;
        self.inner.read_f32::<LE>().map_err(|e| e.into())
    }

    pub fn read_double(&mut self) -> Result<f64> {
        self.len -= 8;
        self.inner.read_f64::<LE>().map_err(|e| e.into())
    }

    pub fn read_bool(&mut self) -> Result<bool> {
        self.read_varint().map(|i| i != 0)
    }

    pub fn read_enum<E: From<u64>>(&mut self) -> Result<E> {
        self.read_varint().map(|i| i.into())
    }

    pub fn read_bytes(&mut self) -> Result<Vec<u8>> {
        let len = self.read_varint()? as usize;
        self.len -= len;
        let mut vec = Vec::with_capacity(len);
        unsafe { vec.set_len(len); }
        self.inner.read_exact(&mut vec[..])?;
        Ok(vec)
    }

    pub fn read_string(&mut self) -> Result<String> {
        let vec = self.read_bytes()?;
        String::from_utf8(vec).map_err(|e| e.into())
    }

    pub fn read_packed_repeated_field(&mut self) -> Result<()> {
        unimplemented!()
    }

    pub fn read_message<M: Message>(&mut self) -> Result<M> {
        let len = self.read_varint()? as usize;
        let cur_len = self.len;
        self.len = len;
        let msg = M::from_reader(self)?;
        self.len = cur_len - len;
        Ok(msg)
    }

    pub fn read_unknown(&mut self, wire_type: WireType) -> Result<()> {
        match wire_type {
            WireType::Varint => { self.read_varint()?; },
            WireType::Fixed64 => {
                self.len -= 8;
                let _ = self.inner.read_exact(&mut [0; 8])?;
            }
            WireType::Fixed32 => {
                self.len -= 4;
                let _ = self.inner.read_exact(&mut [0; 4])?;
            }
            WireType::LengthDelimited => {
                let len = self.read_varint()? as usize;
                if len == 0 { return Ok(()); }
                self.len -= len;
                let mut buf = Vec::with_capacity(len);
                unsafe { buf.set_len(len); }
                self.inner.read_exact(&mut buf)?;
            },
            WireType::StartGroup |
                WireType::EndGroup => { return Err(ErrorKind::Deprecated("group").into()); },
            WireType::Unknown => { return Err(ErrorKind::UnknownWireType.into()); },
        }
        Ok(())
    }

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

#[test]
fn test_varint() {
    let data: &[u8] = &[0x96, 0x01];
    let mut r = Reader::from_reader(data, data.len());
    assert_eq!(150, r.read_varint().unwrap());
    assert!(r.next_tag().is_none());
}

#[test]
fn test_next_field() {
    let data: &[u8] = &[0x08, 0x96, 0x01];
    let mut r = Reader::from_reader(data, data.len());
    let tag = r.next_tag().unwrap().unwrap();
    assert_eq!((1, WireType::Varint), tag.unpack());
    assert_eq!(150, r.read_varint().unwrap());
    assert!(r.next_tag().is_none());
}
<|endoftext|>


<commit_before>use std::{ mem, slice, string };
use handle::Owned;
use raw;
use raw::{ IV, UV, NV };
use raw::{ SVt_PVAV, SVt_PVHV, SVt_PVCV, SVt_PVGV };
use array::{ AV };
use convert::{ IntoSV, FromSV };

pub struct SV(Owned<raw::SV>);

impl SV {
    method! {
        /// Return true if SV is a real scalar value.
        simple fn is_scalar() -> bool = sv_type() < SVt_PVAV
    }
    method! {
        /// Return true if SV contains array.
        simple fn is_array() -> bool = sv_type() == SVt_PVAV
    }
    method! {
        /// Return true if SV contains hash.
        simple fn is_hash() -> bool = sv_type() == SVt_PVHV
    }
    method! {
        /// Return true if SV contains subroutine.
        simple fn is_code() -> bool = sv_type() == SVt_PVCV
    }
    method! {
        /// Return true if SV contains glob.
        simple fn is_glob() -> bool = sv_type() == SVt_PVGV
    }
    method! {
        /// Return true if SV contains a signed integer.
        ///
        /// Perl macro: ['SvIOK'](http://perldoc.perl.org/perlapi.html#SvIOK).
        simple fn iv_ok() -> bool = sv_iok() != 0
    }
    method! {
        /// Coerce the given SV to an integer and return it.
        ///
        /// Perl macro: [`SvIV`](http://perldoc.perl.org/perlapi.html#SvIV).
        simple fn iv() -> IV = sv_iv()
    }
    method! {
        /// Return true if SV contains a unsigned integer.
        ///
        /// Perl macro: ['SvUOK'](http://perldoc.perl.org/perlapi.html#SvUOK).
        simple fn uv_ok() -> bool = sv_uok() != 0
    }
    method! {
        /// Coerce the given SV to an unsigned integer and return it.
        ///
        /// Perl macro: [`SvUV`](http://perldoc.perl.org/perlapi.html#SvUV).
        simple fn uv() -> UV = sv_uv()
    }
    method! {
        /// Return true if SV contains a floating point value.
        ///
        /// Perl macro: ['SvNOK'](http://perldoc.perl.org/perlapi.html#SvNOK).
        simple fn nv_ok() -> bool = sv_nok() != 0
    }
    method! {
        /// Coerce the given SV to a floating point value and return it.
        ///
        /// Perl macro: [`SvNV`](http://perldoc.perl.org/perlapi.html#SvNV).
        simple fn nv() -> NV = sv_nv()
    }
    method! {
        /// Return true if SV contains a string.
        ///
        /// Perl macro: ['SvPOK'](http://perldoc.perl.org/perlapi.html#SvPOK).
        simple fn pv_ok() -> bool = sv_pok() != 0
    }
    method! {
        /// Return UTF8 flag on the SV.
        ///
        /// You should use this after a call to `pv()` or `str()`, in case any call to string
        /// overloading updates the internal flag.
        ///
        /// Perl macro: [`SvUTF8`](http://perldoc.perl.org/perlapi.html#SvUTF8).
        simple fn utf8() -> bool = sv_utf8() != 0
    }

    /// Return a copy of string in the SV as vector of bytes.
    ///
    /// Perl macro: [`SvPV`](http://perldoc.perl.org/perlapi.html#SvPV).
    pub fn pv(&self) -> Vec<u8> {
        unsafe {
            let mut len = 0;
            let ptr = self.pthx().sv_pv(self.as_ptr(), &mut len);
            slice::from_raw_parts(ptr as *const u8, len as usize).to_owned()
        }
    }

    /// Return a copy of string in the SV.
    ///
    /// Perl macro: [`SvPV`](http://perldoc.perl.org/perlapi.html#SvPV).
    pub fn str(&self) -> Result<String, string::FromUtf8Error> {
        String::from_utf8(self.pv())
    }

    method! {
        /// Return true if SV contains a Perl reference.
        ///
        /// Perl macro: ['SvROK'](http://perldoc.perl.org/perlapi.html#SvROK).
        simple fn rv_ok() -> bool = sv_rok() != 0
    }

    unsafe fn deref_raw(&self) -> *mut raw::SV {
        self.pthx().sv_rv(self.as_ptr())
    }

    /// Dereference RV.
    ///
    /// Return `None` if `self` is not a valid Perl reference.
    pub fn deref(&self) -> Option<SV> {
        if self.rv_ok() {
            Some(unsafe { SV::from_raw_borrowed(self.pthx(), self.deref_raw()) })
        } else {
            None
        }
    }

    /// Cast SV into AV.
    pub fn as_av(self) -> Option<AV> {
        if self.is_array() {
            Some(unsafe { AV::from_raw_owned(self.pthx(), self.into_raw() as *mut _) })
        } else {
            None
        }
    }

    /// Consume SV and convert into raw pointer.
    ///
    /// Does not decrement reference count. Returned pointer must be correctly disposed of to avoid
    /// memory leaks.
    pub fn into_raw(self) -> *mut raw::SV {
        let raw = self.0.as_ptr();
        mem::forget(self);
        raw
    }

    /// Construct new instance from a raw SV pointer without incrementing reference counter.
    ///
    /// Owned SV pointers are returned by assorted
    /// [`newSV`](http://perldoc.perl.org/perlapi.html#newSV) functions.
    pub unsafe fn from_raw_owned(pthx: raw::Interpreter, raw: *mut raw::SV) -> SV {
        SV(Owned::from_raw_owned(pthx, raw))
    }

    /// Construct new instance from a raw SV pointer and increment reference counter.
    ///
    /// Borrowed SV pointers exist on stack and are returned by functions like
    /// ['av_fetch`](http://perldoc.perl.org/perlapi.html#av_fetch) or
    /// ['hv_fetch'](http://perldoc.perl.org/perlapi.html#av_fetch).
    pub unsafe fn from_raw_borrowed(pthx: raw::Interpreter, raw: *mut raw::SV) -> SV {
        SV(Owned::from_raw_borrowed(pthx, raw))
    }

    fn pthx(&self) -> raw::Interpreter { self.0.pthx() }

    fn as_ptr(&self) -> *mut raw::SV { self.0.as_ptr() }
}

impl FromSV for IV {
    unsafe fn from_sv(pthx: raw::Interpreter, raw: *mut raw::SV) -> IV {
        pthx.sv_iv(raw)
    }
}

impl FromSV for SV {
    unsafe fn from_sv(pthx: raw::Interpreter, raw: *mut raw::SV) -> SV {
        SV::from_raw_borrowed(pthx, raw)
    }
}

impl IntoSV for IV {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe { SV::from_raw_owned(pthx, pthx.new_sv_iv(self)) }
    }
}

impl IntoSV for UV {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe { SV::from_raw_owned(pthx, pthx.new_sv_uv(self)) }
    }
}

impl IntoSV for NV {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe { SV::from_raw_owned(pthx, pthx.new_sv_nv(self)) }
    }
}

impl IntoSV for bool {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe {
            let raw = if self { pthx.sv_yes() } else { pthx.sv_no() };
            SV::from_raw_owned(pthx, raw)
        }
    }
}

impl<'a> IntoSV for &'a str {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe {
            let svp = pthx.new_sv_pvn(self.as_ptr() as *const i8,
                                      self.len() as raw::STRLEN,
                                      raw::SVf_UTF8 as raw::U32);
            SV::from_raw_owned(pthx, svp)
        }
    }
}
<commit_msg>Fix docstring.<commit_after>use std::{ mem, slice, string };
use handle::Owned;
use raw;
use raw::{ IV, UV, NV };
use raw::{ SVt_PVAV, SVt_PVHV, SVt_PVCV, SVt_PVGV };
use array::{ AV };
use convert::{ IntoSV, FromSV };

pub struct SV(Owned<raw::SV>);

impl SV {
    method! {
        /// Return true if SV is a real scalar value.
        simple fn is_scalar() -> bool = sv_type() < SVt_PVAV
    }
    method! {
        /// Return true if SV contains array.
        simple fn is_array() -> bool = sv_type() == SVt_PVAV
    }
    method! {
        /// Return true if SV contains hash.
        simple fn is_hash() -> bool = sv_type() == SVt_PVHV
    }
    method! {
        /// Return true if SV contains subroutine.
        simple fn is_code() -> bool = sv_type() == SVt_PVCV
    }
    method! {
        /// Return true if SV contains glob.
        simple fn is_glob() -> bool = sv_type() == SVt_PVGV
    }
    method! {
        /// Return true if SV contains a signed integer.
        ///
        /// Perl macro: ['SvIOK'](http://perldoc.perl.org/perlapi.html#SvIOK).
        simple fn iv_ok() -> bool = sv_iok() != 0
    }
    method! {
        /// Coerce the given SV to an integer and return it.
        ///
        /// Perl macro: [`SvIV`](http://perldoc.perl.org/perlapi.html#SvIV).
        simple fn iv() -> IV = sv_iv()
    }
    method! {
        /// Return true if SV contains a unsigned integer.
        ///
        /// Perl macro: ['SvUOK'](http://perldoc.perl.org/perlapi.html#SvUOK).
        simple fn uv_ok() -> bool = sv_uok() != 0
    }
    method! {
        /// Coerce the given SV to an unsigned integer and return it.
        ///
        /// Perl macro: [`SvUV`](http://perldoc.perl.org/perlapi.html#SvUV).
        simple fn uv() -> UV = sv_uv()
    }
    method! {
        /// Return true if SV contains a floating point value.
        ///
        /// Perl macro: ['SvNOK'](http://perldoc.perl.org/perlapi.html#SvNOK).
        simple fn nv_ok() -> bool = sv_nok() != 0
    }
    method! {
        /// Coerce the given SV to a floating point value and return it.
        ///
        /// Perl macro: [`SvNV`](http://perldoc.perl.org/perlapi.html#SvNV).
        simple fn nv() -> NV = sv_nv()
    }
    method! {
        /// Return true if SV contains a string.
        ///
        /// Perl macro: ['SvPOK'](http://perldoc.perl.org/perlapi.html#SvPOK).
        simple fn pv_ok() -> bool = sv_pok() != 0
    }
    method! {
        /// Return UTF8 flag on the SV.
        ///
        /// You should use this after a call to `pv()` or `str()`, in case any call to string
        /// overloading updates the internal flag.
        ///
        /// Perl macro: [`SvUTF8`](http://perldoc.perl.org/perlapi.html#SvUTF8).
        simple fn utf8() -> bool = sv_utf8() != 0
    }

    /// Return a copy of string in the SV as a vector of bytes.
    ///
    /// Perl macro: [`SvPV`](http://perldoc.perl.org/perlapi.html#SvPV).
    pub fn pv(&self) -> Vec<u8> {
        unsafe {
            let mut len = 0;
            let ptr = self.pthx().sv_pv(self.as_ptr(), &mut len);
            slice::from_raw_parts(ptr as *const u8, len as usize).to_owned()
        }
    }

    /// Return a copy of string in the SV.
    ///
    /// Perl macro: [`SvPV`](http://perldoc.perl.org/perlapi.html#SvPV).
    pub fn str(&self) -> Result<String, string::FromUtf8Error> {
        String::from_utf8(self.pv())
    }

    method! {
        /// Return true if SV contains a Perl reference.
        ///
        /// Perl macro: ['SvROK'](http://perldoc.perl.org/perlapi.html#SvROK).
        simple fn rv_ok() -> bool = sv_rok() != 0
    }

    unsafe fn deref_raw(&self) -> *mut raw::SV {
        self.pthx().sv_rv(self.as_ptr())
    }

    /// Dereference RV.
    ///
    /// Return `None` if `self` is not a valid Perl reference.
    pub fn deref(&self) -> Option<SV> {
        if self.rv_ok() {
            Some(unsafe { SV::from_raw_borrowed(self.pthx(), self.deref_raw()) })
        } else {
            None
        }
    }

    /// Cast SV into AV.
    pub fn as_av(self) -> Option<AV> {
        if self.is_array() {
            Some(unsafe { AV::from_raw_owned(self.pthx(), self.into_raw() as *mut _) })
        } else {
            None
        }
    }

    /// Consume SV and convert into raw pointer.
    ///
    /// Does not decrement reference count. Returned pointer must be correctly disposed of to avoid
    /// memory leaks.
    pub fn into_raw(self) -> *mut raw::SV {
        let raw = self.0.as_ptr();
        mem::forget(self);
        raw
    }

    /// Construct new instance from a raw SV pointer without incrementing reference counter.
    ///
    /// Owned SV pointers are returned by assorted
    /// [`newSV`](http://perldoc.perl.org/perlapi.html#newSV) functions.
    pub unsafe fn from_raw_owned(pthx: raw::Interpreter, raw: *mut raw::SV) -> SV {
        SV(Owned::from_raw_owned(pthx, raw))
    }

    /// Construct new instance from a raw SV pointer and increment reference counter.
    ///
    /// Borrowed SV pointers exist on stack and are returned by functions like
    /// ['av_fetch`](http://perldoc.perl.org/perlapi.html#av_fetch) or
    /// ['hv_fetch'](http://perldoc.perl.org/perlapi.html#av_fetch).
    pub unsafe fn from_raw_borrowed(pthx: raw::Interpreter, raw: *mut raw::SV) -> SV {
        SV(Owned::from_raw_borrowed(pthx, raw))
    }

    fn pthx(&self) -> raw::Interpreter { self.0.pthx() }

    fn as_ptr(&self) -> *mut raw::SV { self.0.as_ptr() }
}

impl FromSV for IV {
    unsafe fn from_sv(pthx: raw::Interpreter, raw: *mut raw::SV) -> IV {
        pthx.sv_iv(raw)
    }
}

impl FromSV for SV {
    unsafe fn from_sv(pthx: raw::Interpreter, raw: *mut raw::SV) -> SV {
        SV::from_raw_borrowed(pthx, raw)
    }
}

impl IntoSV for IV {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe { SV::from_raw_owned(pthx, pthx.new_sv_iv(self)) }
    }
}

impl IntoSV for UV {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe { SV::from_raw_owned(pthx, pthx.new_sv_uv(self)) }
    }
}

impl IntoSV for NV {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe { SV::from_raw_owned(pthx, pthx.new_sv_nv(self)) }
    }
}

impl IntoSV for bool {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe {
            let raw = if self { pthx.sv_yes() } else { pthx.sv_no() };
            SV::from_raw_owned(pthx, raw)
        }
    }
}

impl<'a> IntoSV for &'a str {
    fn into_sv(self, pthx: raw::Interpreter) -> SV {
        unsafe {
            let svp = pthx.new_sv_pvn(self.as_ptr() as *const i8,
                                      self.len() as raw::STRLEN,
                                      raw::SVf_UTF8 as raw::U32);
            SV::from_raw_owned(pthx, svp)
        }
    }
}
<|endoftext|>


<commit_before>use configuration::Configuration;
use std::slice::SliceExt;
use std::cmp::Ordering;
use score::Score;

struct Search {
    config: Configuration,
    current: uint,
    query: String,
    selection: Option<String>,
    result: Vec<String>,
}

impl Search {
    fn blank(config: Configuration) -> Search {
        let query = config.initial_search.clone();
        let previous_result = config.choices.clone();
        Search::new(config, query, previous_result, 0)
    }

    fn new(config: Configuration, query: String, result: Vec<String>, index: uint) -> Search {

        let selection = Search::select(&result, index);

        Search { config: config,
                 current: index,
                 query: query,
                 selection: selection,
                 result: result }
    }

    fn new_for_index(self, index: uint) -> Search {
        Search::new(self.config, self.query, self.result, index)
    }

    fn filter(query: &str, choices: &Vec<String>) -> Vec<String> {
        let mut filtered = choices.iter().filter_map( |choice| {
            let quality = Score::score(choice.as_slice(), query);
            if quality > 0.0 {
                Some((quality, choice.to_string()))
            } else {
                None
            }
        }).collect::<Vec<(f32, String)>>();

        filtered.sort_by( |&(quality_a, _), &(quality_b, _)| {
            quality_a.partial_cmp(&quality_b).unwrap_or(Ordering::Equal).reverse()
        });

        filtered.iter().map( |&(_, ref choice)| choice.to_string() ).collect::<Vec<String>>()
    }

    fn select(result: &Vec<String>, index: uint) -> Option<String> {
        if result.len() > 0 {
            Some(result[index].to_string())
        } else {
            None
        }
    }

    fn down(self) -> Search {
        let next_index = self.next_index();
        self.new_for_index(next_index)
    }

    fn up(self) -> Search {
        let next_index = self.prev_index();
        self.new_for_index(next_index)
    }

    fn append_to_search(self, input: &str) -> Search {
        let mut new_query = self.query;
        new_query.push_str(input.as_slice());

        let new_result    = Search::filter(new_query.as_slice(), &self.result);

        Search::new(self.config, new_query, new_result, self.current)
    }

    fn next_index(&self) -> uint {
        let next_index = self.current + 1;

        if next_index >= self.config.visible_limit { 0 } else { next_index }
    }

    fn prev_index(&self) -> uint {
        if self.current == 0 { self.config.visible_limit - 1 } else  { self.current - 1 }
    }
}

#[cfg(test)]

fn one_two_three() -> Vec<String> {
    vec!["one".to_string(),
         "two".to_string(),
         "three".to_string()]
}

#[test]
fn it_selects_the_first_choice_by_default() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.selection, Some("one".to_string()));
}

#[test]
fn it_selets_the_second_when_down_is_called() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.down().selection, Some("two".to_string()));
}

#[test]
fn it_loop_around_when_reaching_end_of_list() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.down().down().down().down().selection, Some("two".to_string()));
}

#[test]
fn it_loop_around_when_reaching_top_of_list() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.up().up().selection, Some("two".to_string()));
}

#[test]
fn it_loop_around_when_reaching_visible_limit() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, Some(2));
    let search = Search::blank(config);
    assert_eq!(search.down().down().down().selection, Some("two".to_string()));
}

#[test]
fn it_moves_down_the_filtered_search_results() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.append_to_search("t").down().selection, Some("three".to_string()));
}

#[test]
fn it_moves_down_the_filtered_search_results_twice() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.append_to_search("t").append_to_search("w").selection, Some("two".to_string()));
}

#[test]
fn it_handles_not_matching_anything() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.append_to_search("x").selection, None);
}

#[test]
fn up_match_nothing_after_filtering_all_out() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config).append_to_search("x");

    assert_eq!(search.up().selection, None);
}

#[test]
fn down_match_nothing_after_filtering_all_out() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config).append_to_search("x");

    assert_eq!(search.down().selection, None);
}
<commit_msg>Implements backspace<commit_after>use configuration::Configuration;
use std::slice::SliceExt;
use std::cmp::Ordering;
use score::Score;

struct Search {
    config: Configuration,
    current: uint,
    query: String,
    selection: Option<String>,
    result: Vec<String>,
}

impl Search {
    fn blank(config: Configuration) -> Search {
        let query = config.initial_search.clone();
        let previous_result = config.choices.clone();
        Search::new(config, query, previous_result, 0)
    }

    fn new(config: Configuration, query: String, result: Vec<String>, index: uint) -> Search {

        let selection = Search::select(&result, index);

        Search { config: config,
                 current: index,
                 query: query,
                 selection: selection,
                 result: result }
    }

    fn new_for_index(self, index: uint) -> Search {
        Search::new(self.config, self.query, self.result, index)
    }

    fn new_for_query(self, new_query: String) -> Search {
        let new_result = Search::filter(new_query.as_slice(), &self.config.choices);

        Search::new(self.config, new_query, new_result, self.current)
    }

    fn filter(query: &str, choices: &Vec<String>) -> Vec<String> {
        let mut filtered = choices.iter().filter_map( |choice| {
            let quality = Score::score(choice.as_slice(), query);
            if quality > 0.0 {
                Some((quality, choice.to_string()))
            } else {
                None
            }
        }).collect::<Vec<(f32, String)>>();

        filtered.sort_by( |&(quality_a, _), &(quality_b, _)| {
            quality_a.partial_cmp(&quality_b).unwrap_or(Ordering::Equal).reverse()
        });

        filtered.iter().map( |&(_, ref choice)| choice.to_string() ).collect::<Vec<String>>()
    }

    fn select(result: &Vec<String>, index: uint) -> Option<String> {
        if result.len() > 0 {
            Some(result[index].to_string())
        } else {
            None
        }
    }

    fn down(self) -> Search {
        let next_index = self.next_index();
        self.new_for_index(next_index)
    }

    fn up(self) -> Search {
        let next_index = self.prev_index();
        self.new_for_index(next_index)
    }

    fn append_to_search(self, input: &str) -> Search {
        let mut new_query = self.query.clone();
        new_query.push_str(input.as_slice());

        self.new_for_query(new_query)
    }

    fn backspace(self) -> Search {
        let mut new_query = self.query.clone();
        new_query.pop();

        self.new_for_query(new_query).new_for_index(0)
    }

    fn next_index(&self) -> uint {
        let next_index = self.current + 1;

        if next_index >= self.config.visible_limit { 0 } else { next_index }
    }

    fn prev_index(&self) -> uint {
        if self.current == 0 { self.config.visible_limit - 1 } else  { self.current - 1 }
    }
}

#[cfg(test)]
fn one_two_three() -> Vec<String> {
    vec!["one".to_string(),
         "two".to_string(),
         "three".to_string()]
}

#[test]
fn it_selects_the_first_choice_by_default() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.selection, Some("one".to_string()));
}

#[test]
fn it_selets_the_second_when_down_is_called() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.down().selection, Some("two".to_string()));
}

#[test]
fn it_loop_around_when_reaching_end_of_list() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.down().down().down().down().selection, Some("two".to_string()));
}

#[test]
fn it_loop_around_when_reaching_top_of_list() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.up().up().selection, Some("two".to_string()));
}

#[test]
fn it_loop_around_when_reaching_visible_limit() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, Some(2));
    let search = Search::blank(config);
    assert_eq!(search.down().down().down().selection, Some("two".to_string()));
}

#[test]
fn it_moves_down_the_filtered_search_results() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.append_to_search("t").down().selection, Some("three".to_string()));
}

#[test]
fn it_moves_down_the_filtered_search_results_twice() {
    let input =  one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.append_to_search("t").append_to_search("w").selection, Some("two".to_string()));
}

#[test]
fn it_handles_not_matching_anything() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config);
    assert_eq!(search.append_to_search("x").selection, None);
}

#[test]
fn up_match_nothing_after_filtering_all_out() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config).append_to_search("x");

    assert_eq!(search.up().selection, None);
}

#[test]
fn down_match_nothing_after_filtering_all_out() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config).append_to_search("x");

    assert_eq!(search.down().selection, None);
}

#[test]
fn backspaces_over_characters() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config).append_to_search("e");

    assert_eq!(search.query, "e");
    assert_eq!(search.backspace().query, "");
}

#[test]
fn resets_the_index() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config).append_to_search("e");

    assert_eq!(search.down().backspace().current, 0);
}

#[test]
fn previous_results_appear_after_backspace() {
    let input = one_two_three();

    let config = Configuration::from_inputs(input, None, None);
    let search = Search::blank(config).append_to_search("t");

    assert_eq!(search.backspace().result.len(), 3);
}
<|endoftext|>


<commit_before>use std::net::{TcpListener, TcpStream};
use std::collections::HashMap;

use std::thread;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender};

use std::io::prelude::*;
use std::io::BufReader;

extern crate hmacsha1;
extern crate uuid;

use self::uuid::Uuid;
use client::Client;
use distributor::Distributor;
use distributor::Kind as DistKind;

pub struct Player {
    client_idx: usize, //this is dynamic in the sense that it may be different on intial run
}

pub struct Server {
    clients: Vec<Client>, // this always grows
    players: HashMap<Uuid, Player>,
    pub dist_tx: Sender<DistKind<TcpStream>>,
}

impl Server {
    pub fn new(ip: &str) {
        let listener = TcpListener::bind(ip).unwrap();

        let (dist_tx,mut dist) = Distributor::new();
        thread::spawn(move || dist.run());

        let server = Server {
            clients: vec!(),
            players: HashMap::new(),
            dist_tx: dist_tx,
        };
        let server = Arc::new(Mutex::new(server));

        for s in listener.incoming() {
            match s {
                Ok(s) => {
                    let server = server.clone();
                    thread::spawn(|| Server::handler(server,s));
                },
                _ => {},
            }
        }
    }

    fn handler (mut server: Arc<Mutex<Server>>, mut s: TcpStream) {
        let mut cmd = [0;1];

        //new conn needs auth code
        let m = uuid::Uuid::new_v4();
        s.write_all(m.as_bytes());

        let mut client_idx = None;

        loop {
            if let Ok(_) = s.read_exact(&mut cmd) {
                match cmd[0] {
                    0 => { //login
                        if let Some(c) = Client::load(&mut s) {
                            let mut server = server.lock().unwrap();

                            let mut reg_key = None;
                            for (i,n) in server.clients.iter_mut().enumerate() {
                                if n.id == c.id {
                                    reg_key = Some(n.key);
                                    client_idx = Some(i);

                                    break
                                }
                            }

                            if let Some(key) = reg_key {
                                let hm = hmacsha1::hmac_sha1(&key, m.as_bytes());
                                if c.key == hm {
                                    server.players.insert(c.id,
                                                          Player {client_idx:client_idx.unwrap()});

                                    if let Ok(stmp) = s.try_clone() {
                                        //n.stream = Some(Arc::new(Mutex::new(stmp)));
                                        server.dist_tx.send(DistKind::Add(c.id,stmp));
                                    }

                                    println!("login:{:?}",c.id);
                                    println!("total clients:{:?}",server.clients.len());
                                }
                                else {
                                    panic!("client invalid login {:?}", c)
                                }

                            }
                            else { panic!("client unregistered {:?}", c) }
                        }
                    },
                    1 => { //register
                        if let Some(c) = Client::load(&mut s) {
                            let mut server = server.lock().unwrap();

                            for n in server.clients.iter() {
                                if n.id == c.id { continue }
                            }

                            println!("registered:{:?}",c.id);
                            server.clients.push(c);
                        }
                    },
                    2 => { //chat
                        let mut text = String::new();
                        {
                            let mut bs = BufReader::new(&s);
                            bs.read_line(&mut text);
                        }

                        if text.chars().count() > 0 {
                            println!("chat-client:{:?}",text.trim());

                            //broadcast
                            let mut data = Vec::new();
                            data.push(2u8);
                            data.append(&mut text.into_bytes());

                            let mut server = server.lock().unwrap();
                            server.dist_tx.send(DistKind::Broadcast(data));
                        }
                    },
                    _ => panic!("cmd:{:?}",cmd)
                }
            }
        }

        println!("client dropped");
    }
}
<commit_msg>logic for authentication and routing, refactor<commit_after>use std::net::{TcpListener, TcpStream};
use std::collections::HashMap;

use std::thread;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender};

use std::io::prelude::*;
use std::io::BufReader;

extern crate hmacsha1;
extern crate uuid;

use self::uuid::Uuid;
use client::Client;
use distributor::Distributor;
use distributor::Kind as DistKind;

pub struct Player {
    client_idx: usize, //this is dynamic in the sense that it may be different on intial run
}

pub struct Server {
    clients: Vec<Client>, // this always grows
    players: HashMap<Uuid, Player>,
    pub dist_tx: Sender<DistKind<TcpStream>>,
}

impl Server {
    pub fn new(ip: &str) {
        let listener = TcpListener::bind(ip).unwrap();

        let (dist_tx,mut dist) = Distributor::new();
        thread::spawn(move || dist.run());

        let server = Server {
            clients: vec!(),
            players: HashMap::new(),
            dist_tx: dist_tx,
        };
        let server = Arc::new(Mutex::new(server));

        for s in listener.incoming() {
            match s {
                Ok(s) => {
                    let server = server.clone();
                    thread::spawn(|| Server::handler(server,s));
                },
                _ => {},
            }
        }
    }

    fn handler (mut server: Arc<Mutex<Server>>, mut s: TcpStream) {
        let mut cmd = [0;1];

        //new conn needs auth code
        let m = uuid::Uuid::new_v4();
        s.write_all(m.as_bytes());

        let mut client_idx = None;

        loop {
            if let Ok(_) = s.read_exact(&mut cmd) {
                match cmd[0] {
                    0 => { //login
                        client_idx = Server::login(&mut server, &mut s, m);
                    },
                    1 => { //register
                        if let Some(c) = Client::load(&mut s) {
                            let mut server = server.lock().unwrap();

                            for n in server.clients.iter() {
                                if n.id == c.id { continue }
                            }

                            println!("registered:{:?}",c.id);
                            server.clients.push(c);
                        }
                    },
                    _ => {
                        if client_idx.is_some() {
                            match cmd[0] {
                                2 => { //chat
                                    Server::chat(&mut server, &mut s);
                                },
                                _ => panic!("unknown cmd:{:?}",cmd)
                            }
                        }
                    }
                }
            }
            else { break } //drop dead client
        }

        println!("client dropped");
    }

    fn chat (server: &mut Arc<Mutex<Server>>,
             mut s: &mut TcpStream,) {
        let mut text = String::new();
        {
            let mut bs = BufReader::new(s);
            bs.read_line(&mut text);
        }

        if text.chars().count() > 0 {
            println!("chat-client:{:?}",text.trim());

            //broadcast
            let mut data = Vec::new();
            data.push(2u8);
            data.append(&mut text.into_bytes());

            let mut server = server.lock().unwrap();
            server.dist_tx.send(DistKind::Broadcast(data));
        }
    }

    fn login (server: &mut Arc<Mutex<Server>>,
              mut s: &mut TcpStream,
              m: Uuid) -> Option<usize> {
        let mut client_idx = None;

        if let Some(c) = Client::load(&mut s) {
            let mut server = server.lock().unwrap();

            let mut reg_key = None;
            for (i,n) in server.clients.iter_mut().enumerate() {
                if n.id == c.id {
                    reg_key = Some(n.key);
                    client_idx = Some(i);

                    break
                }
            }

            if let Some(key) = reg_key {
                let hm = hmacsha1::hmac_sha1(&key, m.as_bytes());
                if c.key == hm {
                    server.players.insert(c.id,
                                          Player {client_idx:client_idx.unwrap()});

                    if let Ok(stmp) = s.try_clone() {
                        //n.stream = Some(Arc::new(Mutex::new(stmp)));
                        server.dist_tx.send(DistKind::Add(c.id,stmp));
                    }

                    println!("login:{:?}",c.id);
                    println!("total clients:{:?}",server.clients.len());
                }
                else {
                    panic!("client invalid login {:?}", c)
                }

            }
            else { panic!("client unregistered {:?}", c) }
        }

       client_idx
    }
}
<|endoftext|>