<commit_before>use crate::base::dimension::{Dim, DimName, Dynamic, U1};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};

use num_rational::Ratio;
/*
 *
 * Slice constructors.
 *
 */
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
    MatrixSliceMN<'a, N, R, C, RStride, CStride>
{
    /// Creates, without bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_with_strides_generic_unchecked(
        data: &'a [N],
        start: usize,
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        let data = SliceStorage::from_raw_parts(
            data.as_ptr().offset(start as isize),
            (nrows, ncols),
            (rstride, cstride),
        );
        Self::from_data(data)
    }

    /// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_with_strides_generic(
        data: &'a [N],
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        // NOTE: The assertion implements the following formula, but without subtractions to avoid
        // underflow panics:
        //      len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
        assert!(
            data.len() + cstride.value() + rstride.value()
                >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
            "Matrix slice: input data buffer to small."
        );

        unsafe {
            Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
    MatrixSliceMutMN<'a, N, R, C, RStride, CStride>
{
    /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_with_strides_generic_unchecked(
        data: &'a mut [N],
        start: usize,
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        let data = SliceStorageMut::from_raw_parts(
            data.as_mut_ptr().offset(start as isize),
            (nrows, ncols),
            (rstride, cstride),
        );
        Self::from_data(data)
    }

    /// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_with_strides_generic(
        data: &'a mut [N],
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        // NOTE: The assertion implements the following formula, but without subtractions to avoid
        // underflow panics:
        //      len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
        assert!(
            data.len() + cstride.value() + rstride.value()
                >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
            "Matrix slice: input data buffer to small."
        );

        assert!({
            let nrows = nrows.value();
            let ncols = ncols.value();
            let rstride = rstride.value();
            let cstride = cstride.value();

            // `Storage::linear_index`
            let index = |i, j| (i * rstride) + (j * cstride);

            // The final condition of each arm is an expression in the form:
            //    index(i₀, j₀) != index(i₁, j₁)
            // If this expression is `false`, then the values (i₀, j₀)
            // and (i₁, j₁) are concrete examples of indices that would
            // collide if the matrix was actually constructed.
            nrows * ncols <= 1 ||
                match (rstride, cstride) {
                    (0, 0) => index(0, 0) != index(nrows - 1, ncols - 1),
                    (0, _) => nrows <= 1 || index(0, 0) != index(nrows - 1, 0),
                    (_, 0) => ncols <= 1 || index(0, 0) != index(0, ncols - 1),
                    (_, _) => {
                        let ratio = Ratio::new(rstride, cstride);
                        let numer = *ratio.numer();
                        let denom = *ratio.denom();

                        nrows <= denom || ncols <= numer
                            || index(0, numer) != index(denom, 0)
                    }
                }
            },
            "Matrix slice: dimensions and strides result in aliased indices.");

        unsafe {
            Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
    /// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_generic_unchecked(
        data: &'a [N],
        start: usize,
        nrows: R,
        ncols: C,
    ) -> Self
    {
        Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
    }

    /// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_generic(data: &'a [N], nrows: R, ncols: C) -> Self {
        Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows)
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
    /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_generic_unchecked(
        data: &'a mut [N],
        start: usize,
        nrows: R,
        ncols: C,
    ) -> Self
    {
        Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
    }

    /// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_generic(data: &'a mut [N], nrows: R, ncols: C) -> Self {
        Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows)
    }
}

macro_rules! impl_constructors(
    ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
        impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMN<'a, N, $($Dims),*> {
            /// Creates a new matrix slice from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice(data: &'a [N], $($args: usize),*) -> Self {
                Self::from_slice_generic(data, $($gargs),*)
            }

            /// Creates, without bound checking, a new matrix slice from the given data array.
            #[inline]
            pub unsafe fn from_slice_unchecked(data: &'a [N], start: usize, $($args: usize),*) -> Self {
                Self::from_slice_generic_unchecked(data, start, $($gargs),*)
            }
        }

        impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMN<'a, N, $($Dims,)* Dynamic, Dynamic> {
            /// Creates a new matrix slice with the specified strides from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice_with_strides(data: &'a [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }

            /// Creates, without bound checking, a new matrix slice with the specified strides from the given data array.
            #[inline]
            pub unsafe fn from_slice_with_strides_unchecked(data: &'a [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }
        }
    }
);

// FIXME: this is not very pretty. We could find a better call syntax.
impl_constructors!(R, C;                         // Arguments for Matrix<N, ..., S>
                   => R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
                   R::name(), C::name();         // Arguments for `_generic` constructors.
                   ); // Arguments for non-generic constructors.

impl_constructors!(R, Dynamic;
                   => R: DimName;
                   R::name(), Dynamic::new(ncols);
                   ncols);

impl_constructors!(Dynamic, C;
                   => C: DimName;
                   Dynamic::new(nrows), C::name();
                   nrows);

impl_constructors!(Dynamic, Dynamic;
                   ;
                   Dynamic::new(nrows), Dynamic::new(ncols);
                   nrows, ncols);

macro_rules! impl_constructors_mut(
    ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
        impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, N, $($Dims),*> {
            /// Creates a new mutable matrix slice from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice(data: &'a mut [N], $($args: usize),*) -> Self {
                Self::from_slice_generic(data, $($gargs),*)
            }

            /// Creates, without bound checking, a new mutable matrix slice from the given data array.
            #[inline]
            pub unsafe fn from_slice_unchecked(data: &'a mut [N], start: usize, $($args: usize),*) -> Self {
                Self::from_slice_generic_unchecked(data, start, $($gargs),*)
            }
        }

        impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, N, $($Dims,)* Dynamic, Dynamic> {
            /// Creates a new mutable matrix slice with the specified strides from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice_with_strides_mut(data: &'a mut [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic(
                    data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }

            /// Creates, without bound checking, a new mutable matrix slice with the specified strides from the given data array.
            #[inline]
            pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic_unchecked(
                    data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }
        }
    }
);

// FIXME: this is not very pretty. We could find a better call syntax.
impl_constructors_mut!(R, C;                         // Arguments for Matrix<N, ..., S>
                       => R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
                       R::name(), C::name();         // Arguments for `_generic` constructors.
                       ); // Arguments for non-generic constructors.

impl_constructors_mut!(R, Dynamic;
                       => R: DimName;
                       R::name(), Dynamic::new(ncols);
                       ncols);

impl_constructors_mut!(Dynamic, C;
                       => C: DimName;
                       Dynamic::new(nrows), C::name();
                       nrows);

impl_constructors_mut!(Dynamic, Dynamic;
                       ;
                       Dynamic::new(nrows), Dynamic::new(ncols);
                       nrows, ncols);
<commit_msg>simplify anti-aliasing assertion<commit_after>use crate::base::dimension::{Dim, DimName, Dynamic, U1};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};

use num_rational::Ratio;
/*
 *
 * Slice constructors.
 *
 */
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
    MatrixSliceMN<'a, N, R, C, RStride, CStride>
{
    /// Creates, without bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_with_strides_generic_unchecked(
        data: &'a [N],
        start: usize,
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        let data = SliceStorage::from_raw_parts(
            data.as_ptr().offset(start as isize),
            (nrows, ncols),
            (rstride, cstride),
        );
        Self::from_data(data)
    }

    /// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_with_strides_generic(
        data: &'a [N],
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        // NOTE: The assertion implements the following formula, but without subtractions to avoid
        // underflow panics:
        //      len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
        assert!(
            data.len() + cstride.value() + rstride.value()
                >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
            "Matrix slice: input data buffer to small."
        );

        unsafe {
            Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
    MatrixSliceMutMN<'a, N, R, C, RStride, CStride>
{
    /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_with_strides_generic_unchecked(
        data: &'a mut [N],
        start: usize,
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        let data = SliceStorageMut::from_raw_parts(
            data.as_mut_ptr().offset(start as isize),
            (nrows, ncols),
            (rstride, cstride),
        );
        Self::from_data(data)
    }

    /// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_with_strides_generic(
        data: &'a mut [N],
        nrows: R,
        ncols: C,
        rstride: RStride,
        cstride: CStride,
    ) -> Self
    {
        // NOTE: The assertion implements the following formula, but without subtractions to avoid
        // underflow panics:
        //      len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
        assert!(
            data.len() + cstride.value() + rstride.value()
                >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
            "Matrix slice: input data buffer to small."
        );

        assert!({
            let nrows = nrows.value();
            let ncols = ncols.value();
            let rstride = rstride.value();
            let cstride = cstride.value();

            nrows * ncols <= 1 ||
                match (rstride, cstride) {
                    (0, 0) => false,      // otherwise: matrix[(0, 0)] == index[(nrows - 1, ncols - 1)],
                    (0, _) => nrows <= 1, // otherwise: matrix[(0, 0)] == index[(nrows - 1, 0)],
                    (_, 0) => ncols <= 1, // otherwise: matrix[(0, 0)] == index[(0, ncols - 1)],
                    (_, _) => {           // otherwise: matrix[(0, numer)] == index[(denom, 0)]
                        let ratio = Ratio::new(rstride, cstride);
                        nrows <= *ratio.denom() || ncols <= *ratio.numer()
                    }
                }
            },
            "Matrix slice: dimensions and strides result in aliased indices.");

        unsafe {
            Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
    /// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_generic_unchecked(
        data: &'a [N],
        start: usize,
        nrows: R,
        ncols: C,
    ) -> Self
    {
        Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
    }

    /// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_generic(data: &'a [N], nrows: R, ncols: C) -> Self {
        Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows)
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
    /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances.
    ///
    /// This method is unsafe because the input data array is not checked to contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub unsafe fn from_slice_generic_unchecked(
        data: &'a mut [N],
        start: usize,
        nrows: R,
        ncols: C,
    ) -> Self
    {
        Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
    }

    /// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
    ///
    /// Panics if the input data array dose not contain enough elements.
    /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
    #[inline]
    pub fn from_slice_generic(data: &'a mut [N], nrows: R, ncols: C) -> Self {
        Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows)
    }
}

macro_rules! impl_constructors(
    ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
        impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMN<'a, N, $($Dims),*> {
            /// Creates a new matrix slice from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice(data: &'a [N], $($args: usize),*) -> Self {
                Self::from_slice_generic(data, $($gargs),*)
            }

            /// Creates, without bound checking, a new matrix slice from the given data array.
            #[inline]
            pub unsafe fn from_slice_unchecked(data: &'a [N], start: usize, $($args: usize),*) -> Self {
                Self::from_slice_generic_unchecked(data, start, $($gargs),*)
            }
        }

        impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMN<'a, N, $($Dims,)* Dynamic, Dynamic> {
            /// Creates a new matrix slice with the specified strides from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice_with_strides(data: &'a [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }

            /// Creates, without bound checking, a new matrix slice with the specified strides from the given data array.
            #[inline]
            pub unsafe fn from_slice_with_strides_unchecked(data: &'a [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }
        }
    }
);

// FIXME: this is not very pretty. We could find a better call syntax.
impl_constructors!(R, C;                         // Arguments for Matrix<N, ..., S>
                   => R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
                   R::name(), C::name();         // Arguments for `_generic` constructors.
                   ); // Arguments for non-generic constructors.

impl_constructors!(R, Dynamic;
                   => R: DimName;
                   R::name(), Dynamic::new(ncols);
                   ncols);

impl_constructors!(Dynamic, C;
                   => C: DimName;
                   Dynamic::new(nrows), C::name();
                   nrows);

impl_constructors!(Dynamic, Dynamic;
                   ;
                   Dynamic::new(nrows), Dynamic::new(ncols);
                   nrows, ncols);

macro_rules! impl_constructors_mut(
    ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
        impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, N, $($Dims),*> {
            /// Creates a new mutable matrix slice from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice(data: &'a mut [N], $($args: usize),*) -> Self {
                Self::from_slice_generic(data, $($gargs),*)
            }

            /// Creates, without bound checking, a new mutable matrix slice from the given data array.
            #[inline]
            pub unsafe fn from_slice_unchecked(data: &'a mut [N], start: usize, $($args: usize),*) -> Self {
                Self::from_slice_generic_unchecked(data, start, $($gargs),*)
            }
        }

        impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, N, $($Dims,)* Dynamic, Dynamic> {
            /// Creates a new mutable matrix slice with the specified strides from the given data array.
            ///
            /// Panics if `data` does not contain enough elements.
            #[inline]
            pub fn from_slice_with_strides_mut(data: &'a mut [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic(
                    data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }

            /// Creates, without bound checking, a new mutable matrix slice with the specified strides from the given data array.
            #[inline]
            pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
                Self::from_slice_with_strides_generic_unchecked(
                    data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
            }
        }
    }
);

// FIXME: this is not very pretty. We could find a better call syntax.
impl_constructors_mut!(R, C;                         // Arguments for Matrix<N, ..., S>
                       => R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
                       R::name(), C::name();         // Arguments for `_generic` constructors.
                       ); // Arguments for non-generic constructors.

impl_constructors_mut!(R, Dynamic;
                       => R: DimName;
                       R::name(), Dynamic::new(ncols);
                       ncols);

impl_constructors_mut!(Dynamic, C;
                       => C: DimName;
                       Dynamic::new(nrows), C::name();
                       nrows);

impl_constructors_mut!(Dynamic, Dynamic;
                       ;
                       Dynamic::new(nrows), Dynamic::new(ncols);
                       nrows, ncols);
<|endoftext|>


<commit_before>use crate::aliased_command;
use cargo::util::errors::CargoResult;
use cargo::{drop_println, Config};
use cargo_util::paths::resolve_executable;
use flate2::read::GzDecoder;
use std::ffi::OsString;
use std::io::Read;
use std::io::Write;
use std::path::Path;

const COMPRESSED_MAN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/man.tgz"));

/// Checks if the `help` command is being issued.
///
/// This runs before clap processing, because it needs to intercept the `help`
/// command if a man page is available.
///
/// Returns `true` if help information was successfully displayed to the user.
/// In this case, Cargo should exit.
pub fn handle_embedded_help(config: &Config) -> bool {
    match try_help(config) {
        Ok(true) => true,
        Ok(false) => false,
        Err(e) => {
            log::warn!("help failed: {:?}", e);
            false
        }
    }
}

fn try_help(config: &Config) -> CargoResult<bool> {
    let mut args = std::env::args_os()
        .skip(1)
        .skip_while(|arg| arg.to_str().map_or(false, |s| s.starts_with('-')));
    if !args
        .next()
        .map_or(false, |arg| arg.to_str() == Some("help"))
    {
        return Ok(false);
    }
    let subcommand = match args.next() {
        Some(arg) => arg,
        None => return Ok(false),
    };
    let subcommand = match subcommand.to_str() {
        Some(s) => s,
        None => return Ok(false),
    };

    let subcommand = match check_alias(config, subcommand) {
        // If this alias is more than a simple subcommand pass-through, show the alias.
        Some(argv) if argv.len() > 1 => {
            let alias = argv.join(" ");
            drop_println!(config, "`{}` is aliased to `{}`", subcommand, alias);
            return Ok(true);
        }
        // Otherwise, resolve the alias into its subcommand.
        Some(argv) => {
            // An alias with an empty argv can be created via `"empty-alias" = ""`.
            let first = argv.get(0).map(String::as_str).unwrap_or(subcommand);
            first.to_string()
        }
        None => subcommand.to_string(),
    };

    let subcommand = match check_builtin(&subcommand) {
        Some(s) => s,
        None => return Ok(false),
    };

    if resolve_executable(Path::new("man")).is_ok() {
        let man = match extract_man(&subcommand, "1") {
            Some(man) => man,
            None => return Ok(false),
        };
        write_and_spawn(&subcommand, &man, "man")?;
    } else {
        let txt = match extract_man(&subcommand, "txt") {
            Some(txt) => txt,
            None => return Ok(false),
        };
        if resolve_executable(Path::new("less")).is_ok() {
            write_and_spawn(&subcommand, &txt, "less")?;
        } else if resolve_executable(Path::new("more")).is_ok() {
            write_and_spawn(&subcommand, &txt, "more")?;
        } else {
            drop(std::io::stdout().write_all(&txt));
        }
    }
    Ok(true)
}

/// Checks if the given subcommand is an alias.
///
/// Returns None if it is not an alias.
fn check_alias(config: &Config, subcommand: &str) -> Option<Vec<String>> {
    aliased_command(config, subcommand).ok().flatten()
}

/// Checks if the given subcommand is a built-in command (not via an alias).
///
/// Returns None if it is not a built-in command.
fn check_builtin(subcommand: &str) -> Option<&str> {
    super::builtin_exec(subcommand).map(|_| subcommand)
}

/// Extracts the given man page from the compressed archive.
///
/// Returns None if the command wasn't found.
fn extract_man(subcommand: &str, extension: &str) -> Option<Vec<u8>> {
    let extract_name = OsString::from(format!("cargo-{}.{}", subcommand, extension));
    let gz = GzDecoder::new(COMPRESSED_MAN);
    let mut ar = tar::Archive::new(gz);
    // Unwraps should be safe here, since this is a static archive generated
    // by our build script. It should never be an invalid format!
    for entry in ar.entries().unwrap() {
        let mut entry = entry.unwrap();
        let path = entry.path().unwrap();
        if path.file_name().unwrap() != extract_name {
            continue;
        }
        let mut result = Vec::new();
        entry.read_to_end(&mut result).unwrap();
        return Some(result);
    }
    None
}

/// Write the contents of a man page to disk and spawn the given command to
/// display it.
fn write_and_spawn(name: &str, contents: &[u8], command: &str) -> CargoResult<()> {
    let prefix = format!("cargo-{}.", name);
    let mut tmp = tempfile::Builder::new().prefix(&prefix).tempfile()?;
    let f = tmp.as_file_mut();
    f.write_all(contents)?;
    f.flush()?;
    let path = tmp.path();
    // Use a path relative to the temp directory so that it can work on
    // cygwin/msys systems which don't handle windows-style paths.
    let mut relative_name = std::ffi::OsString::from("./");
    relative_name.push(path.file_name().unwrap());
    let mut cmd = std::process::Command::new(command)
        .arg(relative_name)
        .current_dir(path.parent().unwrap())
        .spawn()?;
    drop(cmd.wait());
    Ok(())
}
<commit_msg>Auto merge of #10205 - hi-rustin:rustin-patch-clippy, r=Eh2406<commit_after>use crate::aliased_command;
use cargo::util::errors::CargoResult;
use cargo::{drop_println, Config};
use cargo_util::paths::resolve_executable;
use flate2::read::GzDecoder;
use std::ffi::OsString;
use std::io::Read;
use std::io::Write;
use std::path::Path;

const COMPRESSED_MAN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/man.tgz"));

/// Checks if the `help` command is being issued.
///
/// This runs before clap processing, because it needs to intercept the `help`
/// command if a man page is available.
///
/// Returns `true` if help information was successfully displayed to the user.
/// In this case, Cargo should exit.
pub fn handle_embedded_help(config: &Config) -> bool {
    match try_help(config) {
        Ok(true) => true,
        Ok(false) => false,
        Err(e) => {
            log::warn!("help failed: {:?}", e);
            false
        }
    }
}

fn try_help(config: &Config) -> CargoResult<bool> {
    let mut args = std::env::args_os()
        .skip(1)
        .skip_while(|arg| arg.to_str().map_or(false, |s| s.starts_with('-')));
    if !args
        .next()
        .map_or(false, |arg| arg.to_str() == Some("help"))
    {
        return Ok(false);
    }
    let subcommand = match args.next() {
        Some(arg) => arg,
        None => return Ok(false),
    };
    let subcommand = match subcommand.to_str() {
        Some(s) => s,
        None => return Ok(false),
    };

    let subcommand = match check_alias(config, subcommand) {
        // If this alias is more than a simple subcommand pass-through, show the alias.
        Some(argv) if argv.len() > 1 => {
            let alias = argv.join(" ");
            drop_println!(config, "`{}` is aliased to `{}`", subcommand, alias);
            return Ok(true);
        }
        // Otherwise, resolve the alias into its subcommand.
        Some(argv) => {
            // An alias with an empty argv can be created via `"empty-alias" = ""`.
            let first = argv.get(0).map(String::as_str).unwrap_or(subcommand);
            first.to_string()
        }
        None => subcommand.to_string(),
    };

    let subcommand = match check_builtin(&subcommand) {
        Some(s) => s,
        None => return Ok(false),
    };

    if resolve_executable(Path::new("man")).is_ok() {
        let man = match extract_man(subcommand, "1") {
            Some(man) => man,
            None => return Ok(false),
        };
        write_and_spawn(subcommand, &man, "man")?;
    } else {
        let txt = match extract_man(subcommand, "txt") {
            Some(txt) => txt,
            None => return Ok(false),
        };
        if resolve_executable(Path::new("less")).is_ok() {
            write_and_spawn(subcommand, &txt, "less")?;
        } else if resolve_executable(Path::new("more")).is_ok() {
            write_and_spawn(subcommand, &txt, "more")?;
        } else {
            drop(std::io::stdout().write_all(&txt));
        }
    }
    Ok(true)
}

/// Checks if the given subcommand is an alias.
///
/// Returns None if it is not an alias.
fn check_alias(config: &Config, subcommand: &str) -> Option<Vec<String>> {
    aliased_command(config, subcommand).ok().flatten()
}

/// Checks if the given subcommand is a built-in command (not via an alias).
///
/// Returns None if it is not a built-in command.
fn check_builtin(subcommand: &str) -> Option<&str> {
    super::builtin_exec(subcommand).map(|_| subcommand)
}

/// Extracts the given man page from the compressed archive.
///
/// Returns None if the command wasn't found.
fn extract_man(subcommand: &str, extension: &str) -> Option<Vec<u8>> {
    let extract_name = OsString::from(format!("cargo-{}.{}", subcommand, extension));
    let gz = GzDecoder::new(COMPRESSED_MAN);
    let mut ar = tar::Archive::new(gz);
    // Unwraps should be safe here, since this is a static archive generated
    // by our build script. It should never be an invalid format!
    for entry in ar.entries().unwrap() {
        let mut entry = entry.unwrap();
        let path = entry.path().unwrap();
        if path.file_name().unwrap() != extract_name {
            continue;
        }
        let mut result = Vec::new();
        entry.read_to_end(&mut result).unwrap();
        return Some(result);
    }
    None
}

/// Write the contents of a man page to disk and spawn the given command to
/// display it.
fn write_and_spawn(name: &str, contents: &[u8], command: &str) -> CargoResult<()> {
    let prefix = format!("cargo-{}.", name);
    let mut tmp = tempfile::Builder::new().prefix(&prefix).tempfile()?;
    let f = tmp.as_file_mut();
    f.write_all(contents)?;
    f.flush()?;
    let path = tmp.path();
    // Use a path relative to the temp directory so that it can work on
    // cygwin/msys systems which don't handle windows-style paths.
    let mut relative_name = std::ffi::OsString::from("./");
    relative_name.push(path.file_name().unwrap());
    let mut cmd = std::process::Command::new(command)
        .arg(relative_name)
        .current_dir(path.parent().unwrap())
        .spawn()?;
    drop(cmd.wait());
    Ok(())
}
<|endoftext|>


<commit_before>//! Accept connections from clients over TCP.
//!
//! This is a (still incomplete) rewrite of the original mio-based code.

use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use bytes::BufMut;
use cache::Cache;
use client_query::*;
use dns::{self, NormalizedQuestion};
use futures::future::{self, Future};
use futures::Sink;
use futures::stream::Stream;
use futures::sync::mpsc::{channel, Sender};
use std::cell::RefCell;
use std::io::{self, Read, Write};
use std::net::{self, SocketAddr};
use std::rc::Rc;
use std::time;
use std::sync::{Arc, mpsc};
use std::thread;
use super::EdgeDNSContext;
use super::{DNS_QUERY_MAX_SIZE, DNS_QUERY_MIN_SIZE, MAX_TCP_IDLE_MS};
use tcp_arbitrator::TcpArbitrator;
use tokio_core::net::{TcpListener, TcpStream};
use tokio_core::reactor::{Core, Handle};
use tokio_io::io::{read_exact, write_all, ReadHalf, WriteHalf};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_timer::{wheel, Timer};
use varz::Varz;

struct TcpAcceptor {
    timer: Timer,
    handle: Handle,
    net_tcp_listener: net::TcpListener,
    resolver_tx: Sender<ClientQuery>,
    cache: Cache,
    varz: Arc<Varz>,
    tcp_arbitrator: TcpArbitrator,
}

pub struct TcpAcceptorCore {
    timer: Timer,
    handle: Handle,
    net_tcp_listener: net::TcpListener,
    resolver_tx: Sender<ClientQuery>,
    cache: Cache,
    varz: Arc<Varz>,
    service_ready_tx: Option<mpsc::SyncSender<u8>>,
    tcp_arbitrator: TcpArbitrator,
}

struct TcpClientQuery {
    timer: Timer,
    wh: WriteHalf<TcpStream>,
    handle: Handle,
    resolver_tx: Sender<ClientQuery>,
    cache: Cache,
    varz: Arc<Varz>,
}

impl TcpClientQuery {
    pub fn new(tcp_acceptor: &TcpAcceptor, wh: WriteHalf<TcpStream>) -> Self {
        TcpClientQuery {
            timer: tcp_acceptor.timer.clone(),
            wh: wh,
            handle: tcp_acceptor.handle.clone(),
            resolver_tx: tcp_acceptor.resolver_tx.clone(),
            cache: tcp_acceptor.cache.clone(),
            varz: tcp_acceptor.varz.clone(),
        }
    }

    fn fut_process_query(mut self,
                         normalized_question: NormalizedQuestion)
                         -> Box<Future<Item = (), Error = io::Error>> {
        let (tcpclient_tx, tcpclient_rx) = channel(1);
        let cache_entry = self.cache.get2(&normalized_question);
        let client_query = ClientQuery::tcp(tcpclient_tx, normalized_question, self.varz.clone());
        let wh_cell = RefCell::new(self.wh);
        let fut = tcpclient_rx
            .into_future()
            .map_err(|_| {})
            .map(|(resolver_response, _)| resolver_response)
            .and_then(move |resolver_response| match resolver_response {
                          None => {
                              warn!("No resolver response - TX part of the channel closed");
                              future::err(())
                          }
                          Some(resolver_response) => future::ok(resolver_response),
                      })
            .and_then(|resolver_response| {
                          let wh = wh_cell.into_inner();
                          write_all(wh, resolver_response.packet)
                              .map(|_| {})
                              .map_err(|_| {})
                      });
        if let Some(mut cache_entry) = cache_entry {
            if !cache_entry.is_expired() {
                self.varz.client_queries_cached.inc();
                self.handle.spawn(fut.map_err(|_| {}));
                return client_query.response_send(&mut cache_entry.packet, None);
            }
            debug!("expired");
            self.varz.client_queries_expired.inc();
        }
        let fut_send = self.resolver_tx.send(client_query).map_err(|_| {});
        let futs = fut.join(fut_send);
        Box::new(futs.map(|_| {}).map_err(|_| io::Error::last_os_error()))
    }
}

impl TcpAcceptor {
    fn new(tcp_acceptor_core: &TcpAcceptorCore) -> Self {
        TcpAcceptor {
            timer: tcp_acceptor_core.timer.clone(),
            handle: tcp_acceptor_core.handle.clone(),
            net_tcp_listener: tcp_acceptor_core
                .net_tcp_listener
                .try_clone()
                .expect("Couldn't clone a TCP socket"),
            resolver_tx: tcp_acceptor_core.resolver_tx.clone(),
            cache: tcp_acceptor_core.cache.clone(),
            varz: tcp_acceptor_core.varz.clone(),
            tcp_arbitrator: tcp_acceptor_core.tcp_arbitrator.clone(),
        }
    }

    fn fut_process_client(&mut self,
                          client: TcpStream,
                          client_addr: SocketAddr)
                          -> Box<Future<Item = (), Error = io::Error>> {
        let (session_rx, session_idx) = match self.tcp_arbitrator.new_session(&client_addr) {
            Ok(r) => r,
            Err(_) => return Box::new(future::err(io::Error::last_os_error())),
        };
        debug!("Incoming connection using TCP, session index {}",
               session_idx);
        let varz = self.varz.clone();
        varz.client_queries_tcp.inc();
        let (rh, wh) = client.split();
        let fut_expected_len = read_exact(rh, vec![0u8; 2]).and_then(move |(rh, len_buf)| {
            let expected_len = BigEndian::read_u16(&len_buf) as usize;
            if expected_len < DNS_QUERY_MIN_SIZE || expected_len > DNS_QUERY_MAX_SIZE {
                info!("Suspicious query length: {}", expected_len);
                varz.client_queries_errors.inc();
                return future::err(io::Error::new(io::ErrorKind::InvalidInput,
                                                  "Suspicious query length"));
            }
            debug!("Expected length: {}", expected_len);
            future::ok((rh, expected_len))
        });
        let fut_packet_read =
            fut_expected_len.and_then(|(rh, expected_len)| read_exact(rh, vec![0u8; expected_len]));
        let varz = self.varz.clone();
        let tcp_client_query = TcpClientQuery::new(self, wh);
        let fut_packet = fut_packet_read.and_then(move |(rh, packet)| {
            let normalized_question = match dns::normalize(&packet, true) {
                Ok(normalized_question) => normalized_question,
                Err(e) => {
                    debug!("Error while parsing the question: {}", e);
                    varz.client_queries_errors.inc();
                    return Box::new(future::err(io::Error::new(io::ErrorKind::InvalidInput,
                                                               "Suspicious query"))) as
                           Box<Future<Item = _, Error = _>>;
                }
            };
            tcp_client_query.fut_process_query(normalized_question)
        });
        let fut_timeout = self.timer
            .timeout(fut_packet, time::Duration::from_millis(MAX_TCP_IDLE_MS));
        let mut tcp_arbitrator = self.tcp_arbitrator.clone();
        let fut_with_timeout = fut_timeout.then(move |_| {
            debug!("Closing TCP connection with session index {}", session_idx);
            tcp_arbitrator.delete_session(session_idx);
            future::ok(())
        });
        let fut_session_rx = session_rx.map(|_| {});
        let fut = fut_session_rx
            .select(fut_with_timeout)
            .map(|_| {})
            .map_err(|_| io::Error::last_os_error());
        Box::new(fut) as Box<Future<Item = _, Error = _>>
    }

    fn fut_process_stream<'a>(mut self,
                              handle: &Handle)
                              -> impl Future<Item = (), Error = io::Error> + 'a {
        let tcp_listener = TcpListener::from_listener(self.net_tcp_listener
                                                          .try_clone()
                                                          .expect("Unable to clone a TCP socket"),
                                                      &self.net_tcp_listener.local_addr().unwrap(),
                                                      handle)
                .expect("Unable to create a tokio TCP listener");
        let handle = handle.clone();
        tcp_listener
            .incoming()
            .for_each(move |(client, client_addr)| {
                          let fut_client = self.fut_process_client(client, client_addr);
                          handle.spawn(fut_client.map_err(|_| {}));
                          Ok(())
                      })
            .map_err(|_| io::Error::last_os_error())
    }
}

impl TcpAcceptorCore {
    fn run(mut self, mut event_loop: Core, tcp_acceptor: TcpAcceptor) -> io::Result<()> {
        let service_ready_tx = self.service_ready_tx.take().unwrap();
        let handle = event_loop.handle();
        let stream = tcp_acceptor.fut_process_stream(&handle);
        handle.spawn(stream.map_err(|_| {}).map(|_| {}));
        service_ready_tx
            .send(0)
            .map_err(|_| io::Error::last_os_error())?;
        loop {
            event_loop.turn(None)
        }
    }

    pub fn spawn(edgedns_context: &EdgeDNSContext,
                 resolver_tx: Sender<ClientQuery>,
                 service_ready_tx: mpsc::SyncSender<u8>)
                 -> io::Result<(thread::JoinHandle<()>)> {
        let net_tcp_listener = edgedns_context.tcp_listener.try_clone()?;
        let cache = edgedns_context.cache.clone();
        let varz = edgedns_context.varz.clone();
        let tcp_arbitrator = edgedns_context.tcp_arbitrator.clone();
        let timer = wheel()
            .tick_duration(time::Duration::from_millis(MAX_TCP_IDLE_MS / 2))
            .max_timeout(time::Duration::from_millis(MAX_TCP_IDLE_MS))
            .build();
        let tcp_acceptor_th = thread::Builder::new()
            .name("tcp_acceptor".to_string())
            .spawn(move || {
                let event_loop = Core::new().unwrap();
                let tcp_acceptor_core = TcpAcceptorCore {
                    timer: timer,
                    handle: event_loop.handle(),
                    net_tcp_listener: net_tcp_listener,
                    cache: cache,
                    resolver_tx: resolver_tx,
                    service_ready_tx: Some(service_ready_tx),
                    varz: varz,
                    tcp_arbitrator: tcp_arbitrator,
                };
                let tcp_acceptor = TcpAcceptor::new(&tcp_acceptor_core);
                tcp_acceptor_core
                    .run(event_loop, tcp_acceptor)
                    .expect("Unable to spawn a tcp listener");
            })
            .unwrap();
        info!("TCP listener is ready");
        Ok(tcp_acceptor_th)
    }
}
<commit_msg>`tcp_acceptor` is pretty much a rewrite of the original mio code<commit_after>//! Accept connections from clients over TCP.
//!
//! This is a rewrite of the original mio-based code.

use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use bytes::BufMut;
use cache::Cache;
use client_query::*;
use dns::{self, NormalizedQuestion};
use futures::future::{self, Future};
use futures::Sink;
use futures::stream::Stream;
use futures::sync::mpsc::{channel, Sender};
use std::cell::RefCell;
use std::io::{self, Read, Write};
use std::net::{self, SocketAddr};
use std::rc::Rc;
use std::time;
use std::sync::{Arc, mpsc};
use std::thread;
use super::EdgeDNSContext;
use super::{DNS_QUERY_MAX_SIZE, DNS_QUERY_MIN_SIZE, MAX_TCP_IDLE_MS};
use tcp_arbitrator::TcpArbitrator;
use tokio_core::net::{TcpListener, TcpStream};
use tokio_core::reactor::{Core, Handle};
use tokio_io::io::{read_exact, write_all, ReadHalf, WriteHalf};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_timer::{wheel, Timer};
use varz::Varz;

struct TcpAcceptor {
    timer: Timer,
    handle: Handle,
    net_tcp_listener: net::TcpListener,
    resolver_tx: Sender<ClientQuery>,
    cache: Cache,
    varz: Arc<Varz>,
    tcp_arbitrator: TcpArbitrator,
}

pub struct TcpAcceptorCore {
    timer: Timer,
    handle: Handle,
    net_tcp_listener: net::TcpListener,
    resolver_tx: Sender<ClientQuery>,
    cache: Cache,
    varz: Arc<Varz>,
    service_ready_tx: Option<mpsc::SyncSender<u8>>,
    tcp_arbitrator: TcpArbitrator,
}

struct TcpClientQuery {
    timer: Timer,
    wh: WriteHalf<TcpStream>,
    handle: Handle,
    resolver_tx: Sender<ClientQuery>,
    cache: Cache,
    varz: Arc<Varz>,
}

impl TcpClientQuery {
    pub fn new(tcp_acceptor: &TcpAcceptor, wh: WriteHalf<TcpStream>) -> Self {
        TcpClientQuery {
            timer: tcp_acceptor.timer.clone(),
            wh: wh,
            handle: tcp_acceptor.handle.clone(),
            resolver_tx: tcp_acceptor.resolver_tx.clone(),
            cache: tcp_acceptor.cache.clone(),
            varz: tcp_acceptor.varz.clone(),
        }
    }

    fn fut_process_query(mut self,
                         normalized_question: NormalizedQuestion)
                         -> Box<Future<Item = (), Error = io::Error>> {
        let (tcpclient_tx, tcpclient_rx) = channel(1);
        let cache_entry = self.cache.get2(&normalized_question);
        let client_query = ClientQuery::tcp(tcpclient_tx, normalized_question, self.varz.clone());
        let wh_cell = RefCell::new(self.wh);
        let fut = tcpclient_rx
            .into_future()
            .map_err(|_| {})
            .map(|(resolver_response, _)| resolver_response)
            .and_then(move |resolver_response| match resolver_response {
                          None => {
                              warn!("No resolver response - TX part of the channel closed");
                              future::err(())
                          }
                          Some(resolver_response) => future::ok(resolver_response),
                      })
            .and_then(|resolver_response| {
                          let wh = wh_cell.into_inner();
                          write_all(wh, resolver_response.packet)
                              .map(|_| {})
                              .map_err(|_| {})
                      });
        if let Some(mut cache_entry) = cache_entry {
            if !cache_entry.is_expired() {
                self.varz.client_queries_cached.inc();
                self.handle.spawn(fut.map_err(|_| {}));
                return client_query.response_send(&mut cache_entry.packet, None);
            }
            debug!("expired");
            self.varz.client_queries_expired.inc();
        }
        let fut_send = self.resolver_tx.send(client_query).map_err(|_| {});
        let futs = fut.join(fut_send);
        Box::new(futs.map(|_| {}).map_err(|_| io::Error::last_os_error()))
    }
}

impl TcpAcceptor {
    fn new(tcp_acceptor_core: &TcpAcceptorCore) -> Self {
        TcpAcceptor {
            timer: tcp_acceptor_core.timer.clone(),
            handle: tcp_acceptor_core.handle.clone(),
            net_tcp_listener: tcp_acceptor_core
                .net_tcp_listener
                .try_clone()
                .expect("Couldn't clone a TCP socket"),
            resolver_tx: tcp_acceptor_core.resolver_tx.clone(),
            cache: tcp_acceptor_core.cache.clone(),
            varz: tcp_acceptor_core.varz.clone(),
            tcp_arbitrator: tcp_acceptor_core.tcp_arbitrator.clone(),
        }
    }

    fn fut_process_client(&mut self,
                          client: TcpStream,
                          client_addr: SocketAddr)
                          -> Box<Future<Item = (), Error = io::Error>> {
        let (session_rx, session_idx) = match self.tcp_arbitrator.new_session(&client_addr) {
            Ok(r) => r,
            Err(_) => return Box::new(future::err(io::Error::last_os_error())),
        };
        debug!("Incoming connection using TCP, session index {}",
               session_idx);
        let varz = self.varz.clone();
        varz.client_queries_tcp.inc();
        let (rh, wh) = client.split();
        let fut_expected_len = read_exact(rh, vec![0u8; 2]).and_then(move |(rh, len_buf)| {
            let expected_len = BigEndian::read_u16(&len_buf) as usize;
            if expected_len < DNS_QUERY_MIN_SIZE || expected_len > DNS_QUERY_MAX_SIZE {
                info!("Suspicious query length: {}", expected_len);
                varz.client_queries_errors.inc();
                return future::err(io::Error::new(io::ErrorKind::InvalidInput,
                                                  "Suspicious query length"));
            }
            debug!("Expected length: {}", expected_len);
            future::ok((rh, expected_len))
        });
        let fut_packet_read =
            fut_expected_len.and_then(|(rh, expected_len)| read_exact(rh, vec![0u8; expected_len]));
        let varz = self.varz.clone();
        let tcp_client_query = TcpClientQuery::new(self, wh);
        let fut_packet = fut_packet_read.and_then(move |(rh, packet)| {
            let normalized_question = match dns::normalize(&packet, true) {
                Ok(normalized_question) => normalized_question,
                Err(e) => {
                    debug!("Error while parsing the question: {}", e);
                    varz.client_queries_errors.inc();
                    return Box::new(future::err(io::Error::new(io::ErrorKind::InvalidInput,
                                                               "Suspicious query"))) as
                           Box<Future<Item = _, Error = _>>;
                }
            };
            tcp_client_query.fut_process_query(normalized_question)
        });
        let fut_timeout = self.timer
            .timeout(fut_packet, time::Duration::from_millis(MAX_TCP_IDLE_MS));
        let mut tcp_arbitrator = self.tcp_arbitrator.clone();
        let fut_with_timeout = fut_timeout.then(move |_| {
            debug!("Closing TCP connection with session index {}", session_idx);
            tcp_arbitrator.delete_session(session_idx);
            future::ok(())
        });
        let fut_session_rx = session_rx.map(|_| {});
        let fut = fut_session_rx
            .select(fut_with_timeout)
            .map(|_| {})
            .map_err(|_| io::Error::last_os_error());
        Box::new(fut) as Box<Future<Item = _, Error = _>>
    }

    fn fut_process_stream<'a>(mut self,
                              handle: &Handle)
                              -> impl Future<Item = (), Error = io::Error> + 'a {
        let tcp_listener = TcpListener::from_listener(self.net_tcp_listener
                                                          .try_clone()
                                                          .expect("Unable to clone a TCP socket"),
                                                      &self.net_tcp_listener.local_addr().unwrap(),
                                                      handle)
                .expect("Unable to create a tokio TCP listener");
        let handle = handle.clone();
        tcp_listener
            .incoming()
            .for_each(move |(client, client_addr)| {
                          let fut_client = self.fut_process_client(client, client_addr);
                          handle.spawn(fut_client.map_err(|_| {}));
                          Ok(())
                      })
            .map_err(|_| io::Error::last_os_error())
    }
}

impl TcpAcceptorCore {
    fn run(mut self, mut event_loop: Core, tcp_acceptor: TcpAcceptor) -> io::Result<()> {
        let service_ready_tx = self.service_ready_tx.take().unwrap();
        let handle = event_loop.handle();
        let stream = tcp_acceptor.fut_process_stream(&handle);
        handle.spawn(stream.map_err(|_| {}).map(|_| {}));
        service_ready_tx
            .send(0)
            .map_err(|_| io::Error::last_os_error())?;
        loop {
            event_loop.turn(None)
        }
    }

    pub fn spawn(edgedns_context: &EdgeDNSContext,
                 resolver_tx: Sender<ClientQuery>,
                 service_ready_tx: mpsc::SyncSender<u8>)
                 -> io::Result<(thread::JoinHandle<()>)> {
        let net_tcp_listener = edgedns_context.tcp_listener.try_clone()?;
        let cache = edgedns_context.cache.clone();
        let varz = edgedns_context.varz.clone();
        let tcp_arbitrator = edgedns_context.tcp_arbitrator.clone();
        let timer = wheel()
            .tick_duration(time::Duration::from_millis(MAX_TCP_IDLE_MS / 2))
            .max_timeout(time::Duration::from_millis(MAX_TCP_IDLE_MS))
            .build();
        let tcp_acceptor_th = thread::Builder::new()
            .name("tcp_acceptor".to_string())
            .spawn(move || {
                let event_loop = Core::new().unwrap();
                let tcp_acceptor_core = TcpAcceptorCore {
                    timer: timer,
                    handle: event_loop.handle(),
                    net_tcp_listener: net_tcp_listener,
                    cache: cache,
                    resolver_tx: resolver_tx,
                    service_ready_tx: Some(service_ready_tx),
                    varz: varz,
                    tcp_arbitrator: tcp_arbitrator,
                };
                let tcp_acceptor = TcpAcceptor::new(&tcp_acceptor_core);
                tcp_acceptor_core
                    .run(event_loop, tcp_acceptor)
                    .expect("Unable to spawn a tcp listener");
            })
            .unwrap();
        info!("TCP listener is ready");
        Ok(tcp_acceptor_th)
    }
}
<|endoftext|>


<commit_before>use std::fmt::Write;
use serde_json::{self, Value};
use semver;
use serde::{ser, de, Serializer};

pub use cargo_shim::rustc_diagnostic::Diagnostic;

// TODO: Upstream `Serializable` for these to `cargo-metadata`.

#[derive(Clone, Serialize, Deserialize, Debug)]
/// A single target (lib, bin, example, ...) provided by a crate
pub struct Target {
    /// Name as given in the `Cargo.toml` or generated from the file name
    pub name: String,
    /// Kind of target ("bin", "example", "test", "bench", "lib")
    pub kind: Vec<String>,
    /// Almost the same as `kind`, except when an example is a library instad of an executable.
    /// In that case `crate_types` contains things like `rlib` and `dylib` while `kind` is `example`
    #[serde(default)]
    pub crate_types: Vec<String>,
    /// Path to the main source file of the target
    pub src_path: String,
    #[doc(hidden)]
    #[serde(skip)]
    __do_not_match_exhaustively: (),
}

#[derive(Clone, Debug)]
/// A workspace member. This is basically identical to `cargo::core::package_id::PackageId`, expect
/// that this does not use `Arc` internally.
pub struct PackageId {
    /// A name of workspace member.
    pub name: String,
    /// A version of workspace member.
    pub version: semver::Version,
    /// A source id of workspace member.
    pub url: String,
    #[doc(hidden)]
    __do_not_match_exhaustively: (),
}

impl<'de> de::Deserialize<'de> for PackageId {
    fn deserialize<D>(d: D) -> Result<PackageId, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        let string = String::deserialize(d)?;
        let mut s = string.splitn(3, ' ');
        let name = s.next().unwrap();
        let version = s.next().unwrap();
        let version = semver::Version::parse(&version).map_err(de::Error::custom)?;
        let url = &s.next().unwrap();
        let url = &url[1..url.len() - 1];
        Ok(PackageId {
            name: name.to_owned(),
            version: version,
            url: url.to_owned(),
            __do_not_match_exhaustively: (),
        })
    }
}

impl ser::Serialize for PackageId {
    fn serialize< S >( &self, serializer: S ) -> Result< S::Ok, S::Error >
    where
        S: Serializer
    {
        let mut output = String::new();
        write!( output, "{} {} ({})", self.name, self.version, self.url ).unwrap();
        serializer.serialize_str( &output )
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Profile {
    pub opt_level: String,
    pub debuginfo: Option< u32 >,
    pub debug_assertions: bool,
    pub overflow_checks: bool,
    pub test: bool
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Message {
    pub message: Diagnostic,
    pub package_id: PackageId,
    pub target: Target
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Artifact {
    pub package_id: PackageId,
    pub target: Target,
    pub profile: Profile,
    pub features: Vec< String >,
    pub filenames: Vec< String >,
    pub fresh: bool
}

#[derive(Serialize, Deserialize, Debug)]
pub struct BuildScriptExecuted {
    pub package_id: PackageId,
    pub linked_libs: Vec< String >,
    pub linked_paths: Vec< String >,
    pub cfgs: Vec< String >,
    pub env: Vec< (String, String) >
}

fn any_to_json< T: ser::Serialize >( obj: T, reason: &str ) -> Value {
    let mut value = serde_json::to_value( obj ).unwrap();
    value.as_object_mut().unwrap().insert( "reason".to_owned(), reason.into() );
    value
}

impl Message {
    pub fn to_json_value( &self ) -> Value { any_to_json( self, "message" ) }
}

impl Artifact {
    pub fn to_json_value( &self ) -> Value { any_to_json( self, "compiler-artifact" ) }
}

impl BuildScriptExecuted {
    pub fn to_json_value( &self ) -> Value { any_to_json( self, "build-script-executed" ) }
}

#[derive(Debug)]
pub enum CargoOutput {
    Message( Message ),
    Artifact( Artifact ),
    BuildScriptExecuted( BuildScriptExecuted )
}

impl CargoOutput {
    pub fn parse( string: &str ) -> Option< CargoOutput > {
        let json: Value = serde_json::from_str( &string ).expect( "failed to parse cargo output as JSON" );
        let reason = json.get( "reason" ).expect( "missing `reason` field in cargo output" ).as_str().expect( "`reason` field is not a string" );
        let output = match reason {
            "compiler-message" => {
                CargoOutput::Message( serde_json::from_str( &string ).expect( "failed to parse compiler message" ) )
            },
            "compiler-artifact" => {
                CargoOutput::Artifact( serde_json::from_str( &string ).expect( "failed to parse compiler artifact" ) )
            },
            "build-script-executed" => {
                CargoOutput::BuildScriptExecuted( serde_json::from_str( &string ).expect( "failed to parse build script result" ) )
            },
            _ => return None
        };

        Some( output )
    }
}
<commit_msg>Switch to upstream `cargo_metadata` types<commit_after>use serde_json::{self, Value};
use serde::ser;

pub use cargo_shim::rustc_diagnostic::Diagnostic;
pub use cargo_metadata::Target;
pub use cargo_metadata::WorkspaceMember as PackageId;

#[derive(Serialize, Deserialize, Debug)]
pub struct Profile {
    pub opt_level: String,
    pub debuginfo: Option< u32 >,
    pub debug_assertions: bool,
    pub overflow_checks: bool,
    pub test: bool
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Message {
    pub message: Diagnostic,
    pub package_id: PackageId,
    pub target: Target
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Artifact {
    pub package_id: PackageId,
    pub target: Target,
    pub profile: Profile,
    pub features: Vec< String >,
    pub filenames: Vec< String >,
    pub fresh: bool
}

#[derive(Serialize, Deserialize, Debug)]
pub struct BuildScriptExecuted {
    pub package_id: PackageId,
    pub linked_libs: Vec< String >,
    pub linked_paths: Vec< String >,
    pub cfgs: Vec< String >,
    pub env: Vec< (String, String) >
}

fn any_to_json< T: ser::Serialize >( obj: T, reason: &str ) -> Value {
    let mut value = serde_json::to_value( obj ).unwrap();
    value.as_object_mut().unwrap().insert( "reason".to_owned(), reason.into() );
    value
}

impl Message {
    pub fn to_json_value( &self ) -> Value { any_to_json( self, "message" ) }
}

impl Artifact {
    pub fn to_json_value( &self ) -> Value { any_to_json( self, "compiler-artifact" ) }
}

impl BuildScriptExecuted {
    pub fn to_json_value( &self ) -> Value { any_to_json( self, "build-script-executed" ) }
}

#[derive(Debug)]
pub enum CargoOutput {
    Message( Message ),
    Artifact( Artifact ),
    BuildScriptExecuted( BuildScriptExecuted )
}

impl CargoOutput {
    pub fn parse( string: &str ) -> Option< CargoOutput > {
        let json: Value = serde_json::from_str( &string ).expect( "failed to parse cargo output as JSON" );
        let reason = json.get( "reason" ).expect( "missing `reason` field in cargo output" ).as_str().expect( "`reason` field is not a string" );
        let output = match reason {
            "compiler-message" => {
                CargoOutput::Message( serde_json::from_str( &string ).expect( "failed to parse compiler message" ) )
            },
            "compiler-artifact" => {
                CargoOutput::Artifact( serde_json::from_str( &string ).expect( "failed to parse compiler artifact" ) )
            },
            "build-script-executed" => {
                CargoOutput::BuildScriptExecuted( serde_json::from_str( &string ).expect( "failed to parse build script result" ) )
            },
            _ => return None
        };

        Some( output )
    }
}
<|endoftext|>


<commit_before>/*
Basic interval implementation and other common functions/data structures
 */
#![feature(float_extras)]

// External libraries
use std::cmp::{PartialOrd, Ordering, PartialEq, Ord};
use std::f64::{NEG_INFINITY, INFINITY};

// Internal libraries
extern crate gr;
use gr::GI;

// Datatypes
pub type Flt = f64;
pub static INF:  Flt = INFINITY;
pub static NINF: Flt = NEG_INFINITY;

#[macro_export]
macro_rules! max {
    ($x:expr) => {{ $x }};
    ($x:expr, $($y:expr),* ) => {{
        let mut max = $x;
        $(
            max = if max > $y {max} else {$y};
        )*
            max
    }}
}

#[macro_export]
macro_rules! min {
    ($x:expr) => {{ $x }};
    ( $x:expr, $($y:expr),*) => {{
        let mut min = $x;
        $(
            min = if min < $y {min} else {$y};
        )*
            min
    }}
}

// Evolutionary algo
#[derive(Debug, Copy, Clone)]
pub struct Parameters {
    pub population:usize,
    pub selection: usize,
    pub elitism:   usize,
    pub mutation:    Flt,
    pub crossover:   Flt,
}
// Evolutionary algo end

// Quple
// Data structure for insertion of a box into a priority queue
#[derive(Clone)]
pub struct Quple {
    pub p: Flt,
    pub pf: u32,
    pub data: Vec<GI>,
    pub fdata: GI
}

// Allow ordering of Quples
impl PartialEq for Quple {
    fn eq(&self, other: &Quple) -> bool {
        if self.pf == other.pf &&
            self.p == other.p {
                return true;
            }
        return false;
    }
}

impl Eq for Quple { }

impl PartialOrd for Quple {
    fn partial_cmp(&self, other: &Quple) -> Option<Ordering> {
        // This element is greater than the other element
        if self.pf < other.pf {
            return Some(Ordering::Greater);
        }
        else if self.pf == other.pf {
            return self.p.partial_cmp(&other.p);
        }
        else {
            return Some(Ordering::Less);
        }
    }
}

impl Ord for Quple {
    fn cmp(&self, other: &Quple) -> Ordering {
        if self.pf < other.pf {
            return Ordering::Greater;
        }
        else if self.pf == other.pf {
            if self.p > other.p {
                return Ordering::Greater;
            }
            else if self.p == other.p {
                return Ordering::Equal;
            }
            else {
                return Ordering::Less;
            }
        }
        else {
            return Ordering::Less;
        }
    }
}
// End Quple ordering.
// End Quple

pub fn eps_tol(fx: GI, est: f64, e_f: f64, e_f_r: f64) -> bool {
    (fx.upper() - est).abs() <= e_f_r*est +  e_f
}
<commit_msg>Needed member for GA params pack<commit_after>/*
Basic interval implementation and other common functions/data structures
 */
#![feature(float_extras)]

// External libraries
use std::cmp::{PartialOrd, Ordering, PartialEq, Ord};
use std::f64::{NEG_INFINITY, INFINITY};

// Internal libraries
extern crate gr;
use gr::GI;

// Datatypes
pub type Flt = f64;
pub static INF:  Flt = INFINITY;
pub static NINF: Flt = NEG_INFINITY;

#[macro_export]
macro_rules! max {
    ($x:expr) => {{ $x }};
    ($x:expr, $($y:expr),* ) => {{
        let mut max = $x;
        $(
            max = if max > $y {max} else {$y};
        )*
            max
    }}
}

#[macro_export]
macro_rules! min {
    ($x:expr) => {{ $x }};
    ( $x:expr, $($y:expr),*) => {{
        let mut min = $x;
        $(
            min = if min < $y {min} else {$y};
        )*
            min
    }}
}

// Evolutionary algo
#[derive(Debug, Copy, Clone)]
pub struct Parameters {
    pub population:usize,
    pub selection: usize,
    pub elitism:   usize,
    pub mutation:    Flt,
    pub crossover:   Flt,
    pub seed:        u32,
}
// Evolutionary algo end

// Quple
// Data structure for insertion of a box into a priority queue
#[derive(Clone)]
pub struct Quple {
    pub p: Flt,
    pub pf: u32,
    pub data: Vec<GI>,
    pub fdata: GI
}

// Allow ordering of Quples
impl PartialEq for Quple {
    fn eq(&self, other: &Quple) -> bool {
        if self.pf == other.pf &&
            self.p == other.p {
                return true;
            }
        return false;
    }
}

impl Eq for Quple { }

impl PartialOrd for Quple {
    fn partial_cmp(&self, other: &Quple) -> Option<Ordering> {
        // This element is greater than the other element
        if self.pf < other.pf {
            return Some(Ordering::Greater);
        }
        else if self.pf == other.pf {
            return self.p.partial_cmp(&other.p);
        }
        else {
            return Some(Ordering::Less);
        }
    }
}

impl Ord for Quple {
    fn cmp(&self, other: &Quple) -> Ordering {
        if self.pf < other.pf {
            return Ordering::Greater;
        }
        else if self.pf == other.pf {
            if self.p > other.p {
                return Ordering::Greater;
            }
            else if self.p == other.p {
                return Ordering::Equal;
            }
            else {
                return Ordering::Less;
            }
        }
        else {
            return Ordering::Less;
        }
    }
}
// End Quple ordering.
// End Quple

pub fn eps_tol(fx: GI, est: f64, e_f: f64, e_f_r: f64) -> bool {
    (fx.upper() - est).abs() <= e_f_r*est +  e_f
}
<|endoftext|>


<commit_before>use header::{Header, Raw, Host};
use std::borrow::Cow;
use std::fmt;
use std::str::FromStr;
use header::parsing::from_one_raw_str;

/// The `Origin` header.
///
/// The `Origin` header is a version of the `Referer` header that is used for all HTTP fetches and `POST`s whose CORS flag is set.
/// This header is often used to inform recipients of the security context of where the request was initiated.
///
///
/// Following the spec, https://fetch.spec.whatwg.org/#origin-header, the value of this header is composed of
/// a String (scheme), header::Host (host/port)
///
/// # Examples
/// ```
/// use hyper::header::{Headers, Origin};
///
/// let mut headers = Headers::new();
/// headers.set(
///     Origin::new("http", "hyper.rs", None)
/// );
/// ```
/// ```
/// use hyper::header::{Headers, Origin};
///
/// let mut headers = Headers::new();
/// headers.set(
///     Origin::new("https", "wikipedia.org", Some(443))
/// );
/// ```

#[derive(Clone, Debug)]
pub struct Origin {
    /// The scheme, such as http or https
    scheme: Cow<'static,str>,
    /// The host, such as Host{hostname: "hyper.rs".to_owned(), port: None}
    host: Host,
}

impl Origin {
    /// Creates a new `Origin` header.
    pub fn new<S: Into<Cow<'static,str>>, H: Into<Cow<'static,str>>>(scheme: S, hostname: H, port: Option<u16>) -> Origin{
        Origin {
            scheme: scheme.into(),
            host: Host::new(hostname, port),
        }
    }

    /// The scheme, such as http or https
    /// ```
    /// use hyper::header::Origin;
    /// let origin = Origin::new("https", "foo.com", Some(443));
    /// assert_eq!(origin.scheme(), "https");
    /// ```
    pub fn scheme(&self) -> &str {
        &(self.scheme)
    }

    /// The host, such as Host{hostname: "hyper.rs".to_owned(), port: None}
    /// ```
    /// use hyper::header::{Origin,Host};
    /// let origin = Origin::new("https", "foo.com", Some(443));
    /// assert_eq!(origin.host(), &Host::new("foo.com", Some(443)));
    /// ```
    pub fn host(&self) -> &Host {
        &(self.host)
    }
}

impl Header for Origin {
    fn header_name() -> &'static str {
        static NAME: &'static str = "Origin";
        NAME
    }

    fn parse_header(raw: &Raw) -> ::Result<Origin> {
        from_one_raw_str(raw)
    }

    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, f)
    }
}

impl FromStr for Origin {
    type Err = ::Error;

    fn from_str(s: &str) -> ::Result<Origin> {
        let idx = match s.find("://") {
            Some(idx) => idx,
            None => return Err(::Error::Header)
        };
        // idx + 3 because that's how long "://" is
        let (scheme, etc) = (&s[..idx], &s[idx + 3..]);
        let host = try!(Host::from_str(etc));

        Ok(Origin{
            scheme: scheme.to_owned().into(),
            host: host
        })
    }
}

impl fmt::Display for Origin {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}://{}", self.scheme, self.host)
    }
}

impl PartialEq for Origin {
    fn eq(&self, other: &Origin) -> bool {
        self.scheme == other.scheme && self.host == other.host
    }
}

#[cfg(test)]
mod tests {
    use super::Origin;
    use header::Header;

    #[test]
    fn test_origin() {
        let origin = Header::parse_header(&vec![b"http://foo.com".to_vec()].into());
        assert_eq!(origin.ok(), Some(Origin::new("http", "foo.com", None)));

        let origin = Header::parse_header(&vec![b"https://foo.com:443".to_vec()].into());
        assert_eq!(origin.ok(), Some(Origin::new("https", "foo.com", Some(443))));
    }
}

bench_header!(bench, Origin, { vec![b"https://foo.com".to_vec()] });
<commit_msg>refactor(headers): use static "http"/"https" for scheme<commit_after>use header::{Header, Raw, Host};
use std::borrow::Cow;
use std::fmt;
use std::str::FromStr;
use header::parsing::from_one_raw_str;

/// The `Origin` header.
///
/// The `Origin` header is a version of the `Referer` header that is used for all HTTP fetches and `POST`s whose CORS flag is set.
/// This header is often used to inform recipients of the security context of where the request was initiated.
///
///
/// Following the spec, https://fetch.spec.whatwg.org/#origin-header, the value of this header is composed of
/// a String (scheme), header::Host (host/port)
///
/// # Examples
/// ```
/// use hyper::header::{Headers, Origin};
///
/// let mut headers = Headers::new();
/// headers.set(
///     Origin::new("http", "hyper.rs", None)
/// );
/// ```
/// ```
/// use hyper::header::{Headers, Origin};
///
/// let mut headers = Headers::new();
/// headers.set(
///     Origin::new("https", "wikipedia.org", Some(443))
/// );
/// ```

#[derive(Clone, Debug)]
pub struct Origin {
    /// The scheme, such as http or https
    scheme: Cow<'static,str>,
    /// The host, such as Host{hostname: "hyper.rs".to_owned(), port: None}
    host: Host,
}

impl Origin {
    /// Creates a new `Origin` header.
    pub fn new<S: Into<Cow<'static,str>>, H: Into<Cow<'static,str>>>(scheme: S, hostname: H, port: Option<u16>) -> Origin{
        Origin {
            scheme: scheme.into(),
            host: Host::new(hostname, port),
        }
    }

    /// The scheme, such as http or https
    /// ```
    /// use hyper::header::Origin;
    /// let origin = Origin::new("https", "foo.com", Some(443));
    /// assert_eq!(origin.scheme(), "https");
    /// ```
    pub fn scheme(&self) -> &str {
        &(self.scheme)
    }

    /// The host, such as Host{hostname: "hyper.rs".to_owned(), port: None}
    /// ```
    /// use hyper::header::{Origin,Host};
    /// let origin = Origin::new("https", "foo.com", Some(443));
    /// assert_eq!(origin.host(), &Host::new("foo.com", Some(443)));
    /// ```
    pub fn host(&self) -> &Host {
        &(self.host)
    }
}

impl Header for Origin {
    fn header_name() -> &'static str {
        static NAME: &'static str = "Origin";
        NAME
    }

    fn parse_header(raw: &Raw) -> ::Result<Origin> {
        from_one_raw_str(raw)
    }

    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, f)
    }
}

static HTTP : &'static str = "http";
static HTTPS : &'static str = "https";

impl FromStr for Origin {
    type Err = ::Error;

    fn from_str(s: &str) -> ::Result<Origin> {
        let idx = match s.find("://") {
            Some(idx) => idx,
            None => return Err(::Error::Header)
        };
        // idx + 3 because that's how long "://" is
        let (scheme, etc) = (&s[..idx], &s[idx + 3..]);
        let host = try!(Host::from_str(etc));
        let scheme = match scheme {
            "http"  => Cow::Borrowed(HTTP),
            "https" => Cow::Borrowed(HTTPS),
            s       => Cow::Owned(s.to_owned())
        };

        Ok(Origin{
            scheme: scheme,
            host: host
        })
    }
}

impl fmt::Display for Origin {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}://{}", self.scheme, self.host)
    }
}

impl PartialEq for Origin {
    fn eq(&self, other: &Origin) -> bool {
        self.scheme == other.scheme && self.host == other.host
    }
}

#[cfg(test)]
mod tests {
    use super::Origin;
    use header::Header;
    use std::borrow::Cow;

    macro_rules! assert_borrowed{
        ($expr : expr) => {
            match $expr {
                Cow::Owned(ref v) => panic!("assertion failed: `{}` owns {:?}", stringify!($expr), v),
                _ => {}
            }
        }
    }

    #[test]
    fn test_origin() {
        let origin : Origin = Header::parse_header(&vec![b"http://foo.com".to_vec()].into()).unwrap();
        assert_eq!(&origin, &Origin::new("http", "foo.com", None));
        assert_borrowed!(origin.scheme);

        let origin : Origin = Header::parse_header(&vec![b"https://foo.com:443".to_vec()].into()).unwrap();
        assert_eq!(&origin, &Origin::new("https", "foo.com", Some(443)));
        assert_borrowed!(origin.scheme);
    }
}

bench_header!(bench, Origin, { vec![b"https://foo.com".to_vec()] });
<|endoftext|>


<commit_before><commit_msg>delete empty file<commit_after><|endoftext|>


<commit_before>use index::lsmtree::placement::sm::client::SMClient as PlacementClient;
use index::lsmtree::placement::sm::Placement as PlacementMeta;
use index::lsmtree::service::AsyncServiceClient;
use index::EntryKey;
use linked_hash_map::LinkedHashMap;
use parking_lot::RwLock;
use ram::types::Id;
use server::NebServer;
use std::collections::btree_map::BTreeMap;
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use std::sync::Arc;

pub struct IndexEntry {
    id: Id,
    val: u64,
}

pub struct Cursor {
    buffer: Vec<IndexEntry>,
    at_end: bool,
    pos: usize,
}

pub struct Placement {
    meta: PlacementMeta,
    client: Arc<AsyncServiceClient>,
}

pub struct LSMTreeClient {
    counter: AtomicUsize,
    placements: RwLock<BTreeMap<EntryKey, Placement>>,
    cursors: LinkedHashMap<usize, Cursor>,
    placement_client: PlacementClient,
    neb: Arc<NebServer>,
}
<commit_msg>inspect and update placement<commit_after>use index::lsmtree::placement::sm::client::SMClient as PlacementClient;
use index::lsmtree::placement::sm::{Placement as PlacementMeta, QueryError};
use index::lsmtree::service::AsyncServiceClient;
use index::EntryKey;
use linked_hash_map::LinkedHashMap;
use parking_lot::RwLock;
use ram::types::Id;
use server::NebServer;
use std::collections::btree_map::BTreeMap;
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use std::sync::Arc;
use futures::prelude::*;
use index::lsmtree::split::placement_client;

pub struct IndexEntry {
    id: Id,
    val: u64,
}

pub struct Cursor {
    buffer: Vec<IndexEntry>,
    at_end: bool,
    pos: usize,
}

pub struct Placement {
    meta: PlacementMeta,
    client: Arc<AsyncServiceClient>,
}

pub struct LSMTreeClient {
    counter: AtomicUsize,
    placements: RwLock<BTreeMap<Vec<u8>, Placement>>,
    cursors: LinkedHashMap<usize, Cursor>,
    placement_client: PlacementClient,
    neb: Arc<NebServer>,
}

impl LSMTreeClient {
    fn inspect_placement(&self, id: &Id) {
        match self.placement_client.get(id).wait().unwrap() {
            Ok(placement) => {
                let mut placements = self.placements.write();
                let rpc_client = placement_client(id, &self.neb).wait().unwrap();
                placements.insert(placement.starts.clone(), Placement {
                    meta: placement,
                    client: rpc_client
                });
            },
            Err(QueryError::PlacementNotFound) => panic!("cannot find a suitable placement"),
            Err(e) => panic!("{:?}", e)
        }
    }
}
<|endoftext|>


<commit_before>use {
    BackEnd,
    Borrowed,
    Field,
    Fill,
    Image,
    Matrix2d,
    Rectangle,
    RelativeRectangle,
    Value,
    Transform2d,
};
use vecmath::{
    margin_rectangle,
    multiply,
    relative_rectangle,
    rotate_radians,
    scale,
    shear,
    translate,
};

/// An image rectangle context.
pub struct ImageRectangleContext<'a> {
    /// Base/original transformation.
    pub base: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current color.
    pub image: Field<'a, Image>,
}

impl<'a> Transform2d<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn trans_local(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(self.transform.get(), &trans))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad_local(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(self.transform.get(), &rot))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(self.transform.get(), &scale))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(self.transform.get(), &shear))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }
}

impl<'a> Fill<'a> for ImageRectangleContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32_uv_f32() {
            /*
            let rect = self.rect.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            back_end.tri_list_xy_f32_rgba_f32(
                rect_tri_list_xy_f32(self.transform.get(), rect),
                rect_tri_list_rgba_f32(color)
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
            */
        } else {
            unimplemented!();
        }
    }
}

impl<'a> RelativeRectangle<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn margin(&'a self, m: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(margin_rectangle(self.rect.get(), m)),
        }
    }

    #[inline(always)]
    fn rel(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(relative_rectangle(self.rect.get(), x, y)),
        }
    }
}
<commit_msg>Implemented `Draw`<commit_after>use {
    BackEnd,
    Borrowed,
    Draw,
    Field,
    Image,
    Matrix2d,
    Rectangle,
    RelativeRectangle,
    Value,
    Transform2d,
};
use vecmath::{
    margin_rectangle,
    multiply,
    relative_rectangle,
    rotate_radians,
    scale,
    shear,
    translate,
};
use triangulation::{
    rect_tri_list_xy_f32,
    rect_tri_list_rgba_f32,
    rect_tri_list_uv_f32,
};

/// An image rectangle context.
pub struct ImageRectangleContext<'a> {
    /// Base/original transformation.
    pub base: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current color.
    pub image: Field<'a, Image>,
}

impl<'a> Transform2d<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn trans_local(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(self.transform.get(), &trans))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad_local(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(self.transform.get(), &rot))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(self.transform.get(), &scale))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(self.transform.get(), &shear))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }
}

impl<'a> Draw<'a> for ImageRectangleContext<'a> {
    fn draw<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32_uv_f32() {
            let rect = self.rect.get();
            let color: [f32, ..4] = [1.0, 1.0, 1.0, 1.0];
            let texture_id = self.image.get().texture_id;
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque or if the texture has alpha channel.
            let needs_alpha = color[3] != 1.0 || back_end.has_texture_alpha(texture_id);
            if needs_alpha { back_end.enable_alpha_blend(); }
            back_end.tri_list_xy_f32_rgba_f32_uv_f32(
                rect_tri_list_xy_f32(self.transform.get(), rect),
                rect_tri_list_rgba_f32(color),
                rect_tri_list_uv_f32(self.image.get())
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> RelativeRectangle<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn margin(&'a self, m: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(margin_rectangle(self.rect.get(), m)),
        }
    }

    #[inline(always)]
    fn rel(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(relative_rectangle(self.rect.get(), x, y)),
        }
    }
}
<|endoftext|>