<commit_before>//! Matrix iterators.

use std::marker::PhantomData;
use std::mem;

use crate::base::dimension::{Dim, U1};
use crate::base::storage::{Storage, StorageMut};
use crate::base::{Scalar, Matrix, MatrixSlice, MatrixSliceMut};

macro_rules! iterator {
    (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
        /// An iterator through a dense matrix with arbitrary strides matrix.
        pub struct $Name<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> {
            ptr: $Ptr,
            inner_ptr: $Ptr,
            inner_end: $Ptr,
            size: usize, // We can't use an end pointer here because a stride might be zero.
            strides: (S::RStride, S::CStride),
            _phantoms: PhantomData<($Ref, R, C, S)>,
        }

        // FIXME: we need to specialize for the case where the matrix storage is owned (in which
        // case the iterator is trivial because it does not have any stride).
        impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> $Name<'a, N, R, C, S> {
            /// Creates a new iterator for the given matrix storage.
            pub fn new(storage: $SRef) -> $Name<'a, N, R, C, S> {
                let shape = storage.shape();
                let strides = storage.strides();
                let inner_offset = shape.0.value() * strides.0.value();
                let size = shape.0.value() * shape.1.value();
                let ptr = storage.$ptr();

                // If we have a size of 0, 'ptr' must be
                // dangling. Howver, 'inner_offset' might
                // not be zero if only one dimension is zero, so
                // we don't want to call 'offset'.
                // This pointer will never actually get used
                // if our size is '0', so it's fine to use
                // 'ptr' for both the start and end.
                let inner_end = if size == 0 {
                    ptr
                } else {
                    // Safety:
                    // If 'size' is non-zero, we know that 'ptr'
                    // is not dangling, and 'inner_offset' must lie
                    // within the allocation
                    unsafe { ptr.offset(inner_offset as isize) }
                };

                $Name {
                    ptr: ptr,
                    inner_ptr: ptr,
                    inner_end,
                    size: shape.0.value() * shape.1.value(),
                    strides: strides,
                    _phantoms: PhantomData,
                }
            }
        }

        impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> Iterator
            for $Name<'a, N, R, C, S>
        {
            type Item = $Ref;

            #[inline]
            fn next(&mut self) -> Option<$Ref> {
                unsafe {
                    if self.size == 0 {
                        None
                    } else {
                        self.size -= 1;

                        // Jump to the next outer dimension if needed.
                        if self.ptr == self.inner_end {
                            let stride = self.strides.1.value() as isize;
                            self.inner_end = self.ptr.offset(stride);
                            self.ptr = self.inner_ptr.offset(stride);
                            self.inner_ptr = self.ptr;
                        }

                        // Go to the next element.
                        let old = self.ptr;

                        let stride = self.strides.0.value() as isize;
                        self.ptr = self.ptr.offset(stride);

                        Some(mem::transmute(old))
                    }
                }
            }

            #[inline]
            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.size, Some(self.size))
            }

            #[inline]
            fn count(self) -> usize {
                self.size_hint().0
            }
        }

        impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> ExactSizeIterator
            for $Name<'a, N, R, C, S>
        {
            #[inline]
            fn len(&self) -> usize {
                self.size
            }
        }
    };
}

iterator!(struct MatrixIter for Storage.ptr -> *const N, &'a N, &'a S);
iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a mut S);

/*
 *
 * Row iterators.
 *
 */
#[derive(Clone)]
/// An iterator through the rows of a matrix.
pub struct RowIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> {
    mat: &'a Matrix<N, R, C, S>,
    curr: usize
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> RowIter<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
        RowIter {
            mat, curr: 0
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIter<'a, N, R, C, S> {
    type Item = MatrixSlice<'a, N, U1, C, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.mat.nrows() {
            let res = self.mat.row(self.curr);
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.mat.nrows() - self.curr, Some(self.mat.nrows() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.mat.nrows() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator for RowIter<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.mat.nrows() - self.curr
    }
}

/// An iterator through the mutable rows of a matrix.
pub struct RowIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
    mat: *mut Matrix<N, R, C, S>,
    curr: usize,
    phantom: PhantomData<&'a mut Matrix<N, R, C, S>>
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
        RowIterMut {
            mat,
            curr: 0,
            phantom: PhantomData
        }
    }

    fn nrows(&self) -> usize {
        unsafe {
            (*self.mat).nrows()
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for RowIterMut<'a, N, R, C, S> {
    type Item = MatrixSliceMut<'a, N, U1, C, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.nrows() {
            let res = unsafe { (*self.mat).row_mut(self.curr) };
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.nrows() - self.curr, Some(self.nrows() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.nrows() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator for RowIterMut<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.nrows() - self.curr
    }
}

/*
 *
 * Column iterators.
 *
 */
#[derive(Clone)]
/// An iterator through the columns of a matrix.
pub struct ColumnIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> {
    mat: &'a Matrix<N, R, C, S>,
    curr: usize
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ColumnIter<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
        ColumnIter {
            mat, curr: 0
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for ColumnIter<'a, N, R, C, S> {
    type Item = MatrixSlice<'a, N, R, U1, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.mat.ncols() {
            let res = self.mat.column(self.curr);
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.mat.ncols() - self.curr, Some(self.mat.ncols() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.mat.ncols() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator for ColumnIter<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.mat.ncols() - self.curr
    }
}

/// An iterator through the mutable columns of a matrix.
pub struct ColumnIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
    mat: *mut Matrix<N, R, C, S>,
    curr: usize,
    phantom: PhantomData<&'a mut Matrix<N, R, C, S>>
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
        ColumnIterMut {
            mat,
            curr: 0,
            phantom: PhantomData
        }
    }

    fn ncols(&self) -> usize {
        unsafe {
            (*self.mat).ncols()
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for ColumnIterMut<'a, N, R, C, S> {
    type Item = MatrixSliceMut<'a, N, R, U1, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.ncols() {
            let res = unsafe { (*self.mat).column_mut(self.curr) };
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.ncols() - self.curr, Some(self.ncols() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.ncols() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator for ColumnIterMut<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.ncols() - self.curr
    }
}

<commit_msg>Fix some out-of-bounds `offset` calls<commit_after>//! Matrix iterators.

use std::marker::PhantomData;
use std::mem;

use crate::base::dimension::{Dim, U1};
use crate::base::storage::{Storage, StorageMut};
use crate::base::{Scalar, Matrix, MatrixSlice, MatrixSliceMut};

macro_rules! iterator {
    (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
        /// An iterator through a dense matrix with arbitrary strides matrix.
        pub struct $Name<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> {
            ptr: $Ptr,
            inner_ptr: $Ptr,
            inner_end: $Ptr,
            size: usize, // We can't use an end pointer here because a stride might be zero.
            strides: (S::RStride, S::CStride),
            _phantoms: PhantomData<($Ref, R, C, S)>,
        }

        // FIXME: we need to specialize for the case where the matrix storage is owned (in which
        // case the iterator is trivial because it does not have any stride).
        impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> $Name<'a, N, R, C, S> {
            /// Creates a new iterator for the given matrix storage.
            pub fn new(storage: $SRef) -> $Name<'a, N, R, C, S> {
                let shape = storage.shape();
                let strides = storage.strides();
                let inner_offset = shape.0.value() * strides.0.value();
                let size = shape.0.value() * shape.1.value();
                let ptr = storage.$ptr();

                // If we have a size of 0, 'ptr' must be
                // dangling. Howver, 'inner_offset' might
                // not be zero if only one dimension is zero, so
                // we don't want to call 'offset'.
                // This pointer will never actually get used
                // if our size is '0', so it's fine to use
                // 'ptr' for both the start and end.
                let inner_end = if size == 0 {
                    ptr
                } else {
                    // Safety:
                    // If 'size' is non-zero, we know that 'ptr'
                    // is not dangling, and 'inner_offset' must lie
                    // within the allocation
                    unsafe { ptr.offset(inner_offset as isize) }
                };

                $Name {
                    ptr: ptr,
                    inner_ptr: ptr,
                    inner_end,
                    size: shape.0.value() * shape.1.value(),
                    strides: strides,
                    _phantoms: PhantomData,
                }
            }
        }

        impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> Iterator
            for $Name<'a, N, R, C, S>
        {
            type Item = $Ref;

            #[inline]
            fn next(&mut self) -> Option<$Ref> {
                unsafe {
                    if self.size == 0 {
                        None
                    } else {
                        self.size -= 1;

                        // Jump to the next outer dimension if needed.
                        if self.ptr == self.inner_end {
                            let stride = self.strides.1.value() as isize;
                            // This might go past the end of the allocation,
                            // depending on the value of 'size'. We use
                            // `wrapping_offset` to avoid UB
                            self.inner_end = self.ptr.wrapping_offset(stride);
                            // This will always be in bounds, since
                            // we're going to dereference it
                            self.ptr = self.inner_ptr.offset(stride);
                            self.inner_ptr = self.ptr;
                        }

                        // Go to the next element.
                        let old = self.ptr;

                        let stride = self.strides.0.value() as isize;
                        // Don't offset `self.ptr` for the last element,
                        // as this will be out of bounds. Iteration is done
                        // at this point (the next call to `next` will return `None`)
                        // so this is not observable.
                        if self.size != 0 {
                            self.ptr = self.ptr.offset(stride);
                        }
                        Some(mem::transmute(old))
                    }
                }
            }

            #[inline]
            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.size, Some(self.size))
            }

            #[inline]
            fn count(self) -> usize {
                self.size_hint().0
            }
        }

        impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> ExactSizeIterator
            for $Name<'a, N, R, C, S>
        {
            #[inline]
            fn len(&self) -> usize {
                self.size
            }
        }
    };
}

iterator!(struct MatrixIter for Storage.ptr -> *const N, &'a N, &'a S);
iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a mut S);

/*
 *
 * Row iterators.
 *
 */
#[derive(Clone)]
/// An iterator through the rows of a matrix.
pub struct RowIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> {
    mat: &'a Matrix<N, R, C, S>,
    curr: usize
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> RowIter<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
        RowIter {
            mat, curr: 0
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIter<'a, N, R, C, S> {
    type Item = MatrixSlice<'a, N, U1, C, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.mat.nrows() {
            let res = self.mat.row(self.curr);
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.mat.nrows() - self.curr, Some(self.mat.nrows() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.mat.nrows() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator for RowIter<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.mat.nrows() - self.curr
    }
}

/// An iterator through the mutable rows of a matrix.
pub struct RowIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
    mat: *mut Matrix<N, R, C, S>,
    curr: usize,
    phantom: PhantomData<&'a mut Matrix<N, R, C, S>>
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
        RowIterMut {
            mat,
            curr: 0,
            phantom: PhantomData
        }
    }

    fn nrows(&self) -> usize {
        unsafe {
            (*self.mat).nrows()
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for RowIterMut<'a, N, R, C, S> {
    type Item = MatrixSliceMut<'a, N, U1, C, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.nrows() {
            let res = unsafe { (*self.mat).row_mut(self.curr) };
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.nrows() - self.curr, Some(self.nrows() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.nrows() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator for RowIterMut<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.nrows() - self.curr
    }
}

/*
 *
 * Column iterators.
 *
 */
#[derive(Clone)]
/// An iterator through the columns of a matrix.
pub struct ColumnIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> {
    mat: &'a Matrix<N, R, C, S>,
    curr: usize
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ColumnIter<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
        ColumnIter {
            mat, curr: 0
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for ColumnIter<'a, N, R, C, S> {
    type Item = MatrixSlice<'a, N, R, U1, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.mat.ncols() {
            let res = self.mat.column(self.curr);
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.mat.ncols() - self.curr, Some(self.mat.ncols() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.mat.ncols() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator for ColumnIter<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.mat.ncols() - self.curr
    }
}

/// An iterator through the mutable columns of a matrix.
pub struct ColumnIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
    mat: *mut Matrix<N, R, C, S>,
    curr: usize,
    phantom: PhantomData<&'a mut Matrix<N, R, C, S>>
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'a, N, R, C, S> {
    pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
        ColumnIterMut {
            mat,
            curr: 0,
            phantom: PhantomData
        }
    }

    fn ncols(&self) -> usize {
        unsafe {
            (*self.mat).ncols()
        }
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for ColumnIterMut<'a, N, R, C, S> {
    type Item = MatrixSliceMut<'a, N, R, U1, S::RStride, S::CStride>;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.ncols() {
            let res = unsafe { (*self.mat).column_mut(self.curr) };
            self.curr += 1;
            Some(res)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.ncols() - self.curr, Some(self.ncols() - self.curr))
    }

    #[inline]
    fn count(self) -> usize {
        self.ncols() - self.curr
    }
}

impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator for ColumnIterMut<'a, N, R, C, S> {
    #[inline]
    fn len(&self) -> usize {
        self.ncols() - self.curr
    }
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;

extern crate brain;

use std::process;
use std::io::prelude::*;
use std::fs::File;
use std::path::{Path, PathBuf};

use clap::{Arg, App};

fn main() {
    let args = App::new(crate_name!())
        .version(crate_version!())
        .version_short("v")
        .author(crate_authors!())
        .about(crate_description!())
        .arg(Arg::with_name("input-file")
            .help("The brain file to process")
            .value_name("file")
            .takes_value(true)
            .required(true)
        )
        .arg(Arg::with_name("output-file")
            .short("o")
            .help("Write output to <target>")
            .value_name("target")
            .takes_value(true)
        )
        .get_matches();

    let source_file = Path::new(args.value_of("input-file").unwrap());
    if !source_file.exists() {
        println!("No such file: '{}'", source_file.display());
        process::exit(1);
    }

    let output = args.value_of("output-file").map_or_else(|| {
        let mut path = source_file.to_path_buf();
        path.set_extension("bf");
        path
    }, |s| PathBuf::from(s));

    println!("{} -> {}", source_file.display(), output.display());

//    println!("Source Code:\n\n{}\n", source);
//
//    let mut f = try!(File::open("foo.txt"));
//    let mut s = String::new();
//    try!(f.read_to_string(&mut s));
//    println!("AST:\n\n{:#?}", brain::parse(source));
}
<commit_msg>Validating source_file and output file<commit_after>#[macro_use]
extern crate clap;

extern crate brain;

use std::process;
use std::io::prelude::*;
use std::fs::File;
use std::path::{Path, PathBuf};

use clap::{Arg, App};

macro_rules! println_stderr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

fn main() {
    let args = App::new(crate_name!())
        .version(crate_version!())
        .version_short("v")
        .author(crate_authors!())
        .about(crate_description!())
        .arg(Arg::with_name("input-file")
            .help("The brain file to process")
            .value_name("file")
            .takes_value(true)
            .required(true)
        )
        .arg(Arg::with_name("output-file")
            .short("o")
            .help("Write output to <target>")
            .value_name("target")
            .takes_value(true)
        )
        .get_matches();

    let source_file = Path::new(args.value_of("input-file").unwrap());
    if !source_file.exists() || !source_file.is_file() {
        println_stderr!("Not a valid file: '{}'", source_file.display());
        process::exit(1);
    }

    let output = args.value_of("output-file").map_or_else(|| {
        let mut path = PathBuf::from(source_file.file_name().and_then(|s| s.to_str()).unwrap_or(""));
        path.set_extension("bf");
        path
    }, |s| PathBuf::from(s));

    println!("{} -> {}", source_file.display(), output.display());

//    println!("Source Code:\n\n{}\n", source);
//
//    let mut f = try!(File::open("foo.txt"));
//    let mut s = String::new();
//    try!(f.read_to_string(&mut s));
//    println!("AST:\n\n{:#?}", brain::parse(source));
}
<|endoftext|>


<commit_before>
/// Modbus protocol exceptions
///
/// Documentation source: https://en.wikipedia.org/wiki/Modbus#Main_Modbus_exception_codes
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Exception {
    /// (1) Illegal Function - Function code received in the query is not recognized or allowed by slave
    ILLEGAL_FUNCTION = 1,
    /// (2) Illegal Data Address - Data address of some or all the required entities are not allowed or do not exist in
    /// slave
    ILLEGAL_DATA_ADDRESS,
    /// (3) Illegal Data Value - Value is not accepted by slave
    ILLEGAL_DATA_VALUE,
    /// (4) Slave Device Failure - Unrecoverable error occurred while slave was attempting to perform requested action
    SLAVE_OR_SERVER_FAILURE,
    /// (5) Acknowledge - Slave has accepted request and is processing it, but a long duration of time is required.
    /// This response is returned to prevent a timeout error from occurring in the master. Master can next issue a Poll
    /// Program Complete message to determine whether processing is completed
    ACKNOWLEDGE,
    /// (6) Slave Device Busy - Slave is engaged in processing a long-duration command. Master should retry later
    SLAVE_OR_SERVER_BUSY,
    /// (7) Negative Acknowledge - Slave cannot perform the programming functions. Master should request diagnostic or
    /// error information from slave
    NEGATIVE_ACKNOWLEDGE,
    /// (8) Memory Parity Error - Slave detected a parity error in memory. Master can retry the request, but service
    /// may be required on the slave device
    MEMORY_PARITY,
    /// (9) Not defined
    NOT_DEFINED,
    /// (10) Gateway Path Unavailable - Specialized for Modbus gateways. Indicates a misconfigured gateway
    GATEWAY_PATH,
    /// (11) Gateway Target Device Failed to Respond - Specialized for Modbus gateways. Sent when slave fails to respond
    GATEWAY_TARGET,
}

/// Modbus function codes
///
/// Documentation source: https://en.wikipedia.org/wiki/Modbus#Supported_function_codes
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum FunctionCode {
    /// 0x01 Read Coils
    READ_COILS = 1,
    /// 0x02 Read Discrete Inputs
    READ_DISCRETE_INPUTS = 2,
    /// 0x03 Read Multiple Holding Registers
    READ_HOLDING_REGISTERS = 3,
    /// 0x04 Read Input Registers
    READ_INPUT_REGISTERS = 4,
    /// 0x05 Write Single Coil
    WRITE_SINGLE_COIL = 5,
    /// 0x06 Write Single Holding Register
    WRITE_SINGLE_REGISTER = 6,
    /// 0x07 Read Exception Status
    READ_EXCEPTION_STATUS = 7,
    /// 0x15 Write Multiple Coils
    WRITE_MULTIPLE_COILS = 15,
    /// 0x16 Write Multiple Holding Registers
    WRITE_MULTIPLE_REGISTERS = 16,
    /// 0x17 Report Slave ID
    REPORT_SLAVE_ID = 17,
    /// 0x22 Mask Write Register
    MASK_WRITE_REGISTER = 22,
    /// 0x23 Read/Write Multiple Registers
    WRITE_AND_READ_REGISTERS = 23,
}
<commit_msg>Add ErrorRecoveryMode<commit_after>
/// Modbus protocol exceptions
///
/// Documentation source: https://en.wikipedia.org/wiki/Modbus#Main_Modbus_exception_codes
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Exception {
    /// (1) Illegal Function - Function code received in the query is not recognized or allowed by slave
    ILLEGAL_FUNCTION = 1,
    /// (2) Illegal Data Address - Data address of some or all the required entities are not allowed or do not exist in
    /// slave
    ILLEGAL_DATA_ADDRESS,
    /// (3) Illegal Data Value - Value is not accepted by slave
    ILLEGAL_DATA_VALUE,
    /// (4) Slave Device Failure - Unrecoverable error occurred while slave was attempting to perform requested action
    SLAVE_OR_SERVER_FAILURE,
    /// (5) Acknowledge - Slave has accepted request and is processing it, but a long duration of time is required.
    /// This response is returned to prevent a timeout error from occurring in the master. Master can next issue a Poll
    /// Program Complete message to determine whether processing is completed
    ACKNOWLEDGE,
    /// (6) Slave Device Busy - Slave is engaged in processing a long-duration command. Master should retry later
    SLAVE_OR_SERVER_BUSY,
    /// (7) Negative Acknowledge - Slave cannot perform the programming functions. Master should request diagnostic or
    /// error information from slave
    NEGATIVE_ACKNOWLEDGE,
    /// (8) Memory Parity Error - Slave detected a parity error in memory. Master can retry the request, but service
    /// may be required on the slave device
    MEMORY_PARITY,
    /// (9) Not defined
    NOT_DEFINED,
    /// (10) Gateway Path Unavailable - Specialized for Modbus gateways. Indicates a misconfigured gateway
    GATEWAY_PATH,
    /// (11) Gateway Target Device Failed to Respond - Specialized for Modbus gateways. Sent when slave fails to respond
    GATEWAY_TARGET,
}

/// Modbus function codes
///
/// Documentation source: https://en.wikipedia.org/wiki/Modbus#Supported_function_codes
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum FunctionCode {
    /// 0x01 Read Coils
    READ_COILS = 1,
    /// 0x02 Read Discrete Inputs
    READ_DISCRETE_INPUTS = 2,
    /// 0x03 Read Multiple Holding Registers
    READ_HOLDING_REGISTERS = 3,
    /// 0x04 Read Input Registers
    READ_INPUT_REGISTERS = 4,
    /// 0x05 Write Single Coil
    WRITE_SINGLE_COIL = 5,
    /// 0x06 Write Single Holding Register
    WRITE_SINGLE_REGISTER = 6,
    /// 0x07 Read Exception Status
    READ_EXCEPTION_STATUS = 7,
    /// 0x15 Write Multiple Coils
    WRITE_MULTIPLE_COILS = 15,
    /// 0x16 Write Multiple Holding Registers
    WRITE_MULTIPLE_REGISTERS = 16,
    /// 0x17 Report Slave ID
    REPORT_SLAVE_ID = 17,
    /// 0x22 Mask Write Register
    MASK_WRITE_REGISTER = 22,
    /// 0x23 Read/Write Multiple Registers
    WRITE_AND_READ_REGISTERS = 23,
}

#[repr(u32)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum ErrorRecoveryMode {
    NONE = 0u32,
    LINK = 2,
    PROTOCOL = 4,
}
<|endoftext|>


<commit_before>use std::string::FromUtf8Error;
use rustc_serialize::base64::FromBase64Error;
use rustc_serialize::json;

#[derive(Debug)]
pub enum Error {
    Format,
    Base64,
    Decode,
    Encode,
    Json,
    Parse,
    Utf8,
}

macro_rules! error_wrap {
    ($f: ty, $e: expr) => {
    impl From<$f> for Error {
        fn from(_: $f) -> Error { $e }
    }
}
}

error_wrap!(FromBase64Error, Error::Base64);
error_wrap!(json::DecoderError, Error::Decode);
error_wrap!(json::EncoderError, Error::Encode);
error_wrap!(json::ErrorCode, Error::Json);
error_wrap!(json::ParserError, Error::Parse);
error_wrap!(FromUtf8Error, Error::Utf8);
<commit_msg>Wrap external errors in Error type<commit_after>use std::string::FromUtf8Error;
use rustc_serialize::base64::FromBase64Error;
use rustc_serialize::json;

#[derive(Debug)]
pub enum Error {
    Format,
    Base64(FromBase64Error),
    Decode(json::DecoderError),
    Encode(json::EncoderError),
    Json(json::ErrorCode),
    Parse(json::ParserError),
    Utf8(FromUtf8Error),
}

macro_rules! error_wrap {
    ($f: ty, $e: expr) => {
        impl From<$f> for Error {
            fn from(f: $f) -> Error { $e(f) }
        }
    }
}

error_wrap!(FromBase64Error, Error::Base64);
error_wrap!(json::DecoderError, Error::Decode);
error_wrap!(json::EncoderError, Error::Encode);
error_wrap!(json::ErrorCode, Error::Json);
error_wrap!(json::ParserError, Error::Parse);
error_wrap!(FromUtf8Error, Error::Utf8);
<|endoftext|>


<commit_before>use core::fmt;

/// A unified error type for anything returned by a method in the time crate.
///
/// This can be used when you either don't know or don't care about the exact
/// error returned. `Result<_, time::Error>` will work in these situations.
#[allow(clippy::missing_docs_in_private_items)] // variants only
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
    ConversionRange(ConversionRangeError),
    ComponentRange(ComponentRangeError),
}

impl fmt::Display for Error {
    #[inline(always)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::ConversionRange(e) => e.fmt(f),
            Self::ComponentRange(e) => e.fmt(f),
        }
    }
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}

/// An error type indicating that a conversion failed because the target type
/// could not store the initial value.
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ConversionRangeError;

impl fmt::Display for ConversionRangeError {
    #[inline(always)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("Source value is out of range for the target type")
    }
}

#[cfg(feature = "std")]
impl std::error::Error for ConversionRangeError {}

impl From<ConversionRangeError> for Error {
    #[inline(always)]
    fn from(original: ConversionRangeError) -> Self {
        Self::ConversionRange(original)
    }
}

/// An error type indicating that a component provided to a method was out of
/// range, causing a failure.
#[allow(missing_copy_implementations)] // Non-copy fields may be added.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ComponentRangeError;

impl fmt::Display for ComponentRangeError {
    #[inline(always)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("A component's value is out of range")
    }
}

impl From<ComponentRangeError> for Error {
    #[inline(always)]
    fn from(original: ComponentRangeError) -> Self {
        Self::ComponentRange(original)
    }
}

#[cfg(feature = "std")]
impl std::error::Error for ComponentRangeError {}
<commit_msg>Add `ParseError` to `Error` enum<commit_after>use crate::format::ParseError;
use core::fmt;

/// A unified error type for anything returned by a method in the time crate.
///
/// This can be used when you either don't know or don't care about the exact
/// error returned. `Result<_, time::Error>` will work in these situations.
#[allow(clippy::missing_docs_in_private_items)] // variants only
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
    ConversionRange(ConversionRangeError),
    ComponentRange(ComponentRangeError),
    Parse(ParseError),
}

impl fmt::Display for Error {
    #[inline(always)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::ConversionRange(e) => e.fmt(f),
            Self::ComponentRange(e) => e.fmt(f),
            Self::Parse(e) => e.fmt(f),
        }
    }
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}

/// An error type indicating that a conversion failed because the target type
/// could not store the initial value.
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ConversionRangeError;

impl fmt::Display for ConversionRangeError {
    #[inline(always)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("Source value is out of range for the target type")
    }
}

#[cfg(feature = "std")]
impl std::error::Error for ConversionRangeError {}

impl From<ConversionRangeError> for Error {
    #[inline(always)]
    fn from(original: ConversionRangeError) -> Self {
        Self::ConversionRange(original)
    }
}

/// An error type indicating that a component provided to a method was out of
/// range, causing a failure.
#[allow(missing_copy_implementations)] // Non-copy fields may be added.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ComponentRangeError;

impl fmt::Display for ComponentRangeError {
    #[inline(always)]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("A component's value is out of range")
    }
}

impl From<ComponentRangeError> for Error {
    #[inline(always)]
    fn from(original: ComponentRangeError) -> Self {
        Self::ComponentRange(original)
    }
}

#[cfg(feature = "std")]
impl std::error::Error for ComponentRangeError {}

impl From<ParseError> for Error {
    #[inline(always)]
    fn from(original: ParseError) -> Self {
        Self::Parse(original)
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::fmt;
use std::error;
use failure::{Failure, MaybeFailure};
use fibers::sync::oneshot::MonitorError;

#[derive(Debug)]
pub enum Error {
    Timeout,
    Full,
    NotStunMessage(String),
    Unsupported(String),
    Failed(Failure),
}
impl Error {
    pub fn failed<E>(error: E) -> Self
        where E: Into<Box<error::Error + Send + Sync>>
    {
        Error::from(Failure::new(error))
    }
    pub fn unsupported<T: Into<String>>(message: T) -> Self {
        Error::Unsupported(message.into())
    }
}
impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Timeout => write!(f, "Timeout"),
            Error::Full => write!(f, "Over capacity"),
            Error::NotStunMessage(ref s) => write!(f, "Not STUN message: {}", s),
            Error::Unsupported(ref s) => write!(f, "Unsupported feature: {}", s),
            Error::Failed(ref failure) => write!(f, "{}", failure),
        }
    }
}
impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Timeout => "Timeout",
            Error::Full => "Over capacity",
            Error::NotStunMessage(_) => "Not STUN message",
            Error::Unsupported(_) => "Unsupported feature",
            Error::Failed(_) => "Failed",
        }
    }
    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Failed(ref e) => e.cause(),
            _ => None,
        }
    }
}
impl From<Failure> for Error {
    fn from(f: Failure) -> Self {
        Error::Failed(f)
    }
}
impl From<io::Error> for Error {
    fn from(f: io::Error) -> Self {
        Error::Failed(Failure::new(f))
    }
}
impl From<MonitorError<Error>> for Error {
    fn from(f: MonitorError<Error>) -> Self {
        f.unwrap_or_else(|| Error::failed("Monitor channel disconnected"))
    }
}
impl MaybeFailure for Error {
    fn try_as_failure_mut(&mut self) -> Option<&mut Failure> {
        if let Error::Failed(ref mut f) = *self {
            Some(f)
        } else {
            None
        }
    }
    fn try_into_failure(self) -> Result<Failure, Self> {
        if let Error::Failed(f) = self {
            Ok(f)
        } else {
            Err(self)
        }
    }
}
<commit_msg>Add Error::Other field<commit_after>use std::io;
use std::fmt;
use std::error;
use std::any::Any;
use failure::{Failure, MaybeFailure};
use fibers::sync::oneshot::MonitorError;

pub enum Error {
    Timeout,
    Full,
    NotStunMessage(String),
    Unsupported(String),
    Other(String, Box<Any + Send + Sync>),
    Failed(Failure),
}
impl Error {
    pub fn failed<E>(error: E) -> Self
        where E: Into<Box<error::Error + Send + Sync>>
    {
        Error::from(Failure::new(error))
    }
    pub fn unsupported<T: Into<String>>(message: T) -> Self {
        Error::Unsupported(message.into())
    }
    pub fn other<E>(other: E) -> Self
        where E: fmt::Display + Any + Send + Sync
    {
        Error::Other(other.to_string(), Box::new(other))
    }
    pub fn get<T: Any>(&self) -> Option<&T> {
        use std::ops::Deref;
        if let Error::Other(_, ref e) = *self {
            let e: &Any = e.deref();
            e.downcast_ref()
        } else {
            None
        }
    }
}
impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Timeout => write!(f, "Timeout"),
            Error::Full => write!(f, "Full"),
            Error::NotStunMessage(ref s) => write!(f, "NotStunMessage({:?})", s),
            Error::Unsupported(ref s) => write!(f, "Unsupported({:?})", s),
            Error::Other(ref e, _) => write!(f, "Other({:?}, _)", e),
            Error::Failed(ref failure) => write!(f, "Failed({:?})", failure),
        }
    }
}
impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Timeout => write!(f, "Timeout"),
            Error::Full => write!(f, "Over capacity"),
            Error::NotStunMessage(ref s) => write!(f, "Not STUN message: {}", s),
            Error::Unsupported(ref s) => write!(f, "Unsupported feature: {}", s),
            Error::Other(ref e, _) => write!(f, "{}", e),
            Error::Failed(ref failure) => write!(f, "{}", failure),
        }
    }
}
impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Timeout => "Timeout",
            Error::Full => "Over capacity",
            Error::NotStunMessage(_) => "Not STUN message",
            Error::Unsupported(_) => "Unsupported feature",
            Error::Other(ref e, _) => e,
            Error::Failed(_) => "Failed",
        }
    }
    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Failed(ref e) => e.cause(),
            _ => None,
        }
    }
}
impl From<Failure> for Error {
    fn from(f: Failure) -> Self {
        Error::Failed(f)
    }
}
impl From<io::Error> for Error {
    fn from(f: io::Error) -> Self {
        Error::Failed(Failure::new(f))
    }
}
impl From<MonitorError<Error>> for Error {
    fn from(f: MonitorError<Error>) -> Self {
        f.unwrap_or_else(|| Error::failed("Monitor channel disconnected"))
    }
}
impl MaybeFailure for Error {
    fn try_as_failure_mut(&mut self) -> Option<&mut Failure> {
        if let Error::Failed(ref mut f) = *self {
            Some(f)
        } else {
            None
        }
    }
    fn try_into_failure(self) -> Result<Failure, Self> {
        if let Error::Failed(f) = self {
            Ok(f)
        } else {
            Err(self)
        }
    }
}

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

    #[test]
    fn downcast_works() {
        use std::io;
        let inner = io::Error::new(io::ErrorKind::Other, "other");
        let e = Error::other(inner);
        assert!(e.get::<io::Error>().is_some());
    }
}
<|endoftext|>


<commit_before>use {Arg, Client, Connection, IntoArg, Result};
use ql2::proto::{Term, Term_AssocPair as TermPair};
use serde_json::value::Value;
use types::FromJson;

impl IntoArg for Arg {
    fn into_arg(self) -> Arg {
        self
    }
}

impl IntoArg for Client {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.query,
            term: self.term,
            pool: None,
        }
    }
}

impl IntoArg for Term {
    fn into_arg(self) -> Arg {
        Arg {
            string: String::new(),
            term: Ok(self),
            pool: None,
        }
    }
}

impl IntoArg for String {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!(r#""{}""#, self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for char {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!("'{}'", self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl<'a> IntoArg for &'a String {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!(r#""{}""#, self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl<'a> IntoArg for &'a str {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!(r#""{}""#, self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for f32 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for i32 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for u32 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for f64 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for i64 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for u64 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for bool {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for Value {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for Connection {
    fn into_arg(self) -> Arg {
        Arg {
            string: String::from("conn"),
            term: Ok(Term::new()),
            pool: Some(self),
        }
    }
}

impl Arg {
    /// Create a new command argument
    ///
    /// This is the return type of the `IntoArg` trait. You need to
    /// use `Arg::new` to create an argument when implementing that
    /// trait for any additional types that you want to pass to ReQL
    /// commands.
    ///
    /// ReQL commands are represented as `term`s so you must first
    /// convert your argument to a term and pass it as `term` to this method.
    /// For debugging and logging purposes, this method also requires that you
    /// pass the string representation of your argument i.e. `as_str`.
    pub fn new() -> Arg {
        Arg {
            string: String::new(),
            term: Ok(Term::new()),
            pool: None,
        }
    }

    #[doc(hidden)]
    pub fn set_string(&mut self, string: &str) {
        self.string = string.into();
    }

    #[doc(hidden)]
    pub fn set_term(&mut self, term: Result<Term>) {
        self.term = term;
    }

    #[doc(hidden)]
    pub fn add_arg(&mut self, arg: Arg) {
        if let Some(pool) = arg.pool {
            self.pool = Some(pool);
        }
        let mut error = None;
        if let Ok(ref mut term) = self.term {
            match arg.term {
                Ok(aterm) => term.mut_args().push(aterm),
                Err(e) => {
                    error = Some(e);
                }
            }
        }
        if let Some(e) = error {
            self.term = Err(e);
        }
    }

    #[doc(hidden)]
    pub fn add_opt(&mut self, temp_pair: TermPair) {
        if let Ok(ref mut term) = self.term {
            term.mut_optargs().push(temp_pair);
        }
    }

    #[doc(hidden)]
    pub fn create_term_pair<T: ::IntoArg>(key: &str, val: T) -> Result<TermPair> {
        let mut temp = Term::new();
        temp.mut_args().push(val.into_arg().term?);
        let mut temp_pair = TermPair::new();
        temp_pair.set_key(key.into());
        temp_pair.set_val(temp);
        Ok(temp_pair)
    }
}
<commit_msg>impl IntoArg for &Client<commit_after>use {Arg, Client, Connection, IntoArg, Result};
use ql2::proto::{Term, Term_AssocPair as TermPair};
use serde_json::value::Value;
use types::FromJson;

impl IntoArg for Arg {
    fn into_arg(self) -> Arg {
        self
    }
}

impl IntoArg for Client {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.query,
            term: self.term,
            pool: None,
        }
    }
}

impl<'a> IntoArg for &'a Client {
    fn into_arg(self) -> Arg {
        self.clone().into_arg()
    }
}

impl IntoArg for Term {
    fn into_arg(self) -> Arg {
        Arg {
            string: String::new(),
            term: Ok(self),
            pool: None,
        }
    }
}

impl IntoArg for String {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!(r#""{}""#, self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for char {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!("'{}'", self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl<'a> IntoArg for &'a String {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!(r#""{}""#, self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl<'a> IntoArg for &'a str {
    fn into_arg(self) -> Arg {
        Arg {
            string: format!(r#""{}""#, self),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for f32 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for i32 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for u32 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for f64 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for i64 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for u64 {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for bool {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for Value {
    fn into_arg(self) -> Arg {
        Arg {
            string: self.to_string(),
            term: Term::from_json(self),
            pool: None,
        }
    }
}

impl IntoArg for Connection {
    fn into_arg(self) -> Arg {
        Arg {
            string: String::from("conn"),
            term: Ok(Term::new()),
            pool: Some(self),
        }
    }
}

impl Arg {
    /// Create a new command argument
    ///
    /// This is the return type of the `IntoArg` trait. You need to
    /// use `Arg::new` to create an argument when implementing that
    /// trait for any additional types that you want to pass to ReQL
    /// commands.
    ///
    /// ReQL commands are represented as `term`s so you must first
    /// convert your argument to a term and pass it as `term` to this method.
    /// For debugging and logging purposes, this method also requires that you
    /// pass the string representation of your argument i.e. `as_str`.
    pub fn new() -> Arg {
        Arg {
            string: String::new(),
            term: Ok(Term::new()),
            pool: None,
        }
    }

    #[doc(hidden)]
    pub fn set_string(&mut self, string: &str) {
        self.string = string.into();
    }

    #[doc(hidden)]
    pub fn set_term(&mut self, term: Result<Term>) {
        self.term = term;
    }

    #[doc(hidden)]
    pub fn add_arg(&mut self, arg: Arg) {
        if let Some(pool) = arg.pool {
            self.pool = Some(pool);
        }
        let mut error = None;
        if let Ok(ref mut term) = self.term {
            match arg.term {
                Ok(aterm) => term.mut_args().push(aterm),
                Err(e) => {
                    error = Some(e);
                }
            }
        }
        if let Some(e) = error {
            self.term = Err(e);
        }
    }

    #[doc(hidden)]
    pub fn add_opt(&mut self, temp_pair: TermPair) {
        if let Ok(ref mut term) = self.term {
            term.mut_optargs().push(temp_pair);
        }
    }

    #[doc(hidden)]
    pub fn create_term_pair<T: ::IntoArg>(key: &str, val: T) -> Result<TermPair> {
        let mut temp = Term::new();
        temp.mut_args().push(val.into_arg().term?);
        let mut temp_pair = TermPair::new();
        temp_pair.set_key(key.into());
        temp_pair.set_val(temp);
        Ok(temp_pair)
    }
}
<|endoftext|>


<commit_before>mod keyboard;
mod mouse;
mod state;

pub use self::keyboard::{Keyboard, KeyboardState};
pub use self::mouse::{Mouse, MousePosition, MouseProximity, MouseState};
pub use self::state::{Element, Input, InputState, InputDifference, InputTransition, State};

pub use event::{MouseButton, VirtualKeyCode};

#[cfg(test)]
mod tests {
    use super::*;
}
<commit_msg>Remove re-exports of internal traits.<commit_after>mod keyboard;
mod mouse;
mod state;

pub use self::keyboard::{Keyboard, KeyboardState};
pub use self::mouse::{Mouse, MousePosition, MouseProximity, MouseState};
pub use self::state::{Input, InputState, InputDifference, InputTransition};

pub use event::{MouseButton, VirtualKeyCode};

#[cfg(test)]
mod tests {
    use super::*;
}
<|endoftext|>


<commit_before><commit_msg>Impl draw 3d<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2017 Jason White
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::collections::BTreeMap;
use std::fmt;
use std::io::Write as IoWrite;
use std::io::{self, Read};
use std::path::{Path, PathBuf};

use tempfile;

use crate::error::Error;

use super::traits::Task;
use crate::detect::Detected;

use crate::util::{progress_dummy, Arguments, Process, Retry};

/// A task to create a directory.
#[derive(
    Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq, Hash, Clone,
)]
pub struct BatchScript {
    /// Contents of the batch script. This is first written to a temporary file
    /// and then executed.
    contents: String,

    /// Optional working directory to spawn the process in. If `None`, uses the
    /// working directory of the parent process (i.e., the build process).
    cwd: Option<PathBuf>,

    /// Optional environment variables.
    env: Option<BTreeMap<String, String>>,

    /// String to display when executing the task.
    display: Option<String>,

    /// Turn echo off
    #[serde(default)]
    quiet: bool,

    /// Retry settings.
    retry: Option<Retry>,
}

impl BatchScript {
    fn execute_impl(
        &self,
        root: &Path,
        log: &mut dyn io::Write,
    ) -> Result<Detected, Error> {
        // Write the script contents to a temporary file for execution. This
        // temporary file must outlive the spawned process.
        let temppath = {
            let mut tmp = tempfile::Builder::new().suffix(".bat").tempfile()?;
            tmp.as_file_mut().write_all(self.contents.as_bytes())?;
            tmp.into_temp_path()
        };

        let mut args = Arguments::new();

        if self.quiet {
            args.push("/Q".into());
        }

        args.push("/c".into());
        args.push("call".into());
        args.push(temppath.to_str().unwrap().into());

        let mut process = Process::new(PathBuf::from("cmd.exe"), args);
        process.env = self.env.clone();

        let (mut reader, child) = process.spawn(root)?;

        let mut buf = [0u8; 4096];
        loop {
            let n = reader.read(&mut buf)?;
            if n == 0 {
                break;
            }

            log.write_all(&buf[0..n])?;
        }

        child.wait()?;

        // Don't do dependency detection for now. We may want to use generic
        // dependency detection in this case.
        Ok(Detected::new())
    }
}

impl fmt::Display for BatchScript {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.display {
            Some(ref display) => write!(f, "batch script: {}", display),
            None => write!(f, "batch script"),
        }
    }
}

impl fmt::Debug for BatchScript {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self)
    }
}

impl Task for BatchScript {
    fn execute(
        &self,
        root: &Path,
        log: &mut dyn io::Write,
    ) -> Result<Detected, Error> {
        if let Some(ref retry) = self.retry {
            retry.call(|| self.execute_impl(root, log), progress_dummy)
        } else {
            self.execute_impl(root, log)
        }
    }
}
<commit_msg>Fix cwd field not working on batch script task<commit_after>// Copyright (c) 2017 Jason White
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::collections::BTreeMap;
use std::fmt;
use std::io::Write as IoWrite;
use std::io::{self, Read};
use std::path::{Path, PathBuf};

use tempfile;

use crate::error::Error;

use super::traits::Task;
use crate::detect::Detected;

use crate::util::{progress_dummy, Arguments, Process, Retry};

/// A task to create a directory.
#[derive(
    Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq, Hash, Clone,
)]
pub struct BatchScript {
    /// Contents of the batch script. This is first written to a temporary file
    /// and then executed.
    contents: String,

    /// Optional working directory to spawn the process in. If `None`, uses the
    /// working directory of the parent process (i.e., the build process).
    cwd: Option<PathBuf>,

    /// Optional environment variables.
    env: Option<BTreeMap<String, String>>,

    /// String to display when executing the task.
    display: Option<String>,

    /// Turn echo off
    #[serde(default)]
    quiet: bool,

    /// Retry settings.
    retry: Option<Retry>,
}

impl BatchScript {
    fn execute_impl(
        &self,
        root: &Path,
        log: &mut dyn io::Write,
    ) -> Result<Detected, Error> {
        // Write the script contents to a temporary file for execution. This
        // temporary file must outlive the spawned process.
        let temppath = {
            let mut tmp = tempfile::Builder::new().suffix(".bat").tempfile()?;
            tmp.as_file_mut().write_all(self.contents.as_bytes())?;
            tmp.into_temp_path()
        };

        let mut args = Arguments::new();

        if self.quiet {
            args.push("/Q".into());
        }

        args.push("/c".into());
        args.push("call".into());
        args.push(temppath.to_str().unwrap().into());

        let mut process = Process::new(PathBuf::from("cmd.exe"), args);
        process.env = self.env.clone();
        process.cwd = self.cwd.clone();

        let (mut reader, child) = process.spawn(root)?;

        let mut buf = [0u8; 4096];
        loop {
            let n = reader.read(&mut buf)?;
            if n == 0 {
                break;
            }

            log.write_all(&buf[0..n])?;
        }

        child.wait()?;

        // Don't do dependency detection for now. We may want to use generic
        // dependency detection in this case.
        Ok(Detected::new())
    }
}

impl fmt::Display for BatchScript {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.display {
            Some(ref display) => write!(f, "batch script: {}", display),
            None => write!(f, "batch script"),
        }
    }
}

impl fmt::Debug for BatchScript {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self)
    }
}

impl Task for BatchScript {
    fn execute(
        &self,
        root: &Path,
        log: &mut dyn io::Write,
    ) -> Result<Detected, Error> {
        if let Some(ref retry) = self.retry {
            retry.call(|| self.execute_impl(root, log), progress_dummy)
        } else {
            self.execute_impl(root, log)
        }
    }
}
<|endoftext|>


<commit_before>
fn main() {
    let mut vec = vec![0];
    for x in 0..1000 {
        if x % 3 == 0 {
            vec.push(x);
        } else if x % 5 == 0 {
            vec.push(x);
        }
    }
    let vecsum: u32 = vec.iter().sum();
    println!("The sum of all multiples of 3 and 5 below 1000 equals to {}", vecsum);
}
<commit_msg>fixed code style<commit_after>fn main() {
    let mut vec = vec![0];

    for x in 0..1000 {
        if x % 3 == 0 {
            vec.push(x);
        } else if x % 5 == 0 {
            vec.push(x);
        }
    }

    let vecsum: u32 = vec.iter().sum();
    println!("The sum of all multiples of 3 and 5 below 1000 equals to {}", vecsum);
}
<|endoftext|>


<commit_before>use crate::errors::*;
use crate::registry::{registry_path, registry_url};
use crate::{Dependency, Manifest};
use env_proxy;
use git2::Repository;
use regex::Regex;
use reqwest;
use semver;
use std::env;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::time::Duration;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

#[derive(Deserialize)]
struct CrateVersion {
    name: String,
    #[serde(rename = "vers")]
    version: semver::Version,
    yanked: bool,
}

/// Query latest version from a registry index
///
/// The latest version will be returned as a `Dependency`. This will fail, when
///
/// - there is no Internet connection and offline is false.
/// - summaries in registry index with an incorrect format.
/// - a crate with the given name does not exist on crates.io.
pub fn get_latest_dependency(
    crate_name: &str,
    flag_allow_prerelease: bool,
    manifest_path: &Path,
) -> Result<Dependency> {
    if env::var("CARGO_IS_TEST").is_ok() {
        // We are in a simulated reality. Nothing is real here.
        // FIXME: Use actual test handling code.
        let new_version = if flag_allow_prerelease {
            format!("{}--PRERELEASE_VERSION_TEST", crate_name)
        } else {
            format!("{}--CURRENT_VERSION_TEST", crate_name)
        };

        return Ok(Dependency::new(crate_name).set_version(&new_version));
    }
    if crate_name.is_empty() {
        return Err(ErrorKind::EmptyCrateName.into());
    }

    let registry_path = registry_path(manifest_path)?;
    let crate_versions = fuzzy_query_registry_index(crate_name, &registry_path)?;

    let dep = read_latest_version(&crate_versions, flag_allow_prerelease)?;

    if dep.name != crate_name {
        println!("WARN: Added `{}` instead of `{}`", dep.name, crate_name);
    }

    Ok(dep)
}

// Checks whether a version object is a stable release
fn version_is_stable(version: &CrateVersion) -> bool {
    !version.version.is_prerelease()
}

/// Read latest version from Versions structure
///
/// Assumes the version are sorted so that the first non-yanked version is the
/// latest, and thus the one we want.
fn read_latest_version(
    versions: &[CrateVersion],
    flag_allow_prerelease: bool,
) -> Result<Dependency> {
    let latest = versions
        .iter()
        .filter(|&v| flag_allow_prerelease || version_is_stable(v))
        .filter(|&v| !v.yanked)
        .max_by_key(|&v| v.version.clone())
        .ok_or(ErrorKind::NoVersionsAvailable)?;

    let name = &latest.name;
    let version = latest.version.to_string();
    Ok(Dependency::new(name).set_version(&version))
}

/// update registry index for given project
pub fn update_registry_index(manifest_path: &Path) -> Result<()> {
    let registry_path = registry_path(manifest_path)?;
    let registry_url = registry_url(manifest_path)?;

    let repo = git2::Repository::open(&registry_path)?;
    let colorchoice = if atty::is(atty::Stream::Stdout) {
        ColorChoice::Auto
    } else {
        ColorChoice::Never
    };
    let mut output = StandardStream::stdout(colorchoice);
    output.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
    write!(output, "{:>12}", "Updating")?;
    output.reset()?;
    writeln!(output, " '{}' index", registry_url)?;

    repo.remote_anonymous(registry_url.as_str())?.fetch(
        &["refs/heads/master:refs/remotes/origin/master"],
        None,
        None,
    )?;

    Ok(())
}

#[test]
fn get_latest_stable_version_from_json() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "foo",
          "vers": "0.6.0-alpha",
          "yanked": false
        },
        {
          "name": "foo",
          "vers": "0.5.0",
          "yanked": false
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert_eq!(
        read_latest_version(&versions, false)
            .unwrap()
            .version()
            .unwrap(),
        "0.5.0"
    );
}

#[test]
fn get_latest_unstable_or_stable_version_from_json() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "foo",
          "vers": "0.6.0-alpha",
          "yanked": false
        },
        {
          "name": "foo",
          "vers": "0.5.0",
          "yanked": false
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert_eq!(
        read_latest_version(&versions, true)
            .unwrap()
            .version()
            .unwrap(),
        "0.6.0-alpha"
    );
}

#[test]
fn get_latest_version_from_json_test() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "treexml",
          "vers": "0.3.1",
          "yanked": true
        },
        {
          "name": "treexml",
          "vers": "0.3.0",
          "yanked": false
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert_eq!(
        read_latest_version(&versions, false)
            .unwrap()
            .version()
            .unwrap(),
        "0.3.0"
    );
}

#[test]
fn get_no_latest_version_from_json_when_all_are_yanked() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "treexml",
          "vers": "0.3.1",
          "yanked": true
        },
        {
          "name": "treexml",
          "vers": "0.3.0",
          "yanked": true
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert!(read_latest_version(&versions, false).is_err());
}

/// Fuzzy query crate from registry index
fn fuzzy_query_registry_index(
    crate_name: impl Into<String>,
    registry_path: impl AsRef<Path>,
) -> Result<Vec<CrateVersion>> {
    let crate_name = crate_name.into();
    let repo = Repository::open(registry_path)?;
    let tree = repo
        .find_reference("refs/remotes/origin/master")?
        .peel_to_tree()?;

    let mut found_crate = false;
    let mut result = vec![];

    let names = gen_fuzzy_crate_names(crate_name.clone())?;
    for the_name in names {
        let file = match tree.get_path(&PathBuf::from(summary_raw_path(&the_name))) {
            Ok(x) => x.to_object(&repo)?.peel_to_blob()?,
            Err(_) => continue,
        };
        found_crate = true;
        let content = String::from_utf8(file.content().to_vec())
            .map_err(|_| ErrorKind::InvalidSummaryJson)?;
        for line in content.lines() {
            result.push(
                serde_json::from_str::<CrateVersion>(line)
                    .map_err(|_| ErrorKind::InvalidSummaryJson)?,
            );
        }
    }
    if !found_crate {
        return Err(ErrorKind::NoCrate(crate_name).into());
    }

    Ok(result)
}

fn get_crate_name_from_repository<T>(repo: &str, matcher: &Regex, url_template: T) -> Result<String>
where
    T: Fn(&str, &str) -> String,
{
    matcher
        .captures(repo)
        .ok_or_else(|| "Unable to parse git repo URL".into())
        .and_then(|cap| match (cap.get(1), cap.get(2)) {
            (Some(user), Some(repo)) => {
                let url = url_template(user.as_str(), repo.as_str());
                let data: Result<Manifest> = get_cargo_toml_from_git_url(&url)
                    .and_then(|m| m.parse().chain_err(|| ErrorKind::ParseCargoToml));
                data.and_then(|ref manifest| get_name_from_manifest(manifest))
            }
            _ => Err("Git repo url seems incomplete".into()),
        })
}

/// Query crate name by accessing a github repo Cargo.toml
///
/// The name will be returned as a string. This will fail, when
///
/// - there is no Internet connection,
/// - Cargo.toml is not present in the root of the master branch,
/// - the response from github is an error or in an incorrect format.
pub fn get_crate_name_from_github(repo: &str) -> Result<String> {
    let re =
        Regex::new(r"^https://github.com/([-_0-9a-zA-Z]+)/([-_0-9a-zA-Z]+)(/|.git)?$").unwrap();
    get_crate_name_from_repository(repo, &re, |user, repo| {
        format!(
            "https://raw.githubusercontent.com/{user}/{repo}/master/Cargo.toml",
            user = user,
            repo = repo
        )
    })
}

/// Query crate name by accessing a gitlab repo Cargo.toml
///
/// The name will be returned as a string. This will fail, when
///
/// - there is no Internet connection,
/// - Cargo.toml is not present in the root of the master branch,
/// - the response from gitlab is an error or in an incorrect format.
pub fn get_crate_name_from_gitlab(repo: &str) -> Result<String> {
    let re =
        Regex::new(r"^https://gitlab.com/([-_0-9a-zA-Z]+)/([-_0-9a-zA-Z]+)(/|.git)?$").unwrap();
    get_crate_name_from_repository(repo, &re, |user, repo| {
        format!(
            "https://gitlab.com/{user}/{repo}/raw/master/Cargo.toml",
            user = user,
            repo = repo
        )
    })
}

/// Query crate name by accessing Cargo.toml in a local path
///
/// The name will be returned as a string. This will fail, when
/// Cargo.toml is not present in the root of the path.
pub fn get_crate_name_from_path(path: &str) -> Result<String> {
    let cargo_file = Path::new(path).join("Cargo.toml");
    Manifest::open(&Some(cargo_file))
        .chain_err(|| "Unable to open local Cargo.toml")
        .and_then(|ref manifest| get_name_from_manifest(manifest))
}

fn get_name_from_manifest(manifest: &Manifest) -> Result<String> {
    manifest
        .data
        .as_table()
        .get("package")
        .and_then(|m| m["name"].as_str().map(std::string::ToString::to_string))
        .ok_or_else(|| ErrorKind::ParseCargoToml.into())
}

const fn get_default_timeout() -> Duration {
    Duration::from_secs(10)
}

fn get_with_timeout(url: &str, timeout: Duration) -> reqwest::Result<reqwest::Response> {
    let client = reqwest::ClientBuilder::new()
        .timeout(timeout)
        .proxy(reqwest::Proxy::custom(|url| {
            env_proxy::for_url(url).to_url()
        }))
        .build()?;

    client
        .get(url)
        .send()
        .and_then(reqwest::Response::error_for_status)
}

fn get_cargo_toml_from_git_url(url: &str) -> Result<String> {
    let mut res = get_with_timeout(url, get_default_timeout())
        .chain_err(|| "Failed to fetch crate from git")?;
    let mut body = String::new();
    res.read_to_string(&mut body)
        .chain_err(|| "Git response not a valid `String`")?;
    Ok(body)
}

/// Generate all similar crate names
///
/// Examples:
///
/// | input | output |
/// | ----- | ------ |
/// | cargo | cargo  |
/// | cargo-edit | cargo-edit, cargo_edit |
/// | parking_lot_core | parking_lot_core, parking_lot-core, parking-lot_core, parking-lot-core |
fn gen_fuzzy_crate_names(crate_name: String) -> Result<Vec<String>> {
    const PATTERN: [u8; 2] = [b'-', b'_'];

    let wildcard_indexs = crate_name
        .bytes()
        .enumerate()
        .filter(|(_, item)| PATTERN.contains(item))
        .map(|(index, _)| index)
        .take(10)
        .collect::<Vec<usize>>();
    if wildcard_indexs.is_empty() {
        return Ok(vec![crate_name]);
    }

    let mut result = vec![];
    let mut bytes = crate_name.into_bytes();
    for mask in 0..2u128.pow(wildcard_indexs.len() as u32) {
        for (mask_index, wildcard_index) in wildcard_indexs.iter().enumerate() {
            let mask_value = (mask >> mask_index) & 1 == 1;
            if mask_value {
                bytes[*wildcard_index] = b'-';
            } else {
                bytes[*wildcard_index] = b'_';
            }
        }
        result.push(String::from_utf8(bytes.clone()).unwrap());
    }
    Ok(result)
}

#[test]
fn test_gen_fuzzy_crate_names() {
    fn test_helper(input: &str, expect: &[&str]) {
        let mut actual = gen_fuzzy_crate_names(input.to_string()).unwrap();
        actual.sort();

        let mut expect = expect.iter().map(|x| x.to_string()).collect::<Vec<_>>();
        expect.sort();

        assert_eq!(actual, expect);
    }

    test_helper("", &[""]);
    test_helper("-", &["_", "-"]);
    test_helper("DCjanus", &["DCjanus"]);
    test_helper("DC-janus", &["DC-janus", "DC_janus"]);
    test_helper(
        "DC-_janus",
        &["DC__janus", "DC_-janus", "DC-_janus", "DC--janus"],
    );
}

fn summary_raw_path(crate_name: &str) -> String {
    match crate_name.len() {
        0 => unreachable!("we check that crate_name is not empty here"),
        1 => format!("1/{}", crate_name),
        2 => format!("2/{}", crate_name),
        3 => format!("3/{}/{}", &crate_name[..1], crate_name),
        _ => format!("{}/{}/{}", &crate_name[..2], &crate_name[2..4], crate_name),
    }
}

#[test]
fn test_summary_raw_path() {
    assert_eq!(summary_raw_path("a"), "1/a");
    assert_eq!(summary_raw_path("ab"), "2/ab");
    assert_eq!(summary_raw_path("abc"), "3/a/abc");
    assert_eq!(summary_raw_path("abcd"), "ab/cd/abcd");
    assert_eq!(summary_raw_path("abcdefg"), "ab/cd/abcdefg");
}
<commit_msg>fix: fuzzy match origin crate first<commit_after>use crate::errors::*;
use crate::registry::{registry_path, registry_url};
use crate::{Dependency, Manifest};
use env_proxy;
use git2::Repository;
use regex::Regex;
use reqwest;
use semver;
use std::env;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::time::Duration;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

#[derive(Deserialize)]
struct CrateVersion {
    name: String,
    #[serde(rename = "vers")]
    version: semver::Version,
    yanked: bool,
}

/// Query latest version from a registry index
///
/// The latest version will be returned as a `Dependency`. This will fail, when
///
/// - there is no Internet connection and offline is false.
/// - summaries in registry index with an incorrect format.
/// - a crate with the given name does not exist on crates.io.
pub fn get_latest_dependency(
    crate_name: &str,
    flag_allow_prerelease: bool,
    manifest_path: &Path,
) -> Result<Dependency> {
    if env::var("CARGO_IS_TEST").is_ok() {
        // We are in a simulated reality. Nothing is real here.
        // FIXME: Use actual test handling code.
        let new_version = if flag_allow_prerelease {
            format!("{}--PRERELEASE_VERSION_TEST", crate_name)
        } else {
            format!("{}--CURRENT_VERSION_TEST", crate_name)
        };

        return Ok(Dependency::new(crate_name).set_version(&new_version));
    }
    if crate_name.is_empty() {
        return Err(ErrorKind::EmptyCrateName.into());
    }

    let registry_path = registry_path(manifest_path)?;
    let crate_versions = fuzzy_query_registry_index(crate_name, &registry_path)?;

    let dep = read_latest_version(&crate_versions, flag_allow_prerelease)?;

    if dep.name != crate_name {
        println!("WARN: Added `{}` instead of `{}`", dep.name, crate_name);
    }

    Ok(dep)
}

// Checks whether a version object is a stable release
fn version_is_stable(version: &CrateVersion) -> bool {
    !version.version.is_prerelease()
}

/// Read latest version from Versions structure
fn read_latest_version(
    versions: &[CrateVersion],
    flag_allow_prerelease: bool,
) -> Result<Dependency> {
    let latest = versions
        .iter()
        .filter(|&v| flag_allow_prerelease || version_is_stable(v))
        .filter(|&v| !v.yanked)
        .max_by_key(|&v| v.version.clone())
        .ok_or(ErrorKind::NoVersionsAvailable)?;

    let name = &latest.name;
    let version = latest.version.to_string();
    Ok(Dependency::new(name).set_version(&version))
}

/// update registry index for given project
pub fn update_registry_index(manifest_path: &Path) -> Result<()> {
    let registry_path = registry_path(manifest_path)?;
    let registry_url = registry_url(manifest_path)?;

    let repo = git2::Repository::open(&registry_path)?;
    let colorchoice = if atty::is(atty::Stream::Stdout) {
        ColorChoice::Auto
    } else {
        ColorChoice::Never
    };
    let mut output = StandardStream::stdout(colorchoice);
    output.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
    write!(output, "{:>12}", "Updating")?;
    output.reset()?;
    writeln!(output, " '{}' index", registry_url)?;

    repo.remote_anonymous(registry_url.as_str())?.fetch(
        &["refs/heads/master:refs/remotes/origin/master"],
        None,
        None,
    )?;

    Ok(())
}

#[test]
fn get_latest_stable_version_from_json() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "foo",
          "vers": "0.6.0-alpha",
          "yanked": false
        },
        {
          "name": "foo",
          "vers": "0.5.0",
          "yanked": false
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert_eq!(
        read_latest_version(&versions, false)
            .unwrap()
            .version()
            .unwrap(),
        "0.5.0"
    );
}

#[test]
fn get_latest_unstable_or_stable_version_from_json() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "foo",
          "vers": "0.6.0-alpha",
          "yanked": false
        },
        {
          "name": "foo",
          "vers": "0.5.0",
          "yanked": false
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert_eq!(
        read_latest_version(&versions, true)
            .unwrap()
            .version()
            .unwrap(),
        "0.6.0-alpha"
    );
}

#[test]
fn get_latest_version_from_json_test() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "treexml",
          "vers": "0.3.1",
          "yanked": true
        },
        {
          "name": "treexml",
          "vers": "0.3.0",
          "yanked": false
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert_eq!(
        read_latest_version(&versions, false)
            .unwrap()
            .version()
            .unwrap(),
        "0.3.0"
    );
}

#[test]
fn get_no_latest_version_from_json_when_all_are_yanked() {
    let versions: Vec<CrateVersion> = serde_json::from_str(
        r#"[
        {
          "name": "treexml",
          "vers": "0.3.1",
          "yanked": true
        },
        {
          "name": "treexml",
          "vers": "0.3.0",
          "yanked": true
        }
      ]"#,
    )
    .expect("crate version is correctly parsed");

    assert!(read_latest_version(&versions, false).is_err());
}

/// Fuzzy query crate from registry index
fn fuzzy_query_registry_index(
    crate_name: impl Into<String>,
    registry_path: impl AsRef<Path>,
) -> Result<Vec<CrateVersion>> {
    let crate_name = crate_name.into();
    let repo = Repository::open(registry_path)?;
    let tree = repo
        .find_reference("refs/remotes/origin/master")?
        .peel_to_tree()?;

    let mut names = gen_fuzzy_crate_names(crate_name.clone())?;
    if let Some(index) = names.iter().position(|x| *x == crate_name) {
        // ref: https://github.com/killercup/cargo-edit/pull/317#discussion_r307365704
        names.swap(index, 0);
    }

    for the_name in names {
        let file = match tree.get_path(&PathBuf::from(summary_raw_path(&the_name))) {
            Ok(x) => x.to_object(&repo)?.peel_to_blob()?,
            Err(_) => continue,
        };
        let content = String::from_utf8(file.content().to_vec())
            .map_err(|_| ErrorKind::InvalidSummaryJson)?;

        return content
            .lines()
            .map(|line: &str| {
                serde_json::from_str::<CrateVersion>(line)
                    .map_err(|_| ErrorKind::InvalidSummaryJson.into())
            })
            .collect::<Result<Vec<CrateVersion>>>();
    }
    Err(ErrorKind::NoCrate(crate_name).into())
}

fn get_crate_name_from_repository<T>(repo: &str, matcher: &Regex, url_template: T) -> Result<String>
where
    T: Fn(&str, &str) -> String,
{
    matcher
        .captures(repo)
        .ok_or_else(|| "Unable to parse git repo URL".into())
        .and_then(|cap| match (cap.get(1), cap.get(2)) {
            (Some(user), Some(repo)) => {
                let url = url_template(user.as_str(), repo.as_str());
                let data: Result<Manifest> = get_cargo_toml_from_git_url(&url)
                    .and_then(|m| m.parse().chain_err(|| ErrorKind::ParseCargoToml));
                data.and_then(|ref manifest| get_name_from_manifest(manifest))
            }
            _ => Err("Git repo url seems incomplete".into()),
        })
}

/// Query crate name by accessing a github repo Cargo.toml
///
/// The name will be returned as a string. This will fail, when
///
/// - there is no Internet connection,
/// - Cargo.toml is not present in the root of the master branch,
/// - the response from github is an error or in an incorrect format.
pub fn get_crate_name_from_github(repo: &str) -> Result<String> {
    let re =
        Regex::new(r"^https://github.com/([-_0-9a-zA-Z]+)/([-_0-9a-zA-Z]+)(/|.git)?$").unwrap();
    get_crate_name_from_repository(repo, &re, |user, repo| {
        format!(
            "https://raw.githubusercontent.com/{user}/{repo}/master/Cargo.toml",
            user = user,
            repo = repo
        )
    })
}

/// Query crate name by accessing a gitlab repo Cargo.toml
///
/// The name will be returned as a string. This will fail, when
///
/// - there is no Internet connection,
/// - Cargo.toml is not present in the root of the master branch,
/// - the response from gitlab is an error or in an incorrect format.
pub fn get_crate_name_from_gitlab(repo: &str) -> Result<String> {
    let re =
        Regex::new(r"^https://gitlab.com/([-_0-9a-zA-Z]+)/([-_0-9a-zA-Z]+)(/|.git)?$").unwrap();
    get_crate_name_from_repository(repo, &re, |user, repo| {
        format!(
            "https://gitlab.com/{user}/{repo}/raw/master/Cargo.toml",
            user = user,
            repo = repo
        )
    })
}

/// Query crate name by accessing Cargo.toml in a local path
///
/// The name will be returned as a string. This will fail, when
/// Cargo.toml is not present in the root of the path.
pub fn get_crate_name_from_path(path: &str) -> Result<String> {
    let cargo_file = Path::new(path).join("Cargo.toml");
    Manifest::open(&Some(cargo_file))
        .chain_err(|| "Unable to open local Cargo.toml")
        .and_then(|ref manifest| get_name_from_manifest(manifest))
}

fn get_name_from_manifest(manifest: &Manifest) -> Result<String> {
    manifest
        .data
        .as_table()
        .get("package")
        .and_then(|m| m["name"].as_str().map(std::string::ToString::to_string))
        .ok_or_else(|| ErrorKind::ParseCargoToml.into())
}

const fn get_default_timeout() -> Duration {
    Duration::from_secs(10)
}

fn get_with_timeout(url: &str, timeout: Duration) -> reqwest::Result<reqwest::Response> {
    let client = reqwest::ClientBuilder::new()
        .timeout(timeout)
        .proxy(reqwest::Proxy::custom(|url| {
            env_proxy::for_url(url).to_url()
        }))
        .build()?;

    client
        .get(url)
        .send()
        .and_then(reqwest::Response::error_for_status)
}

fn get_cargo_toml_from_git_url(url: &str) -> Result<String> {
    let mut res = get_with_timeout(url, get_default_timeout())
        .chain_err(|| "Failed to fetch crate from git")?;
    let mut body = String::new();
    res.read_to_string(&mut body)
        .chain_err(|| "Git response not a valid `String`")?;
    Ok(body)
}

/// Generate all similar crate names
///
/// Examples:
///
/// | input | output |
/// | ----- | ------ |
/// | cargo | cargo  |
/// | cargo-edit | cargo-edit, cargo_edit |
/// | parking_lot_core | parking_lot_core, parking_lot-core, parking-lot_core, parking-lot-core |
fn gen_fuzzy_crate_names(crate_name: String) -> Result<Vec<String>> {
    const PATTERN: [u8; 2] = [b'-', b'_'];

    let wildcard_indexs = crate_name
        .bytes()
        .enumerate()
        .filter(|(_, item)| PATTERN.contains(item))
        .map(|(index, _)| index)
        .take(10)
        .collect::<Vec<usize>>();
    if wildcard_indexs.is_empty() {
        return Ok(vec![crate_name]);
    }

    let mut result = vec![];
    let mut bytes = crate_name.into_bytes();
    for mask in 0..2u128.pow(wildcard_indexs.len() as u32) {
        for (mask_index, wildcard_index) in wildcard_indexs.iter().enumerate() {
            let mask_value = (mask >> mask_index) & 1 == 1;
            if mask_value {
                bytes[*wildcard_index] = b'-';
            } else {
                bytes[*wildcard_index] = b'_';
            }
        }
        result.push(String::from_utf8(bytes.clone()).unwrap());
    }
    Ok(result)
}

#[test]
fn test_gen_fuzzy_crate_names() {
    fn test_helper(input: &str, expect: &[&str]) {
        let mut actual = gen_fuzzy_crate_names(input.to_string()).unwrap();
        actual.sort();

        let mut expect = expect.iter().map(|x| x.to_string()).collect::<Vec<_>>();
        expect.sort();

        assert_eq!(actual, expect);
    }

    test_helper("", &[""]);
    test_helper("-", &["_", "-"]);
    test_helper("DCjanus", &["DCjanus"]);
    test_helper("DC-janus", &["DC-janus", "DC_janus"]);
    test_helper(
        "DC-_janus",
        &["DC__janus", "DC_-janus", "DC-_janus", "DC--janus"],
    );
}

fn summary_raw_path(crate_name: &str) -> String {
    match crate_name.len() {
        0 => unreachable!("we check that crate_name is not empty here"),
        1 => format!("1/{}", crate_name),
        2 => format!("2/{}", crate_name),
        3 => format!("3/{}/{}", &crate_name[..1], crate_name),
        _ => format!("{}/{}/{}", &crate_name[..2], &crate_name[2..4], crate_name),
    }
}

#[test]
fn test_summary_raw_path() {
    assert_eq!(summary_raw_path("a"), "1/a");
    assert_eq!(summary_raw_path("ab"), "2/ab");
    assert_eq!(summary_raw_path("abc"), "3/a/abc");
    assert_eq!(summary_raw_path("abcd"), "ab/cd/abcd");
    assert_eq!(summary_raw_path("abcdefg"), "ab/cd/abcdefg");
}
<|endoftext|>


<commit_before>#![allow(dead_code, unused_variables)]
use alloc::heap::{Heap, Alloc, Layout};
use bytes::BytesMut;

use audiosample::*;
use pixel::*;
use timeinfo::*;

error_chain! {
    errors {
        InvalidIndex
    }
}

#[derive(Clone)]
pub struct VideoInfo {
    pub width: usize,
    pub height: usize,
    pub format: Box<Formaton>,
}

impl VideoInfo {
    fn size(&self, align: usize) -> usize {
        let mut size = 0;
        for &component in self.format.into_iter() {
            if let Some(c) = component {
                size += c.get_data_size(self.width, self.height, align);
            }
        }
        size
    }
}

#[derive(Clone)]
pub struct AudioInfo {
    pub samples: usize,
    pub rate: usize,
    pub map: ChannelMap,
    pub format: Box<Soniton>,
}

impl AudioInfo {
    fn size(&self, align: usize) -> usize {
        unimplemented!()
    }
}

#[derive(Clone)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

use self::MediaKind::*;

pub trait FrameBuffer {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [u8]>;
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]>;
    fn linesize(&self, idx: usize) -> Result<usize>;
    fn count(&self) -> usize;
}

pub struct Frame {
    kind: MediaKind,
    buf: Box<FrameBuffer>,
    t: TimeInfo,
}

const ALIGNMENT: usize = 32;

struct Plane {
    buf: BytesMut,
    linesize: usize,
}

struct DefaultFrameBuffer {
    buf: BytesMut,
    planes: Vec<Plane>,
}

impl FrameBuffer for DefaultFrameBuffer {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [u8]> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&plane.buf)
        }
    }
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]> {
        match self.planes.get_mut(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&mut plane.buf)
        }
    }
    fn linesize(&self, idx: usize) -> Result<usize> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(plane.linesize)
        }
    }
    fn count(&self) -> usize {
        self.planes.len()
    }
}

impl DefaultFrameBuffer {
    pub fn new(kind: &MediaKind) -> DefaultFrameBuffer {
        match kind {
            &Video(ref video) => {
                let size = video.size(ALIGNMENT);
                let data = unsafe { Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap()).unwrap() };
                //let data = unsafe { Heap.alloc_zeroed(Layout::from_size_align(size, ALIGNMENT)) };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for &component in video.format.into_iter() {
                    if let Some(c) = component {
                        let planesize = c.get_data_size(video.width, video.height, ALIGNMENT);
                        let linesize = c.get_linesize(video.width, ALIGNMENT);
                        buffer.planes.push(Plane {
                            buf: buffer.buf.split_to(planesize),
                            linesize: linesize,
                        });
                    }
                }
                buffer
            }
            _ => unimplemented!(),
        }
    }
}
<commit_msg>frame: Use Rc for the format fields<commit_after>#![allow(dead_code, unused_variables)]
use alloc::heap::{Heap, Alloc, Layout};
use bytes::BytesMut;

use std::rc::Rc;

use audiosample::*;
use pixel::*;
use timeinfo::*;

error_chain! {
    errors {
        InvalidIndex
    }
}

#[derive(Clone)]
pub struct VideoInfo {
    pub width: usize,
    pub height: usize,
    pub format: Rc<Formaton>,
}

impl VideoInfo {
    fn size(&self, align: usize) -> usize {
        let mut size = 0;
        for &component in self.format.into_iter() {
            if let Some(c) = component {
                size += c.get_data_size(self.width, self.height, align);
            }
        }
        size
    }
}

#[derive(Clone)]
pub struct AudioInfo {
    pub samples: usize,
    pub rate: usize,
    pub map: ChannelMap,
    pub format: Rc<Soniton>,
}

impl AudioInfo {
    fn size(&self, align: usize) -> usize {
        unimplemented!()
    }
}

#[derive(Clone)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

use self::MediaKind::*;

pub trait FrameBuffer {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [u8]>;
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]>;
    fn linesize(&self, idx: usize) -> Result<usize>;
    fn count(&self) -> usize;
}

pub struct Frame {
    kind: MediaKind,
    buf: Box<FrameBuffer>,
    t: TimeInfo,
}

const ALIGNMENT: usize = 32;

struct Plane {
    buf: BytesMut,
    linesize: usize,
}

struct DefaultFrameBuffer {
    buf: BytesMut,
    planes: Vec<Plane>,
}

impl FrameBuffer for DefaultFrameBuffer {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [u8]> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&plane.buf)
        }
    }
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8]> {
        match self.planes.get_mut(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(&mut plane.buf)
        }
    }
    fn linesize(&self, idx: usize) -> Result<usize> {
        match self.planes.get(idx) {
            None => Err(Error::from_kind(ErrorKind::InvalidIndex)),
            Some(plane) => Ok(plane.linesize)
        }
    }
    fn count(&self) -> usize {
        self.planes.len()
    }
}

impl DefaultFrameBuffer {
    pub fn new(kind: &MediaKind) -> DefaultFrameBuffer {
        match kind {
            &Video(ref video) => {
                let size = video.size(ALIGNMENT);
                let data = unsafe { Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap()).unwrap() };
                //let data = unsafe { Heap.alloc_zeroed(Layout::from_size_align(size, ALIGNMENT)) };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for &component in video.format.into_iter() {
                    if let Some(c) = component {
                        let planesize = c.get_data_size(video.width, video.height, ALIGNMENT);
                        let linesize = c.get_linesize(video.width, ALIGNMENT);
                        buffer.planes.push(Plane {
                            buf: buffer.buf.split_to(planesize),
                            linesize: linesize,
                        });
                    }
                }
                buffer
            }
            _ => unimplemented!(),
        }
    }
}
<|endoftext|>


<commit_before>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use clap::{App, ArgMatches};
use config::reader::from_file;
use config::types::Config as Cfg;
use config::types::Value as V;
use config::types::ScalarValue as S;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config);

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(&rtp) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp,
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.verbose
    }

    pub fn is_debugging(&self) -> bool {
        self.debugging
    }

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> String {
    String::from(config.cli_matches.value_of("rtp").unwrap_or("~/.imag/store/"))
}

fn fetch_config(rtp: &String) -> Option<Cfg> {
    from_file(Path::new(&(rtp.clone() + "/config"))).ok()
}

<commit_msg>Fix: unused import<commit_after>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use config::reader::from_file;
use config::types::Config as Cfg;
use config::types::Value as V;
use config::types::ScalarValue as S;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config);

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(&rtp) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp,
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.verbose
    }

    pub fn is_debugging(&self) -> bool {
        self.debugging
    }

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> String {
    String::from(config.cli_matches.value_of("rtp").unwrap_or("~/.imag/store/"))
}

fn fetch_config(rtp: &String) -> Option<Cfg> {
    from_file(Path::new(&(rtp.clone() + "/config"))).ok()
}

<|endoftext|>