<commit_before>// Copyright 2016 bluss and ndarray developers.
//
// 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.

extern crate rand;
extern crate ndarray;

use std::iter::FromIterator;

use rand::Rng;
use rand::distributions::Sample;
use rand::distributions::IndependentSample;

use ndarray::{
    ArrayBase,
    Dimension,
    DataOwned,
};

/// Constructors for n-dimensional arrays with random elements.
///
/// This trait extends ndarray’s `ArrayBase` and can not be implemented
/// for other types.
///
/// The default Rng is a fast automatically seeded rng (currently `rand::weak_rng`).
pub trait RandomExt<S, D>
    where S: DataOwned,
          D: Dimension,
{
    /// Create an array with shape `dim` with elements drawn from
    /// `distribution`  using the default rng.
    ///
    /// ***Panics*** if the number of elements overflows usize.
    ///
    /// ```
    /// extern crate rand;
    /// extern crate ndarray;
    /// extern crate ndarray_rand;
    ///
    /// use rand::distributions::Range;
    /// use ndarray::OwnedArray;
    /// use ndarray_rand::RandomExt;
    ///
    /// # fn main() {
    /// let a = OwnedArray::random((2, 5), Range::new(0., 10.));
    /// println!("{:8.4}", a);
    /// // Output:
    /// // [[  8.6900,   6.9824,   3.8922,   6.5861,   2.4890],
    /// //  [  0.0914,   5.5186,   5.8135,   5.2361,   3.1879]]
    /// # }
    fn random<IdS>(dim: D, distribution: IdS) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>;

    /// Create an array with shape `dim` with elements drawn from
    /// `distribution`, using a specific Rng `rng`.
    ///
    /// ***Panics*** if the number of elements overflows usize.
    fn random_using<IdS, R>(dim: D, distribution: IdS, rng: &mut R) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>,
              R: Rng;
}

impl<S, D> RandomExt<S, D> for ArrayBase<S, D>
    where S: DataOwned,
          D: Dimension,
{
    fn random<IdS>(dim: D, dist: IdS) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>
    {
        Self::random_using(dim, dist, &mut rand::weak_rng())
    }

    fn random_using<IdS, R>(dim: D, dist: IdS, rng: &mut R) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>,
              R: Rng
    {
        unsafe {
            let elements = Vec::from_iter((0..dim.size()).map(move |_| dist.ind_sample(rng)));
            Self::from_vec_dim(dim, elements).unwrap()
        }
    }
}

/// A wrapper type that allows casting f64 distributions to f32
#[derive(Copy, Clone, Debug)]
pub struct F32<S>(pub S);

impl<S> Sample<f32> for F32<S>
    where S: Sample<f64>
{
    fn sample<R>(&mut self, rng: &mut R) -> f32 where R: Rng {
        self.0.sample(rng) as f32
    }
}

impl<S> IndependentSample<f32> for F32<S>
    where S: IndependentSample<f64>
{
    fn ind_sample<R>(&self, rng: &mut R) -> f32 where R: Rng {
        self.0.ind_sample(rng) as f32
    }
}
<commit_msg>ndarray-rand: rm `unsafe`<commit_after>// Copyright 2016 bluss and ndarray developers.
//
// 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.

extern crate rand;
extern crate ndarray;

use std::iter::FromIterator;

use rand::Rng;
use rand::distributions::Sample;
use rand::distributions::IndependentSample;

use ndarray::{
    ArrayBase,
    Dimension,
    DataOwned,
};

/// Constructors for n-dimensional arrays with random elements.
///
/// This trait extends ndarray’s `ArrayBase` and can not be implemented
/// for other types.
///
/// The default Rng is a fast automatically seeded rng (currently `rand::weak_rng`).
pub trait RandomExt<S, D>
    where S: DataOwned,
          D: Dimension,
{
    /// Create an array with shape `dim` with elements drawn from
    /// `distribution`  using the default rng.
    ///
    /// ***Panics*** if the number of elements overflows usize.
    ///
    /// ```
    /// extern crate rand;
    /// extern crate ndarray;
    /// extern crate ndarray_rand;
    ///
    /// use rand::distributions::Range;
    /// use ndarray::OwnedArray;
    /// use ndarray_rand::RandomExt;
    ///
    /// # fn main() {
    /// let a = OwnedArray::random((2, 5), Range::new(0., 10.));
    /// println!("{:8.4}", a);
    /// // Output:
    /// // [[  8.6900,   6.9824,   3.8922,   6.5861,   2.4890],
    /// //  [  0.0914,   5.5186,   5.8135,   5.2361,   3.1879]]
    /// # }
    fn random<IdS>(dim: D, distribution: IdS) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>;

    /// Create an array with shape `dim` with elements drawn from
    /// `distribution`, using a specific Rng `rng`.
    ///
    /// ***Panics*** if the number of elements overflows usize.
    fn random_using<IdS, R>(dim: D, distribution: IdS, rng: &mut R) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>,
              R: Rng;
}

impl<S, D> RandomExt<S, D> for ArrayBase<S, D>
    where S: DataOwned,
          D: Dimension,
{
    fn random<IdS>(dim: D, dist: IdS) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>
    {
        Self::random_using(dim, dist, &mut rand::weak_rng())
    }

    fn random_using<IdS, R>(dim: D, dist: IdS, rng: &mut R) -> ArrayBase<S, D>
        where IdS: IndependentSample<S::Elem>,
              R: Rng
    {
        let elements = Vec::from_iter((0..dim.size()).map(move |_| dist.ind_sample(rng)));
        Self::from_vec_dim(dim, elements).unwrap()
    }
}

/// A wrapper type that allows casting f64 distributions to f32
#[derive(Copy, Clone, Debug)]
pub struct F32<S>(pub S);

impl<S> Sample<f32> for F32<S>
    where S: Sample<f64>
{
    fn sample<R>(&mut self, rng: &mut R) -> f32 where R: Rng {
        self.0.sample(rng) as f32
    }
}

impl<S> IndependentSample<f32> for F32<S>
    where S: IndependentSample<f64>
{
    fn ind_sample<R>(&self, rng: &mut R) -> f32 where R: Rng {
        self.0.ind_sample(rng) as f32
    }
}
<|endoftext|>


<commit_before>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::marker::Unpin;
use crate::ops;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// A future represents an asynchronous computation.
///
/// A future is a value that may not have finished computing yet. This kind of
/// "asynchronous value" makes it possible for a thread to continue doing useful
/// work while it waits for the value to become available.
///
/// # The `poll` method
///
/// The core method of future, `poll`, *attempts* to resolve the future into a
/// final value. This method does not block if the value is not ready. Instead,
/// the current task is scheduled to be woken up when it's possible to make
/// further progress by `poll`ing again. The `context` passed to the `poll`
/// method can provide a [`Waker`], which is a handle for waking up the current
/// task.
///
/// When using a future, you generally won't call `poll` directly, but instead
/// `.await` the value.
///
/// [`Waker`]: ../task/struct.Waker.html
#[doc(spotlight)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")]
#[lang = "future_trait"]
#[rustc_on_unimplemented(label = "`{Self}` is not a future", message = "`{Self}` is not a future")]
pub trait Future {
    /// The type of value produced on completion.
    #[stable(feature = "futures_api", since = "1.36.0")]
    type Output;

    /// Attempt to resolve the future to a final value, registering
    /// the current task for wakeup if the value is not yet available.
    ///
    /// # Return value
    ///
    /// This function returns:
    ///
    /// - [`Poll::Pending`] if the future is not ready yet
    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
    ///   finished successfully.
    ///
    /// Once a future has finished, clients should not `poll` it again.
    ///
    /// When a future is not ready yet, `poll` returns `Poll::Pending` and
    /// stores a clone of the [`Waker`] copied from the current [`Context`].
    /// This [`Waker`] is then woken once the future can make progress.
    /// For example, a future waiting for a socket to become
    /// readable would call `.clone()` on the [`Waker`] and store it.
    /// When a signal arrives elsewhere indicating that the socket is readable,
    /// [`Waker::wake`] is called and the socket future's task is awoken.
    /// Once a task has been woken up, it should attempt to `poll` the future
    /// again, which may or may not produce a final value.
    ///
    /// Note that on multiple calls to `poll`, only the [`Waker`] from the
    /// [`Context`] passed to the most recent call should be scheduled to
    /// receive a wakeup.
    ///
    /// # Runtime characteristics
    ///
    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
    /// progress, meaning that each time the current task is woken up, it should
    /// actively re-`poll` pending futures that it still has an interest in.
    ///
    /// The `poll` function is not called repeatedly in a tight loop -- instead,
    /// it should only be called when the future indicates that it is ready to
    /// make progress (by calling `wake()`). If you're familiar with the
    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
    /// typically do *not* suffer the same problems of "all wakeups must poll
    /// all events"; they are more like `epoll(4)`.
    ///
    /// An implementation of `poll` should strive to return quickly, and should
    /// not block. Returning quickly prevents unnecessarily clogging up
    /// threads or event loops. If it is known ahead of time that a call to
    /// `poll` may end up taking awhile, the work should be offloaded to a
    /// thread pool (or something similar) to ensure that `poll` can return
    /// quickly.
    ///
    /// # Panics
    ///
    /// Once a future has completed (returned `Ready` from `poll`), calling its
    /// `poll` method again may panic, block forever, or cause other kinds of
    /// problems; the `Future` trait places no requirements on the effects of
    /// such a call. However, as the `poll` method is not marked `unsafe`,
    /// Rust's usual rules apply: calls must never cause undefined behavior
    /// (memory corruption, incorrect use of `unsafe` functions, or the like),
    /// regardless of the future's state.
    ///
    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
    /// [`Context`]: ../task/struct.Context.html
    /// [`Waker`]: ../task/struct.Waker.html
    /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
    #[lang = "poll"]
    #[stable(feature = "futures_api", since = "1.36.0")]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: ?Sized + Future + Unpin> Future for &mut F {
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        F::poll(Pin::new(&mut **self), cx)
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl
 Future for Pin

where
    P: Unpin + ops::DerefMut<Target: Future>,
{
    type Output = <
::Target as Future>::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        Pin::get_mut(self).as_mut().poll(cx)
    }
}
<commit_msg>Use intra-doc links in `core::future::future`<commit_after>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::marker::Unpin;
use crate::ops;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// A future represents an asynchronous computation.
///
/// A future is a value that may not have finished computing yet. This kind of
/// "asynchronous value" makes it possible for a thread to continue doing useful
/// work while it waits for the value to become available.
///
/// # The `poll` method
///
/// The core method of future, `poll`, *attempts* to resolve the future into a
/// final value. This method does not block if the value is not ready. Instead,
/// the current task is scheduled to be woken up when it's possible to make
/// further progress by `poll`ing again. The `context` passed to the `poll`
/// method can provide a [`Waker`], which is a handle for waking up the current
/// task.
///
/// When using a future, you generally won't call `poll` directly, but instead
/// `.await` the value.
///
/// [`Waker`]: crate::task::Waker
#[doc(spotlight)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")]
#[lang = "future_trait"]
#[rustc_on_unimplemented(label = "`{Self}` is not a future", message = "`{Self}` is not a future")]
pub trait Future {
    /// The type of value produced on completion.
    #[stable(feature = "futures_api", since = "1.36.0")]
    type Output;

    /// Attempt to resolve the future to a final value, registering
    /// the current task for wakeup if the value is not yet available.
    ///
    /// # Return value
    ///
    /// This function returns:
    ///
    /// - [`Poll::Pending`] if the future is not ready yet
    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
    ///   finished successfully.
    ///
    /// Once a future has finished, clients should not `poll` it again.
    ///
    /// When a future is not ready yet, `poll` returns `Poll::Pending` and
    /// stores a clone of the [`Waker`] copied from the current [`Context`].
    /// This [`Waker`] is then woken once the future can make progress.
    /// For example, a future waiting for a socket to become
    /// readable would call `.clone()` on the [`Waker`] and store it.
    /// When a signal arrives elsewhere indicating that the socket is readable,
    /// [`Waker::wake`] is called and the socket future's task is awoken.
    /// Once a task has been woken up, it should attempt to `poll` the future
    /// again, which may or may not produce a final value.
    ///
    /// Note that on multiple calls to `poll`, only the [`Waker`] from the
    /// [`Context`] passed to the most recent call should be scheduled to
    /// receive a wakeup.
    ///
    /// # Runtime characteristics
    ///
    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
    /// progress, meaning that each time the current task is woken up, it should
    /// actively re-`poll` pending futures that it still has an interest in.
    ///
    /// The `poll` function is not called repeatedly in a tight loop -- instead,
    /// it should only be called when the future indicates that it is ready to
    /// make progress (by calling `wake()`). If you're familiar with the
    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
    /// typically do *not* suffer the same problems of "all wakeups must poll
    /// all events"; they are more like `epoll(4)`.
    ///
    /// An implementation of `poll` should strive to return quickly, and should
    /// not block. Returning quickly prevents unnecessarily clogging up
    /// threads or event loops. If it is known ahead of time that a call to
    /// `poll` may end up taking awhile, the work should be offloaded to a
    /// thread pool (or something similar) to ensure that `poll` can return
    /// quickly.
    ///
    /// # Panics
    ///
    /// Once a future has completed (returned `Ready` from `poll`), calling its
    /// `poll` method again may panic, block forever, or cause other kinds of
    /// problems; the `Future` trait places no requirements on the effects of
    /// such a call. However, as the `poll` method is not marked `unsafe`,
    /// Rust's usual rules apply: calls must never cause undefined behavior
    /// (memory corruption, incorrect use of `unsafe` functions, or the like),
    /// regardless of the future's state.
    ///
    /// [`Poll::Pending`]: Poll::Pending
    /// [`Poll::Ready(val)`]: Poll::Ready
    /// [`Waker`]: crate::task::Waker
    /// [`Waker::wake`]: crate::task::Waker::wake
    #[lang = "poll"]
    #[stable(feature = "futures_api", since = "1.36.0")]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: ?Sized + Future + Unpin> Future for &mut F {
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        F::poll(Pin::new(&mut **self), cx)
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl
 Future for Pin

where
    P: Unpin + ops::DerefMut<Target: Future>,
{
    type Output = <
::Target as Future>::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        Pin::get_mut(self).as_mut().poll(cx)
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 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(unknown_lints)]
// Check that an arena (TypedArena) can carry elements whose drop
// methods might access borrowed data, as long as the borrowed data
// has lifetime that strictly outlives the arena itself.
//
// Compare against compile-fail/dropck_tarena_unsound_drop.rs, which
// shows a similar setup, but restricts `f` so that the struct `C<'a>`
// is force-fed a lifetime equal to that of the borrowed arena.

#![allow(unstable)]
#![feature(rustc_private)]

extern crate arena;

use arena::TypedArena;

trait HasId { fn count(&self) -> usize; }

struct CheckId<T:HasId> { v: T }

// In the code below, the impl of HasId for `&'a usize` does not
// actually access the borrowed data, but the point is that the
// interface to CheckId does not (and cannot) know that, and therefore
// when encountering the a value V of type CheckId<S>, we must
// conservatively force the type S to strictly outlive V.
impl<T:HasId> Drop for CheckId<T> {
    fn drop(&mut self) {
        assert!(self.v.count() > 0);
    }
}

struct C<'a> { _v: CheckId<&'a usize>, }

impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } }

fn f<'a, 'b>(_arena: &'a TypedArena<C<'b>>) {}

fn main() {
    let arena: TypedArena<C> = TypedArena::new();
    f(&arena);
}
<commit_msg>Update a compiler-test to the `Default` changes<commit_after>// Copyright 2015 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(unknown_lints)]
// Check that an arena (TypedArena) can carry elements whose drop
// methods might access borrowed data, as long as the borrowed data
// has lifetime that strictly outlives the arena itself.
//
// Compare against compile-fail/dropck_tarena_unsound_drop.rs, which
// shows a similar setup, but restricts `f` so that the struct `C<'a>`
// is force-fed a lifetime equal to that of the borrowed arena.

#![allow(unstable)]
#![feature(rustc_private)]

extern crate arena;

use arena::TypedArena;

trait HasId { fn count(&self) -> usize; }

struct CheckId<T:HasId> { v: T }

// In the code below, the impl of HasId for `&'a usize` does not
// actually access the borrowed data, but the point is that the
// interface to CheckId does not (and cannot) know that, and therefore
// when encountering the a value V of type CheckId<S>, we must
// conservatively force the type S to strictly outlive V.
impl<T:HasId> Drop for CheckId<T> {
    fn drop(&mut self) {
        assert!(self.v.count() > 0);
    }
}

struct C<'a> { _v: CheckId<&'a usize>, }

impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } }

fn f<'a, 'b>(_arena: &'a TypedArena<C<'b>>) {}

fn main() {
    let arena: TypedArena<C> = TypedArena::default();
    f(&arena);
}
<|endoftext|>


<commit_before>// ignore-tidy-linelength

pub trait MyTrait {
    type Assoc;
    const VALUE: u32;
    fn trait_function(&self);
    fn defaulted(&self) {}
    fn defaulted_override(&self) {}
}

impl MyTrait for String {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="anchor"]/@href' #associatedtype.Assoc-1
    type Assoc = ();
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-1
    const VALUE: u32 = 5;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="anchor"]/@href' #method.defaulted_override-1
    fn defaulted_override(&self) {}
}

impl MyTrait for Vec<u8> {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="anchor"]/@href' #associatedtype.Assoc-2
    type Assoc = ();
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-2
    const VALUE: u32 = 5;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-1"]//a[@class="anchor"]/@href' #method.trait_function-1
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="anchor"]/@href' #method.defaulted_override-2
    fn defaulted_override(&self) {}
}

impl MyTrait for MyStruct {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="type"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc
    type Assoc = bool;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE
    const VALUE: u32 = 20;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="anchor"]/@href' #method.trait_function-2
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="anchor"]/@href' #method.defaulted_override-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted_override
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override
    fn defaulted_override(&self) {}
}

pub struct MyStruct;
<commit_msg>forgot test assertions for default method<commit_after>// ignore-tidy-linelength

pub trait MyTrait {
    type Assoc;
    const VALUE: u32;
    fn trait_function(&self);
    fn defaulted(&self) {}
    fn defaulted_override(&self) {}
}

impl MyTrait for String {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="anchor"]/@href' #associatedtype.Assoc-1
    type Assoc = ();
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-1
    const VALUE: u32 = 5;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="anchor"]/@href' #method.defaulted_override-1
    fn defaulted_override(&self) {}
}

impl MyTrait for Vec<u8> {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="anchor"]/@href' #associatedtype.Assoc-2
    type Assoc = ();
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-2
    const VALUE: u32 = 5;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-1"]//a[@class="anchor"]/@href' #method.trait_function-1
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="anchor"]/@href' #method.defaulted_override-2
    fn defaulted_override(&self) {}
}

impl MyTrait for MyStruct {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="type"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc
    type Assoc = bool;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE
    const VALUE: u32 = 20;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="anchor"]/@href' #method.trait_function-2
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="anchor"]/@href' #method.defaulted_override-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted_override
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override
    fn defaulted_override(&self) {}
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="anchor"]/@href' #method.defaulted
}

pub struct MyStruct;
<|endoftext|>


<commit_before>/// low level wrapper for the state machine, encoding and decoding from lapin-async
use lapin_async::connection::*;
use lapin_async::format::frame::*;

use nom::{IResult,Offset};
use cookie_factory::GenError;
use bytes::{BufMut, BytesMut};
use std::cmp;
use std::collections::HashMap;
use std::iter::repeat;
use std::io::{self,Error,ErrorKind};
use futures::{Async,AsyncSink,Poll,Sink,StartSend,Stream,Future,future,task};
use tokio_io::{AsyncRead,AsyncWrite};
use tokio_io::codec::{Decoder,Encoder,Framed};
use channel::BasicProperties;
use client::ConnectionOptions;

/// implements tokio-io's Decoder and Encoder
pub struct AMQPCodec {
    pub frame_max: u32,
}

impl Decoder for AMQPCodec {
    type Item = Frame;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Frame>, io::Error> {
        let (consumed, f) = match frame(buf) {
          IResult::Incomplete(_) => {
            return Ok(None)
          },
          IResult::Error(e) => {
            return Err(io::Error::new(io::ErrorKind::Other, format!("parse error: {:?}", e)))
          },
          IResult::Done(i, frame) => {
            (buf.offset(i), frame)
          }
        };

        trace!("amqp decoder; frame={:?}", f);

        buf.split_to(consumed);

        Ok(Some(f))
    }
}

impl Encoder for AMQPCodec {
    type Item = Frame;
    type Error = io::Error;

    fn encode(&mut self, frame: Frame, buf: &mut BytesMut) -> Result<(), Self::Error> {
      let frame_max = cmp::max(self.frame_max, 8192) as usize;
      trace!("encoder; frame={:?}", frame);
      let offset = buf.len();
      loop {
        // If the buffer starts running out of capacity (the threshold is 1/4 of a frame), we
        // reserve more bytes upfront to avoid putting too much strain on the allocator.
        if buf.remaining_mut() < frame_max / 4 {
          trace!("encoder; reserve={}", frame_max * 2);
          buf.reserve(frame_max * 2);
        }

        let gen_res = match &frame {
          &Frame::ProtocolHeader => {
            gen_protocol_header((buf, offset)).map(|tup| tup.1)
          },
          &Frame::Heartbeat(_) => {
            gen_heartbeat_frame((buf, offset)).map(|tup| tup.1)
          },
          &Frame::Method(channel, ref method) => {
            gen_method_frame((buf, offset), channel, method).map(|tup| tup.1)
          },
          &Frame::Header(channel_id, class_id, ref header) => {
            gen_content_header_frame((buf, offset), channel_id, class_id, header.body_size, &header.properties).map(|tup| tup.1)
          },
          &Frame::Body(channel_id, ref data) => {
            gen_content_body_frame((buf, offset), channel_id, data).map(|tup| tup.1)
          }
        };

        match gen_res {
          Ok(sz) => {
            trace!("encoder; frame_size={}", sz - offset);
            return Ok(());
          },
          Err(GenError::BufferTooSmall(sz)) => {
            // BufferTooSmall error variant returns the index the next write would have
            // occured if there was enough space in the buffer. Thus we subtract the
            // buffer's length to know how much bytes we sould make available.
            let length = buf.len();
            trace!("encoder; sz={} length={} extend={}", sz, length, sz - length);
            buf.extend(repeat(0).take(sz - length));
          },
          Err(e) => {
            error!("error generating frame: {:?}", e);
            return Err(Error::new(ErrorKind::InvalidData, "could not generate"));
          }
        }
      }
    }
}

/// Wrappers over a `Framed` stream using `AMQPCodec` and lapin-async's `Connection`
pub struct AMQPTransport<T> {
  upstream:  Framed<T,AMQPCodec>,
  consumers: HashMap<String, task::Task>,
  pub conn:  Connection,
}

impl<T> AMQPTransport<T>
   where T: AsyncRead+AsyncWrite,
         T: Send,
         T: 'static               {

  /// starts the connection process
  ///
  /// returns a future of a `AMQPTransport` that is connected
  pub fn connect(stream: T, options: &ConnectionOptions) -> Box<Future<Item = AMQPTransport<T>, Error = io::Error> + Send> {
    let mut conn = Connection::new();
    conn.set_credentials(&options.username, &options.password);
    conn.set_vhost(&options.vhost);
    conn.set_frame_max(options.frame_max);
    conn.set_heartbeat(options.heartbeat);
    if let Err(e) = conn.connect() {
      let err = format!("Failed to connect: {:?}", e);
      return Box::new(future::err(Error::new(ErrorKind::ConnectionAborted, err)));
    }

    let codec = AMQPCodec {
      frame_max: conn.configuration.frame_max,
    };
    let t = AMQPTransport {
      upstream:     stream.framed(codec),
      consumers:    HashMap::new(),
      conn:         conn,
    };
    let connector = AMQPTransportConnector {
      transport: Some(t),
    };
    Box::new(connector)
  }

  /// Send a frame to the broker.
  ///
  /// # Notes
  ///
  /// This function only appends the frame to a queue, to actually send the frame you have to
  /// call either `poll` or `poll_send`.
  pub fn send_frame(&mut self, frame: Frame) {
    self.conn.frame_queue.push_back(frame);
  }

  /// Send content frames to the broker.
  ///
  /// # Notes
  ///
  /// This function only appends the frames to a queue, to actually send the frames you have to
  /// call either `poll` or `poll_send`.
  pub fn send_content_frames(&mut self, channel_id: u16, payload: &[u8], properties: BasicProperties) {
    self.conn.send_content_frames(channel_id, 60, payload, properties);
  }

  /// Poll the network to receive & handle incoming frames.
  ///
  /// # Return value
  ///
  /// This function will always return `Ok(Async::NotReady)` except in two cases:
  ///
  /// * In case of error, it will return `Err(e)`
  /// * If the socket was closed, it will return `Ok(Async::Ready(()))`
  pub fn poll_recv(&mut self) -> Poll<(), io::Error> {
    loop {
      match self.upstream.poll() {
        Ok(Async::Ready(Some(frame))) => {
          trace!("transport poll_recv; frame={:?}", frame);
          if let Err(e) = self.conn.handle_frame(frame) {
            let err = format!("failed to handle frame: {:?}", e);
            return Err(io::Error::new(io::ErrorKind::Other, err));
          }
        },
        Ok(Async::Ready(None)) => {
          trace!("transport poll_recv; status=Ready(None)");
          return Ok(Async::Ready(()));
        },
        Ok(Async::NotReady) => {
          trace!("transport poll_recv; status=NotReady");
          return Ok(Async::NotReady);
        },
        Err(e) => {
          error!("transport poll_recv; status=Err({:?})", e);
          return Err(From::from(e));
        },
      };
    }
  }

  /// Poll the network to send outcoming frames.
  pub fn poll_send(&mut self) -> Poll<(), io::Error> {
    while let Some(frame) = self.conn.next_frame() {
      trace!("transport poll_send; frame={:?}", frame);
      match self.start_send(frame)? {
        AsyncSink::Ready => {
          trace!("transport poll_send; status=Ready");
        },
        AsyncSink::NotReady(frame) => {
          trace!("transport poll_send; status=NotReady");
          self.conn.frame_queue.push_front(frame);
          return Ok(Async::NotReady);
        }
      }
    }
    self.poll_complete()
  }

  pub fn register_consumer(&mut self, consumer_tag: &str, consumer_task: task::Task) {
      self.consumers.insert(consumer_tag.to_string(), consumer_task);
  }
}

impl<T> Future for AMQPTransport<T>
    where T: AsyncRead + AsyncWrite,
          T: Send,
          T: 'static {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        trace!("transport poll");
        if let Async::Ready(_) = self.poll_recv()? {
            return Ok(Async::Ready(()));
        }
        self.poll_send()?;
        Ok(Async::NotReady)
    }
}

impl <T> Sink for AMQPTransport<T>
    where T: AsyncWrite,
          T: Send,
          T: 'static {
    type SinkItem = Frame;
    type SinkError = io::Error;

    fn start_send(&mut self, frame: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        trace!("transport start_send; frame={:?}", frame);
        self.upstream.start_send(frame)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        trace!("transport poll_complete");
        self.upstream.poll_complete()
    }
}

/// implements a future of `AMQPTransport`
///
/// this structure is used to perform the AMQP handshake and provide
/// a connected transport afterwards
pub struct AMQPTransportConnector<T> {
  pub transport: Option<AMQPTransport<T>>,
}

impl<T> Future for AMQPTransportConnector<T>
    where T: AsyncRead + AsyncWrite,
          T: Send,
          T: 'static {

  type Item  = AMQPTransport<T>;
  type Error = io::Error;

  fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
    trace!("connector poll; has_transport={:?}", !self.transport.is_none());
    let mut transport = self.transport.take().unwrap();

    if let Async::Ready(_) = transport.poll()? {
      trace!("connector poll transport; status=Ready");
      return Err(io::Error::new(io::ErrorKind::Other, "The connection was closed during the handshake"));
    }

    trace!("connector poll; state=ConnectionState::{:?}", transport.conn.state);
    if transport.conn.state == ConnectionState::Connected {
      return Ok(Async::Ready(transport))
    }

    self.transport = Some(transport);
    Ok(Async::NotReady)
  }
}

#[macro_export]
macro_rules! lock_transport (
    ($t: expr) => ({
        match $t.lock() {
            Ok(t) => t,
            Err(_) => if $t.is_poisoned() {
                return Err(io::Error::new(io::ErrorKind::Other, "Transport mutex is poisoned"))
            } else {
                task::current().notify();
                return Ok(Async::NotReady)
            }
        }
    });
);

#[cfg(test)]
mod tests {
  extern crate env_logger;

  use super::*;

  #[test]
  fn encode_multiple_frames() {
    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let mut buffer = BytesMut::with_capacity(8192);
    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(8, buffer.len());
    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(16, buffer.len());
    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(24, buffer.len());
  }

  #[test]
  fn encode_nested_frame() {
    use lapin_async::content::ContentHeader;

    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let mut buffer = BytesMut::with_capacity(8192);
    let frame = Frame::Header(0, 10, ContentHeader {
      class_id: 10,
      weight: 0,
      body_size: 64,
      properties: BasicProperties::default()
    });
    let r = codec.encode(frame, &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(22, buffer.len());
  }

  #[test]
  fn encode_initial_extend_buffer() {
    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let frame_max = codec.frame_max as usize;
    let mut buffer = BytesMut::new();

    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(true, buffer.capacity() >= frame_max);
    assert_eq!(8, buffer.len());
  }

  #[test]
  fn encode_anticipation_extend_buffer() {
    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let frame_max = codec.frame_max as usize;
    let mut buffer = BytesMut::new();

    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(frame_max * 2, buffer.capacity());
    assert_eq!(8, buffer.len());

    let payload = repeat(0u8)
      // Use 80% of the remaining space (it shouldn't trigger buffer capacity expansion)
      .take(((buffer.capacity() as f64 - buffer.len() as f64) * 0.8) as usize)
      .collect::<Vec<u8>>();
    let r = codec.encode(Frame::Body(1, payload), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(frame_max * 2, buffer.capacity());

    let payload = repeat(0u8)
      // Use 80% of the remaining space (it should trigger a buffer capacity expansion)
      .take(((buffer.capacity() as f64 - buffer.len() as f64) * 0.8) as usize)
      .collect::<Vec<u8>>();
    let r = codec.encode(Frame::Body(1, payload), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(frame_max * 4, buffer.capacity());
  }
}
<commit_msg>futures: notify consumers when exiting poll_recv if there are pending deliveries<commit_after>/// low level wrapper for the state machine, encoding and decoding from lapin-async
use lapin_async::connection::*;
use lapin_async::format::frame::*;

use nom::{IResult,Offset};
use cookie_factory::GenError;
use bytes::{BufMut, BytesMut};
use std::cmp;
use std::collections::HashMap;
use std::iter::repeat;
use std::io::{self,Error,ErrorKind};
use futures::{Async,AsyncSink,Poll,Sink,StartSend,Stream,Future,future,task};
use tokio_io::{AsyncRead,AsyncWrite};
use tokio_io::codec::{Decoder,Encoder,Framed};
use channel::BasicProperties;
use client::ConnectionOptions;

/// implements tokio-io's Decoder and Encoder
pub struct AMQPCodec {
    pub frame_max: u32,
}

impl Decoder for AMQPCodec {
    type Item = Frame;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Frame>, io::Error> {
        let (consumed, f) = match frame(buf) {
          IResult::Incomplete(_) => {
            return Ok(None)
          },
          IResult::Error(e) => {
            return Err(io::Error::new(io::ErrorKind::Other, format!("parse error: {:?}", e)))
          },
          IResult::Done(i, frame) => {
            (buf.offset(i), frame)
          }
        };

        trace!("amqp decoder; frame={:?}", f);

        buf.split_to(consumed);

        Ok(Some(f))
    }
}

impl Encoder for AMQPCodec {
    type Item = Frame;
    type Error = io::Error;

    fn encode(&mut self, frame: Frame, buf: &mut BytesMut) -> Result<(), Self::Error> {
      let frame_max = cmp::max(self.frame_max, 8192) as usize;
      trace!("encoder; frame={:?}", frame);
      let offset = buf.len();
      loop {
        // If the buffer starts running out of capacity (the threshold is 1/4 of a frame), we
        // reserve more bytes upfront to avoid putting too much strain on the allocator.
        if buf.remaining_mut() < frame_max / 4 {
          trace!("encoder; reserve={}", frame_max * 2);
          buf.reserve(frame_max * 2);
        }

        let gen_res = match &frame {
          &Frame::ProtocolHeader => {
            gen_protocol_header((buf, offset)).map(|tup| tup.1)
          },
          &Frame::Heartbeat(_) => {
            gen_heartbeat_frame((buf, offset)).map(|tup| tup.1)
          },
          &Frame::Method(channel, ref method) => {
            gen_method_frame((buf, offset), channel, method).map(|tup| tup.1)
          },
          &Frame::Header(channel_id, class_id, ref header) => {
            gen_content_header_frame((buf, offset), channel_id, class_id, header.body_size, &header.properties).map(|tup| tup.1)
          },
          &Frame::Body(channel_id, ref data) => {
            gen_content_body_frame((buf, offset), channel_id, data).map(|tup| tup.1)
          }
        };

        match gen_res {
          Ok(sz) => {
            trace!("encoder; frame_size={}", sz - offset);
            return Ok(());
          },
          Err(GenError::BufferTooSmall(sz)) => {
            // BufferTooSmall error variant returns the index the next write would have
            // occured if there was enough space in the buffer. Thus we subtract the
            // buffer's length to know how much bytes we sould make available.
            let length = buf.len();
            trace!("encoder; sz={} length={} extend={}", sz, length, sz - length);
            buf.extend(repeat(0).take(sz - length));
          },
          Err(e) => {
            error!("error generating frame: {:?}", e);
            return Err(Error::new(ErrorKind::InvalidData, "could not generate"));
          }
        }
      }
    }
}

/// Wrappers over a `Framed` stream using `AMQPCodec` and lapin-async's `Connection`
pub struct AMQPTransport<T> {
  upstream:  Framed<T,AMQPCodec>,
  consumers: HashMap<String, task::Task>,
  pub conn:  Connection,
}

impl<T> AMQPTransport<T>
   where T: AsyncRead+AsyncWrite,
         T: Send,
         T: 'static               {

  /// starts the connection process
  ///
  /// returns a future of a `AMQPTransport` that is connected
  pub fn connect(stream: T, options: &ConnectionOptions) -> Box<Future<Item = AMQPTransport<T>, Error = io::Error> + Send> {
    let mut conn = Connection::new();
    conn.set_credentials(&options.username, &options.password);
    conn.set_vhost(&options.vhost);
    conn.set_frame_max(options.frame_max);
    conn.set_heartbeat(options.heartbeat);
    if let Err(e) = conn.connect() {
      let err = format!("Failed to connect: {:?}", e);
      return Box::new(future::err(Error::new(ErrorKind::ConnectionAborted, err)));
    }

    let codec = AMQPCodec {
      frame_max: conn.configuration.frame_max,
    };
    let t = AMQPTransport {
      upstream:     stream.framed(codec),
      consumers:    HashMap::new(),
      conn:         conn,
    };
    let connector = AMQPTransportConnector {
      transport: Some(t),
    };
    Box::new(connector)
  }

  /// Send a frame to the broker.
  ///
  /// # Notes
  ///
  /// This function only appends the frame to a queue, to actually send the frame you have to
  /// call either `poll` or `poll_send`.
  pub fn send_frame(&mut self, frame: Frame) {
    self.conn.frame_queue.push_back(frame);
  }

  /// Send content frames to the broker.
  ///
  /// # Notes
  ///
  /// This function only appends the frames to a queue, to actually send the frames you have to
  /// call either `poll` or `poll_send`.
  pub fn send_content_frames(&mut self, channel_id: u16, payload: &[u8], properties: BasicProperties) {
    self.conn.send_content_frames(channel_id, 60, payload, properties);
  }

  /// Poll the network to receive & handle incoming frames.
  ///
  /// # Return value
  ///
  /// This function will always return `Ok(Async::NotReady)` except in two cases:
  ///
  /// * In case of error, it will return `Err(e)`
  /// * If the socket was closed, it will return `Ok(Async::Ready(()))`
  pub fn poll_recv(&mut self) -> Poll<(), io::Error> {
    loop {
      match self.upstream.poll() {
        Ok(Async::Ready(Some(frame))) => {
          trace!("transport poll_recv; frame={:?}", frame);
          if let Err(e) = self.conn.handle_frame(frame) {
            let err = format!("failed to handle frame: {:?}", e);
            return Err(io::Error::new(io::ErrorKind::Other, err));
          }
        },
        Ok(Async::Ready(None)) => {
          trace!("transport poll_recv; status=Ready(None)");
          return Ok(Async::Ready(()));
        },
        Ok(Async::NotReady) => {
          trace!("transport poll_recv; status=NotReady");
          if self.conn.has_pending_deliveries() {
            for t in self.consumers.values() {
              t.notify();
            }
          }
          return Ok(Async::NotReady);
        },
        Err(e) => {
          error!("transport poll_recv; status=Err({:?})", e);
          return Err(From::from(e));
        },
      };
    }
  }

  /// Poll the network to send outcoming frames.
  pub fn poll_send(&mut self) -> Poll<(), io::Error> {
    while let Some(frame) = self.conn.next_frame() {
      trace!("transport poll_send; frame={:?}", frame);
      match self.start_send(frame)? {
        AsyncSink::Ready => {
          trace!("transport poll_send; status=Ready");
        },
        AsyncSink::NotReady(frame) => {
          trace!("transport poll_send; status=NotReady");
          self.conn.frame_queue.push_front(frame);
          return Ok(Async::NotReady);
        }
      }
    }
    self.poll_complete()
  }

  pub fn register_consumer(&mut self, consumer_tag: &str, consumer_task: task::Task) {
      self.consumers.insert(consumer_tag.to_string(), consumer_task);
  }
}

impl<T> Future for AMQPTransport<T>
    where T: AsyncRead + AsyncWrite,
          T: Send,
          T: 'static {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        trace!("transport poll");
        if let Async::Ready(_) = self.poll_recv()? {
            return Ok(Async::Ready(()));
        }
        self.poll_send()?;
        Ok(Async::NotReady)
    }
}

impl <T> Sink for AMQPTransport<T>
    where T: AsyncWrite,
          T: Send,
          T: 'static {
    type SinkItem = Frame;
    type SinkError = io::Error;

    fn start_send(&mut self, frame: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        trace!("transport start_send; frame={:?}", frame);
        self.upstream.start_send(frame)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        trace!("transport poll_complete");
        self.upstream.poll_complete()
    }
}

/// implements a future of `AMQPTransport`
///
/// this structure is used to perform the AMQP handshake and provide
/// a connected transport afterwards
pub struct AMQPTransportConnector<T> {
  pub transport: Option<AMQPTransport<T>>,
}

impl<T> Future for AMQPTransportConnector<T>
    where T: AsyncRead + AsyncWrite,
          T: Send,
          T: 'static {

  type Item  = AMQPTransport<T>;
  type Error = io::Error;

  fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
    trace!("connector poll; has_transport={:?}", !self.transport.is_none());
    let mut transport = self.transport.take().unwrap();

    if let Async::Ready(_) = transport.poll()? {
      trace!("connector poll transport; status=Ready");
      return Err(io::Error::new(io::ErrorKind::Other, "The connection was closed during the handshake"));
    }

    trace!("connector poll; state=ConnectionState::{:?}", transport.conn.state);
    if transport.conn.state == ConnectionState::Connected {
      return Ok(Async::Ready(transport))
    }

    self.transport = Some(transport);
    Ok(Async::NotReady)
  }
}

#[macro_export]
macro_rules! lock_transport (
    ($t: expr) => ({
        match $t.lock() {
            Ok(t) => t,
            Err(_) => if $t.is_poisoned() {
                return Err(io::Error::new(io::ErrorKind::Other, "Transport mutex is poisoned"))
            } else {
                task::current().notify();
                return Ok(Async::NotReady)
            }
        }
    });
);

#[cfg(test)]
mod tests {
  extern crate env_logger;

  use super::*;

  #[test]
  fn encode_multiple_frames() {
    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let mut buffer = BytesMut::with_capacity(8192);
    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(8, buffer.len());
    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(16, buffer.len());
    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(24, buffer.len());
  }

  #[test]
  fn encode_nested_frame() {
    use lapin_async::content::ContentHeader;

    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let mut buffer = BytesMut::with_capacity(8192);
    let frame = Frame::Header(0, 10, ContentHeader {
      class_id: 10,
      weight: 0,
      body_size: 64,
      properties: BasicProperties::default()
    });
    let r = codec.encode(frame, &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(22, buffer.len());
  }

  #[test]
  fn encode_initial_extend_buffer() {
    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let frame_max = codec.frame_max as usize;
    let mut buffer = BytesMut::new();

    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(true, buffer.capacity() >= frame_max);
    assert_eq!(8, buffer.len());
  }

  #[test]
  fn encode_anticipation_extend_buffer() {
    let _ = env_logger::try_init();

    let mut codec = AMQPCodec { frame_max: 8192 };
    let frame_max = codec.frame_max as usize;
    let mut buffer = BytesMut::new();

    let r = codec.encode(Frame::Heartbeat(0), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(frame_max * 2, buffer.capacity());
    assert_eq!(8, buffer.len());

    let payload = repeat(0u8)
      // Use 80% of the remaining space (it shouldn't trigger buffer capacity expansion)
      .take(((buffer.capacity() as f64 - buffer.len() as f64) * 0.8) as usize)
      .collect::<Vec<u8>>();
    let r = codec.encode(Frame::Body(1, payload), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(frame_max * 2, buffer.capacity());

    let payload = repeat(0u8)
      // Use 80% of the remaining space (it should trigger a buffer capacity expansion)
      .take(((buffer.capacity() as f64 - buffer.len() as f64) * 0.8) as usize)
      .collect::<Vec<u8>>();
    let r = codec.encode(Frame::Body(1, payload), &mut buffer);
    assert_eq!(false, r.is_err());
    assert_eq!(frame_max * 4, buffer.capacity());
  }
}
<|endoftext|>


<commit_before>pub struct Treiber;

/*
pub struct Treiber<T> {
    head: ::Option<Node<T>>,
}

struct Node<T> {
    data: T,
    next: ::Option<Node<T>>,
}

impl<T> Treiber<T> {
    pub fn new() -> Stack<T> {
        Stack {
            head: ::Option::default(),
        }
    }

    pub fn push(&self, item: T) -> Option<T> {
        // TODO: Use `catch {}` here when it lands.
        let mut head = self.head.load(atomic::Ordering::Acquire);
        loop {
            if let Some(head) =  {
                let next = head.next

                match self.head.compare_and_swap(head, next, atomic::Ordering::Release) {
                    Ok()
                    Err(new_head) => head = new_head,
                }
            } else {
                return None;
            }
        }
    }
}
*/
<commit_msg>Initial implementation of treiber stacks for `conc`.<commit_after>use std::sync::atomic;
use Atomic;

pub struct Treiber<T> {
    head: Atomic<Node<T>>,
}

struct Node<T> {
    data: T,
    next: *mut T,
}

impl<T> Treiber<T> {
    pub fn new() -> Treiber<T> {
        Treiber {
            head: Atomic::default(),
        }
    }

    pub fn pop(&self, item: T) -> Option<::Guard<T>> {
        // TODO: Use `catch {}` here when it lands.
        let mut head = self.head.load(atomic::Ordering::Acquire);
        while let Some(node) = head {
            // TODO: This should be something that ignores the guard creation when the CAS
            //       fails, because it's expensive to do and not used anyway. It should be easy
            //       enough to implement, but I am struggling to come up with a good name for
            //       the method.
            match self.head.compare_and_swap_raw(head, node.next, atomic::Ordering::Release) {
                Ok(_) => return node.map(|x| x.data),
                Err(new_head) => head = new_head,
            }
        }
    }

    pub fn push(&self, item: T) {
        // TODO: Use `catch {}` here when it lands.
        let mut head = Box::new(Node {
            data: item,
            next: self.head.load(atomic::Ordering::Acquire),
        });

        loop {
            // TODO: This should be something that ignores the guard creation when the CAS
            //       succeeds, because it's expensive to do and not used anyway. It should be easy
            //       enough to implement, but I am struggling to come up with a good name for the
            //       method.
            match self.head.compare_and_swap_raw(head.next, Some(head), atomic::Ordering::Release) {
                Ok(_) => break,
                Err((new_head, Some(node))) => {
                    head = node;
                    head.next = new_head;
                },
                _ => unreachable!(),
            }
        }
    }
}
<|endoftext|>


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

//! Utility functions for doubly-linked lists.

use std::collections::DList;
use std::mem;
use std::ptr;

struct RawDList<T> {
    length: uint,
    head: Option<Box<RawNode<T>>>,
    tail: *mut RawNode<T>,
}

#[allow(dead_code)]
struct RawNode<T> {
    next: Option<Box<RawNode<T>>>,
    prev: *mut RawNode<T>,
    value: T,
}

#[unsafe_destructor]
impl<T> Drop for RawDList<T> {
    fn drop(&mut self) {
        fail!("shouldn't happen")
    }
}

/// Workaround for a missing method on Rust's `DList` type. Splits the head off a list in O(1)
/// time.
pub fn split<T>(list: &mut DList<T>) -> DList<T> {
    let list = unsafe {
        mem::transmute::<&mut DList<T>,&mut RawDList<T>>(list)
    };

    if list.length == 0 {
        fail!("split_dlist(): empty list")
    }
    let mut head_node = mem::replace(&mut list.head, None);
    let head_node_ptr: *mut RawNode<T> = &mut **head_node.as_mut().unwrap();
    let mut head_list = RawDList {
        length: 1,
        head: head_node,
        tail: head_node_ptr,
    };
    debug_assert!(list.head.is_none());
    mem::swap(&mut head_list.head.as_mut().unwrap().next, &mut list.head);
    debug_assert!(head_list.head.as_mut().unwrap().next.is_none());
    debug_assert!(head_list.head.as_mut().unwrap().prev.is_null());
    head_list.head.as_mut().unwrap().prev = ptr::null_mut();

    list.length -= 1;
    if list.length == 0 {
        list.tail = ptr::null_mut()
    } else {
        if list.length == 1 {
            list.tail = &mut **list.head.as_mut().unwrap() as *mut RawNode<T>
        }
        list.head.as_mut().unwrap().prev = ptr::null_mut()
    }

    unsafe {
        mem::transmute::<RawDList<T>,DList<T>>(head_list)
    }
}

<commit_msg>util: Add a method to push all elements from another doubly-linked list without any moves.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Utility functions for doubly-linked lists.

use std::collections::DList;
use std::mem;
use std::ptr;

struct RawDList<T> {
    length: uint,
    head: Option<Box<RawNode<T>>>,
    tail: *mut RawNode<T>,
}

#[allow(dead_code)]
struct RawNode<T> {
    next: Option<Box<RawNode<T>>>,
    prev: *mut RawNode<T>,
    value: T,
}

#[unsafe_destructor]
impl<T> Drop for RawDList<T> {
    fn drop(&mut self) {
        fail!("shouldn't happen")
    }
}

/// Workaround for a missing method on Rust's `DList` type. Splits the head off a list in O(1)
/// time.
pub fn split<T>(list: &mut DList<T>) -> DList<T> {
    let list = unsafe {
        mem::transmute::<&mut DList<T>,&mut RawDList<T>>(list)
    };

    if list.length == 0 {
        fail!("split_dlist(): empty list")
    }
    let mut head_node = mem::replace(&mut list.head, None);
    let head_node_ptr: *mut RawNode<T> = &mut **head_node.as_mut().unwrap();
    let mut head_list = RawDList {
        length: 1,
        head: head_node,
        tail: head_node_ptr,
    };
    debug_assert!(list.head.is_none());
    mem::swap(&mut head_list.head.as_mut().unwrap().next, &mut list.head);
    debug_assert!(head_list.head.as_mut().unwrap().next.is_none());
    debug_assert!(head_list.head.as_mut().unwrap().prev.is_null());
    head_list.head.as_mut().unwrap().prev = ptr::null_mut();

    list.length -= 1;
    if list.length == 0 {
        list.tail = ptr::null_mut()
    } else {
        if list.length == 1 {
            list.tail = &mut **list.head.as_mut().unwrap() as *mut RawNode<T>
        }
        list.head.as_mut().unwrap().prev = ptr::null_mut()
    }

    unsafe {
        mem::transmute::<RawDList<T>,DList<T>>(head_list)
    }
}

/// Appends the items in the other list to this one, leaving the other list empty.
#[inline]
pub fn append_from<T>(this: &mut DList<T>, other: &mut DList<T>) {
    unsafe {
        let this = mem::transmute::<&mut DList<T>,&mut RawDList<T>>(this);
        let other = mem::transmute::<&mut DList<T>,&mut RawDList<T>>(other);
        if this.length == 0 {
            this.head = mem::replace(&mut other.head, None);
            this.tail = mem::replace(&mut other.tail, ptr::null_mut());
            this.length = mem::replace(&mut other.length, 0);
            return
        }

        (*this.tail).next = match mem::replace(&mut other.head, None) {
            None => return,
            Some(mut head) => {
                head.prev = this.tail;
                Some(head)
            }
        };
        this.tail = mem::replace(&mut other.tail, ptr::null_mut());
        this.length += other.length;
        other.length = 0;
    }
}

<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    account_commands::AccountCommand, client_proxy::ClientProxy, dev_commands::DevCommand,
    query_commands::QueryCommand, transfer_commands::TransferCommand,
};

use failure::prelude::*;
use metrics::counters::*;
use std::{collections::HashMap, sync::Arc};
use types::account_address::ADDRESS_LENGTH;

/// Print the error and bump up error counter.
pub fn report_error(msg: &str, e: Error) {
    println!("[ERROR] {}: {}", msg, pretty_format_error(e));
    COUNTER_CLIENT_ERRORS.inc();
}

fn pretty_format_error(e: Error) -> String {
    if let Some(grpc_error) = e.downcast_ref::<grpcio::Error>() {
        if let grpcio::Error::RpcFailure(grpc_rpc_failure) = grpc_error {
            match grpc_rpc_failure.status {
                grpcio::RpcStatusCode::Unavailable | grpcio::RpcStatusCode::DeadlineExceeded => {
                    return "Server unavailable, please retry and/or check \
                            if host passed to the client is running"
                        .to_string();
                }
                _ => {}
            }
        }
    }

    return format!("{}", e);
}

/// Check whether a command is blocking.
pub fn blocking_cmd(cmd: &str) -> bool {
    cmd.ends_with('b')
}

/// Check whether a command is debugging command.
pub fn debug_format_cmd(cmd: &str) -> bool {
    cmd.ends_with('?')
}

/// Check whether the input string is a valid libra address.
pub fn is_address(data: &str) -> bool {
    match hex::decode(data) {
        Ok(vec) => vec.len() == ADDRESS_LENGTH,
        Err(_) => false,
    }
}

/// Returns all the commands available, as well as the reverse index from the aliases to the
/// commands.
pub fn get_commands() -> (
    Vec<Arc<dyn Command>>,
    HashMap<&'static str, Arc<dyn Command>>,
) {
    let commands: Vec<Arc<dyn Command>> = vec![
        Arc::new(AccountCommand {}),
        Arc::new(QueryCommand {}),
        Arc::new(TransferCommand {}),
        Arc::new(DevCommand {}),
    ];
    let mut alias_to_cmd = HashMap::new();
    for command in &commands {
        for alias in command.get_aliases() {
            alias_to_cmd.insert(alias, Arc::clone(command));
        }
    }
    (commands, alias_to_cmd)
}

/// Parse a cmd string, the first element in the returned vector is the command to run
pub fn parse_cmd(cmd_str: &str) -> Vec<&str> {
    let input = &cmd_str[..];
    input.trim().split(' ').map(str::trim).collect()
}

/// Print the help message for all sub commands.
pub fn print_subcommand_help(parent_command: &str, commands: &[Box<dyn Command>]) {
    println!(
        "usage: {} <arg>\n\nUse the following args for this command:\n",
        parent_command
    );
    for cmd in commands {
        println!(
            "{} {}\n\t{}",
            cmd.get_aliases().join(" | "),
            cmd.get_params_help(),
            cmd.get_description()
        );
    }
    println!("\n");
}

/// Execute sub command.
// TODO: Convert subcommands arrays to lazy statics
pub fn subcommand_execute(
    parent_command_name: &str,
    commands: Vec<Box<dyn Command>>,
    client: &mut ClientProxy,
    params: &[&str],
) {
    let mut commands_map = HashMap::new();
    for (i, cmd) in commands.iter().enumerate() {
        for alias in cmd.get_aliases() {
            if commands_map.insert(alias, i) != None {
                panic!("Duplicate alias {}", alias);
            }
        }
    }

    if params.is_empty() {
        print_subcommand_help(parent_command_name, &commands);
        return;
    }

    match commands_map.get(&params[0]) {
        Some(&idx) => commands[idx].execute(client, &params),
        _ => print_subcommand_help(parent_command_name, &commands),
    }
}

/// Trait to perform client operations.
pub trait Command {
    /// all commands and aliases this command support.
    fn get_aliases(&self) -> Vec<&'static str>;
    /// string that describes params.
    fn get_params_help(&self) -> &'static str {
        ""
    }
    /// string that describes what the command does.
    fn get_description(&self) -> &'static str;
    /// code to execute.
    fn execute(&self, client: &mut ClientProxy, params: &[&str]);
}
<commit_msg>fix multiple whitespace error<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    account_commands::AccountCommand, client_proxy::ClientProxy, dev_commands::DevCommand,
    query_commands::QueryCommand, transfer_commands::TransferCommand,
};

use failure::prelude::*;
use metrics::counters::*;
use std::{collections::HashMap, sync::Arc};
use types::account_address::ADDRESS_LENGTH;

/// Print the error and bump up error counter.
pub fn report_error(msg: &str, e: Error) {
    println!("[ERROR] {}: {}", msg, pretty_format_error(e));
    COUNTER_CLIENT_ERRORS.inc();
}

fn pretty_format_error(e: Error) -> String {
    if let Some(grpc_error) = e.downcast_ref::<grpcio::Error>() {
        if let grpcio::Error::RpcFailure(grpc_rpc_failure) = grpc_error {
            match grpc_rpc_failure.status {
                grpcio::RpcStatusCode::Unavailable | grpcio::RpcStatusCode::DeadlineExceeded => {
                    return "Server unavailable, please retry and/or check \
                            if host passed to the client is running"
                        .to_string();
                }
                _ => {}
            }
        }
    }

    return format!("{}", e);
}

/// Check whether a command is blocking.
pub fn blocking_cmd(cmd: &str) -> bool {
    cmd.ends_with('b')
}

/// Check whether a command is debugging command.
pub fn debug_format_cmd(cmd: &str) -> bool {
    cmd.ends_with('?')
}

/// Check whether the input string is a valid libra address.
pub fn is_address(data: &str) -> bool {
    match hex::decode(data) {
        Ok(vec) => vec.len() == ADDRESS_LENGTH,
        Err(_) => false,
    }
}

/// Returns all the commands available, as well as the reverse index from the aliases to the
/// commands.
pub fn get_commands() -> (
    Vec<Arc<dyn Command>>,
    HashMap<&'static str, Arc<dyn Command>>,
) {
    let commands: Vec<Arc<dyn Command>> = vec![
        Arc::new(AccountCommand {}),
        Arc::new(QueryCommand {}),
        Arc::new(TransferCommand {}),
        Arc::new(DevCommand {}),
    ];
    let mut alias_to_cmd = HashMap::new();
    for command in &commands {
        for alias in command.get_aliases() {
            alias_to_cmd.insert(alias, Arc::clone(command));
        }
    }
    (commands, alias_to_cmd)
}

/// Parse a cmd string, the first element in the returned vector is the command to run
pub fn parse_cmd(cmd_str: &str) -> Vec<&str> {
    cmd_str.split_ascii_whitespace().collect()
}

/// Print the help message for all sub commands.
pub fn print_subcommand_help(parent_command: &str, commands: &[Box<dyn Command>]) {
    println!(
        "usage: {} <arg>\n\nUse the following args for this command:\n",
        parent_command
    );
    for cmd in commands {
        println!(
            "{} {}\n\t{}",
            cmd.get_aliases().join(" | "),
            cmd.get_params_help(),
            cmd.get_description()
        );
    }
    println!("\n");
}

/// Execute sub command.
// TODO: Convert subcommands arrays to lazy statics
pub fn subcommand_execute(
    parent_command_name: &str,
    commands: Vec<Box<dyn Command>>,
    client: &mut ClientProxy,
    params: &[&str],
) {
    let mut commands_map = HashMap::new();
    for (i, cmd) in commands.iter().enumerate() {
        for alias in cmd.get_aliases() {
            if commands_map.insert(alias, i) != None {
                panic!("Duplicate alias {}", alias);
            }
        }
    }

    if params.is_empty() {
        print_subcommand_help(parent_command_name, &commands);
        return;
    }

    match commands_map.get(&params[0]) {
        Some(&idx) => commands[idx].execute(client, &params),
        _ => print_subcommand_help(parent_command_name, &commands),
    }
}

/// Trait to perform client operations.
pub trait Command {
    /// all commands and aliases this command support.
    fn get_aliases(&self) -> Vec<&'static str>;
    /// string that describes params.
    fn get_params_help(&self) -> &'static str {
        ""
    }
    /// string that describes what the command does.
    fn get_description(&self) -> &'static str;
    /// code to execute.
    fn execute(&self, client: &mut ClientProxy, params: &[&str]);
}
<|endoftext|>


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

extern crate walkdir;

use std::collections::{HashMap, HashSet};
use std::env;
use std::fs;
use std::fs::DirBuilder;
use std::path::{Path, PathBuf};
use std::process;
use std::process::{Command, Stdio};
use walkdir::WalkDir;

fn main() {
    let (args, passthrough) = parse_arguments();

    // Find all the native shared libraries that exist in the target directory.
    let native_shared_libs = find_native_libs(&args);

    // Get the SDK path from the ANDROID_HOME env.
    let sdk_path = env::var("ANDROID_HOME").ok().expect("Please set the ANDROID_HOME environment variable");
    let sdk_path = Path::new(&sdk_path);

    // Get the NDK path from NDK_HOME env.
    let ndk_path = env::var("NDK_HOME").ok().expect("Please set the NDK_HOME environment variable");
    let ndk_path = Path::new(&ndk_path);

    // Get the target android platform from ANDROID_PLATFORM env. Expecting "android-{version}"
    let android_platform = env::var("ANDROID_PLATFORM")
        .ok()
        .expect("Please set the ANDROID_PLATFORM environment variable")

    // Get the standalone NDK path from NDK_STANDALONE env.
    //  let standalone_path = env::var("NDK_STANDALONE").ok().unwrap_or("/opt/ndk_standalone".to_string());
    //  let standalone_path = Path::new(&standalone_path);

    let debug = passthrough.contains(&"-d".to_string());

    // Set the build directory that will contain all the necessary files to create the apk
    let directory = args.root_path.join("support").join("android").join("apk");
    let resdir = args.root_path.join("resources/");

    // executing ndk-build
    env::set_var("V", "1");
    if debug {
        env::set_var("NDK_DEBUG", "1");
        env::set_var("APP_OPTIM", "0");
    } else {
        // Overrides android:debuggable propery in the .xml file.
        env::set_var("APP_OPTIM", "1");
    }

    // Copy libservo.so into the jni folder for inclusion in the build
    // TODO: pass/detect target architecture
    {
        let source = &args.target_path.join("libservo.so");
        let target_dir = &directory.join("jni").join("armeabi");
        let _ = DirBuilder::new().recursive(true).create(target_dir);
        let target = target_dir.join("libmain.so");
        println!("Copying the file {:?} to {:?}", source, target);
        fs::copy(source, target).unwrap();
    }

    let ndkcmd = Command::new(ndk_path.join("ndk-build"))
                              .arg("-B")
                              .stdout(Stdio::inherit())
                              .stderr(Stdio::inherit())
                              .current_dir(directory.clone())
                              .status();
    if ndkcmd.is_err() || ndkcmd.unwrap().code().unwrap() != 0 {
        println!("Error while executing program `ndk-build`, or missing program.");
        process::exit(1);
    }

    // Copy the additional native libs into the libs directory.
    for (name, path) in native_shared_libs.iter() {
        let target = &directory.join("libs").join("armeabi").join(name);
        println!("Copying the file {:?} to {:?}", name, target);
        fs::copy(path, target).unwrap();
    }

    // Copy over the resources
    let cpcmd = Command::new("cp")
                             .arg("-R")
                             .arg(&resdir)
                             .arg(&directory.join("assets"))
                             .stdout(Stdio::inherit())
                             .stderr(Stdio::inherit())
                             .current_dir(directory.clone())
                             .status();
    if cpcmd.is_err() || cpcmd.unwrap().code().unwrap() != 0 {
        println!("Error while copying files from the resources dir to the assets dir");
        process::exit(1);
    }

    // Update the project
    let androidcmd = Command::new(sdk_path.join("tools").join("android"))
                                  .arg("update")
                                  .arg("project")
                                  .arg("--name")
                                  .arg("Servo")
                                  .arg("--target")
                                  .arg(&android_platform)
                                  .arg("--path")
                                  .arg(".")
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
    if androidcmd.is_err() || androidcmd.unwrap().code().unwrap() != 0 {
        println!("Error while updating the project with the android command");
        process::exit(1);
    }

    // Build the APK
    let mut antcmd = Command::new("ant");
    if debug {
        antcmd.arg("debug");
    } else {
        antcmd.arg("release");
    }
    let antresult = antcmd
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .current_dir(directory.clone())
        .status();
    if antresult.is_err() || antresult.unwrap().code().unwrap() != 0 {
        println!("Error while executing program `ant`, or missing program.");
        process::exit(1);
    }

    // Copying apk file to the requested output
    // Release builds also need to be signed. For now, we use a simple debug
    // signing key.
    if debug {
        fs::copy(&directory.join("bin").join("Servo-debug.apk"),
                 &args.output).unwrap();
    } else {
        let keystore_dir = env::home_dir().expect("Please have a home directory");
        let keystore_dir = Path::new(&keystore_dir).join(".keystore");
        let keytoolcmd = Command::new("keytool")
                                  .arg("-list")
                                  .arg("-storepass")
                                  .arg("android")
                                  .arg("-alias")
                                  .arg("androiddebugkey")
                                  .arg("-keystore")
                                  .arg(&keystore_dir)
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
        if keytoolcmd.is_err() || keytoolcmd.unwrap().code().unwrap() != 0 {
            let keytoolcreatecmd = Command::new("keytool")
                                  .arg("-genkeypair")
                                  .arg("-keystore")
                                  .arg(&keystore_dir)
                                  .arg("-storepass")
                                  .arg("android")
                                  .arg("-alias")
                                  .arg("androiddebugkey")
                                  .arg("-keypass")
                                  .arg("android")
                                  .arg("-dname")
                                  .arg("CN=Android Debug,O=Android,C=US")
                                  .arg("-keyalg")
                                  .arg("RSA")
                                  .arg("-validity")
                                  .arg("365")
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
            if keytoolcreatecmd.is_err() ||
               keytoolcreatecmd.unwrap().code().unwrap() != 0 {
                   println!("Error while using `keytool` to create the debug keystore.");
                   process::exit(1);
               }
        }

        let jarsigncmd = Command::new("jarsigner")
                                  .arg("-digestalg")
                                  .arg("SHA1")
                                  .arg("-sigalg")
                                  .arg("MD5withRSA")
                                  .arg("-storepass")
                                  .arg("android")
                                  .arg("-keystore")
                                  .arg(&keystore_dir)
                                  .arg(&directory.join("bin").join("Servo-release-unsigned.apk"))
                                  .arg("androiddebugkey")
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
        if jarsigncmd.is_err() || jarsigncmd.unwrap().code().unwrap() != 0 {
            println!("Error while using `jarsign` to sign the APK.");
            process::exit(1);
        }

        fs::copy(&directory.join("bin").join("Servo-release-unsigned.apk"),
                 &args.output).unwrap();
    }

}

struct Args {
    output: PathBuf,
    root_path: PathBuf,
    target_path: PathBuf,
    shared_libraries: HashSet<String>,
}

fn parse_arguments() -> (Args, Vec<String>) {
    let mut result_output = None;
    let mut result_root_path = None;
    let mut result_target_path = None;
    let mut result_shared_libraries = HashSet::new();
    let mut result_passthrough = Vec::new();

    let args = env::args();
    let mut args = args.skip(1);

    loop {
        let arg = match args.next() {
            None => return (
                Args {
                    output: result_output.expect("Could not find -o argument"),
                    root_path: result_root_path.expect("Could not find -r enlistment root argument"),
                    target_path: result_target_path.expect("Could not find -t target path argument"),
                    shared_libraries: result_shared_libraries,
                },
                result_passthrough
            ),
            Some(arg) => arg
        };

        match &*arg {
            "-o" => {
                result_output = Some(PathBuf::from(args.next().expect("-o must be followed by the output name")));
            },
            "-r" => {
                result_root_path =
                    Some(PathBuf::from(args.next().expect("-r must be followed by the enlistment root directory")));
            },
            "-t" => {
                result_target_path =
                    Some(PathBuf::from(args.next().expect("-t must be followed by the target output directory")));
            },
            "-l" => {
                let name = args.next().expect("-l must be followed by a library name");
                result_shared_libraries.insert(vec!["lib", &name, ".so"].concat());

                // Also pass these through.
                result_passthrough.push(arg);
                result_passthrough.push(name);
            }
            _ => {
                if arg.starts_with("-l") {
                    result_shared_libraries.insert(vec!["lib", &arg[2..], ".so"].concat());
                }
                result_passthrough.push(arg)
            }
        };
    }
}

fn find_native_libs(args: &Args) -> HashMap<String, PathBuf> {
    let mut native_shared_libs: HashMap<String, PathBuf> = HashMap::new();

    // Add requested .so files
    for dir_entry in WalkDir::new(&args.target_path) {
        let dir_entry = dir_entry.unwrap();
        let path = dir_entry.path();

        match (path.file_name(), path.extension()) {
            (Some(file_name), Some(extension)) => {
                let file_name = file_name.to_str().unwrap();

                if file_name.starts_with("lib") &&
                    extension == "so" &&
                    args.shared_libraries.contains(file_name) {
                        println!("Adding the file {:?}", file_name);
                        native_shared_libs.insert(file_name.to_string(), path.to_path_buf().clone());
                        break;
                }
            }
            _ => {}
        }
    }

    native_shared_libs
}
<commit_msg>Fix Android APK building (packaging)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate walkdir;

use std::collections::{HashMap, HashSet};
use std::env;
use std::fs;
use std::fs::DirBuilder;
use std::path::{Path, PathBuf};
use std::process;
use std::process::{Command, Stdio};
use walkdir::WalkDir;

fn main() {
    let (args, passthrough) = parse_arguments();

    // Find all the native shared libraries that exist in the target directory.
    let native_shared_libs = find_native_libs(&args);

    // Get the SDK path from the ANDROID_HOME env.
    let sdk_path = env::var("ANDROID_HOME").ok().expect("Please set the ANDROID_HOME environment variable");
    let sdk_path = Path::new(&sdk_path);

    // Get the NDK path from NDK_HOME env.
    let ndk_path = env::var("NDK_HOME").ok().expect("Please set the NDK_HOME environment variable");
    let ndk_path = Path::new(&ndk_path);

    // Get the target android platform from ANDROID_PLATFORM env. Expecting "android-{version}"
    let android_platform = env::var("ANDROID_PLATFORM")
        .ok()
        .expect("Please set the ANDROID_PLATFORM environment variable");

    // Get the standalone NDK path from NDK_STANDALONE env.
    //  let standalone_path = env::var("NDK_STANDALONE").ok().unwrap_or("/opt/ndk_standalone".to_string());
    //  let standalone_path = Path::new(&standalone_path);

    let debug = passthrough.contains(&"-d".to_string());

    // Set the build directory that will contain all the necessary files to create the apk
    let directory = args.root_path.join("support").join("android").join("apk");
    let resdir = args.root_path.join("resources/");

    // executing ndk-build
    env::set_var("V", "1");
    if debug {
        env::set_var("NDK_DEBUG", "1");
        env::set_var("APP_OPTIM", "0");
    } else {
        // Overrides android:debuggable propery in the .xml file.
        env::set_var("APP_OPTIM", "1");
    }

    // Copy libservo.so into the jni folder for inclusion in the build
    // TODO: pass/detect target architecture
    {
        let source = &args.target_path.join("libservo.so");
        let target_dir = &directory.join("jni").join("armeabi");
        let _ = DirBuilder::new().recursive(true).create(target_dir);
        let target = target_dir.join("libmain.so");
        println!("Copying the file {:?} to {:?}", source, target);
        fs::copy(source, target).unwrap();
    }

    let ndkcmd = Command::new(ndk_path.join("ndk-build"))
                              .arg("-B")
                              .stdout(Stdio::inherit())
                              .stderr(Stdio::inherit())
                              .current_dir(directory.clone())
                              .status();
    if ndkcmd.is_err() || ndkcmd.unwrap().code().unwrap() != 0 {
        println!("Error while executing program `ndk-build`, or missing program.");
        process::exit(1);
    }

    // Copy the additional native libs into the libs directory.
    for (name, path) in native_shared_libs.iter() {
        let target = &directory.join("libs").join("armeabi").join(name);
        println!("Copying the file {:?} to {:?}", name, target);
        fs::copy(path, target).unwrap();
    }

    // Copy over the resources
    let cpcmd = Command::new("cp")
                             .arg("-R")
                             .arg(&resdir)
                             .arg(&directory.join("assets"))
                             .stdout(Stdio::inherit())
                             .stderr(Stdio::inherit())
                             .current_dir(directory.clone())
                             .status();
    if cpcmd.is_err() || cpcmd.unwrap().code().unwrap() != 0 {
        println!("Error while copying files from the resources dir to the assets dir");
        process::exit(1);
    }

    // Update the project
    let androidcmd = Command::new(sdk_path.join("tools").join("android"))
                                  .arg("update")
                                  .arg("project")
                                  .arg("--name")
                                  .arg("Servo")
                                  .arg("--target")
                                  .arg(&android_platform)
                                  .arg("--path")
                                  .arg(".")
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
    if androidcmd.is_err() || androidcmd.unwrap().code().unwrap() != 0 {
        println!("Error while updating the project with the android command");
        process::exit(1);
    }

    // Build the APK
    let mut antcmd = Command::new("ant");
    if debug {
        antcmd.arg("debug");
    } else {
        antcmd.arg("release");
    }
    let antresult = antcmd
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .current_dir(directory.clone())
        .status();
    if antresult.is_err() || antresult.unwrap().code().unwrap() != 0 {
        println!("Error while executing program `ant`, or missing program.");
        process::exit(1);
    }

    // Copying apk file to the requested output
    // Release builds also need to be signed. For now, we use a simple debug
    // signing key.
    if debug {
        fs::copy(&directory.join("bin").join("Servo-debug.apk"),
                 &args.output).unwrap();
    } else {
        let keystore_dir = env::home_dir().expect("Please have a home directory");
        let keystore_dir = Path::new(&keystore_dir).join(".keystore");
        let keytoolcmd = Command::new("keytool")
                                  .arg("-list")
                                  .arg("-storepass")
                                  .arg("android")
                                  .arg("-alias")
                                  .arg("androiddebugkey")
                                  .arg("-keystore")
                                  .arg(&keystore_dir)
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
        if keytoolcmd.is_err() || keytoolcmd.unwrap().code().unwrap() != 0 {
            let keytoolcreatecmd = Command::new("keytool")
                                  .arg("-genkeypair")
                                  .arg("-keystore")
                                  .arg(&keystore_dir)
                                  .arg("-storepass")
                                  .arg("android")
                                  .arg("-alias")
                                  .arg("androiddebugkey")
                                  .arg("-keypass")
                                  .arg("android")
                                  .arg("-dname")
                                  .arg("CN=Android Debug,O=Android,C=US")
                                  .arg("-keyalg")
                                  .arg("RSA")
                                  .arg("-validity")
                                  .arg("365")
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
            if keytoolcreatecmd.is_err() ||
               keytoolcreatecmd.unwrap().code().unwrap() != 0 {
                   println!("Error while using `keytool` to create the debug keystore.");
                   process::exit(1);
               }
        }

        let jarsigncmd = Command::new("jarsigner")
                                  .arg("-digestalg")
                                  .arg("SHA1")
                                  .arg("-sigalg")
                                  .arg("MD5withRSA")
                                  .arg("-storepass")
                                  .arg("android")
                                  .arg("-keystore")
                                  .arg(&keystore_dir)
                                  .arg(&directory.join("bin").join("Servo-release-unsigned.apk"))
                                  .arg("androiddebugkey")
                                  .stdout(Stdio::inherit())
                                  .stderr(Stdio::inherit())
                                  .current_dir(directory.clone())
                                  .status();
        if jarsigncmd.is_err() || jarsigncmd.unwrap().code().unwrap() != 0 {
            println!("Error while using `jarsign` to sign the APK.");
            process::exit(1);
        }

        fs::copy(&directory.join("bin").join("Servo-release-unsigned.apk"),
                 &args.output).unwrap();
    }

}

struct Args {
    output: PathBuf,
    root_path: PathBuf,
    target_path: PathBuf,
    shared_libraries: HashSet<String>,
}

fn parse_arguments() -> (Args, Vec<String>) {
    let mut result_output = None;
    let mut result_root_path = None;
    let mut result_target_path = None;
    let mut result_shared_libraries = HashSet::new();
    let mut result_passthrough = Vec::new();

    let args = env::args();
    let mut args = args.skip(1);

    loop {
        let arg = match args.next() {
            None => return (
                Args {
                    output: result_output.expect("Could not find -o argument"),
                    root_path: result_root_path.expect("Could not find -r enlistment root argument"),
                    target_path: result_target_path.expect("Could not find -t target path argument"),
                    shared_libraries: result_shared_libraries,
                },
                result_passthrough
            ),
            Some(arg) => arg
        };

        match &*arg {
            "-o" => {
                result_output = Some(PathBuf::from(args.next().expect("-o must be followed by the output name")));
            },
            "-r" => {
                result_root_path =
                    Some(PathBuf::from(args.next().expect("-r must be followed by the enlistment root directory")));
            },
            "-t" => {
                result_target_path =
                    Some(PathBuf::from(args.next().expect("-t must be followed by the target output directory")));
            },
            "-l" => {
                let name = args.next().expect("-l must be followed by a library name");
                result_shared_libraries.insert(vec!["lib", &name, ".so"].concat());

                // Also pass these through.
                result_passthrough.push(arg);
                result_passthrough.push(name);
            }
            _ => {
                if arg.starts_with("-l") {
                    result_shared_libraries.insert(vec!["lib", &arg[2..], ".so"].concat());
                }
                result_passthrough.push(arg)
            }
        };
    }
}

fn find_native_libs(args: &Args) -> HashMap<String, PathBuf> {
    let mut native_shared_libs: HashMap<String, PathBuf> = HashMap::new();

    // Add requested .so files
    for dir_entry in WalkDir::new(&args.target_path) {
        let dir_entry = dir_entry.unwrap();
        let path = dir_entry.path();

        match (path.file_name(), path.extension()) {
            (Some(file_name), Some(extension)) => {
                let file_name = file_name.to_str().unwrap();

                if file_name.starts_with("lib") &&
                    extension == "so" &&
                    args.shared_libraries.contains(file_name) {
                        println!("Adding the file {:?}", file_name);
                        native_shared_libs.insert(file_name.to_string(), path.to_path_buf().clone());
                        break;
                }
            }
            _ => {}
        }
    }

    native_shared_libs
}
<|endoftext|>