<commit_before>// Copyright 2014-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.

//! Constructor methods for ndarray
//!

use libnum;

use imp_prelude::*;
use dimension;
use linspace;
use error::{self, ShapeError, ErrorKind};

/// A contiguous array shape of n dimensions.
///
/// Either c- or f- memory ordered.
pub struct Shape<D> {
    dim: D,
    is_c: bool,
}

/// An array shape of n dimensions with possibly custom strides.
pub struct StrideShape<D> {
    dim: D,
    strides: D,
    custom: bool,
}

pub trait ShapeBuilder {
    type Dim: Dimension;

    fn f(self) -> Shape<Self::Dim>;
    fn strides(self, st: Self::Dim) -> StrideShape<Self::Dim>;
}

impl<D> From<D> for Shape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        Shape {
            dim: d,
            is_c: true,
        }
    }
}

impl<D> From<D> for StrideShape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        StrideShape {
            strides: d.default_strides(),
            dim: d,
            custom: false,
        }
    }
}

impl<D> From<Shape<D>> for StrideShape<D>
    where D: Dimension
{
    fn from(shape: Shape<D>) -> Self {
        let d = shape.dim;
        let st = if shape.is_c { d.default_strides() } else { d.fortran_strides() };
        StrideShape {
            strides: st,
            dim: d,
            custom: false,
        }
    }
}

impl<D> ShapeBuilder for D
    where D: Dimension
{
    type Dim = D;
    fn f(self) -> Shape<D> {
        Shape::from(self).f()
    }
    fn strides(self, st: D) -> StrideShape<D> {
        Shape::from(self).strides(st)
    }
}

impl<D> ShapeBuilder for Shape<D>
    where D: Dimension
{
    type Dim = D;
    fn f(mut self) -> Self {
        self.is_c = false;
        self
    }
    fn strides(self, st: D) -> StrideShape<D> {
        StrideShape {
            dim: self.dim,
            strides: st,
            custom: true,
        }
    }
}

/// Constructor methods for one-dimensional arrays.
///
/// Note that the constructor methods apply to `OwnedArray` and `RcArray`,
/// the two array types that have owned storage.
impl<S> ArrayBase<S, Ix>
    where S: DataOwned
{
    /// Create a one-dimensional array from a vector (no copying needed).
    ///
    /// ```rust
    /// use ndarray::OwnedArray;
    ///
    /// let array = OwnedArray::from_vec(vec![1., 2., 3., 4.]);
    /// ```
    pub fn from_vec(v: Vec<S::Elem>) -> ArrayBase<S, Ix> {
        unsafe { Self::from_vec_dim_unchecked(v.len() as Ix, v) }
    }

    /// Create a one-dimensional array from an iterable.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::from_iter((0..5).map(|x| x * x));
    /// assert!(array == arr1(&[0, 1, 4, 9, 16]))
    /// ```
    pub fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=S::Elem>
    {
        Self::from_vec(iterable.into_iter().collect())
    }

    /// Create a one-dimensional array from the inclusive interval
    /// `[start, end]` with `n` elements. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::linspace(0., 1., 5);
    /// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
    /// ```
    pub fn linspace<F>(start: F, end: F, n: usize) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: libnum::Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::linspace(start, end, n)))
    }

    /// Create a one-dimensional array from the half-open interval
    /// `[start, end)` with elements spaced by `step`. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::range(0., 5., 1.);
    /// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
    /// ```
    pub fn range<F>(start: F, end: F, step: F) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: libnum::Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::range(start, end, step)))
    }
}

/// Constructor methods for two-dimensional arrays.
impl<S, A> ArrayBase<S, (Ix, Ix)>
    where S: DataOwned<Elem=A>,
{
    /// Create an identity matrix of size `n` (square 2D array).
    ///
    /// **Panics** if `n * n` would overflow usize.
    pub fn eye(n: Ix) -> ArrayBase<S, (Ix, Ix)>
        where S: DataMut,
              A: Clone + libnum::Zero + libnum::One,
    {
        let mut eye = Self::zeros((n, n));
        for a_ii in eye.diag_mut() {
            *a_ii = A::one();
        }
        eye
    }
}

macro_rules! size_checked_unwrap {
    ($dim:expr) => {
        match $dim.size_checked() {
            Some(sz) => sz,
            None => panic!("ndarray: Shape too large, number of elements overflows usize"),
        }
    }
}

/// Constructor methods for n-dimensional arrays.
impl<S, A, D> ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
{
    /// Create an array with copies of `elem`, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    ///
    /// ```
    /// use ndarray::OwnedArray;
    /// use ndarray::arr3;
    ///
    /// let a = OwnedArray::from_elem((2, 2, 2), 1.);
    ///
    /// assert!(
    ///     a == arr3(&[[[1., 1.],
    ///                  [1., 1.]],
    ///                 [[1., 1.],
    ///                  [1., 1.]]])
    /// );
    /// assert!(a.strides() == &[4, 2, 1]);
    /// ```
    pub fn from_elem(dim: D, elem: A) -> ArrayBase<S, D>
        where A: Clone
    {
        // Note: We don't need to check the case of a size between
        // isize::MAX -> usize::MAX; in this case, the vec constructor itself
        // panics.
        let size = size_checked_unwrap!(dim);
        let v = vec![elem; size];
        unsafe { Self::from_vec_dim_unchecked(dim, v) }
    }

    /// Create an array with copies of `elem`, dimension `dim` and fortran
    /// memory order.
    ///
    /// **Panics** if the number of elements would overflow usize.
    ///
    /// ```
    /// use ndarray::OwnedArray;
    ///
    /// let a = OwnedArray::from_elem_f((2, 2, 2), 1.);
    /// assert!(a.strides() == &[1, 2, 4]);
    /// ```
    pub fn from_elem_f(dim: D, elem: A) -> ArrayBase<S, D>
        where A: Clone
    {
        let size = size_checked_unwrap!(dim);
        let v = vec![elem; size];
        unsafe { Self::from_vec_dim_unchecked_f(dim, v) }
    }

    /// Create an array with zeros, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn zeros(dim: D) -> ArrayBase<S, D>
        where A: Clone + libnum::Zero
    {
        Self::from_elem(dim, libnum::zero())
    }

    /// Create an array with zeros, dimension `dim` and fortran memory order.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn zeros_f(dim: D) -> ArrayBase<S, D>
        where A: Clone + libnum::Zero
    {
        Self::from_elem_f(dim, libnum::zero())
    }

    /// Create an array with default values, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn default(dim: D) -> ArrayBase<S, D>
        where A: Default
    {
        let v = (0..dim.size()).map(|_| A::default()).collect();
        unsafe { Self::from_vec_dim_unchecked(dim, v) }
    }

    /// Create an array with the given shape from a vector (no copying needed).
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_shape_vec<Sh>(shape: Sh, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
        where Sh: Into<StrideShape<D>>,
    {
        let shape = shape.into();
        if shape.custom {
            Self::from_vec_dim_stride(shape.dim, shape.strides, v)
        } else {
            let dim = shape.dim;
            let strides = shape.strides;
            if dim.size_checked() != Some(v.len()) {
                return Err(error::incompatible_shapes(&v.len(), &dim));
            }
            unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
        }
    }

    /// Create an array from a vector (no copying needed).
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_vec_dim(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked(dim, v)) }
    }

    /// Create an array from a vector (no copying needed) using fortran
    /// memory order to interpret the data.
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_vec_dim_f(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked_f(dim, v)) }
    }

    /// Create an array from a vector (no copying needed).
    ///
    /// Unsafe because dimension is unchecked, and must be correct.
    pub unsafe fn from_vec_dim_unchecked(dim: D, mut v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: dim.default_strides(),
            dim: dim,
        }
    }

    /// Create an array from a vector (with no copying needed),
    /// using fortran memory order to interpret the data.
    ///
    /// Unsafe because dimension is unchecked, and must be correct.
    pub unsafe fn from_vec_dim_unchecked_f(dim: D, v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        let strides = dim.fortran_strides();
        Self::from_vec_dim_stride_unchecked(dim, strides, v)
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. No allocation needed.
    ///
    /// Checks whether `dim` and `strides` are compatible with the vector's
    /// length, returning an `Err` if not compatible.
    ///
    /// **Errors** if strides and dimensions can point out of bounds of `v`.<br>
    /// **Errors** if strides allow multiple indices to point to the same element.
    pub fn from_vec_dim_stride(dim: D, strides: D, v: Vec<A>)
        -> Result<ArrayBase<S, D>, ShapeError>
    {
        dimension::can_index_slice(&v, &dim, &strides).map(|_| {
            unsafe {
                Self::from_vec_dim_stride_unchecked(dim, strides, v)
            }
        })
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. No allocation needed.
    ///
    /// Unsafe because dimension and strides are unchecked.
    pub unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>)
        -> ArrayBase<S, D>
    {
        // debug check for issues that indicates wrong use of this constructor
        debug_assert!(match dimension::can_index_slice(&v, &dim, &strides) {
            Ok(_) => true,
            Err(ref e) => match e.kind() {
                ErrorKind::OutOfBounds => false,
                ErrorKind::RangeLimited => false,
                _ => true,
            }
        });
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: strides,
            dim: dim
        }
    }

}
<commit_msg>Use Shape for from_elem, zeros, default constructors<commit_after>// Copyright 2014-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.

//! Constructor methods for ndarray
//!

use libnum::{Zero, One, Float};

use imp_prelude::*;
use dimension;
use linspace;
use error::{self, ShapeError, ErrorKind};

/// A contiguous array shape of n dimensions.
///
/// Either c- or f- memory ordered.
pub struct Shape<D> {
    dim: D,
    is_c: bool,
}

/// An array shape of n dimensions with possibly custom strides.
pub struct StrideShape<D> {
    dim: D,
    strides: D,
    custom: bool,
}

pub trait ShapeBuilder {
    type Dim: Dimension;

    fn f(self) -> Shape<Self::Dim>;
    fn strides(self, st: Self::Dim) -> StrideShape<Self::Dim>;
}

impl<D> From<D> for Shape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        Shape {
            dim: d,
            is_c: true,
        }
    }
}

impl<D> From<D> for StrideShape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        StrideShape {
            strides: d.default_strides(),
            dim: d,
            custom: false,
        }
    }
}

impl<D> From<Shape<D>> for StrideShape<D>
    where D: Dimension
{
    fn from(shape: Shape<D>) -> Self {
        let d = shape.dim;
        let st = if shape.is_c { d.default_strides() } else { d.fortran_strides() };
        StrideShape {
            strides: st,
            dim: d,
            custom: false,
        }
    }
}

impl<D> ShapeBuilder for D
    where D: Dimension
{
    type Dim = D;
    fn f(self) -> Shape<D> {
        Shape::from(self).f()
    }
    fn strides(self, st: D) -> StrideShape<D> {
        Shape::from(self).strides(st)
    }
}

impl<D> ShapeBuilder for Shape<D>
    where D: Dimension
{
    type Dim = D;
    fn f(mut self) -> Self {
        self.is_c = false;
        self
    }
    fn strides(self, st: D) -> StrideShape<D> {
        StrideShape {
            dim: self.dim,
            strides: st,
            custom: true,
        }
    }
}

/// Constructor methods for one-dimensional arrays.
///
/// Note that the constructor methods apply to `OwnedArray` and `RcArray`,
/// the two array types that have owned storage.
impl<S> ArrayBase<S, Ix>
    where S: DataOwned
{
    /// Create a one-dimensional array from a vector (no copying needed).
    ///
    /// ```rust
    /// use ndarray::OwnedArray;
    ///
    /// let array = OwnedArray::from_vec(vec![1., 2., 3., 4.]);
    /// ```
    pub fn from_vec(v: Vec<S::Elem>) -> ArrayBase<S, Ix> {
        unsafe { Self::from_vec_dim_unchecked(v.len() as Ix, v) }
    }

    /// Create a one-dimensional array from an iterable.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::from_iter((0..5).map(|x| x * x));
    /// assert!(array == arr1(&[0, 1, 4, 9, 16]))
    /// ```
    pub fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=S::Elem>
    {
        Self::from_vec(iterable.into_iter().collect())
    }

    /// Create a one-dimensional array from the inclusive interval
    /// `[start, end]` with `n` elements. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::linspace(0., 1., 5);
    /// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
    /// ```
    pub fn linspace<F>(start: F, end: F, n: usize) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::linspace(start, end, n)))
    }

    /// Create a one-dimensional array from the half-open interval
    /// `[start, end)` with elements spaced by `step`. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::range(0., 5., 1.);
    /// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
    /// ```
    pub fn range<F>(start: F, end: F, step: F) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::range(start, end, step)))
    }
}

/// Constructor methods for two-dimensional arrays.
impl<S, A> ArrayBase<S, (Ix, Ix)>
    where S: DataOwned<Elem=A>,
{
    /// Create an identity matrix of size `n` (square 2D array).
    ///
    /// **Panics** if `n * n` would overflow usize.
    pub fn eye(n: Ix) -> ArrayBase<S, (Ix, Ix)>
        where S: DataMut,
              A: Clone + Zero + One,
    {
        let mut eye = Self::zeros((n, n));
        for a_ii in eye.diag_mut() {
            *a_ii = A::one();
        }
        eye
    }
}

macro_rules! size_checked_unwrap {
    ($dim:expr) => {
        match $dim.size_checked() {
            Some(sz) => sz,
            None => panic!("ndarray: Shape too large, number of elements overflows usize"),
        }
    }
}

/// Constructor methods for n-dimensional arrays.
impl<S, A, D> ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
{
    /// Create an array with copies of `elem`, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    ///
    /// ```
    /// use ndarray::OwnedArray;
    /// use ndarray::arr3;
    ///
    /// let a = OwnedArray::from_elem((2, 2, 2), 1.);
    ///
    /// assert!(
    ///     a == arr3(&[[[1., 1.],
    ///                  [1., 1.]],
    ///                 [[1., 1.],
    ///                  [1., 1.]]])
    /// );
    /// assert!(a.strides() == &[4, 2, 1]);
    /// ```
    pub fn from_elem<Sh>(shape: Sh, elem: A) -> ArrayBase<S, D>
        where A: Clone,
              Sh: Into<Shape<D>>,
    {
        // Note: We don't need to check the case of a size between
        // isize::MAX -> usize::MAX; in this case, the vec constructor itself
        // panics.
        let shape = shape.into();
        let size = size_checked_unwrap!(shape.dim);
        let v = vec![elem; size];
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with copies of `elem`, dimension `dim` and fortran
    /// memory order.
    ///
    /// **Panics** if the number of elements would overflow usize.
    ///
    /// ```
    /// use ndarray::OwnedArray;
    ///
    /// let a = OwnedArray::from_elem_f((2, 2, 2), 1.);
    /// assert!(a.strides() == &[1, 2, 4]);
    /// ```
    pub fn from_elem_f(dim: D, elem: A) -> ArrayBase<S, D>
        where A: Clone
    {
        Self::from_elem(dim.f(), elem)
    }

    /// Create an array with zeros, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn zeros<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Clone + Zero,
              Sh: Into<Shape<D>>,
    {
        Self::from_elem(shape, A::zero())
    }

    /// Create an array with zeros, dimension `dim` and fortran memory order.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn zeros_f(dim: D) -> ArrayBase<S, D>
        where A: Clone + Zero
    {
        Self::from_elem_f(dim, A::zero())
    }

    /// Create an array with default values, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn default(dim: D) -> ArrayBase<S, D>
        where A: Default
    {
        let v = (0..dim.size()).map(|_| A::default()).collect();
        unsafe { Self::from_vec_dim_unchecked(dim, v) }
    }

    /// Create an array with the given shape from a vector (no copying needed).
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_shape_vec<Sh>(shape: Sh, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
        where Sh: Into<StrideShape<D>>,
    {
        let shape = shape.into();
        if shape.custom {
            Self::from_vec_dim_stride(shape.dim, shape.strides, v)
        } else {
            let dim = shape.dim;
            let strides = shape.strides;
            if dim.size_checked() != Some(v.len()) {
                return Err(error::incompatible_shapes(&v.len(), &dim));
            }
            unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
        }
    }

    /// Create an array with the given shape from a vector (no copying needed).
    pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec<A>) -> ArrayBase<S, D>
        where Sh: Into<StrideShape<D>>,
    {
        let shape = shape.into();
        Self::from_vec_dim_stride_unchecked(shape.dim, shape.strides, v)
    }

    /// Create an array from a vector (no copying needed).
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_vec_dim(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked(dim, v)) }
    }

    /// Create an array from a vector (no copying needed) using fortran
    /// memory order to interpret the data.
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_vec_dim_f(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked_f(dim, v)) }
    }

    /// Create an array from a vector (no copying needed).
    ///
    /// Unsafe because dimension is unchecked, and must be correct.
    pub unsafe fn from_vec_dim_unchecked(dim: D, mut v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: dim.default_strides(),
            dim: dim,
        }
    }

    /// Create an array from a vector (with no copying needed),
    /// using fortran memory order to interpret the data.
    ///
    /// Unsafe because dimension is unchecked, and must be correct.
    pub unsafe fn from_vec_dim_unchecked_f(dim: D, v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        let strides = dim.fortran_strides();
        Self::from_vec_dim_stride_unchecked(dim, strides, v)
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. No allocation needed.
    ///
    /// Checks whether `dim` and `strides` are compatible with the vector's
    /// length, returning an `Err` if not compatible.
    ///
    /// **Errors** if strides and dimensions can point out of bounds of `v`.<br>
    /// **Errors** if strides allow multiple indices to point to the same element.
    pub fn from_vec_dim_stride(dim: D, strides: D, v: Vec<A>)
        -> Result<ArrayBase<S, D>, ShapeError>
    {
        dimension::can_index_slice(&v, &dim, &strides).map(|_| {
            unsafe {
                Self::from_vec_dim_stride_unchecked(dim, strides, v)
            }
        })
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. No allocation needed.
    ///
    /// Unsafe because dimension and strides are unchecked.
    pub unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>)
        -> ArrayBase<S, D>
    {
        // debug check for issues that indicates wrong use of this constructor
        debug_assert!(match dimension::can_index_slice(&v, &dim, &strides) {
            Ok(_) => true,
            Err(ref e) => match e.kind() {
                ErrorKind::OutOfBounds => false,
                ErrorKind::RangeLimited => false,
                _ => true,
            }
        });
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: strides,
            dim: dim
        }
    }

}
<|endoftext|>


<commit_before>use std::collections::hash_map::{HashMap, Occupied, Vacant};

// Holds a number of variables and their values.
#[deriving(Show, Clone)]
pub struct Scope<'s> {
	var_values: Vec<f32>, // values of vars by id
	vars: HashMap<&'s str, uint>, // map of var name -> var id
}

impl<'a> Scope<'a> {
	// Constructs an empty scope object.
	pub fn new() -> Scope<'a> {
		Scope {
			var_values: Vec::new(),
			vars: HashMap::new(),
		}
	}

	// Returns a uint identifier which can be passed to set_var to quickly update the value of a
	// variable.
	pub fn var_id(&self, var: &'a str) -> Option<uint> {
		match self.vars.get(&var) {
			Some(v) => Some(*v),
			None => None,
		}
	}

	// Sets a variable to an id retrieved from var_id. Return value indicates whether it was set
	// sucessfully or not.
	pub fn set_var(&mut self, var_id: uint, value: f32) -> bool {
		if var_id > self.var_values.len() {
			return false;
		}
		self.var_values[var_id] = value;
		true
	}

	// Returns the value of a variable by id.
	pub fn get_var(&self, var_id: uint) -> Option<f32> {
		if var_id >= self.var_values.len() {
			None
		} else {
			Some(self.var_values[var_id])
		}
	}

	// Sets a variable to a specified value, creating the variable if it does not exist.
	pub fn define(&mut self, var: &'a str, value: f32) {
		let nv = self.vars.len();
		match self.vars.entry(var) {
			Occupied(entry) => {
				self.var_values[*entry.get()] = value;
			},
			Vacant(entry) => {
				entry.set(nv);
				self.var_values.push(value);
			},
		}
	}

	// Returns the number of variables set in the scope.
	pub fn num_vars(&self) -> uint {
		self.vars.len()
	}
}
<commit_msg>Extend scopes to contain functions.<commit_after>use std::collections::hash_map::{HashMap, Occupied, Vacant};
use super::function::Function;

// Holds a number of variables and their values.
#[deriving(Clone)]
pub struct Scope<'a> {
	var_values: Vec<f32>, // values of vars by id
	vars: HashMap<&'a str, uint>, // map of var name -> var id

	functions: HashMap<&'a str, &'a Box<Function + 'a>>,
}

impl<'a> Scope<'a> {
	// Constructs an empty scope object.
	pub fn new() -> Scope<'a> {
		Scope {
			var_values: Vec::new(),
			vars: HashMap::new(),
			functions: HashMap::new(),
		}
	}

	// Returns a uint identifier which can be passed to set_var to quickly update the value of a
	// variable.
	pub fn var_id(&self, var: &'a str) -> Option<uint> {
		match self.vars.get(&var) {
			Some(v) => Some(*v),
			None => None,
		}
	}

	// Sets a variable to an id retrieved from var_id. Return value indicates whether it was set
	// sucessfully or not.
	pub fn set_var(&mut self, var_id: uint, value: f32) -> bool {
		if var_id > self.var_values.len() {
			return false;
		}
		self.var_values[var_id] = value;
		true
	}

	// Returns the value of a variable by id.
	pub fn get_var(&self, var_id: uint) -> Option<f32> {
		if var_id >= self.var_values.len() {
			None
		} else {
			Some(self.var_values[var_id])
		}
	}

	// Sets a variable to a specified value, creating the variable if it does not exist.
	pub fn define_var(&mut self, var: &'a str, value: f32) {
		let nv = self.vars.len();
		match self.vars.entry(var) {
			Occupied(entry) => {
				self.var_values[*entry.get()] = value;
			},
			Vacant(entry) => {
				entry.set(nv);
				self.var_values.push(value);
			},
		}
	}

	// Returns the number of variables set in the scope.
	pub fn num_vars(&self) -> uint {
		self.vars.len()
	}

	pub fn define_function(&mut self, name: &'a str, func: &'a Box<Function + 'a>) {
		self.functions[name] = func;
	}

	pub fn get_function(&self, name: &'a str) -> Option<&'a Box<Function + 'a>> {
		match self.functions.get(&name) {
			Some(v) => Some(*v),
			None => None,
		}
	}
}
<|endoftext|>


<commit_before>use std::cell::{Ref, RefCell};
use std::mem;

pub struct Steal<T> {
    value: RefCell<Option<T>>
}

impl<T> Steal<T> {
    pub fn new(value: T) -> Self {
        Steal {
            value: RefCell::new(Some(value))
        }
    }

    pub fn borrow(&self) -> Ref<T> {
        Ref::map(self.value.borrow(), |opt| match *opt {
            None => panic!("attempted to read from stolen value"),
            Some(ref v) => v
        })
    }

    pub fn steal(&self) -> T {
        let value_ref = &mut *self.value.borrow_mut();
        let value = mem::replace(value_ref, None);
        value.expect("attempt to read from stolen value")
    }
}
<commit_msg>add comments to `Steal` and use `bug!`<commit_after>use std::cell::{Ref, RefCell};
use std::mem;

/// The `Steal` struct is intended to used as the value for a query.
/// Specifically, we sometimes have queries (*cough* MIR *cough*)
/// where we create a large, complex value that we want to iteratively
/// update (e.g., optimize). We could clone the value for each
/// optimization, but that'd be expensive. And yet we don't just want
/// to mutate it in place, because that would spoil the idea that
/// queries are these pure functions that produce an immutable value
/// (since if you did the query twice, you could observe the
/// mutations). So instead we have the query produce a `&'tcx
/// Steal<Mir<'tcx>>` (to be very specific). Now we can read from this
/// as much as we want (using `borrow()`), but you can also
/// `steal()`. Once you steal, any further attempt to read will panic.
/// Therefore we know that -- assuming no ICE -- nobody is observing
/// the fact that the MIR was updated.
///
/// Obviously, whenever you have a query that yields a `Steal` value,
/// you must treat it with caution, and make sure that you know that
/// -- once the value is stolen -- it will never be read from again.
pub struct Steal<T> {
    value: RefCell<Option<T>>
}

impl<T> Steal<T> {
    pub fn new(value: T) -> Self {
        Steal {
            value: RefCell::new(Some(value))
        }
    }

    pub fn borrow(&self) -> Ref<T> {
        Ref::map(self.value.borrow(), |opt| match *opt {
            None => bug!("attempted to read from stolen value"),
            Some(ref v) => v
        })
    }

    pub fn steal(&self) -> T {
        let value_ref = &mut *self.value.borrow_mut();
        let value = mem::replace(value_ref, None);
        value.expect("attempt to read from stolen value")
    }
}
<|endoftext|>


<commit_before>use std::mem;

use futures::prelude::*;
use futures::stream;

use errors::*;
use marshal::{Hasher, ObjectHash, LargeObject, SmallRecord};
use trace::MarshalTrace;

/// The branching factor of the data object B+ tree structure.
const BRANCH_FACTOR: usize = 1024;

const ERR_BRANCH_FACTOR_TOO_SMALL: &'static str = "BRANCH_FACTOR too small (less than 2?) freshly split node should always have space for one more child!";
const ERR_BYTE_OUTSIDE_OF_TREE: &'static str = "Node::search_bytes should only be called when we know the byte is in the tree!";

/// A `Leaf` node of a B+ tree contains a list of records.
#[derive(Clone, Debug)]
struct Leaf {
    size: u64,
    records: Vec<SmallRecord>,
}

impl From<Vec<SmallRecord>> for Leaf {
    fn from(records: Vec<SmallRecord>) -> Self {
        let size = records.iter().map(SmallRecord::size).sum();

        Leaf { size, records }
    }
}

impl Leaf {
    fn new() -> Self {
        Vec::new().into()
    }

    /// The size, in bytes, of the data the `Leaf` represents.
    fn size(&self) -> u64 {
        self.size
    }

    /// The total number of records in this leaf.
    fn count(&self) -> usize {
        self.records.len()
    }

    /// The total number of objects in this leaf (1 + the number of records.)
    fn total(&self) -> usize {
        self.records.len() + 1
    }

    /// Append a record to a leaf; if the leaf cannot hold the record and must split, this function
    /// will return `Err` with the left-hand side of the split.
    fn append(&mut self, record: SmallRecord) -> ::std::result::Result<(), Leaf> {
        if self.records.len() < BRANCH_FACTOR {
            self.size += record.size();
            self.records.push(record);
            Ok(())
        } else {
            let right_records = self.records.split_off(BRANCH_FACTOR / 2);
            let mut right = Leaf::from(right_records);

            self.size -= right.size();

            right.append(record).expect(ERR_BRANCH_FACTOR_TOO_SMALL);

            Err(mem::replace(self, right))
        }
    }

    fn marshal<T: MarshalTrace>(
        self,
        mut hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        let result = {
            let mut hasher_captured = hasher.clone();
            let size = self.size();
            let futures = self.records.into_iter().map(move |child| {
                let child_size = child.size();

                let computed = hasher_captured.compute(child);
                computed.map(move |child_hash| (child_size, child_hash))
            });

            stream::iter_ok(futures)
                .and_then(|x| x)// .buffered(MARSHAL_FUTURE_BUFFER_SIZE)
                .collect()
                .and_then(move |children| {
                    hasher.compute(LargeObject { size, children })
                })
        };

        Box::new(result)
    }
}

/// An internal node of a B+ tree.
#[derive(Clone, Debug)]
struct Internal {
    size: u64,
    count: usize,
    total: usize,
    children: Vec<Node>,
}

impl From<Vec<Node>> for Internal {
    fn from(children: Vec<Node>) -> Self {
        let size = children.iter().map(Node::size).sum();
        let count = children.iter().map(Node::count).sum();
        let total = children.iter().map(Node::total).sum();

        Internal {
            size,
            count,
            total,
            children,
        }
    }
}

impl Internal {
    /// Construct an internal node containing a single child.
    fn singleton(elem: Node) -> Self {
        Internal {
            size: elem.size(),
            count: elem.count(),
            total: elem.total(),
            children: vec![elem],
        }
    }

    /// The size, in bytes, of the contiguous range of a file this `Internal` node represents.
    fn size(&self) -> u64 {
        self.size
    }

    /// The total number of records held in child nodes.
    fn count(&self) -> usize {
        self.count
    }

    /// The total number of objects held in the tree, including branch nodes.
    fn total(&self) -> usize {
        self.total + 1
    }

    /// Append a node; if we must split to accomodate the new node, the left-hand side of the split
    /// is returned as `Err`.
    fn append(&mut self, node: Node) -> ::std::result::Result<(), Self> {
        if self.children.len() < BRANCH_FACTOR {
            self.size += node.size();
            self.count += node.count();
            self.children.push(node);
            Ok(())
        } else {
            let right_children = self.children.split_off(BRANCH_FACTOR / 2);
            let mut right = Internal::from(right_children);

            self.size -= right.size;
            self.count -= right.count;
            self.total -= right.total;

            right.append(node).expect(ERR_BRANCH_FACTOR_TOO_SMALL);

            Err(mem::replace(self, right))
        }
    }

    fn marshal<T: MarshalTrace>(
        self,
        mut hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        let hasher_captured = hasher.clone();
        let children_future = stream::iter_ok(self.children.into_iter().map(move |child| {
            let child_size = child.size();

            child.marshal(hasher_captured.clone()).map(
                move |child_hash| {
                    (child_size, child_hash)
                },
            )
        })).and_then(|x| x)//.buffered(MARSHAL_FUTURE_BUFFER_SIZE)
            .collect();

        let self_size = self.size;

        let result = children_future.and_then(move |children| {
            hasher.compute(LargeObject {
                size: self_size,
                children: children,
            })
        });

        Box::new(result)
    }
}

/// The general `Node` enum representing either an internal or leaf node in the B+ tree.
#[derive(Clone, Debug)]
enum Node {
    Internal(Internal),
    Leaf(Leaf),
}

impl Node {
    /// Convenience function to construct an internal node from a vec of child nodes.
    fn internal(children: Vec<Node>) -> Self {
        Node::Internal(Internal::from(children))
    }

    /// Get the size, in bytes, of the data this node represents.
    fn size(&self) -> u64 {
        match *self {
            Node::Internal(ref internal) => internal.size(),
            Node::Leaf(ref leaf) => leaf.size(),
        }
    }

    /// Get the number of objects this node holds, including itself.
    fn total(&self) -> usize {
        match *self {
            Node::Internal(ref internal) => internal.total(),
            Node::Leaf(ref leaf) => leaf.total(),
        }
    }

    /// The number of records held in child nodes of this node.
    fn count(&self) -> usize {
        match *self {
            Node::Internal(ref internal) => internal.count(),
            Node::Leaf(ref leaf) => leaf.count(),
        }
    }

    /// Perform a "bulk-loading" operation, constructing a whole B+ tree from an iterator of
    /// records.
    // TODO: This could probably be made *much* simpler and *much* more efficient.
    fn load<I>(iterable: I) -> Self
    where
        I: IntoIterator<Item = SmallRecord>,
    {
        fn insert_into_spine<'a, I>(mut stack: I, node: Node) -> Option<Internal>
        where
            I: Iterator<Item = &'a mut Internal>,
        {
            let free = match stack.next() {
                Some(parent) => {
                    match parent.append(node) {
                        Ok(()) => return None,
                        Err(left) => left,
                    }
                }
                None => return Some(Internal::singleton(node)),
            };

            insert_into_spine(stack, Node::Internal(free))
        }

        let mut spine = Vec::new();
        let mut leaf = Leaf::new();

        for record in iterable.into_iter() {
            match leaf.append(record) {
                Ok(()) => {}
                Err(left) => {
                    match insert_into_spine(spine.iter_mut(), Node::Leaf(left)) {
                        Some(internal) => spine.push(internal),
                        None => {}
                    }
                }
            }
        }

        let mut stack = vec![Node::Leaf(leaf)];
        for mut node in spine {
            let mut overflow = None;

            for free in stack.drain(..) {
                match node.append(free) {
                    Ok(()) => {}
                    Err(left) => {
                        assert!(overflow.is_none());
                        overflow = Some(left);
                    }
                }
            }

            if let Some(free) = overflow {
                stack.push(Node::Internal(free));
            }

            stack.push(Node::Internal(node));
        }

        if stack.len() == 1 {
            stack.pop().unwrap()
        } else {
            Node::internal(stack)
        }
    }

    // TODO: While we will eventually  need this functionality, at the moment this implementation
    // of `push` does not correctly preserve record counts.
    //
    // fn push(&mut self, record: SmallRecord) -> Result<(), Self> {
    //     // Attempt to push this node into our local children (whether we are a leaf or an internal
    //     // node.) If `left` is not empty, we swap ourselves with it and return it as `Err`; it is
    //     // the left side of our new split.
    //     let left = match *self {
    //         Node::Internal(ref mut internal) => {
    //             match internal
    //                 .children
    //                 .last_mut()
    //                 .expect(ERR_INTERNAL_NONEMPTY)
    //                 .push(record) {
    //                 Ok(()) => return Ok(()),
    //                 Err(left) => left,
    //             }
    //         }

    //         Node::Leaf(ref mut leaf) => {
    //             match leaf.append(record) {
    //                 Ok(()) => return Ok(()),
    //                 Err(left) => Node::Leaf(left),
    //             }
    //         }
    //     };

    //     Err(mem::replace(self, left))
    // }

    /// Search the tree to find out what chunk a given byte lives in.
    fn search_bytes(&self, byte: u64) -> usize {
        match *self {
            Node::Internal(ref internal) => {
                let mut loc = 0;
                let mut count = 0;

                for node in internal.children.iter() {
                    if loc + node.size() > byte {
                        return node.search_bytes(byte - loc) + count;
                    }

                    loc += node.size();
                    count += node.count();
                }

                unreachable!(ERR_BYTE_OUTSIDE_OF_TREE);
            }

            Node::Leaf(ref leaf) => {
                let mut loc = 0;

                for (i, record) in leaf.records.iter().enumerate() {
                    if loc + record.size() > byte {
                        return i;
                    }

                    loc += record.size();
                }

                unreachable!(ERR_BYTE_OUTSIDE_OF_TREE);
            }
        }
    }

    /// Search the tree to find the `n`th chunk.
    fn search(&self, idx: usize) -> &SmallRecord {
        match *self {
            Node::Internal(ref internal) => {
                let mut loc = 0;

                for node in internal.children.iter() {
                    if loc + node.count() > idx {
                        return node.search(idx - loc);
                    }

                    loc += node.count();
                }

                unreachable!(ERR_BYTE_OUTSIDE_OF_TREE);
            }

            Node::Leaf(ref leaf) => &leaf.records[idx],
        }
    }

    fn marshal<T: MarshalTrace>(
        self,
        hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        match self {
            Node::Internal(internal) => internal.marshal(hasher),
            Node::Leaf(leaf) => leaf.marshal(hasher),
        }
    }
}

/// A B+ tree used to marshal small objects into a B+ tree structure with large objects as nodes
/// and small objects as records.
#[derive(Clone, Debug)]
pub struct DataTree {
    root: Node,
}

impl DataTree {
    /// Bulk-load the tree.
    pub fn load<I: IntoIterator<Item = SmallRecord>>(iterable: I) -> Self {
        DataTree { root: Node::load(iterable) }
    }

    /// The number of records in the tree.
    pub fn len(&self) -> usize {
        self.root.count()
    }

    /// The number of nodes in the tree, including branch nodes.
    pub fn total(&self) -> usize {
        self.root.total()
    }

    /// The size of the file represented by the tree, in bytes.
    pub fn size(&self) -> u64 {
        self.root.size()
    }

    /// Search the tree for the `nth` chunk.
    pub fn search(&self, idx: usize) -> Option<&SmallRecord> {
        if idx < self.root.count() {
            Some(self.root.search(idx))
        } else {
            None
        }
    }

    /// Find the chunk that a given byte lives in.
    pub fn search_bytes(&self, byte: u64) -> Option<usize> {
        if byte < self.root.size() {
            Some(self.root.search_bytes(byte))
        } else {
            None
        }
    }

    // pub fn push(&mut self, record: SmallRecord) {
    //     if let Err(right) = self.root.push(record) {
    //         // Replace `left` with a dummy value.
    //         let left = mem::replace(&mut self.root, Node::internal(Vec::new()));

    //         // Fill in `left` with a fresh two-element root node.
    //         self.root = Node::internal(vec![left, right]);
    //     }
    // }

    pub fn marshal<T: MarshalTrace>(
        self,
        hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        self.root.marshal(hasher)
    }
}

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

    use quickcheck::TestResult;

    quickcheck! {
        fn search_vs_bulk_load(chunks: Vec<Vec<u8>>) -> TestResult {
            for chunk in chunks.iter() {
                if chunk.len() == 0 {
                    return TestResult::discard();
                }
            }

            let mut pos = 0;
            let mut index = Vec::new();

            let tree = DataTree::load(chunks.iter().map(|chunk| {
                let slice = chunk.as_ref();

                index.push((pos, slice));
                pos += chunk.len() as u64;

                SmallRecord::Deep(Cow::Borrowed(chunk))
            }));

            if tree.len() != chunks.len() || tree.size() != pos {
                return TestResult::failed();
            }

            for (i, (pos, chunk)) in index.into_iter().enumerate() {
                if tree.search_bytes(pos) != Some(i) ||
                    tree.search(i) != Some(&SmallRecord::Deep(Cow::Borrowed(chunk)))
                {
                    panic!("byte search: {}, search: {}, tree: {:?}", tree.search_bytes(pos) != Some(i), tree.search(i) != Some(&SmallRecord::Deep(Cow::Borrowed(chunk))), tree);

                    return TestResult::failed();
                }
            }

            TestResult::passed()
        }
    }

    #[test]
    fn load() {
        let chunk = SmallRecord::Deep(Cow::Borrowed(&[0][..]));

        let tree = DataTree::load(vec![chunk; BRANCH_FACTOR + 1]);

        assert_eq!(tree.len(), BRANCH_FACTOR + 1, "{:?}", tree);
    }
}
<commit_msg>Clean up stream::iter_ok => manual flatten pattern<commit_after>use std::mem;

use futures::prelude::*;
use futures::stream;

use errors::*;
use marshal::{Hasher, ObjectHash, LargeObject, SmallRecord};
use trace::MarshalTrace;

/// The branching factor of the data object B+ tree structure.
const BRANCH_FACTOR: usize = 1024;

const ERR_BRANCH_FACTOR_TOO_SMALL: &'static str = "BRANCH_FACTOR too small (less than 2?) freshly split node should always have space for one more child!";
const ERR_BYTE_OUTSIDE_OF_TREE: &'static str = "Node::search_bytes should only be called when we know the byte is in the tree!";

/// A `Leaf` node of a B+ tree contains a list of records.
#[derive(Clone, Debug)]
struct Leaf {
    size: u64,
    records: Vec<SmallRecord>,
}

impl From<Vec<SmallRecord>> for Leaf {
    fn from(records: Vec<SmallRecord>) -> Self {
        let size = records.iter().map(SmallRecord::size).sum();

        Leaf { size, records }
    }
}

impl Leaf {
    fn new() -> Self {
        Vec::new().into()
    }

    /// The size, in bytes, of the data the `Leaf` represents.
    fn size(&self) -> u64 {
        self.size
    }

    /// The total number of records in this leaf.
    fn count(&self) -> usize {
        self.records.len()
    }

    /// The total number of objects in this leaf (1 + the number of records.)
    fn total(&self) -> usize {
        self.records.len() + 1
    }

    /// Append a record to a leaf; if the leaf cannot hold the record and must split, this function
    /// will return `Err` with the left-hand side of the split.
    fn append(&mut self, record: SmallRecord) -> ::std::result::Result<(), Leaf> {
        if self.records.len() < BRANCH_FACTOR {
            self.size += record.size();
            self.records.push(record);
            Ok(())
        } else {
            let right_records = self.records.split_off(BRANCH_FACTOR / 2);
            let mut right = Leaf::from(right_records);

            self.size -= right.size();

            right.append(record).expect(ERR_BRANCH_FACTOR_TOO_SMALL);

            Err(mem::replace(self, right))
        }
    }

    fn marshal<T: MarshalTrace>(
        self,
        mut hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        let result = {
            let mut hasher_captured = hasher.clone();
            let size = self.size();

            stream::iter_ok(self.records.into_iter())
                .and_then(move |child| {
                    let child_size = child.size();

                    let computed = hasher_captured.compute(child);
                    computed.map(move |child_hash| (child_size, child_hash))
                })
                .collect()
                .and_then(move |children| {
                    hasher.compute(LargeObject { size, children })
                })
        };

        Box::new(result)
    }
}

/// An internal node of a B+ tree.
#[derive(Clone, Debug)]
struct Internal {
    size: u64,
    count: usize,
    total: usize,
    children: Vec<Node>,
}

impl From<Vec<Node>> for Internal {
    fn from(children: Vec<Node>) -> Self {
        let size = children.iter().map(Node::size).sum();
        let count = children.iter().map(Node::count).sum();
        let total = children.iter().map(Node::total).sum();

        Internal {
            size,
            count,
            total,
            children,
        }
    }
}

impl Internal {
    /// Construct an internal node containing a single child.
    fn singleton(elem: Node) -> Self {
        Internal {
            size: elem.size(),
            count: elem.count(),
            total: elem.total(),
            children: vec![elem],
        }
    }

    /// The size, in bytes, of the contiguous range of a file this `Internal` node represents.
    fn size(&self) -> u64 {
        self.size
    }

    /// The total number of records held in child nodes.
    fn count(&self) -> usize {
        self.count
    }

    /// The total number of objects held in the tree, including branch nodes.
    fn total(&self) -> usize {
        self.total + 1
    }

    /// Append a node; if we must split to accomodate the new node, the left-hand side of the split
    /// is returned as `Err`.
    fn append(&mut self, node: Node) -> ::std::result::Result<(), Self> {
        if self.children.len() < BRANCH_FACTOR {
            self.size += node.size();
            self.count += node.count();
            self.children.push(node);
            Ok(())
        } else {
            let right_children = self.children.split_off(BRANCH_FACTOR / 2);
            let mut right = Internal::from(right_children);

            self.size -= right.size;
            self.count -= right.count;
            self.total -= right.total;

            right.append(node).expect(ERR_BRANCH_FACTOR_TOO_SMALL);

            Err(mem::replace(self, right))
        }
    }

    fn marshal<T: MarshalTrace>(
        self,
        mut hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        let hasher_captured = hasher.clone();
        let children_future = stream::iter_ok(self.children.into_iter())
            .and_then(move |child| {
                let child_size = child.size();

                child.marshal(hasher_captured.clone()).map(
                    move |child_hash| {
                        (child_size, child_hash)
                    },
                )
            })
            .collect();

        let self_size = self.size;

        let result = children_future.and_then(move |children| {
            hasher.compute(LargeObject {
                size: self_size,
                children: children,
            })
        });

        Box::new(result)
    }
}

/// The general `Node` enum representing either an internal or leaf node in the B+ tree.
#[derive(Clone, Debug)]
enum Node {
    Internal(Internal),
    Leaf(Leaf),
}

impl Node {
    /// Convenience function to construct an internal node from a vec of child nodes.
    fn internal(children: Vec<Node>) -> Self {
        Node::Internal(Internal::from(children))
    }

    /// Get the size, in bytes, of the data this node represents.
    fn size(&self) -> u64 {
        match *self {
            Node::Internal(ref internal) => internal.size(),
            Node::Leaf(ref leaf) => leaf.size(),
        }
    }

    /// Get the number of objects this node holds, including itself.
    fn total(&self) -> usize {
        match *self {
            Node::Internal(ref internal) => internal.total(),
            Node::Leaf(ref leaf) => leaf.total(),
        }
    }

    /// The number of records held in child nodes of this node.
    fn count(&self) -> usize {
        match *self {
            Node::Internal(ref internal) => internal.count(),
            Node::Leaf(ref leaf) => leaf.count(),
        }
    }

    /// Perform a "bulk-loading" operation, constructing a whole B+ tree from an iterator of
    /// records.
    // TODO: This could probably be made *much* simpler and *much* more efficient.
    fn load<I>(iterable: I) -> Self
    where
        I: IntoIterator<Item = SmallRecord>,
    {
        fn insert_into_spine<'a, I>(mut stack: I, node: Node) -> Option<Internal>
        where
            I: Iterator<Item = &'a mut Internal>,
        {
            let free = match stack.next() {
                Some(parent) => {
                    match parent.append(node) {
                        Ok(()) => return None,
                        Err(left) => left,
                    }
                }
                None => return Some(Internal::singleton(node)),
            };

            insert_into_spine(stack, Node::Internal(free))
        }

        let mut spine = Vec::new();
        let mut leaf = Leaf::new();

        for record in iterable.into_iter() {
            match leaf.append(record) {
                Ok(()) => {}
                Err(left) => {
                    match insert_into_spine(spine.iter_mut(), Node::Leaf(left)) {
                        Some(internal) => spine.push(internal),
                        None => {}
                    }
                }
            }
        }

        let mut stack = vec![Node::Leaf(leaf)];
        for mut node in spine {
            let mut overflow = None;

            for free in stack.drain(..) {
                match node.append(free) {
                    Ok(()) => {}
                    Err(left) => {
                        assert!(overflow.is_none());
                        overflow = Some(left);
                    }
                }
            }

            if let Some(free) = overflow {
                stack.push(Node::Internal(free));
            }

            stack.push(Node::Internal(node));
        }

        if stack.len() == 1 {
            stack.pop().unwrap()
        } else {
            Node::internal(stack)
        }
    }

    // TODO: While we will eventually  need this functionality, at the moment this implementation
    // of `push` does not correctly preserve record counts.
    //
    // fn push(&mut self, record: SmallRecord) -> Result<(), Self> {
    //     // Attempt to push this node into our local children (whether we are a leaf or an internal
    //     // node.) If `left` is not empty, we swap ourselves with it and return it as `Err`; it is
    //     // the left side of our new split.
    //     let left = match *self {
    //         Node::Internal(ref mut internal) => {
    //             match internal
    //                 .children
    //                 .last_mut()
    //                 .expect(ERR_INTERNAL_NONEMPTY)
    //                 .push(record) {
    //                 Ok(()) => return Ok(()),
    //                 Err(left) => left,
    //             }
    //         }

    //         Node::Leaf(ref mut leaf) => {
    //             match leaf.append(record) {
    //                 Ok(()) => return Ok(()),
    //                 Err(left) => Node::Leaf(left),
    //             }
    //         }
    //     };

    //     Err(mem::replace(self, left))
    // }

    /// Search the tree to find out what chunk a given byte lives in.
    fn search_bytes(&self, byte: u64) -> usize {
        match *self {
            Node::Internal(ref internal) => {
                let mut loc = 0;
                let mut count = 0;

                for node in internal.children.iter() {
                    if loc + node.size() > byte {
                        return node.search_bytes(byte - loc) + count;
                    }

                    loc += node.size();
                    count += node.count();
                }

                unreachable!(ERR_BYTE_OUTSIDE_OF_TREE);
            }

            Node::Leaf(ref leaf) => {
                let mut loc = 0;

                for (i, record) in leaf.records.iter().enumerate() {
                    if loc + record.size() > byte {
                        return i;
                    }

                    loc += record.size();
                }

                unreachable!(ERR_BYTE_OUTSIDE_OF_TREE);
            }
        }
    }

    /// Search the tree to find the `n`th chunk.
    fn search(&self, idx: usize) -> &SmallRecord {
        match *self {
            Node::Internal(ref internal) => {
                let mut loc = 0;

                for node in internal.children.iter() {
                    if loc + node.count() > idx {
                        return node.search(idx - loc);
                    }

                    loc += node.count();
                }

                unreachable!(ERR_BYTE_OUTSIDE_OF_TREE);
            }

            Node::Leaf(ref leaf) => &leaf.records[idx],
        }
    }

    fn marshal<T: MarshalTrace>(
        self,
        hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        match self {
            Node::Internal(internal) => internal.marshal(hasher),
            Node::Leaf(leaf) => leaf.marshal(hasher),
        }
    }
}

/// A B+ tree used to marshal small objects into a B+ tree structure with large objects as nodes
/// and small objects as records.
#[derive(Clone, Debug)]
pub struct DataTree {
    root: Node,
}

impl DataTree {
    /// Bulk-load the tree.
    pub fn load<I: IntoIterator<Item = SmallRecord>>(iterable: I) -> Self {
        DataTree { root: Node::load(iterable) }
    }

    /// The number of records in the tree.
    pub fn len(&self) -> usize {
        self.root.count()
    }

    /// The number of nodes in the tree, including branch nodes.
    pub fn total(&self) -> usize {
        self.root.total()
    }

    /// The size of the file represented by the tree, in bytes.
    pub fn size(&self) -> u64 {
        self.root.size()
    }

    /// Search the tree for the `nth` chunk.
    pub fn search(&self, idx: usize) -> Option<&SmallRecord> {
        if idx < self.root.count() {
            Some(self.root.search(idx))
        } else {
            None
        }
    }

    /// Find the chunk that a given byte lives in.
    pub fn search_bytes(&self, byte: u64) -> Option<usize> {
        if byte < self.root.size() {
            Some(self.root.search_bytes(byte))
        } else {
            None
        }
    }

    // pub fn push(&mut self, record: SmallRecord) {
    //     if let Err(right) = self.root.push(record) {
    //         // Replace `left` with a dummy value.
    //         let left = mem::replace(&mut self.root, Node::internal(Vec::new()));

    //         // Fill in `left` with a fresh two-element root node.
    //         self.root = Node::internal(vec![left, right]);
    //     }
    // }

    pub fn marshal<T: MarshalTrace>(
        self,
        hasher: Hasher<T>,
    ) -> Box<Future<Item = ObjectHash, Error = Error> + Send> {
        self.root.marshal(hasher)
    }
}

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

    use quickcheck::TestResult;

    quickcheck! {
        fn search_vs_bulk_load(chunks: Vec<Vec<u8>>) -> TestResult {
            for chunk in chunks.iter() {
                if chunk.len() == 0 {
                    return TestResult::discard();
                }
            }

            let mut pos = 0;
            let mut index = Vec::new();

            let tree = DataTree::load(chunks.iter().map(|chunk| {
                let slice = chunk.as_ref();

                index.push((pos, slice));
                pos += chunk.len() as u64;

                SmallRecord::Deep(Cow::Borrowed(chunk))
            }));

            if tree.len() != chunks.len() || tree.size() != pos {
                return TestResult::failed();
            }

            for (i, (pos, chunk)) in index.into_iter().enumerate() {
                if tree.search_bytes(pos) != Some(i) ||
                    tree.search(i) != Some(&SmallRecord::Deep(Cow::Borrowed(chunk)))
                {
                    panic!("byte search: {}, search: {}, tree: {:?}", tree.search_bytes(pos) != Some(i), tree.search(i) != Some(&SmallRecord::Deep(Cow::Borrowed(chunk))), tree);

                    return TestResult::failed();
                }
            }

            TestResult::passed()
        }
    }

    #[test]
    fn load() {
        let chunk = SmallRecord::Deep(Cow::Borrowed(&[0][..]));

        let tree = DataTree::load(vec![chunk; BRANCH_FACTOR + 1]);

        assert_eq!(tree.len(), BRANCH_FACTOR + 1, "{:?}", tree);
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;

use antidote::RwLock;
use chrono::NaiveDateTime;
use irc::client::prelude::*;
use rand::{thread_rng, Rng};
use time;

use plugin::*;
use FrippyClient;
pub mod database;
use self::database::Database;

use self::error::*;
use error::ErrorKind as FrippyErrorKind;
use error::FrippyError;
use failure::ResultExt;

enum QuoteResponse {
    Public(String),
    Private(String),
}

#[derive(PluginName)]
pub struct Quote<T: Database, C: Client> {
    quotes: RwLock<T>,
    phantom: PhantomData<C>,
}

impl<T: Database, C: Client> Quote<T, C> {
    pub fn new(db: T) -> Self {
        Quote {
            quotes: RwLock::new(db),
            phantom: PhantomData,
        }
    }

    fn create_quote(
        &self,
        quotee: &str,
        channel: &str,
        content: &str,
        author: &str,
    ) -> Result<&str, QuoteError> {
        let count = self.quotes.read().count_user_quotes(quotee, channel)?;
        let tm = time::now().to_timespec();

        let quote = database::NewQuote {
            quotee,
            channel,
            idx: count + 1,
            content,
            author,
            created: NaiveDateTime::from_timestamp(tm.sec, 0u32),
        };

        Ok(self
            .quotes
            .write()
            .insert_quote(&quote)
            .map(|()| "Successfully added!")?)
    }

    fn add(&self, command: &mut PluginCommand) -> Result<&str, QuoteError> {
        if command.tokens.len() < 2 {
            Err(ErrorKind::InvalidCommand)?;
        }

        if command.target == command.source {
            Err(ErrorKind::PrivateMessageNotAllowed)?;
        }

        let quotee = command.tokens.remove(0);
        let channel = &command.target;
        let content = command.tokens.join(" ");

        Ok(self.create_quote(&quotee, channel, &content, &command.source)?)
    }

    fn get(&self, command: &PluginCommand) -> Result<String, QuoteError> {
        let quotee = &command.tokens.get(0);
        let channel = &command.target;
        let count = if let Some(quotee) = quotee {
            self.quotes.read().count_user_quotes(quotee, channel)?
        } else {
            self.quotes.read().count_channel_quotes(channel)?
        };

        if count < 1 {
            Err(ErrorKind::NotFound)?;
        }

        let len = command.tokens.len();
        let idx = if len < 2 || command.tokens[1].is_empty() {
            thread_rng().gen_range(1, count + 1)
        } else {
            let idx_string = &command.tokens[1];
            let idx = match i32::from_str(idx_string) {
                Ok(i) => i,
                Err(_) => Err(ErrorKind::InvalidIndex)?,
            };

            if idx < 0 {
                count + idx + 1
            } else {
                idx
            }
        };

        let response = if let Some(quotee) = quotee {
            let quote = self
                .quotes
                .read()
                .get_user_quote(quotee, channel, idx)
                .context(ErrorKind::NotFound)?;

            format!(
                "\"{}\" - {}[{}/{}]",
                quote.content, quote.quotee, quote.idx, count
            )
        } else {
            let quote = self
                .quotes
                .read()
                .get_channel_quote(channel, idx)
                .context(ErrorKind::NotFound)?;

            format!(
                "\"{}\" - {}[{}]",
                quote.content, quote.quotee, quote.idx
            )
        };

        Ok(response)
    }

    fn info(&self, command: &PluginCommand) -> Result<String, QuoteError> {
        let tokens = command
            .tokens
            .iter()
            .filter(|t| !t.is_empty())
            .collect::<Vec<_>>();
        match tokens.len() {
            0 => {
                let channel = &command.target;
                let count = self.quotes.read().count_channel_quotes(channel)?;

                Ok(match count {
                    0 => Err(ErrorKind::NotFound)?,
                    1 => format!("1 quote was saved in {}", channel),
                    _ => format!("{} quotes were saved in {}", channel, count),
                })
            }
            1 => {
                let quotee = &command.tokens[0];
                let channel = &command.target;
                let count = self.quotes.read().count_user_quotes(quotee, channel)?;

                Ok(match count {
                    0 => Err(ErrorKind::NotFound)?,
                    1 => format!("{} has 1 quote", quotee),
                    _ => format!("{} has {} quotes", count, quotee),
                })
            }
            _ => {
                let quotee = &command.tokens[0];
                let channel = &command.target;
                let idx = i32::from_str(&command.tokens[1]).context(ErrorKind::InvalidIndex)?;

                let idx = if idx < 0 {
                    self.quotes.read().count_user_quotes(quotee, channel)? + idx + 1
                } else {
                    idx
                };

                let quote = self
                    .quotes
                    .read()
                    .get_user_quote(quotee, channel, idx)
                    .context(ErrorKind::NotFound)?;

                Ok(format!(
                    "{}'s quote was added by {} at {} UTC",
                    quotee, quote.author, quote.created
                ))
            }
        }
    }

    fn help(&self) -> &str {
        "usage: quotes <subcommand>\r\n\
         subcommands: add, get, info, help"
    }
}

impl<T: Database, C: FrippyClient> Plugin for Quote<T, C> {
    type Client = C;
    fn execute(&self, _: &Self::Client, _: &Message) -> ExecutionStatus {
        ExecutionStatus::Done
    }

    fn execute_threaded(&self, _: &Self::Client, _: &Message) -> Result<(), FrippyError> {
        panic!("Quotes should not use threading")
    }

    fn command(
        &self,
        client: &Self::Client,
        mut command: PluginCommand,
    ) -> Result<(), FrippyError> {
        use self::QuoteResponse::{Private, Public};

        if command.tokens.is_empty() {
            client
                .send_notice(&command.source, &ErrorKind::InvalidCommand.to_string())
                .context(FrippyErrorKind::Connection)?;

            return Ok(());
        }

        let target = command.target.clone();
        let source = command.source.clone();

        let sub_command = command.tokens.remove(0);
        let result = match sub_command.as_ref() {
            "add" => self.add(&mut command).map(|s| Private(s.to_owned())),
            "get" => self.get(&command).map(Public),
            "info" => self.info(&command).map(Public),
            "help" => Ok(Private(self.help().to_owned())),
            _ => Err(ErrorKind::InvalidCommand.into()),
        };

        match result {
            Ok(v) => match v {
                Public(m) => client
                    .send_privmsg(&target, &m)
                    .context(FrippyErrorKind::Connection)?,
                Private(m) => client
                    .send_notice(&source, &m)
                    .context(FrippyErrorKind::Connection)?,
            },
            Err(e) => {
                let message = e.to_string();
                client
                    .send_notice(&source, &message)
                    .context(FrippyErrorKind::Connection)?;
                Err(e).context(FrippyErrorKind::Quote)?
            }
        }

        Ok(())
    }

    fn evaluate(&self, _: &Self::Client, _: PluginCommand) -> Result<String, String> {
        Err(String::from(
            "Evaluation of commands is not implemented for Quote at this time",
        ))
    }
}

impl<T: Database, C: FrippyClient> fmt::Debug for Quote<T, C> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Quote {{ ... }}")
    }
}

pub mod error {
    #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)]
    #[error = "QuoteError"]
    pub enum ErrorKind {
        /// Invalid command error
        #[fail(display = "Incorrect command. Send \"quote help\" for help")]
        InvalidCommand,

        /// Invalid index error
        #[fail(display = "Invalid index")]
        InvalidIndex,

        /// Private message error
        #[fail(display = "You can only add quotes in channel messages")]
        PrivateMessageNotAllowed,

        /// Download  error
        #[fail(display = "Download failed")]
        Download,

        /// Duplicate error
        #[fail(display = "Entry already exists")]
        Duplicate,

        /// Not found error
        #[fail(display = "Quote was not found")]
        NotFound,

        /// MySQL error
        #[cfg(feature = "mysql")]
        #[fail(display = "Failed to execute MySQL Query")]
        MysqlError,

        /// No connection error
        #[cfg(feature = "mysql")]
        #[fail(display = "No connection to the database")]
        NoConnection,
    }
}
<commit_msg>Quote: Actually fix info message<commit_after>use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;

use antidote::RwLock;
use chrono::NaiveDateTime;
use irc::client::prelude::*;
use rand::{thread_rng, Rng};
use time;

use plugin::*;
use FrippyClient;
pub mod database;
use self::database::Database;

use self::error::*;
use error::ErrorKind as FrippyErrorKind;
use error::FrippyError;
use failure::ResultExt;

enum QuoteResponse {
    Public(String),
    Private(String),
}

#[derive(PluginName)]
pub struct Quote<T: Database, C: Client> {
    quotes: RwLock<T>,
    phantom: PhantomData<C>,
}

impl<T: Database, C: Client> Quote<T, C> {
    pub fn new(db: T) -> Self {
        Quote {
            quotes: RwLock::new(db),
            phantom: PhantomData,
        }
    }

    fn create_quote(
        &self,
        quotee: &str,
        channel: &str,
        content: &str,
        author: &str,
    ) -> Result<&str, QuoteError> {
        let count = self.quotes.read().count_user_quotes(quotee, channel)?;
        let tm = time::now().to_timespec();

        let quote = database::NewQuote {
            quotee,
            channel,
            idx: count + 1,
            content,
            author,
            created: NaiveDateTime::from_timestamp(tm.sec, 0u32),
        };

        Ok(self
            .quotes
            .write()
            .insert_quote(&quote)
            .map(|()| "Successfully added!")?)
    }

    fn add(&self, command: &mut PluginCommand) -> Result<&str, QuoteError> {
        if command.tokens.len() < 2 {
            Err(ErrorKind::InvalidCommand)?;
        }

        if command.target == command.source {
            Err(ErrorKind::PrivateMessageNotAllowed)?;
        }

        let quotee = command.tokens.remove(0);
        let channel = &command.target;
        let content = command.tokens.join(" ");

        Ok(self.create_quote(&quotee, channel, &content, &command.source)?)
    }

    fn get(&self, command: &PluginCommand) -> Result<String, QuoteError> {
        let quotee = &command.tokens.get(0);
        let channel = &command.target;
        let count = if let Some(quotee) = quotee {
            self.quotes.read().count_user_quotes(quotee, channel)?
        } else {
            self.quotes.read().count_channel_quotes(channel)?
        };

        if count < 1 {
            Err(ErrorKind::NotFound)?;
        }

        let len = command.tokens.len();
        let idx = if len < 2 || command.tokens[1].is_empty() {
            thread_rng().gen_range(1, count + 1)
        } else {
            let idx_string = &command.tokens[1];
            let idx = i32::from_str(idx_string).context(ErrorKind::InvalidIndex)?;

            if idx < 0 {
                count + idx + 1
            } else {
                idx
            }
        };

        let response = if let Some(quotee) = quotee {
            let quote = self
                .quotes
                .read()
                .get_user_quote(quotee, channel, idx)
                .context(ErrorKind::NotFound)?;

            format!(
                "\"{}\" - {}[{}/{}]",
                quote.content, quote.quotee, quote.idx, count
            )
        } else {
            let quote = self
                .quotes
                .read()
                .get_channel_quote(channel, idx)
                .context(ErrorKind::NotFound)?;

            format!(
                "\"{}\" - {}[{}]",
                quote.content, quote.quotee, quote.idx
            )
        };

        Ok(response)
    }

    fn info(&self, command: &PluginCommand) -> Result<String, QuoteError> {
        let tokens = command
            .tokens
            .iter()
            .filter(|t| !t.is_empty())
            .collect::<Vec<_>>();
        match tokens.len() {
            0 => {
                let channel = &command.target;
                let count = self.quotes.read().count_channel_quotes(channel)?;

                Ok(match count {
                    0 => Err(ErrorKind::NotFound)?,
                    1 => format!("1 quote was saved in {}", channel),
                    _ => format!("{} quotes were saved in {}", count, channel),
                })
            }
            1 => {
                let quotee = &command.tokens[0];
                let channel = &command.target;
                let count = self.quotes.read().count_user_quotes(quotee, channel)?;

                Ok(match count {
                    0 => Err(ErrorKind::NotFound)?,
                    1 => format!("{} has 1 quote", quotee),
                    _ => format!("{} has {} quotes", quotee, count),
                })
            }
            _ => {
                let quotee = &command.tokens[0];
                let channel = &command.target;
                let idx = i32::from_str(&command.tokens[1]).context(ErrorKind::InvalidIndex)?;

                let idx = if idx < 0 {
                    self.quotes.read().count_user_quotes(quotee, channel)? + idx + 1
                } else {
                    idx
                };

                let quote = self
                    .quotes
                    .read()
                    .get_user_quote(quotee, channel, idx)
                    .context(ErrorKind::NotFound)?;

                Ok(format!(
                    "{}'s quote was added by {} at {} UTC",
                    quotee, quote.author, quote.created
                ))
            }
        }
    }

    fn help(&self) -> &str {
        "usage: quotes <subcommand>\r\n\
         subcommands: add, get, info, help"
    }
}

impl<T: Database, C: FrippyClient> Plugin for Quote<T, C> {
    type Client = C;
    fn execute(&self, _: &Self::Client, _: &Message) -> ExecutionStatus {
        ExecutionStatus::Done
    }

    fn execute_threaded(&self, _: &Self::Client, _: &Message) -> Result<(), FrippyError> {
        panic!("Quotes should not use threading")
    }

    fn command(
        &self,
        client: &Self::Client,
        mut command: PluginCommand,
    ) -> Result<(), FrippyError> {
        use self::QuoteResponse::{Private, Public};

        if command.tokens.is_empty() {
            client
                .send_notice(&command.source, &ErrorKind::InvalidCommand.to_string())
                .context(FrippyErrorKind::Connection)?;

            return Ok(());
        }

        let target = command.target.clone();
        let source = command.source.clone();

        let sub_command = command.tokens.remove(0);
        let result = match sub_command.as_ref() {
            "add" => self.add(&mut command).map(|s| Private(s.to_owned())),
            "get" => self.get(&command).map(Public),
            "info" => self.info(&command).map(Public),
            "help" => Ok(Private(self.help().to_owned())),
            _ => Err(ErrorKind::InvalidCommand.into()),
        };

        match result {
            Ok(v) => match v {
                Public(m) => client
                    .send_privmsg(&target, &m)
                    .context(FrippyErrorKind::Connection)?,
                Private(m) => client
                    .send_notice(&source, &m)
                    .context(FrippyErrorKind::Connection)?,
            },
            Err(e) => {
                let message = e.to_string();
                client
                    .send_notice(&source, &message)
                    .context(FrippyErrorKind::Connection)?;
                Err(e).context(FrippyErrorKind::Quote)?
            }
        }

        Ok(())
    }

    fn evaluate(&self, _: &Self::Client, _: PluginCommand) -> Result<String, String> {
        Err(String::from(
            "Evaluation of commands is not implemented for Quote at this time",
        ))
    }
}

impl<T: Database, C: FrippyClient> fmt::Debug for Quote<T, C> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Quote {{ ... }}")
    }
}

pub mod error {
    #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)]
    #[error = "QuoteError"]
    pub enum ErrorKind {
        /// Invalid command error
        #[fail(display = "Incorrect command. Send \"quote help\" for help")]
        InvalidCommand,

        /// Invalid index error
        #[fail(display = "Invalid index")]
        InvalidIndex,

        /// Private message error
        #[fail(display = "You can only add quotes in channel messages")]
        PrivateMessageNotAllowed,

        /// Download  error
        #[fail(display = "Download failed")]
        Download,

        /// Duplicate error
        #[fail(display = "Entry already exists")]
        Duplicate,

        /// Not found error
        #[fail(display = "Quote was not found")]
        NotFound,

        /// MySQL error
        #[cfg(feature = "mysql")]
        #[fail(display = "Failed to execute MySQL Query")]
        MysqlError,

        /// No connection error
        #[cfg(feature = "mysql")]
        #[fail(display = "No connection to the database")]
        NoConnection,
    }
}
<|endoftext|>


<commit_before><commit_msg>Initialize sumtree if genesis isn't empty<commit_after><|endoftext|>


<commit_before>extern crate glob;
#[macro_use]
extern crate log;
extern crate env_logger;

extern crate protoc;
extern crate protoc_rust;

use std::io::Read;
use std::io::Write;
use std::fs;
use std::path;

fn glob_simple(pattern: &str) -> Vec<String> {
    glob::glob(pattern).expect("glob")
        .map(|g| {
            g.expect("item").as_path().to_str().expect("utf-8").to_owned()
        })
        .collect()
}

fn clean_old_files() {
    for f in glob_simple("src/*/pb_*.rs") {
        fs::remove_file(f).expect("rm");
    }
    for f in glob_simple("src/*/pb_*.rs") {
        fs::remove_file(f).expect("rm");
    }
}

fn generate_v_from_common() {
    let v3 = protoc::Protoc::from_env_path().version().expect("version").is_3();

    let mut mod_v2 = fs::File::create("src/common/v2/mod.rs").expect("mod.rs");
    let mut mod_v3 = fs::File::create("src/common/v3/mod.rs").expect("mod.rs");

    write!(mod_v2, "// generated\n").expect("write");
    write!(mod_v3, "// generated\n").expect("write");

    for f in glob_simple("src/common/v2/*.rs") {
        let f = path::PathBuf::from(f);
        let base_name = f.as_path().file_name().expect("file_name").to_str().expect("to_str");

        let without_suffix = &base_name[.. base_name.len() - ".rs".len()];

        if without_suffix == "mod" {
            continue;
        }

        if without_suffix.ends_with("_pb") {
            continue;
        }

        let carllerche = without_suffix.contains("carllerche");

        for mod_v in &mut [&mut mod_v2, &mut mod_v3] {
            for suffix in &["", "_pb"] {
                if carllerche {
                    write!(mod_v, "#[cfg(feature = \"bytes\")]").expect("write");
                }
                write!(mod_v, "mod {}{};\n", without_suffix, suffix).expect("write");
            }
        }

        let mut p2f = fs::File::open(&format!("src/common/v2/{}_pb.proto", without_suffix))
            .expect("open v2 .proto");
        let mut proto = String::new();
        p2f.read_to_string(&mut proto).expect("read .proto");
        drop(p2f);

        let mut r2f = fs::File::open(&format!("src/common/v2/{}.rs", without_suffix))
            .expect("open v2 .rs");
        let mut rs = String::new();
        r2f.read_to_string(&mut rs).expect("read .rs");
        drop(r2f);

        let mut p3f = fs::File::create(&format!("src/common/v3/{}_pb.proto", without_suffix))
            .expect("create v3 .proto");
        let mut r3f = fs::File::create(&format!("src/common/v3/{}.rs", without_suffix))
            .expect("create v3 .rs");

        // convert proto2 to proto3
        let proto = proto.replace("optional ", "");
        let proto = proto.replace("required ", "");
        let proto = proto.replace("syntax = \"proto2\";", "syntax = \"proto3\";");
        write!(p3f, "// generated\n").expect("write");
        write!(p3f, "{}", proto).expect("write");
        p3f.flush().expect("flush");

        write!(r3f, "// generated\n").expect("write");
        write!(r3f, "{}", rs).expect("write");
        r3f.flush().expect("flush");

        for &v in &[2, 3] {
            if v == 3 && !v3 {
                continue;
            }

            protoc_rust::run(protoc_rust::Args {
                out_dir: &format!("src/common/v{}", v),
                includes: &[&format!("src/common/v{}", v), "../proto"],
                input: &[&format!("src/common/v{}/{}_pb.proto", v, without_suffix)],
            }).expect("protoc");
        }
    }

    mod_v2.flush().expect("flush");
    mod_v3.flush().expect("flush");
}

fn generate_pb_rs() {

    fn gen_v2_v3(dir: &str) {
        info!("generating protos in {}", dir);

        let protos = glob_simple(&format!("{}/*.proto", dir));

        assert!(!protos.is_empty());

        protoc_rust::run(protoc_rust::Args {
            out_dir: dir,
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", dir],
        }).expect("protoc");
    }

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        gen_v2_v3("src/v3");

        let protos = glob_simple("src/google/protobuf/*.proto");
        protoc_rust::run(protoc_rust::Args {
            out_dir: "src/google/protobuf",
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", "src"],
        }).expect("protoc");
    } else {
        info!("generating stubs in src/v3");

        // Because `#[cfg(nonexistent)]` still requires module files to exist
        // https://github.com/rust-lang/rust/pull/36482

        let g1 = glob::glob("src/v3/*.proto").expect("g1");
        let g2 = glob::glob("src/google/protobuf/*.proto").expect("g2");

        for f in g1.chain(g2) {
            let mut f: String = f.expect("f").as_path().to_str().expect("utf-8").to_owned();
            let suffix = ".proto";
            let len = f.len();
            f.truncate(len - suffix.len());

            let mut f = fs::File::create(f).expect("create");
            let content = b"// generated\n// empty file because protobuf 3 is not available\n";
            f.write_all(content).expect("write");
            f.flush().expect("flush");
        }
    }
}

fn main() {
    env_logger::init().expect("env_logger");

    clean_old_files();
    generate_v_from_common();
    generate_pb_rs();

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        println!("cargo:rustc-cfg=proto3");
    }
}
<commit_msg>Nop code<commit_after>extern crate glob;
#[macro_use]
extern crate log;
extern crate env_logger;

extern crate protoc;
extern crate protoc_rust;

use std::io::Read;
use std::io::Write;
use std::fs;
use std::path;

fn glob_simple(pattern: &str) -> Vec<String> {
    glob::glob(pattern).expect("glob")
        .map(|g| {
            g.expect("item").as_path().to_str().expect("utf-8").to_owned()
        })
        .collect()
}

fn clean_old_files() {
    for f in glob_simple("src/*/pb_*.rs") {
        fs::remove_file(f).expect("rm");
    }
}

fn generate_v_from_common() {
    let v3 = protoc::Protoc::from_env_path().version().expect("version").is_3();

    let mut mod_v2 = fs::File::create("src/common/v2/mod.rs").expect("mod.rs");
    let mut mod_v3 = fs::File::create("src/common/v3/mod.rs").expect("mod.rs");

    write!(mod_v2, "// generated\n").expect("write");
    write!(mod_v3, "// generated\n").expect("write");

    for f in glob_simple("src/common/v2/*.rs") {
        let f = path::PathBuf::from(f);
        let base_name = f.as_path().file_name().expect("file_name").to_str().expect("to_str");

        let without_suffix = &base_name[.. base_name.len() - ".rs".len()];

        if without_suffix == "mod" {
            continue;
        }

        if without_suffix.ends_with("_pb") {
            continue;
        }

        let carllerche = without_suffix.contains("carllerche");

        for mod_v in &mut [&mut mod_v2, &mut mod_v3] {
            for suffix in &["", "_pb"] {
                if carllerche {
                    write!(mod_v, "#[cfg(feature = \"bytes\")]").expect("write");
                }
                write!(mod_v, "mod {}{};\n", without_suffix, suffix).expect("write");
            }
        }

        let mut p2f = fs::File::open(&format!("src/common/v2/{}_pb.proto", without_suffix))
            .expect("open v2 .proto");
        let mut proto = String::new();
        p2f.read_to_string(&mut proto).expect("read .proto");
        drop(p2f);

        let mut r2f = fs::File::open(&format!("src/common/v2/{}.rs", without_suffix))
            .expect("open v2 .rs");
        let mut rs = String::new();
        r2f.read_to_string(&mut rs).expect("read .rs");
        drop(r2f);

        let mut p3f = fs::File::create(&format!("src/common/v3/{}_pb.proto", without_suffix))
            .expect("create v3 .proto");
        let mut r3f = fs::File::create(&format!("src/common/v3/{}.rs", without_suffix))
            .expect("create v3 .rs");

        // convert proto2 to proto3
        let proto = proto.replace("optional ", "");
        let proto = proto.replace("required ", "");
        let proto = proto.replace("syntax = \"proto2\";", "syntax = \"proto3\";");
        write!(p3f, "// generated\n").expect("write");
        write!(p3f, "{}", proto).expect("write");
        p3f.flush().expect("flush");

        write!(r3f, "// generated\n").expect("write");
        write!(r3f, "{}", rs).expect("write");
        r3f.flush().expect("flush");

        for &v in &[2, 3] {
            if v == 3 && !v3 {
                continue;
            }

            protoc_rust::run(protoc_rust::Args {
                out_dir: &format!("src/common/v{}", v),
                includes: &[&format!("src/common/v{}", v), "../proto"],
                input: &[&format!("src/common/v{}/{}_pb.proto", v, without_suffix)],
            }).expect("protoc");
        }
    }

    mod_v2.flush().expect("flush");
    mod_v3.flush().expect("flush");
}

fn generate_pb_rs() {

    fn gen_v2_v3(dir: &str) {
        info!("generating protos in {}", dir);

        let protos = glob_simple(&format!("{}/*.proto", dir));

        assert!(!protos.is_empty());

        protoc_rust::run(protoc_rust::Args {
            out_dir: dir,
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", dir],
        }).expect("protoc");
    }

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        gen_v2_v3("src/v3");

        let protos = glob_simple("src/google/protobuf/*.proto");
        protoc_rust::run(protoc_rust::Args {
            out_dir: "src/google/protobuf",
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", "src"],
        }).expect("protoc");
    } else {
        info!("generating stubs in src/v3");

        // Because `#[cfg(nonexistent)]` still requires module files to exist
        // https://github.com/rust-lang/rust/pull/36482

        let g1 = glob::glob("src/v3/*.proto").expect("g1");
        let g2 = glob::glob("src/google/protobuf/*.proto").expect("g2");

        for f in g1.chain(g2) {
            let mut f: String = f.expect("f").as_path().to_str().expect("utf-8").to_owned();
            let suffix = ".proto";
            let len = f.len();
            f.truncate(len - suffix.len());

            let mut f = fs::File::create(f).expect("create");
            let content = b"// generated\n// empty file because protobuf 3 is not available\n";
            f.write_all(content).expect("write");
            f.flush().expect("flush");
        }
    }
}

fn main() {
    env_logger::init().expect("env_logger");

    clean_old_files();
    generate_v_from_common();
    generate_pb_rs();

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        println!("cargo:rustc-cfg=proto3");
    }
}
<|endoftext|>