<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0373: r##"
This error occurs when an attempt is made to use data captured by a closure,
when that data may no longer exist. It's most commonly seen when attempting to
return a closure:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(|y| x + y)
}
```

Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
closed-over data by reference. This means that once `foo()` returns, `x` no
longer exists. An attempt to access `x` within the closure would thus be unsafe.

Another situation where this might be encountered is when spawning threads:

```
fn foo() {
    let x = 0u32;
    let y = 1u32;

    let thr = std::thread::spawn(|| {
        x + y
    });
}
```

Since our new thread runs in parallel, the stack frame containing `x` and `y`
may well have disappeared by the time we try to use them. Even if we call
`thr.join()` within foo (which blocks until `thr` has completed, ensuring the
stack frame won't disappear), we will not succeed: the compiler cannot prove
that this behaviour is safe, and so won't let us do it.

The solution to this problem is usually to switch to using a `move` closure.
This approach moves (or copies, where possible) data into the closure, rather
than taking references to it. For example:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(move |y| x + y)
}
```

Now that the closure has its own copy of the data, there's no need to worry
about safety.
"##,

E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example:

```
fn main() {
    let x: i32;
    let y = x; // error, use of possibly uninitialized variable
```

To fix this, ensure that any declared variables are initialized before being
used.
"##,

E0384: r##"
This error occurs when an attempt is made to reassign an immutable variable.
For example:

```
fn main(){
    let x = 3;
    x = 5; // error, reassignment of immutable variable
}
```

By default, variables in Rust are immutable. To fix this error, add the keyword
`mut` after the keyword `let` when declaring the variable. For example:

```
fn main(){
    let mut x = 3;
    x = 5;
}
```
"##,

E0387: r##"
This error occurs when an attempt is made to mutate or mutably reference data
that a closure has captured immutably. Examples of this error are shown below:

```
// Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { }

// Attempts to mutate closed-over data.  Error message reads:
// `cannot assign to data in a captured outer variable...`
fn mutable() {
    let mut x = 0u32;
    foo(|| x = 2);
}

// Attempts to take a mutable reference to closed-over data.  Error message
// reads: `cannot borrow data mutably in a captured outer variable...`
fn mut_addr() {
    let mut x = 0u32;
    foo(|| { let y = &mut x; });
}
```

The problem here is that foo is defined as accepting a parameter of type `Fn`.
Closures passed into foo will thus be inferred to be of type `Fn`, meaning that
they capture their context immutably.

The solution is to capture the data mutably. This can be done by defining `foo`
to take FnMut rather than Fn:

```
fn foo<F: FnMut()>(f: F) { }
```
"##

}

register_diagnostics! {
    E0382, // use of partially/collaterally moved value
    E0383, // partial reinitialization of uninitialized structure
    E0385, // {} in an aliasable location
    E0386, // {} in an immutable container
    E0388, // {} in a static location
    E0389  // {} in a `&` reference
}
<commit_msg>add info about cell types to diagnostic message E0387<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0373: r##"
This error occurs when an attempt is made to use data captured by a closure,
when that data may no longer exist. It's most commonly seen when attempting to
return a closure:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(|y| x + y)
}
```

Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
closed-over data by reference. This means that once `foo()` returns, `x` no
longer exists. An attempt to access `x` within the closure would thus be unsafe.

Another situation where this might be encountered is when spawning threads:

```
fn foo() {
    let x = 0u32;
    let y = 1u32;

    let thr = std::thread::spawn(|| {
        x + y
    });
}
```

Since our new thread runs in parallel, the stack frame containing `x` and `y`
may well have disappeared by the time we try to use them. Even if we call
`thr.join()` within foo (which blocks until `thr` has completed, ensuring the
stack frame won't disappear), we will not succeed: the compiler cannot prove
that this behaviour is safe, and so won't let us do it.

The solution to this problem is usually to switch to using a `move` closure.
This approach moves (or copies, where possible) data into the closure, rather
than taking references to it. For example:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(move |y| x + y)
}
```

Now that the closure has its own copy of the data, there's no need to worry
about safety.
"##,

E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example:

```
fn main() {
    let x: i32;
    let y = x; // error, use of possibly uninitialized variable
```

To fix this, ensure that any declared variables are initialized before being
used.
"##,

E0384: r##"
This error occurs when an attempt is made to reassign an immutable variable.
For example:

```
fn main(){
    let x = 3;
    x = 5; // error, reassignment of immutable variable
}
```

By default, variables in Rust are immutable. To fix this error, add the keyword
`mut` after the keyword `let` when declaring the variable. For example:

```
fn main(){
    let mut x = 3;
    x = 5;
}
```
"##,

E0387: r##"
This error occurs when an attempt is made to mutate or mutably reference data
that a closure has captured immutably. Examples of this error are shown below:

```
// Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { }

// Attempts to mutate closed-over data.  Error message reads:
// `cannot assign to data in a captured outer variable...`
fn mutable() {
    let mut x = 0u32;
    foo(|| x = 2);
}

// Attempts to take a mutable reference to closed-over data.  Error message
// reads: `cannot borrow data mutably in a captured outer variable...`
fn mut_addr() {
    let mut x = 0u32;
    foo(|| { let y = &mut x; });
}
```

The problem here is that foo is defined as accepting a parameter of type `Fn`.
Closures passed into foo will thus be inferred to be of type `Fn`, meaning that
they capture their context immutably.

If the definition of `foo` is under your control, the simplest solution is to
capture the data mutably. This can be done by defining `foo` to take FnMut
rather than Fn:

```
fn foo<F: FnMut()>(f: F) { }
```

Alternatively, we can consider using the `Cell` and `RefCell` types to achieve
interior mutability through a shared reference. Our example's `mutable` function
could be redefined as below:

```
fn mutable() {
    let x = std::cell::Cell::new(0u32);
    foo(|| x.set(2));
}
```

You can read more about cell types in the API documentation:

https://doc.rust-lang.org/std/cell/
"##

}

register_diagnostics! {
    E0382, // use of partially/collaterally moved value
    E0383, // partial reinitialization of uninitialized structure
    E0385, // {} in an aliasable location
    E0386, // {} in an immutable container
    E0388, // {} in a static location
    E0389  // {} in a `&` reference
}
<|endoftext|>


<commit_before>use crate::rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_hir as hir;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
use rustc_infer::traits;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{ToPredicate, WithConstness};
use rustc_span::DUMMY_SP;

use super::*;

crate struct BlanketImplFinder<'a, 'tcx> {
    crate cx: &'a mut core::DocContext<'tcx>,
}

impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
    crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
        let param_env = self.cx.tcx.param_env(item_def_id);
        let ty = self.cx.tcx.type_of(item_def_id);

        debug!("get_blanket_impls({:?})", ty);
        let mut impls = Vec::new();
        for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() {
            if !self.cx.cache.access_levels.is_public(trait_def_id)
                || self.cx.generated_synthetics.get(&(ty, trait_def_id)).is_some()
            {
                continue;
            }
            self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
                debug!(
                    "get_blanket_impls: Considering impl for trait '{:?}' {:?}",
                    trait_def_id, impl_def_id
                );
                let trait_ref = self.cx.tcx.impl_trait_ref(impl_def_id).unwrap();
                let may_apply = self.cx.tcx.infer_ctxt().enter(|infcx| {
                    match trait_ref.self_ty().kind() {
                        ty::Param(_) => {}
                        _ => return false,
                    }

                    let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
                    let ty = ty.subst(infcx.tcx, substs);
                    let param_env = param_env.subst(infcx.tcx, substs);

                    let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
                    let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);

                    // Require the type the impl is implemented on to match
                    // our type, and ignore the impl if there was a mismatch.
                    let cause = traits::ObligationCause::dummy();
                    let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty);
                    if let Ok(InferOk { value: (), obligations }) = eq_result {
                        // FIXME(eddyb) ignoring `obligations` might cause false positives.
                        drop(obligations);

                        debug!(
                            "invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
                            param_env, trait_ref, ty
                        );
                        let predicates = self
                            .cx
                            .tcx
                            .predicates_of(impl_def_id)
                            .instantiate(self.cx.tcx, impl_substs)
                            .predicates
                            .into_iter()
                            .chain(Some(trait_ref.without_const().to_predicate(infcx.tcx)));
                        for predicate in predicates {
                            debug!("testing predicate {:?}", predicate);
                            let obligation = traits::Obligation::new(
                                traits::ObligationCause::dummy(),
                                param_env,
                                predicate,
                            );
                            match infcx.evaluate_obligation(&obligation) {
                                Ok(eval_result) if eval_result.may_apply() => {}
                                Err(traits::OverflowError) => {}
                                _ => {
                                    return false;
                                }
                            }
                        }
                        true
                    } else {
                        false
                    }
                });
                debug!(
                    "get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}",
                    may_apply, trait_ref, ty
                );
                if !may_apply {
                    return;
                }

                self.cx.generated_synthetics.insert((ty, trait_def_id));
                let provided_trait_methods = self
                    .cx
                    .tcx
                    .provided_trait_methods(trait_def_id)
                    .map(|meth| meth.ident.name)
                    .collect();

                impls.push(Item {
                    span: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
                    name: None,
                    attrs: Default::default(),
                    visibility: Inherited,
                    def_id: self.cx.next_def_id(impl_def_id.krate),
                    kind: box ImplItem(Impl {
                        unsafety: hir::Unsafety::Normal,
                        generics: (
                            self.cx.tcx.generics_of(impl_def_id),
                            self.cx.tcx.explicit_predicates_of(impl_def_id),
                        )
                            .clean(self.cx),
                        provided_trait_methods,
                        // FIXME(eddyb) compute both `trait_` and `for_` from
                        // the post-inference `trait_ref`, as it's more accurate.
                        trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
                        for_: ty.clean(self.cx),
                        items: self
                            .cx
                            .tcx
                            .associated_items(impl_def_id)
                            .in_definition_order()
                            .collect::<Vec<_>>()
                            .clean(self.cx),
                        negative_polarity: false,
                        synthetic: false,
                        blanket_impl: Some(trait_ref.self_ty().clean(self.cx)),
                    }),
                });
            });
        }
        impls
    }
}
<commit_msg>Auto merge of #82864 - jyn514:short-circuit, r=GuillaumeGomez<commit_after>use crate::rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_hir as hir;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
use rustc_infer::traits;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{ToPredicate, WithConstness};
use rustc_span::DUMMY_SP;

use super::*;

crate struct BlanketImplFinder<'a, 'tcx> {
    crate cx: &'a mut core::DocContext<'tcx>,
}

impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
    crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
        let param_env = self.cx.tcx.param_env(item_def_id);
        let ty = self.cx.tcx.type_of(item_def_id);

        debug!("get_blanket_impls({:?})", ty);
        let mut impls = Vec::new();
        for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() {
            if !self.cx.cache.access_levels.is_public(trait_def_id)
                || self.cx.generated_synthetics.get(&(ty, trait_def_id)).is_some()
            {
                continue;
            }
            self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
                debug!(
                    "get_blanket_impls: Considering impl for trait '{:?}' {:?}",
                    trait_def_id, impl_def_id
                );
                let trait_ref = self.cx.tcx.impl_trait_ref(impl_def_id).unwrap();
                let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_));
                let may_apply = is_param && self.cx.tcx.infer_ctxt().enter(|infcx| {
                    let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
                    let ty = ty.subst(infcx.tcx, substs);
                    let param_env = param_env.subst(infcx.tcx, substs);

                    let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
                    let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);

                    // Require the type the impl is implemented on to match
                    // our type, and ignore the impl if there was a mismatch.
                    let cause = traits::ObligationCause::dummy();
                    let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty);
                    if let Ok(InferOk { value: (), obligations }) = eq_result {
                        // FIXME(eddyb) ignoring `obligations` might cause false positives.
                        drop(obligations);

                        debug!(
                            "invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
                            param_env, trait_ref, ty
                        );
                        let predicates = self
                            .cx
                            .tcx
                            .predicates_of(impl_def_id)
                            .instantiate(self.cx.tcx, impl_substs)
                            .predicates
                            .into_iter()
                            .chain(Some(trait_ref.without_const().to_predicate(infcx.tcx)));
                        for predicate in predicates {
                            debug!("testing predicate {:?}", predicate);
                            let obligation = traits::Obligation::new(
                                traits::ObligationCause::dummy(),
                                param_env,
                                predicate,
                            );
                            match infcx.evaluate_obligation(&obligation) {
                                Ok(eval_result) if eval_result.may_apply() => {}
                                Err(traits::OverflowError) => {}
                                _ => {
                                    return false;
                                }
                            }
                        }
                        true
                    } else {
                        false
                    }
                });
                debug!(
                    "get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}",
                    may_apply, trait_ref, ty
                );
                if !may_apply {
                    return;
                }

                self.cx.generated_synthetics.insert((ty, trait_def_id));
                let provided_trait_methods = self
                    .cx
                    .tcx
                    .provided_trait_methods(trait_def_id)
                    .map(|meth| meth.ident.name)
                    .collect();

                impls.push(Item {
                    span: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
                    name: None,
                    attrs: Default::default(),
                    visibility: Inherited,
                    def_id: self.cx.next_def_id(impl_def_id.krate),
                    kind: box ImplItem(Impl {
                        unsafety: hir::Unsafety::Normal,
                        generics: (
                            self.cx.tcx.generics_of(impl_def_id),
                            self.cx.tcx.explicit_predicates_of(impl_def_id),
                        )
                            .clean(self.cx),
                        provided_trait_methods,
                        // FIXME(eddyb) compute both `trait_` and `for_` from
                        // the post-inference `trait_ref`, as it's more accurate.
                        trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
                        for_: ty.clean(self.cx),
                        items: self
                            .cx
                            .tcx
                            .associated_items(impl_def_id)
                            .in_definition_order()
                            .collect::<Vec<_>>()
                            .clean(self.cx),
                        negative_polarity: false,
                        synthetic: false,
                        blanket_impl: Some(trait_ref.self_ty().clean(self.cx)),
                    }),
                });
            });
        }
        impls
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(cfg_target_has_atomic, no_core, intrinsics, lang_items)]
#![crate_type="rlib"]
#![no_core]

extern "rust-intrinsic" {
    fn atomic_xadd<T>(dst: *mut T, src: T) -> T;
}

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

#[cfg(target_has_atomic = "8")]
pub unsafe fn atomic_u8(x: *mut u8) {
    atomic_xadd(x, 1);
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "8")]
pub unsafe fn atomic_i8(x: *mut i8) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "16")]
pub unsafe fn atomic_u16(x: *mut u16) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "16")]
pub unsafe fn atomic_i16(x: *mut i16) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "32")]
pub unsafe fn atomic_u32(x: *mut u32) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "32")]
pub unsafe fn atomic_i32(x: *mut i32) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "64")]
pub unsafe fn atomic_u64(x: *mut u64) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "64")]
pub unsafe fn atomic_i64(x: *mut i64) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "ptr")]
pub unsafe fn atomic_usize(x: *mut usize) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "ptr")]
pub unsafe fn atomic_isize(x: *mut isize) {
    atomic_xadd(x, 1);
}
<commit_msg>fix `atomic_lock_free` test case<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(cfg_target_has_atomic, no_core, intrinsics, lang_items)]
#![crate_type="rlib"]
#![no_core]

extern "rust-intrinsic" {
    fn atomic_xadd<T>(dst: *mut T, src: T) -> T;
}

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
#[lang = "freeze"]
trait Freeze {}

#[cfg(target_has_atomic = "8")]
pub unsafe fn atomic_u8(x: *mut u8) {
    atomic_xadd(x, 1);
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "8")]
pub unsafe fn atomic_i8(x: *mut i8) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "16")]
pub unsafe fn atomic_u16(x: *mut u16) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "16")]
pub unsafe fn atomic_i16(x: *mut i16) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "32")]
pub unsafe fn atomic_u32(x: *mut u32) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "32")]
pub unsafe fn atomic_i32(x: *mut i32) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "64")]
pub unsafe fn atomic_u64(x: *mut u64) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "64")]
pub unsafe fn atomic_i64(x: *mut i64) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "ptr")]
pub unsafe fn atomic_usize(x: *mut usize) {
    atomic_xadd(x, 1);
}
#[cfg(target_has_atomic = "ptr")]
pub unsafe fn atomic_isize(x: *mut isize) {
    atomic_xadd(x, 1);
}
<|endoftext|>


<commit_before><commit_msg>fix(Cron utilities): Add AM/PM parsing for times<commit_after><|endoftext|>


<commit_before>extern crate http;
extern crate iron;

use std::io::net::ip::Ipv4Addr;
use iron::{Iron, Request, Response, IronResult};
use iron::status;

fn hello_world(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with(status::Ok, "Hello world!"))
}

fn main() {
    Iron::new(hello_world).listen(Ipv4Addr(127, 0, 0, 1), 3000);
    println!("On 3000");
}

<commit_msg>(chore) Remove the explicit dependency on http in the hello-world example.<commit_after>extern crate iron;

use std::io::net::ip::Ipv4Addr;
use iron::{Iron, Request, Response, IronResult};
use iron::status;

fn hello_world(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with(status::Ok, "Hello world!"))
}

fn main() {
    Iron::new(hello_world).listen(Ipv4Addr(127, 0, 0, 1), 3000);
    println!("On 3000");
}

<|endoftext|>


<commit_before><commit_msg>Simplify the vertex and index buffer reallocation<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std;
use io;
use message::*;
use serialize::*;

#[inline]
unsafe fn ptr_inc(p : &mut *mut u8, count : int) {
    *p = std::ptr::mut_offset(*p, count);
}

#[inline]
unsafe fn ptr_sub<T>(p1 : * T, p2 : * T) -> uint {
    let p1Addr : uint = std::cast::transmute(p1);
    let p2Addr : uint = std::cast::transmute(p2);
    return (p1Addr - p2Addr) / std::mem::size_of::<T>();
}

#[inline]
unsafe fn mut_ptr_sub <T>(p1 : *mut T, p2 : *mut T) -> uint {
    let p1Addr : uint = std::cast::transmute(p1);
    let p2Addr : uint = std::cast::transmute(p2);
    return (p1Addr - p2Addr) / std::mem::size_of::<T>();
}

pub struct PackedInputStream<'a, 'b,  R> {
    inner : &'a mut io::BufferedInputStream<'b, R>
}

macro_rules! refresh_buffer(
    ($inner:expr, $size:ident, $inPtr:ident, $inEnd:ident, $out:ident,
     $outBuf:ident, $bufferBegin:ident) => (
        {
            $inner.skip($size);
            let (b, e) = $inner.getReadBuffer();
            $inPtr = b;
            $inEnd = e;
            $size = ptr_sub($inEnd, $inPtr);
            $bufferBegin = b;
            assert!($size > 0);
        }
        );
    )

impl <'a, 'b, R : std::io::Reader> std::io::Reader for PackedInputStream<'a, 'b, R> {
    fn eof(&mut self) -> bool {
        self.inner.eof()
    }

    fn read(&mut self, outBuf: &mut [u8]) -> Option<uint> {
        let len = outBuf.len();

        if (len == 0) { return Some(0); }

        assert!(len % 8 == 0, "PackInputStream reads must be word-aligned");

        unsafe {
            let mut out = outBuf.unsafe_mut_ref(0);
            let outEnd = outBuf.unsafe_mut_ref(len);

            let (mut inPtr, mut inEnd) = self.inner.getReadBuffer();
            let mut bufferBegin = inPtr;
            let mut size = ptr_sub(inEnd, inPtr);
            if size == 0 {
                return Some(0);
            }

            loop {

                let mut tag : u8;

                assert!(mut_ptr_sub(out, outBuf.unsafe_mut_ref(0)) % 8 == 0,
                        "Output pointer should always be aligned here.");

                if ptr_sub(inEnd, inPtr) < 10 {
                    if out >= outEnd {
                        self.inner.skip(ptr_sub(inPtr, bufferBegin));
                        return Some(mut_ptr_sub(out, outBuf.unsafe_mut_ref(0)));
                    }

                    if ptr_sub(inEnd, inPtr) == 0 {
                        refresh_buffer!(self.inner, size, inPtr, inEnd, out, outBuf, bufferBegin);
                        continue;
                    }

                    //# We have at least 1, but not 10, bytes availabe. We need to read
                    //# slowly, doing a bounds check on each byte.

                    tag = *inPtr;
                    inPtr = std::ptr::offset(inPtr, 1);

                    for i in range(0, 8) {
                        if (tag & (1u8 << i)) != 0 {
                            if ptr_sub(inEnd, inPtr) == 0 {
                                refresh_buffer!(self.inner, size, inPtr, inEnd,
                                                out, outBuf, bufferBegin);
                            }
                            *out = *inPtr;
                            out = std::ptr::mut_offset(out, 1);
                            inPtr = std::ptr::offset(inPtr, 1);
                        } else {
                            *out = 0;
                            out = std::ptr::mut_offset(out, 1);
                        }
                    }

                    if ptr_sub(inEnd, inPtr) == 0 && (tag == 0 || tag == 0xff) {
                        refresh_buffer!(self.inner, size, inPtr, inEnd,
                                        out, outBuf, bufferBegin);
                    }
                } else {
                    tag = *inPtr;
                    inPtr = std::ptr::offset(inPtr, 1);

                    for n in range(0, 8) {
                        let isNonzero = (tag & (1 as u8 << n)) != 0;
                        *out = (*inPtr) & ((-(isNonzero as i8)) as u8);
                        out = std::ptr::mut_offset(out, 1);
                        inPtr = std::ptr::offset(inPtr, isNonzero as int);
                    }
                }
                if (tag == 0) {
                    assert!(ptr_sub(inEnd, inPtr) > 0,
                            "Should always have non-empty buffer here");

                    let runLength : uint = (*inPtr) as uint * 8;
                    inPtr = std::ptr::offset(inPtr, 1);

                    assert!(runLength <= mut_ptr_sub(outEnd, out),
                            "Packed input did not end cleanly on a segment boundary");

                    std::ptr::set_memory(out, 0, runLength);
                    out = std::ptr::mut_offset(out, runLength as int);

                } else if (tag == 0xff) {
                    assert!(ptr_sub(inEnd, inPtr) > 0,
                            "Should always have non-empty buffer here");

                    let mut runLength : uint = (*inPtr) as uint * 8;
                    inPtr = std::ptr::offset(inPtr, 1);

                    assert!(runLength <= mut_ptr_sub(outEnd, out),
                            "Packed input did not end cleanly on a segment boundary");

                    let inRemaining = ptr_sub(inEnd, inPtr);
                    if (inRemaining >= runLength) {
                        //# Fast path.
                        std::ptr::copy_nonoverlapping_memory(out, inPtr, runLength);
                        out = std::ptr::mut_offset(out, runLength as int);
                        inPtr = std::ptr::offset(inPtr, runLength as int);
                    } else {
                        //# Copy over the first buffer, then do one big read for the rest.
                        std::ptr::copy_nonoverlapping_memory(out, inPtr, inRemaining);
                        out = std::ptr::mut_offset(out, inRemaining as int);
                        runLength -= inRemaining;

                        self.inner.skip(size);
                        do std::vec::raw::mut_buf_as_slice::<u8,()>(out, runLength) |buf| {
                            self.inner.read(buf);
                        }
                        out = std::ptr::mut_offset(out, runLength as int);

                        if (out == outEnd) {
                            return Some(len);
                        } else {
                            let (b, e) = self.inner.getReadBuffer();
                            inPtr = b;
                            inEnd = e;
                            size = ptr_sub(e, b);
                            bufferBegin = inPtr;
                            continue;
                        }
                    }
                }
            }
        }
    }
}

pub struct PackedOutputStream<'a, 'b, W> {
    inner : &'a mut io::BufferedOutputStream<'b, W>
}

impl <'a, 'b, W : std::io::Writer> std::io::Writer for PackedOutputStream<'a, 'b, W> {
    fn write(&mut self, inBuf : &[u8]) {
        unsafe {
            let (mut out, mut bufferEnd) = self.inner.getWriteBuffer();
            let mut bufferBegin = out;
            let mut slowBuffer : [u8,..20] = [0, ..20];

            let mut inPtr : *u8 = inBuf.unsafe_ref(0);
            let inEnd : *u8 = inBuf.unsafe_ref(inBuf.len());

            while (inPtr < inEnd) {

                if (mut_ptr_sub(bufferEnd, out) < 10) {
                    //# Oops, we're out of space. We need at least 10
                    //# bytes for the fast path, since we don't
                    //# bounds-check on every byte.
                    self.inner.write_ptr(bufferBegin, mut_ptr_sub(out, bufferBegin));

                    out = slowBuffer.unsafe_mut_ref(0);
                    bufferEnd = slowBuffer.unsafe_mut_ref(20);
                    bufferBegin = out;
                }

                let tagPos : *mut u8 = out;
                ptr_inc(&mut out, 1);

                let bit0 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit0 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit1 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit1 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit2 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit2 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit3 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit3 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit4 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit4 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit5 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit5 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit6 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit6 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit7 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit7 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let tag : u8 = (bit0 << 0) | (bit1 << 1) | (bit2 << 2) | (bit3 << 3)
                    | (bit4 << 4) | (bit5 << 5) | (bit6 << 6) | (bit7 << 7);

                *tagPos = tag;

                if (tag == 0) {
                    //# An all-zero word is followed by a count of
                    //# consecutive zero words (not including the first
                    //# one).

                    let mut inWord : *u64 = std::cast::transmute(inPtr);
                    let mut limit : *u64 = std::cast::transmute(inEnd);
                    if (ptr_sub(limit, inWord) > 255) {
                        limit = std::ptr::offset(inWord, 255);
                    }
                    while (inWord < limit && *inWord == 0) {
                        inWord = std::ptr::offset(inWord, 1)
                    }
                    *out = ptr_sub(inWord, std::cast::transmute::<*u8, *u64>(inPtr)) as u8;

                    ptr_inc(&mut out, 1);
                    inPtr = std::cast::transmute::<*u64, *u8>(inWord);

                } else if (tag == 0xff) {
                    //# An all-nonzero word is followed by a count of
                    //# consecutive uncompressed words, followed by the
                    //# uncompressed words themselves.

                    //# Count the number of consecutive words in the input
                    //# which have no more than a single zero-byte. We look
                    //# for at least two zeros because that's the point
                    //# where our compression scheme becomes a net win.
                    let runStart = inPtr;
                    let mut limit = inEnd;
                    if (ptr_sub(limit, inPtr) > 255 * 8) {
                        limit = std::ptr::offset(inPtr, 255 * 8);
                    }

                    while (inPtr < limit) {
                        let mut c = 0;

                        for _ in range(0,8) {
                            c += (*inPtr == 0) as u8;
                            inPtr = std::ptr::offset(inPtr, 1);
                        }

                        if (c >= 2) {
                            //# Un-read the word with multiple zeros, since
                            //# we'll want to compress that one.
                            inPtr = std::ptr::offset(inPtr, -8);
                            break;
                        }
                    }
                    let count : uint = ptr_sub(inPtr, runStart);
                    *out = (count / 8) as u8;
                    ptr_inc(&mut out, 1);

                    if (count <= mut_ptr_sub(bufferEnd, out)) {
                        //# There's enough space to memcpy.

                        let src : *u8 = runStart;
                        std::ptr::copy_nonoverlapping_memory(out, src, count);

                        ptr_inc(&mut out, count as int);
                    } else {
                        //# Input overruns the output buffer. We'll give it
                        //# to the output stream in one chunk and let it
                        //# decide what to do.
                        self.inner.write_ptr(bufferBegin, mut_ptr_sub(out, bufferBegin));

                        do std::vec::raw::buf_as_slice::<u8,()>(runStart, count) |buf| {
                            self.inner.write(buf);
                        }

                        let (out1, bufferEnd1) = self.inner.getWriteBuffer();
                        out = out1; bufferEnd = bufferEnd1;
                        bufferBegin = out;
                    }
                }
            }

            self.inner.write_ptr(bufferBegin, mut_ptr_sub(out, bufferBegin));
            self.inner.flush();
        }
    }

   fn flush(&mut self) { self.inner.flush(); }
}

pub trait WritePacked {
    fn writePackedMessage(&mut self, message : &MessageBuilder);
}

impl <'self, T : std::io::Writer> WritePacked for io::BufferedOutputStream<'self, T> {
    fn writePackedMessage(&mut self, message : &MessageBuilder) {
        let mut packedOutputStream = PackedOutputStream {inner : self};
        writeMessage(&mut packedOutputStream, message);
    }
}

pub struct WritePackedWrapper<'a, T> {writer : &'a mut T }

impl <'a, T: std::io::Writer> WritePacked for WritePackedWrapper<'a, T> {
    fn writePackedMessage(&mut self, message : &MessageBuilder) {
        let mut buffered = io::BufferedOutputStream::new(self.writer);
        buffered.writePackedMessage(message);
    }
}
<commit_msg>forgot to check for end of output<commit_after>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std;
use io;
use message::*;
use serialize::*;

#[inline]
unsafe fn ptr_inc(p : &mut *mut u8, count : int) {
    *p = std::ptr::mut_offset(*p, count);
}

#[inline]
unsafe fn ptr_sub<T>(p1 : * T, p2 : * T) -> uint {
    let p1Addr : uint = std::cast::transmute(p1);
    let p2Addr : uint = std::cast::transmute(p2);
    return (p1Addr - p2Addr) / std::mem::size_of::<T>();
}

#[inline]
unsafe fn mut_ptr_sub <T>(p1 : *mut T, p2 : *mut T) -> uint {
    let p1Addr : uint = std::cast::transmute(p1);
    let p2Addr : uint = std::cast::transmute(p2);
    return (p1Addr - p2Addr) / std::mem::size_of::<T>();
}

pub struct PackedInputStream<'a, 'b,  R> {
    inner : &'a mut io::BufferedInputStream<'b, R>
}

macro_rules! refresh_buffer(
    ($inner:expr, $size:ident, $inPtr:ident, $inEnd:ident, $out:ident,
     $outBuf:ident, $bufferBegin:ident) => (
        {
            $inner.skip($size);
            let (b, e) = $inner.getReadBuffer();
            $inPtr = b;
            $inEnd = e;
            $size = ptr_sub($inEnd, $inPtr);
            $bufferBegin = b;
            assert!($size > 0);
        }
        );
    )

impl <'a, 'b, R : std::io::Reader> std::io::Reader for PackedInputStream<'a, 'b, R> {
    fn eof(&mut self) -> bool {
        self.inner.eof()
    }

    fn read(&mut self, outBuf: &mut [u8]) -> Option<uint> {
        let len = outBuf.len();

        if (len == 0) { return Some(0); }

        assert!(len % 8 == 0, "PackInputStream reads must be word-aligned");

        unsafe {
            let mut out = outBuf.unsafe_mut_ref(0);
            let outEnd = outBuf.unsafe_mut_ref(len);

            let (mut inPtr, mut inEnd) = self.inner.getReadBuffer();
            let mut bufferBegin = inPtr;
            let mut size = ptr_sub(inEnd, inPtr);
            if size == 0 {
                return Some(0);
            }

            loop {

                let mut tag : u8;

                assert!(mut_ptr_sub(out, outBuf.unsafe_mut_ref(0)) % 8 == 0,
                        "Output pointer should always be aligned here.");

                if ptr_sub(inEnd, inPtr) < 10 {
                    if out >= outEnd {
                        self.inner.skip(ptr_sub(inPtr, bufferBegin));
                        return Some(mut_ptr_sub(out, outBuf.unsafe_mut_ref(0)));
                    }

                    if ptr_sub(inEnd, inPtr) == 0 {
                        refresh_buffer!(self.inner, size, inPtr, inEnd, out, outBuf, bufferBegin);
                        continue;
                    }

                    //# We have at least 1, but not 10, bytes availabe. We need to read
                    //# slowly, doing a bounds check on each byte.

                    tag = *inPtr;
                    inPtr = std::ptr::offset(inPtr, 1);

                    for i in range(0, 8) {
                        if (tag & (1u8 << i)) != 0 {
                            if ptr_sub(inEnd, inPtr) == 0 {
                                refresh_buffer!(self.inner, size, inPtr, inEnd,
                                                out, outBuf, bufferBegin);
                            }
                            *out = *inPtr;
                            out = std::ptr::mut_offset(out, 1);
                            inPtr = std::ptr::offset(inPtr, 1);
                        } else {
                            *out = 0;
                            out = std::ptr::mut_offset(out, 1);
                        }
                    }

                    if ptr_sub(inEnd, inPtr) == 0 && (tag == 0 || tag == 0xff) {
                        refresh_buffer!(self.inner, size, inPtr, inEnd,
                                        out, outBuf, bufferBegin);
                    }
                } else {
                    tag = *inPtr;
                    inPtr = std::ptr::offset(inPtr, 1);

                    for n in range(0, 8) {
                        let isNonzero = (tag & (1 as u8 << n)) != 0;
                        *out = (*inPtr) & ((-(isNonzero as i8)) as u8);
                        out = std::ptr::mut_offset(out, 1);
                        inPtr = std::ptr::offset(inPtr, isNonzero as int);
                    }
                }
                if (tag == 0) {
                    assert!(ptr_sub(inEnd, inPtr) > 0,
                            "Should always have non-empty buffer here");

                    let runLength : uint = (*inPtr) as uint * 8;
                    inPtr = std::ptr::offset(inPtr, 1);

                    assert!(runLength <= mut_ptr_sub(outEnd, out),
                            "Packed input did not end cleanly on a segment boundary");

                    std::ptr::set_memory(out, 0, runLength);
                    out = std::ptr::mut_offset(out, runLength as int);

                } else if (tag == 0xff) {
                    assert!(ptr_sub(inEnd, inPtr) > 0,
                            "Should always have non-empty buffer here");

                    let mut runLength : uint = (*inPtr) as uint * 8;
                    inPtr = std::ptr::offset(inPtr, 1);

                    assert!(runLength <= mut_ptr_sub(outEnd, out),
                            "Packed input did not end cleanly on a segment boundary");

                    let inRemaining = ptr_sub(inEnd, inPtr);
                    if (inRemaining >= runLength) {
                        //# Fast path.
                        std::ptr::copy_nonoverlapping_memory(out, inPtr, runLength);
                        out = std::ptr::mut_offset(out, runLength as int);
                        inPtr = std::ptr::offset(inPtr, runLength as int);
                    } else {
                        //# Copy over the first buffer, then do one big read for the rest.
                        std::ptr::copy_nonoverlapping_memory(out, inPtr, inRemaining);
                        out = std::ptr::mut_offset(out, inRemaining as int);
                        runLength -= inRemaining;

                        self.inner.skip(size);
                        do std::vec::raw::mut_buf_as_slice::<u8,()>(out, runLength) |buf| {
                            self.inner.read(buf);
                        }
                        out = std::ptr::mut_offset(out, runLength as int);

                        if (out == outEnd) {
                            return Some(len);
                        } else {
                            let (b, e) = self.inner.getReadBuffer();
                            inPtr = b;
                            inEnd = e;
                            size = ptr_sub(e, b);
                            bufferBegin = inPtr;
                            continue;
                        }
                    }
                }

                if (out == outEnd) {
                    self.inner.skip(ptr_sub(inPtr, bufferBegin));
                    return Some(len);
                }
            }
        }
    }
}

pub struct PackedOutputStream<'a, 'b, W> {
    inner : &'a mut io::BufferedOutputStream<'b, W>
}

impl <'a, 'b, W : std::io::Writer> std::io::Writer for PackedOutputStream<'a, 'b, W> {
    fn write(&mut self, inBuf : &[u8]) {
        unsafe {
            let (mut out, mut bufferEnd) = self.inner.getWriteBuffer();
            let mut bufferBegin = out;
            let mut slowBuffer : [u8,..20] = [0, ..20];

            let mut inPtr : *u8 = inBuf.unsafe_ref(0);
            let inEnd : *u8 = inBuf.unsafe_ref(inBuf.len());

            while (inPtr < inEnd) {

                if (mut_ptr_sub(bufferEnd, out) < 10) {
                    //# Oops, we're out of space. We need at least 10
                    //# bytes for the fast path, since we don't
                    //# bounds-check on every byte.
                    self.inner.write_ptr(bufferBegin, mut_ptr_sub(out, bufferBegin));

                    out = slowBuffer.unsafe_mut_ref(0);
                    bufferEnd = slowBuffer.unsafe_mut_ref(20);
                    bufferBegin = out;
                }

                let tagPos : *mut u8 = out;
                ptr_inc(&mut out, 1);

                let bit0 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit0 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit1 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit1 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit2 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit2 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit3 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit3 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit4 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit4 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit5 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit5 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit6 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit6 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let bit7 = (*inPtr != 0) as u8;
                *out = *inPtr;
                ptr_inc(&mut out, bit7 as int);
                inPtr = std::ptr::offset(inPtr, 1);

                let tag : u8 = (bit0 << 0) | (bit1 << 1) | (bit2 << 2) | (bit3 << 3)
                    | (bit4 << 4) | (bit5 << 5) | (bit6 << 6) | (bit7 << 7);

                *tagPos = tag;

                if (tag == 0) {
                    //# An all-zero word is followed by a count of
                    //# consecutive zero words (not including the first
                    //# one).

                    let mut inWord : *u64 = std::cast::transmute(inPtr);
                    let mut limit : *u64 = std::cast::transmute(inEnd);
                    if (ptr_sub(limit, inWord) > 255) {
                        limit = std::ptr::offset(inWord, 255);
                    }
                    while (inWord < limit && *inWord == 0) {
                        inWord = std::ptr::offset(inWord, 1)
                    }
                    *out = ptr_sub(inWord, std::cast::transmute::<*u8, *u64>(inPtr)) as u8;

                    ptr_inc(&mut out, 1);
                    inPtr = std::cast::transmute::<*u64, *u8>(inWord);

                } else if (tag == 0xff) {
                    //# An all-nonzero word is followed by a count of
                    //# consecutive uncompressed words, followed by the
                    //# uncompressed words themselves.

                    //# Count the number of consecutive words in the input
                    //# which have no more than a single zero-byte. We look
                    //# for at least two zeros because that's the point
                    //# where our compression scheme becomes a net win.
                    let runStart = inPtr;
                    let mut limit = inEnd;
                    if (ptr_sub(limit, inPtr) > 255 * 8) {
                        limit = std::ptr::offset(inPtr, 255 * 8);
                    }

                    while (inPtr < limit) {
                        let mut c = 0;

                        for _ in range(0,8) {
                            c += (*inPtr == 0) as u8;
                            inPtr = std::ptr::offset(inPtr, 1);
                        }

                        if (c >= 2) {
                            //# Un-read the word with multiple zeros, since
                            //# we'll want to compress that one.
                            inPtr = std::ptr::offset(inPtr, -8);
                            break;
                        }
                    }
                    let count : uint = ptr_sub(inPtr, runStart);
                    *out = (count / 8) as u8;
                    ptr_inc(&mut out, 1);

                    if (count <= mut_ptr_sub(bufferEnd, out)) {
                        //# There's enough space to memcpy.

                        let src : *u8 = runStart;
                        std::ptr::copy_nonoverlapping_memory(out, src, count);

                        ptr_inc(&mut out, count as int);
                    } else {
                        //# Input overruns the output buffer. We'll give it
                        //# to the output stream in one chunk and let it
                        //# decide what to do.
                        self.inner.write_ptr(bufferBegin, mut_ptr_sub(out, bufferBegin));

                        do std::vec::raw::buf_as_slice::<u8,()>(runStart, count) |buf| {
                            self.inner.write(buf);
                        }

                        let (out1, bufferEnd1) = self.inner.getWriteBuffer();
                        out = out1; bufferEnd = bufferEnd1;
                        bufferBegin = out;
                    }
                }
            }

            self.inner.write_ptr(bufferBegin, mut_ptr_sub(out, bufferBegin));
            self.inner.flush();
        }
    }

   fn flush(&mut self) { self.inner.flush(); }
}

pub trait WritePacked {
    fn writePackedMessage(&mut self, message : &MessageBuilder);
}

impl <'self, T : std::io::Writer> WritePacked for io::BufferedOutputStream<'self, T> {
    fn writePackedMessage(&mut self, message : &MessageBuilder) {
        let mut packedOutputStream = PackedOutputStream {inner : self};
        writeMessage(&mut packedOutputStream, message);
    }
}

pub struct WritePackedWrapper<'a, T> {writer : &'a mut T }

impl <'a, T: std::io::Writer> WritePacked for WritePackedWrapper<'a, T> {
    fn writePackedMessage(&mut self, message : &MessageBuilder) {
        let mut buffered = io::BufferedOutputStream::new(self.writer);
        buffered.writePackedMessage(message);
    }
}
<|endoftext|>


<commit_before>//! Module for built-in filter functions
//!
//! Contains all the built-in filter functions for use in templates.
//! Currently, there is no way to define filters outside this module.
//
// WHEN ADDING FILTERS, DON'T FORGET TO UPDATE `BUILT_IN_FILTERS` in askama_derive::generator.

#[cfg(feature = "serde-json")]
mod json;

#[cfg(feature = "serde-json")]
pub use self::json::json;

use std::fmt;

use escaping::{self, MarkupDisplay};
use super::Result;

// This is used by the code generator to decide whether a named filter is part of
// Askama or should refer to a local `filters` module. It should contain all the
// filters shipped with Askama, even the optional ones (since optional inclusion
// in the const vector based on features seems impossible right now).
pub const BUILT_IN_FILTERS: [&str; 10] = [
    "e",
    "escape",
    "format",
    "lower",
    "lowercase",
    "safe",
    "trim",
    "upper",
    "uppercase",
    "json", // Optional feature; reserve the name anyway
];

pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>
{
    let res: MarkupDisplay<D> = v.into();
    Ok(res.mark_safe())
}

/// Escapes `&`, `<` and `>` in strings
pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>
{
    let md: MarkupDisplay<D> = i.into();
    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
}

/// Alias for the `escape()` filter
pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>
{
    escape(i)
}

/// Formats arguments according to the specified format
///
/// The first argument to this filter must be a string literal (as in normal
/// Rust). All arguments are passed through to the `format!()`
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
/// the Askama code generator.
pub fn format() { }

/// Converts to lowercase.
pub fn lower(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_lowercase())
}

/// Alias for the `lower()` filter.
pub fn lowercase(s: &fmt::Display) -> Result<String> {
    lower(s)
}

/// Converts to uppercase.
pub fn upper(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_uppercase())
}

/// Alias for the `upper()` filter.
pub fn uppercase(s: &fmt::Display) -> Result<String> {
    upper(s)
}

/// Strip leading and trailing whitespace.
pub fn trim(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.trim().to_owned())
}

/// Joins iterable into a string separated by provided argument
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
    where T: fmt::Display,
          I: Iterator<Item = T>,
          S: AsRef<str>
{
    let separator: &str = separator.as_ref();

    let mut rv = String::new();

    for (num, item) in input.enumerate() {
        if num > 0 {
            rv.push_str(separator);
        }

        rv.push_str(&format!("{}", item));
    }

    Ok(rv)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_lower() {
        assert_eq!(lower(&"Foo").unwrap(), "foo");
        assert_eq!(lower(&"FOO").unwrap(), "foo");
        assert_eq!(lower(&"FooBar").unwrap(), "foobar");
        assert_eq!(lower(&"foo").unwrap(), "foo");
    }

    #[test]
    fn test_upper() {
        assert_eq!(upper(&"Foo").unwrap(), "FOO");
        assert_eq!(upper(&"FOO").unwrap(), "FOO");
        assert_eq!(upper(&"FooBar").unwrap(), "FOOBAR");
        assert_eq!(upper(&"foo").unwrap(), "FOO");
    }

    #[test]
    fn test_trim() {
        assert_eq!(trim(&" Hello\tworld\t").unwrap(), "Hello\tworld");
    }

    #[test]
    fn test_join() {
        assert_eq!(join((&["hello", "world"]).into_iter(), ", ").unwrap(), "hello, world");
        assert_eq!(join((&["hello"]).into_iter(), ", ").unwrap(), "hello");

        let empty: &[&str] = &[];
        assert_eq!(join(empty.into_iter(), ", ").unwrap(), "");

        let input: Vec<String> = vec!["foo".into(), "bar".into(), "bazz".into()];
        assert_eq!(join((&input).into_iter(), ":".to_string()).unwrap(), "foo:bar:bazz");
        assert_eq!(join(input.clone().into_iter(), ":").unwrap(), "foo:bar:bazz");
        assert_eq!(join(input.clone().into_iter(), ":".to_string()).unwrap(), "foo:bar:bazz");

        let input: &[String] = &["foo".into(), "bar".into()];
        assert_eq!(join(input.into_iter(), ":").unwrap(), "foo:bar");
        assert_eq!(join(input.into_iter(), ":".to_string()).unwrap(), "foo:bar");

        let real: String = "blah".into();
        let input: Vec<&str> = vec![&real];
        assert_eq!(join(input.into_iter(), ";").unwrap(), "blah");

        assert_eq!(join((&&&&&["foo", "bar"]).into_iter(), ", ").unwrap(), "foo, bar");
    }
}
<commit_msg>Remove warning, since BUILT_IN_FILTERS is now in the same module<commit_after>//! Module for built-in filter functions
//!
//! Contains all the built-in filter functions for use in templates.
//! Currently, there is no way to define filters outside this module.

#[cfg(feature = "serde-json")]
mod json;

#[cfg(feature = "serde-json")]
pub use self::json::json;

use std::fmt;

use escaping::{self, MarkupDisplay};
use super::Result;

// This is used by the code generator to decide whether a named filter is part of
// Askama or should refer to a local `filters` module. It should contain all the
// filters shipped with Askama, even the optional ones (since optional inclusion
// in the const vector based on features seems impossible right now).
pub const BUILT_IN_FILTERS: [&str; 10] = [
    "e",
    "escape",
    "format",
    "lower",
    "lowercase",
    "safe",
    "trim",
    "upper",
    "uppercase",
    "json", // Optional feature; reserve the name anyway
];

pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>
{
    let res: MarkupDisplay<D> = v.into();
    Ok(res.mark_safe())
}

/// Escapes `&`, `<` and `>` in strings
pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>
{
    let md: MarkupDisplay<D> = i.into();
    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
}

/// Alias for the `escape()` filter
pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From<I>
{
    escape(i)
}

/// Formats arguments according to the specified format
///
/// The first argument to this filter must be a string literal (as in normal
/// Rust). All arguments are passed through to the `format!()`
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
/// the Askama code generator.
pub fn format() { }

/// Converts to lowercase.
pub fn lower(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_lowercase())
}

/// Alias for the `lower()` filter.
pub fn lowercase(s: &fmt::Display) -> Result<String> {
    lower(s)
}

/// Converts to uppercase.
pub fn upper(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_uppercase())
}

/// Alias for the `upper()` filter.
pub fn uppercase(s: &fmt::Display) -> Result<String> {
    upper(s)
}

/// Strip leading and trailing whitespace.
pub fn trim(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.trim().to_owned())
}

/// Joins iterable into a string separated by provided argument
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
    where T: fmt::Display,
          I: Iterator<Item = T>,
          S: AsRef<str>
{
    let separator: &str = separator.as_ref();

    let mut rv = String::new();

    for (num, item) in input.enumerate() {
        if num > 0 {
            rv.push_str(separator);
        }

        rv.push_str(&format!("{}", item));
    }

    Ok(rv)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_lower() {
        assert_eq!(lower(&"Foo").unwrap(), "foo");
        assert_eq!(lower(&"FOO").unwrap(), "foo");
        assert_eq!(lower(&"FooBar").unwrap(), "foobar");
        assert_eq!(lower(&"foo").unwrap(), "foo");
    }

    #[test]
    fn test_upper() {
        assert_eq!(upper(&"Foo").unwrap(), "FOO");
        assert_eq!(upper(&"FOO").unwrap(), "FOO");
        assert_eq!(upper(&"FooBar").unwrap(), "FOOBAR");
        assert_eq!(upper(&"foo").unwrap(), "FOO");
    }

    #[test]
    fn test_trim() {
        assert_eq!(trim(&" Hello\tworld\t").unwrap(), "Hello\tworld");
    }

    #[test]
    fn test_join() {
        assert_eq!(join((&["hello", "world"]).into_iter(), ", ").unwrap(), "hello, world");
        assert_eq!(join((&["hello"]).into_iter(), ", ").unwrap(), "hello");

        let empty: &[&str] = &[];
        assert_eq!(join(empty.into_iter(), ", ").unwrap(), "");

        let input: Vec<String> = vec!["foo".into(), "bar".into(), "bazz".into()];
        assert_eq!(join((&input).into_iter(), ":".to_string()).unwrap(), "foo:bar:bazz");
        assert_eq!(join(input.clone().into_iter(), ":").unwrap(), "foo:bar:bazz");
        assert_eq!(join(input.clone().into_iter(), ":".to_string()).unwrap(), "foo:bar:bazz");

        let input: &[String] = &["foo".into(), "bar".into()];
        assert_eq!(join(input.into_iter(), ":").unwrap(), "foo:bar");
        assert_eq!(join(input.into_iter(), ":".to_string()).unwrap(), "foo:bar");

        let real: String = "blah".into();
        let input: Vec<&str> = vec![&real];
        assert_eq!(join(input.into_iter(), ";").unwrap(), "blah");

        assert_eq!(join((&&&&&["foo", "bar"]).into_iter(), ", ").unwrap(), "foo, bar");
    }
}
<|endoftext|>


<commit_before>use std::io::timer::sleep;
use std::time::Duration;
use mio::*;
use mio::net::*;
use mio::net::tcp::*;
use super::localhost;
use mio::event as evt;

type TestEventLoop = EventLoop<uint, String>;

struct TestHandler {
    sender: EventLoopSender<String>,
    notify: uint
}

impl TestHandler {
    fn new(sender: EventLoopSender<String>) -> TestHandler {
        TestHandler {
            sender: sender,
            notify: 0
        }
    }
}

impl Handler<uint, String> for TestHandler {
    fn notify(&mut self, event_loop: &mut TestEventLoop, msg: String) {
        match self.notify {
            0 => {
                assert!(msg.as_slice() == "First", "actual={}", msg);
                self.sender.send("Second".to_string()).unwrap();
            }
            1 => {
                assert!(msg.as_slice() == "Second", "actual={}", msg);
                event_loop.shutdown();
            }
            v => panic!("unexpected value for notify; val={}", v)
        }

        self.notify += 1;
    }
}

#[test]
pub fn test_notify() {
    debug!("Starting TEST_NOTIFY");
    let mut event_loop = EventLoop::new().unwrap();

    let addr = SockAddr::parse(localhost().as_slice())
        .expect("could not parse InetAddr");

    // Setup a server socket so that the event loop blocks
    let srv = TcpSocket::v4().unwrap();
    srv.set_reuseaddr(true).unwrap();

    let srv = srv.bind(&addr).unwrap()
        .listen(256u).unwrap();

    event_loop.register_opt(&srv, Token(0), evt::ALL, evt::EDGE).unwrap();

    let sender = event_loop.channel();

    spawn(proc() {
        sleep(Duration::seconds(1));
        sender.send("First".to_string()).unwrap();
    });

    let sender = event_loop.channel();

    // Start the event loop
    let h = event_loop.run(TestHandler::new(sender))
        .ok().expect("failed to execute event loop");

    assert!(h.notify == 2, "actual={}", h.notify);
}
<commit_msg>Remove proc() in tests<commit_after>use std::io::timer::sleep;
use std::time::Duration;
use mio::*;
use mio::net::*;
use mio::net::tcp::*;
use super::localhost;
use mio::event as evt;

type TestEventLoop = EventLoop<uint, String>;

struct TestHandler {
    sender: EventLoopSender<String>,
    notify: uint
}

impl TestHandler {
    fn new(sender: EventLoopSender<String>) -> TestHandler {
        TestHandler {
            sender: sender,
            notify: 0
        }
    }
}

impl Handler<uint, String> for TestHandler {
    fn notify(&mut self, event_loop: &mut TestEventLoop, msg: String) {
        match self.notify {
            0 => {
                assert!(msg.as_slice() == "First", "actual={}", msg);
                self.sender.send("Second".to_string()).unwrap();
            }
            1 => {
                assert!(msg.as_slice() == "Second", "actual={}", msg);
                event_loop.shutdown();
            }
            v => panic!("unexpected value for notify; val={}", v)
        }

        self.notify += 1;
    }
}

#[test]
pub fn test_notify() {
    debug!("Starting TEST_NOTIFY");
    let mut event_loop = EventLoop::new().unwrap();

    let addr = SockAddr::parse(localhost().as_slice())
        .expect("could not parse InetAddr");

    // Setup a server socket so that the event loop blocks
    let srv = TcpSocket::v4().unwrap();
    srv.set_reuseaddr(true).unwrap();

    let srv = srv.bind(&addr).unwrap()
        .listen(256u).unwrap();

    event_loop.register_opt(&srv, Token(0), evt::ALL, evt::EDGE).unwrap();

    let sender = event_loop.channel();

    spawn(move || {
        sleep(Duration::seconds(1));
        sender.send("First".to_string()).unwrap();
    });

    let sender = event_loop.channel();

    // Start the event loop
    let h = event_loop.run(TestHandler::new(sender))
        .ok().expect("failed to execute event loop");

    assert!(h.notify == 2, "actual={}", h.notify);
}
<|endoftext|>


<commit_before>extern crate rand;

extern crate intmap;

use intmap::{Entry, IntMap};

#[cfg(test)]
mod tests {
    use super::*;

    fn get_random_range(count: usize) -> Vec<u64> {
        use rand::prelude::StdRng;
        use rand::{Rng, SeedableRng};

        let mut vec = Vec::new();
        let mut rng = StdRng::seed_from_u64(4242);

        for _ in 0..count {
            vec.push(rng.gen::<u64>());
        }

        vec.sort();
        vec.dedup();

        vec
    }

    #[test]
    fn intmap_get_insert_impl() {
        let count = 20_000;
        let data = get_random_range(count as usize);
        let mut map: IntMap<u64> = IntMap::new();

        println!("");
        println!("Starting test");

        for s in data.iter() {
            assert!(map.insert(*s, *s), "intmap insert failed! ix: {:?}", s);
        }

        assert_eq!(map.len(), count);
        assert!(map.assert_count());

        for s in data.iter() {
            assert_eq!(*map.get(*s).unwrap(), *s, "intmap get failed! key: {:?}", s);
        }

        assert_eq!(map.len(), count);

        for s in data.iter() {
            assert!(
                map.contains_key(*s),
                "intmap contains_key failed! key: {:?}",
                s
            );
        }

        assert_eq!(map.len(), count);

        for s in data.iter() {
            let val = map.remove(*s).unwrap();
            assert_eq!(val, *s, "intmap remove failed! key: {:?}", s);
        }

        assert_eq!(map.len(), 0);
        assert!(map.assert_count());
    }

    #[test]
    fn add_string() {
        let mut map = IntMap::new();

        for i in 0..20_000 {
            map.insert(i, format!("item: {:?}", i));
        }
    }

    #[test]
    fn single_add_get() {
        let mut map: IntMap<u64> = IntMap::new();
        map.insert(21, 42);
        let val = map.get(21);
        assert!(val.is_some());
        assert_eq!(*val.unwrap(), 42);
    }

    #[test]
    fn map_iter() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for (k, v) in map.iter() {
            assert_eq!(*k, *v);
        }
    }

    #[test]
    fn map_iter_keys() {
        let count = 20_000;
        let data: Vec<_> = (0..count).collect();
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for k in map.keys() {
            assert_eq!(*k, data[*k as usize]);
        }
    }

    #[test]
    fn map_iter_values() {
        let count = 20_000;
        let data: Vec<_> = (0..count).collect();
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for v in map.values() {
            assert_eq!(*v, data[*v as usize]);
        }
    }

    #[test]
    fn map_iter_values_mut() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for value in map.values_mut() {
            *value += 1;
        }

        for n in 0..count {
            assert_eq!(n + 1, *map.get(n).expect("Failed to get number!"));
        }
    }

    #[test]
    fn map_mut_iter() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for kv in map.iter_mut() {
            *kv.1 += 1;
        }

        for n in 0..count {
            assert_eq!(n + 1, *map.get(n).expect("Failed to get number!"));
        }
    }

    #[test]
    fn map_iter_empty() {
        let mut map: IntMap<u64> = IntMap::new();
        map.clear();

        for kv in map.iter() {
            panic!("Not printing: {:?}", kv);
        }
    }

    #[test]
    fn map_mut_iter_empty() {
        let mut map: IntMap<u64> = IntMap::new();
        map.clear();

        for _ in map.iter_mut() {
            panic!();
        }
    }

    #[test]
    fn map_into_iter() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for (k, v) in map.into_iter() {
            assert_eq!(k, v);
        }
    }

    #[test]
    fn map_drain() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for (k, v) in map.drain() {
            assert_eq!(k, v);
        }
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn map_into_iter_empty() {
        let mut map: IntMap<u64> = IntMap::new();
        map.clear();

        for kv in map.into_iter() {
            panic!("Not printing: {:?}", kv);
        }
    }

    #[test]
    fn extend_two_maps() {
        let count = 20_000;
        let mut map_1: IntMap<u64> = IntMap::new();
        let mut map_2: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map_1.insert(i, i);
        }

        for i in count..(count * 2) {
            map_2.insert(i, i);
        }

        map_1.extend(map_2.into_iter());

        assert_eq!(map_1.len(), (count * 2) as usize);

        for (k, v) in map_1.iter() {
            assert_eq!(k, v);
        }
    }

    #[test]
    fn from_iter_collect() {
        let count = 20_000;

        let map = (0..count).map(|i| (i, i * i)).collect::<IntMap<_>>();

        for k in 0..count {
            assert!(map.contains_key(k));
        }

        for (&k, &v) in map.iter() {
            assert_eq!(k * k, v);
        }
    }

    #[test]
    fn map_equality() {
        let count = 5_000;

        let map_1 = (0..count).map(|i| (i, i * i)).collect::<IntMap<_>>();

        let map_2 = (0..count).rev().map(|i| (i, i * i)).collect::<IntMap<_>>();

        assert_eq!(map_1, map_2);
    }

    #[test]
    fn entry_api() {
        let count = 20_000;
        let data: Vec<u64> = (0..count).collect();
        let mut map: IntMap<u64> = IntMap::new();

        // Insert values 0..19999
        for i in 0..count {
            match map.entry(i) {
                Entry::Occupied(_) => panic!("unexpected while insert, i = {}", i),
                Entry::Vacant(entry) => entry.insert(i),
            };
        }

        assert_eq!(map.len(), count as usize);

        for (k, v) in map.iter() {
            assert_eq!(*v, data[*k as usize]);
        }

        // Replace values 0..19999 with 20000..39999
        for i in 0..count {
            match map.entry(i) {
                Entry::Occupied(mut entry) => {
                    assert_eq!(*entry.get(), i);
                    assert_eq!(*entry.get_mut(), i);
                    assert_eq!(entry.insert(count + i), i);
                }
                Entry::Vacant(_) => panic!("unexpected while replace, i = {}", i),
            };
        }

        assert_eq!(map.len(), count as usize);

        for (k, v) in map.iter() {
            assert_eq!(*v, count + data[*k as usize]);
        }

        // Remove values 20000..39999
        for i in 0..count {
            match map.entry(i) {
                Entry::Occupied(entry) => {
                    assert_eq!(entry.remove(), count + i);
                }
                Entry::Vacant(_) => panic!("unexpected while remove, i = {}", i),
            };
        }

        assert_eq!(map.len(), 0);
    }
}
<commit_msg>Add more test coverage<commit_after>extern crate rand;

extern crate intmap;

use intmap::{Entry, IntMap};

#[cfg(test)]
mod tests {
    use super::*;

    fn get_random_range(count: usize) -> Vec<u64> {
        use rand::prelude::StdRng;
        use rand::{Rng, SeedableRng};

        let mut vec = Vec::new();
        let mut rng = StdRng::seed_from_u64(4242);

        for _ in 0..count {
            vec.push(rng.gen::<u64>());
        }

        vec.sort();
        vec.dedup();

        vec
    }

    #[test]
    fn intmap_get_insert_impl() {
        let count = 20_000;
        let data = get_random_range(count as usize);
        let mut map: IntMap<u64> = IntMap::new();

        println!("");
        println!("Starting test");

        for s in data.iter() {
            assert!(map.insert(*s, *s), "intmap insert failed! ix: {:?}", s);
        }

        assert_eq!(map.len(), count);
        assert!(map.assert_count());

        for s in data.iter() {
            assert_eq!(*map.get(*s).unwrap(), *s, "intmap get failed! key: {:?}", s);
        }

        assert_eq!(map.len(), count);

        for s in data.iter() {
            assert!(
                map.contains_key(*s),
                "intmap contains_key failed! key: {:?}",
                s
            );
        }

        assert_eq!(map.len(), count);

        for s in data.iter() {
            let val = map.remove(*s).unwrap();
            assert_eq!(val, *s, "intmap remove failed! key: {:?}", s);
        }

        assert_eq!(map.len(), 0);
        assert!(map.assert_count());
    }

    #[test]
    fn reserve() {
        let mut map: IntMap<bool> = IntMap::new();
        map.reserve(9001);
    }

    #[test]
    fn add_duplicate() {
        let mut map = IntMap::new();

        for i in 0..20_000 {
            assert_eq!(map.insert(i, format!("item: {:?}", i)), true);
            assert_eq!(map.insert(i, format!("item: {:?}", i)), false);
        }
    }

    #[test]
    fn get_value_map() {
        let mut map = IntMap::new();

        for i in 0..20_000 {
            assert_eq!(map.insert(i, i + 1), true);
        }

        for i in 0..20_000 {
            assert_eq!(map.contains_key(i), true);
            assert_eq!(*map.get(i).unwrap(), i + 1);
            assert_eq!(*map.get_mut(i).unwrap(), i + 1);
            assert_eq!(map.remove(i).unwrap(), i + 1);
        }

        for i in 0..20_000 {
            assert_eq!(map.contains_key(i), false);
            assert_eq!(map.remove(i), None);
        }

        assert!(map.is_empty());
    }

    #[test]
    fn get_value_not_in_map() {
        let mut map = IntMap::new();

        for i in 0..20_000 {
            assert_eq!(map.insert(i, format!("item: {:?}", i)), true);
        }

        for i in 20_000..40_000 {
            assert_eq!(map.get(i), None);
            assert_eq!(map.get_mut(i), None);
        }
    }

    #[test]
    fn add_string() {
        let mut map = IntMap::new();

        for i in 0..20_000 {
            map.insert(i, format!("item: {:?}", i));
        }
    }

    #[test]
    fn retain() {
        let mut map = IntMap::new();

        for i in 0..20_000 {
            map.insert(i, format!("item: {:?}", i));
        }

        map.retain(|k, _v| k > 10_000);

        for i in 10_001..20_000 {
            assert_eq!(map.contains_key(i), true);
        }
    }

    #[test]
    fn single_add_get() {
        let mut map: IntMap<u64> = IntMap::new();
        map.insert(21, 42);
        let val = map.get(21);
        assert!(val.is_some());
        assert_eq!(*val.unwrap(), 42);
    }

    #[test]
    fn map_iter() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for (k, v) in map.iter() {
            assert_eq!(*k, *v);
        }
    }

    #[test]
    fn map_iter_keys() {
        let count = 20_000;
        let data: Vec<_> = (0..count).collect();
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for k in map.keys() {
            assert_eq!(*k, data[*k as usize]);
        }
    }

    #[test]
    fn map_iter_values() {
        let count = 20_000;
        let data: Vec<_> = (0..count).collect();
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for v in map.values() {
            assert_eq!(*v, data[*v as usize]);
        }
    }

    #[test]
    fn map_iter_values_mut() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for value in map.values_mut() {
            *value += 1;
        }

        for n in 0..count {
            assert_eq!(n + 1, *map.get(n).expect("Failed to get number!"));
        }
    }

    #[test]
    fn map_mut_iter() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for kv in map.iter_mut() {
            *kv.1 += 1;
        }

        for n in 0..count {
            assert_eq!(n + 1, *map.get(n).expect("Failed to get number!"));
        }
    }

    #[test]
    fn map_iter_empty() {
        let mut map: IntMap<u64> = IntMap::new();
        map.clear();

        for kv in map.iter() {
            panic!("Not printing: {:?}", kv);
        }
    }

    #[test]
    fn map_mut_iter_empty() {
        let mut map: IntMap<u64> = IntMap::new();
        map.clear();

        for _ in map.iter_mut() {
            panic!();
        }
    }

    #[test]
    fn map_into_iter() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for (k, v) in map.into_iter() {
            assert_eq!(k, v);
        }
    }

    #[test]
    fn map_drain() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        for (k, v) in map.drain() {
            assert_eq!(k, v);
        }
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn map_into_iter_empty() {
        let mut map: IntMap<u64> = IntMap::new();
        map.clear();

        for kv in map.into_iter() {
            panic!("Not printing: {:?}", kv);
        }
    }

    #[test]
    fn extend_two_maps() {
        let count = 20_000;
        let mut map_1: IntMap<u64> = IntMap::new();
        let mut map_2: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map_1.insert(i, i);
        }

        for i in count..(count * 2) {
            map_2.insert(i, i);
        }

        map_1.extend(map_2.into_iter());

        assert_eq!(map_1.len(), (count * 2) as usize);

        for (k, v) in map_1.iter() {
            assert_eq!(k, v);
        }
    }

    #[test]
    fn from_iter_collect() {
        let count = 20_000;

        let map = (0..count).map(|i| (i, i * i)).collect::<IntMap<_>>();

        for k in 0..count {
            assert!(map.contains_key(k));
        }

        for (&k, &v) in map.iter() {
            assert_eq!(k * k, v);
        }
    }

    #[test]
    fn map_equality() {
        let count = 5_000;

        let map_1 = (0..count).map(|i| (i, i * i)).collect::<IntMap<_>>();

        let map_2 = (0..count).rev().map(|i| (i, i * i)).collect::<IntMap<_>>();

        assert_eq!(map_1, map_2);
    }

    #[test]
    fn entry_api() {
        let count = 20_000;
        let data: Vec<u64> = (0..count).collect();
        let mut map: IntMap<u64> = IntMap::new();

        // Insert values 0..19999
        for i in 0..count {
            match map.entry(i) {
                Entry::Occupied(_) => panic!("unexpected while insert, i = {}", i),
                Entry::Vacant(entry) => entry.insert(i),
            };
        }

        assert_eq!(map.len(), count as usize);

        for (k, v) in map.iter() {
            assert_eq!(*v, data[*k as usize]);
        }

        // Replace values 0..19999 with 20000..39999
        for i in 0..count {
            match map.entry(i) {
                Entry::Occupied(mut entry) => {
                    assert_eq!(*entry.get(), i);
                    assert_eq!(*entry.get_mut(), i);
                    assert_eq!(entry.insert(count + i), i);
                    assert_eq!(*entry.into_mut(), count + i);
                }
                Entry::Vacant(_) => panic!("unexpected while replace, i = {}", i),
            };
        }

        assert_eq!(map.len(), count as usize);

        for (k, v) in map.iter() {
            assert_eq!(*v, count + data[*k as usize]);
        }

        // Remove values 20000..39999
        for i in 0..count {
            match map.entry(i) {
                Entry::Occupied(entry) => {
                    assert_eq!(entry.remove(), count + i);
                }
                Entry::Vacant(_) => panic!("unexpected while remove, i = {}", i),
            };
        }

        assert_eq!(map.len(), 0);
    }

    #[test]
    fn test_debug_features() {
        let count = 20_000;
        let mut map: IntMap<u64> = IntMap::new();

        for i in 0..count {
            map.insert(i, i);
        }

        assert_eq!(map.load(), 20_000);
        assert_eq!(map.capacity(), 32_768);
        assert!(map.load_rate() > 0.70);
        assert!(map.collisions().is_empty());

        let mut map: IntMap<u64> = IntMap::new();
        for i in 0..3 {
            map.insert(i, i+1);
        }

        assert_eq!(format!("{:?}", map ) , "{0: 1, 1: 2, 2: 3}");
    }
}
<|endoftext|>


<commit_before>use utils::{
    execute,
    fetch_updates,
    with_slot,
};

#[test]
// The output decoder does not emit any changes for deletions from a table without a primary key.
// This is because Postgres doesn't give the decoder any tuple information in this scenario.
fn delete_without_primary_key() {
    with_slot("no_primary_table", "id int, name text, whatever float", |c| {
        execute(c, "insert into no_primary_table (id, name, whatever) values ($1, $2, $3)", &[&1, &"hello", &3.2]);
        execute(c, "delete from no_primary_table where id = 1", &[]);
        assert_eq!(fetch_updates(c).len(), 1);
    });
}

#[test]
fn works_with_all_datatypes() {
    let columns = "
        id              int primary key,
        abool           boolean,
        anint           int,
        abigint         bigint,
        asmallint       smallint,
        aserialnint     serial,
        aserialbigint   bigserial,
        aserialsmallint smallserial,
        somebits        BIT(3),
        somemorebits    bit varying,
        abox            box,
        somebytes       bytea,
        somechars       character(3),
        morechars       character varying,
        addr            cidr,
        circ            circle,
        adate           date,
        afloat          double precision,
        aninet          inet,
        aninteger       integer,
        ayear           interval year,
        somejson        json,
        somejsonb       jsonb,
        aline           line,
        alineseg        lseg,
        amac            macaddr,
        somedollers     money,
        anumber         numeric(2, 2),
        apath           path,
        alsn            pg_lsn,
        thepoint        point,
        apoly           polygon,
        thereal         real,
        sometext        text,
        thetimezone     time without time zone,
        thetimenozone   time with time zone,
        timestampzone   timestamp without time zone,
        timestampnozone timestamp with time zone,
        aquery          tsquery,
        avec            tsvector,
        txid            txid_snapshot,
        auuid           uuid,
        somexml         xml
    ";

    let values = "
        1,
        true,
        1,
        1,
        1,
        1,
        1,
        1,
        B'101',
        B'101',
        '((0,0),(1,1))',
        E'\x0123456789ABCDEF',
        'abc',
        'abcdef',
        '192.168.100.128/25',
        '((0,0), 1)',
        '1999-01-08',
        1.2,
        '192.168.100.128/25',
        1,
        '1',
        '{\"a\":123}',
        '{\"a\":123}',
        '((0,0),(1,1))',
        '((0,0),(1,1))',
        '08:00:2b:01:02:03',
        '12.23',
        0.1,
        '((0,0),(1,1))',
        '16/B374D848',
        '(0,0)',
        '((0,0),(1,1))',
        1.39284,
        'what we do in life echos in eternity',
        '04:05:06',
        '04:05:06-08:00',
        '1999-01-08 04:05:06',
        '1999-01-08 04:05:06-08:00',
        'fat & rat',
        'fat rat',
        '10:20:10,14,15',
        'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
        '<foo>bar</foo>'
    ";

    with_slot("datatypes", columns, |c| {
        execute(c, &format!("insert into datatypes values ({})", values)[..], &[]);
        assert_eq!(fetch_updates(c).len(), 1);
    });
}
<commit_msg>Adds updating and deleting to the datatypes test<commit_after>use utils::{
    execute,
    fetch_updates,
    with_slot,
};

#[test]
// The output decoder does not emit any changes for deletions from a table without a primary key.
// This is because Postgres doesn't give the decoder any tuple information in this scenario.
fn delete_without_primary_key() {
    with_slot("no_primary_table", "id int, name text, whatever float", |c| {
        execute(c, "insert into no_primary_table (id, name, whatever) values ($1, $2, $3)", &[&1, &"hello", &3.2]);
        execute(c, "delete from no_primary_table where id = 1", &[]);
        assert_eq!(fetch_updates(c).len(), 1);
    });
}

#[test]
fn works_with_all_datatypes() {
    let columns = "
        id              int primary key,
        abool           boolean,
        anint           int,
        abigint         bigint,
        asmallint       smallint,
        aserialnint     serial,
        aserialbigint   bigserial,
        aserialsmallint smallserial,
        somebits        BIT(3),
        somemorebits    bit varying,
        abox            box,
        somebytes       bytea,
        somechars       character(3),
        morechars       character varying,
        addr            cidr,
        circ            circle,
        adate           date,
        afloat          double precision,
        aninet          inet,
        aninteger       integer,
        ayear           interval year,
        somejson        json,
        somejsonb       jsonb,
        aline           line,
        alineseg        lseg,
        amac            macaddr,
        somedollers     money,
        anumber         numeric(2, 2),
        apath           path,
        alsn            pg_lsn,
        thepoint        point,
        apoly           polygon,
        thereal         real,
        sometext        text,
        thetimezone     time without time zone,
        thetimenozone   time with time zone,
        timestampzone   timestamp without time zone,
        timestampnozone timestamp with time zone,
        aquery          tsquery,
        avec            tsvector,
        txid            txid_snapshot,
        auuid           uuid,
        somexml         xml
    ";

    let values = "
        1,
        true,
        1,
        1,
        1,
        1,
        1,
        1,
        B'101',
        B'101',
        '((0,0),(1,1))',
        E'\x0123456789ABCDEF',
        'abc',
        'abcdef',
        '192.168.100.128/25',
        '((0,0), 1)',
        '1999-01-08',
        1.2,
        '192.168.100.128/25',
        1,
        '1',
        '{\"a\":123}',
        '{\"a\":123}',
        '((0,0),(1,1))',
        '((0,0),(1,1))',
        '08:00:2b:01:02:03',
        '12.23',
        0.1,
        '((0,0),(1,1))',
        '16/B374D848',
        '(0,0)',
        '((0,0),(1,1))',
        1.39284,
        'what we do in life echos in eternity',
        '04:05:06',
        '04:05:06-08:00',
        '1999-01-08 04:05:06',
        '1999-01-08 04:05:06-08:00',
        'fat & rat',
        'fat rat',
        '10:20:10,14,15',
        'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
        '<foo>bar</foo>'
    ";

    with_slot("datatypes", columns, |c| {
        execute(c, &format!("insert into datatypes values ({})", values)[..], &[]);
        execute(c, "update datatypes set id = 2", &[]);
        execute(c, "delete from datatypes", &[]);
        assert_eq!(fetch_updates(c).len(), 3);
    });
}
<|endoftext|>