<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_escape]

extern crate blas;

use std::fmt;
use std::mem;
use std::num::NumCast;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use self::blas::default::Default;
use self::blas::matrix::Matrix;
use self::blas::matrix::ops::{
    Gemm,
};
use self::blas::matrix_vector::ops::{
    Gemv,
};
use self::blas::vector::ops::Copy;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn from_vec(rows: uint, cols: uint, vec: Vec<T>) -> Mat<T> {
        Mat { rows: rows, cols: cols, data: vec }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T> Matrix<T> for Mat<T> {
    #[inline]
    fn rows(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.rows());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn cols(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.cols());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        unsafe { self.as_slice().as_ptr() }
    }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T {
        unsafe { self.as_mut_slice().as_mut_ptr() }
    }
}

impl<T: Copy> Clone for Mat<T> {
    fn clone(&self) -> Mat<T> {
        let n = self.rows * self.cols;

        let mut x = Vec::with_capacity(n);
        unsafe {
            Copy::copy(&self.data, &mut x);
            x.set_len(n);
        }

        Mat::from_vec(self.rows, self.cols, x)
    }
}

impl<T: PartialEq> PartialEq for Mat<T> {
    fn eq(&self, other: &Mat<T>) -> bool {
        self.rows == other.rows &&
        self.cols == other.cols &&
        self.data == other.data
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

impl<T> Mul<Vec<T>, Vec<T>> for Mat<T>
where T: Default + Gemv {
    fn mul(&self, x: &Vec<T>) -> Vec<T> {
        let mut result = Vec::with_capacity(self.rows);

        Gemv::gemv(&Default::one(), self, x, &Default::zero(), &mut result);
        unsafe { result.set_len(self.rows); }

        result
    }
}

impl<T> Mul<Mat<T>, Mat<T>> for Mat<T>
where T: Default + Gemm {
    fn mul(&self, b: &Mat<T>) -> Mat<T> {
        let mut result = Mat::zero(self.cols, b.rows);
        Gemm::gemm(&Default::one(), self, b, &Default::zero(), &mut result);

        result
    }
}

#[macro_export]
macro_rules! mat(
    ($([$($e: expr),+]),*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
)

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

    use mat::Mat;

    #[test]
    fn index() {
        let m = mat![[1f32,2f32],[3f32,4f32]];

        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }

    #[test]
    fn mul_vec() {
        let a = mat![
            [1f32, -2f32],
            [2f32, -4f32]
        ];
        let x = vec![2f32, 1f32];

        assert_eq!(a * x, vec![0f32, 0f32]);
    }

    #[test]
    fn mul_mat() {
        let a = mat![
            [1f32, -2f32],
            [2f32, -4f32]
        ];
        let b = mat![
            [1f32, -2f32],
            [2f32, -4f32]
        ];

        let result = mat![
            [-3f32, 6f32],
            [-6f32, 12f32]
        ];
        assert_eq!(a * b, result);
    }
}
<commit_msg>Change matrix macro syntax<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_escape]

extern crate blas;

use std::fmt;
use std::mem;
use std::num::NumCast;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use self::blas::default::Default;
use self::blas::matrix::Matrix;
use self::blas::matrix::ops::{
    Gemm,
};
use self::blas::matrix_vector::ops::{
    Gemv,
};
use self::blas::vector::ops::Copy;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn from_vec(rows: uint, cols: uint, vec: Vec<T>) -> Mat<T> {
        Mat { rows: rows, cols: cols, data: vec }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T> Matrix<T> for Mat<T> {
    #[inline]
    fn rows(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.rows());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn cols(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.cols());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        unsafe { self.as_slice().as_ptr() }
    }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T {
        unsafe { self.as_mut_slice().as_mut_ptr() }
    }
}

impl<T: Copy> Clone for Mat<T> {
    fn clone(&self) -> Mat<T> {
        let n = self.rows * self.cols;

        let mut x = Vec::with_capacity(n);
        unsafe {
            Copy::copy(&self.data, &mut x);
            x.set_len(n);
        }

        Mat::from_vec(self.rows, self.cols, x)
    }
}

impl<T: PartialEq> PartialEq for Mat<T> {
    fn eq(&self, other: &Mat<T>) -> bool {
        self.rows == other.rows &&
        self.cols == other.cols &&
        self.data == other.data
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

impl<T> Mul<Vec<T>, Vec<T>> for Mat<T>
where T: Default + Gemv {
    fn mul(&self, x: &Vec<T>) -> Vec<T> {
        let mut result = Vec::with_capacity(self.rows);

        Gemv::gemv(&Default::one(), self, x, &Default::zero(), &mut result);
        unsafe { result.set_len(self.rows); }

        result
    }
}

impl<T> Mul<Mat<T>, Mat<T>> for Mat<T>
where T: Default + Gemm {
    fn mul(&self, b: &Mat<T>) -> Mat<T> {
        let mut result = Mat::zero(self.cols, b.rows);
        Gemm::gemm(&Default::one(), self, b, &Default::zero(), &mut result);

        result
    }
}

#[macro_export]
macro_rules! mat(
    ($($($e: expr),+);*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
)

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

    use mat::Mat;

    #[test]
    fn index() {
        let a = mat![1f32, 2f32];
        assert_eq!(1.0, a[0][0]);
        assert_eq!(2.0, a[0][1]);

        let b = mat![1f32; 2f32];
        assert_eq!(1.0, b[0][0]);
        assert_eq!(2.0, b[1][0]);

        let m = mat![1f32, 2f32; 3f32, 4f32];
        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }

    #[test]
    fn mul_vec() {
        let a = mat![1f32, -2f32; 2f32, -4f32];
        let x = vec![2f32, 1f32];

        assert_eq!(a * x, vec![0f32, 0f32]);
    }

    #[test]
    fn mul_mat() {
        let a = mat![1f32, -2f32; 2f32, -4f32];
        let b = mat![1f32, -2f32; 2f32, -4f32];

        let result = mat![-3f32, 6f32; -6f32, 12f32];
        assert_eq!(a * b, result);
    }
}
<|endoftext|>


<commit_before>use std::i32;
use std::mem::size_of;

use os;

pub fn ptr_width() -> i32 {
    size_of::<*const u8>() as i32
}

pub fn is_page_aligned(val: usize) -> bool {
    let align = os::page_size_bits();

    // we can use shifts here since we know that
    // page size is power of 2
    val == ((val >> align) << align)
}

#[test]
fn test_is_page_aligned() {
    os::init_page_size();
    let p = os::page_size() as usize;

    assert_eq!(false, is_page_aligned(1));
    assert_eq!(false, is_page_aligned(2));
    assert_eq!(false, is_page_aligned(64));
    assert_eq!(true, is_page_aligned(p));
    assert_eq!(true, is_page_aligned(2*p));
    assert_eq!(true, is_page_aligned(3*p));
}

pub fn page_align(val: usize) -> usize {
    let align = os::page_size_bits();

    // we know that page size is power of 2, hence
    // we can use shifts instead of expensive division
    ((val + (1 << align) - 1) >> align) << align
}

#[test]
fn test_page_align() {
    os::init_page_size();
    let p = os::page_size() as usize;

    assert_eq!(p, page_align(1));
    assert_eq!(p, page_align(p - 1));
    assert_eq!(p, page_align(p));
    assert_eq!(2*p, page_align(p+1));
}

pub fn align(value: u32, align: u32) -> u32 {
    if align == 0 {
        return value;
    }

    ((value + align - 1) / align) * align
}

pub fn align_i32(value: i32, align: i32) -> i32 {
    if align == 0 {
        return value;
    }

    ((value + align - 1) / align) * align
}

pub fn align_usize(value: usize, align: usize) -> usize {
    if align == 0 {
        return value;
    }

    ((value + align - 1) / align) * align
}

pub fn fits_u8(value: i64) -> bool {
    0 <= value && value <= 255
}

pub fn fits_i32(value: i64) -> bool {
    i32::MIN as i64 <= value && value <= i32::MAX as i64
}

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

    #[test]
    fn test_fits_u8() {
        assert_eq!(true, fits_u8(0));
        assert_eq!(true, fits_u8(255));
        assert_eq!(false, fits_u8(256));
        assert_eq!(false, fits_u8(-1));
    }

    #[test]
    fn test_fits_i32() {
        assert_eq!(true, fits_i32(0));
        assert_eq!(true, fits_i32(i32::MAX as i64));
        assert_eq!(true, fits_i32(i32::MIN as i64));
        assert_eq!(false, fits_i32(i32::MAX as i64 + 1));
        assert_eq!(false, fits_i32(i32::MIN as i64 - 1));
    }
}
<commit_msg>added comments<commit_after>use std::i32;
use std::mem::size_of;

use os;

/// return pointer width: either 4 or 8
/// (although only 64bit architectures are supported right now)
pub fn ptr_width() -> i32 {
    size_of::<*const u8>() as i32
}

/// returns true if given value is a multiple of a page size.
pub fn is_page_aligned(val: usize) -> bool {
    let align = os::page_size_bits();

    // we can use shifts here since we know that
    // page size is power of 2
    val == ((val >> align) << align)
}

#[test]
fn test_is_page_aligned() {
    os::init_page_size();
    let p = os::page_size() as usize;

    assert_eq!(false, is_page_aligned(1));
    assert_eq!(false, is_page_aligned(2));
    assert_eq!(false, is_page_aligned(64));
    assert_eq!(true, is_page_aligned(p));
    assert_eq!(true, is_page_aligned(2*p));
    assert_eq!(true, is_page_aligned(3*p));
}

/// round the given value up to the nearest multiple of a page
pub fn page_align(val: usize) -> usize {
    let align = os::page_size_bits();

    // we know that page size is power of 2, hence
    // we can use shifts instead of expensive division
    ((val + (1 << align) - 1) >> align) << align
}

#[test]
fn test_page_align() {
    os::init_page_size();
    let p = os::page_size() as usize;

    assert_eq!(p, page_align(1));
    assert_eq!(p, page_align(p - 1));
    assert_eq!(p, page_align(p));
    assert_eq!(2*p, page_align(p+1));
}

/// rounds the given value `val` up to the nearest multiple
/// of `align`
pub fn align(value: u32, align: u32) -> u32 {
    if align == 0 {
        return value;
    }

    ((value + align - 1) / align) * align
}

/// rounds the given value `val` up to the nearest multiple
/// of `align`
pub fn align_i32(value: i32, align: i32) -> i32 {
    if align == 0 {
        return value;
    }

    ((value + align - 1) / align) * align
}

/// rounds the given value `val` up to the nearest multiple
/// of `align`
pub fn align_usize(value: usize, align: usize) -> usize {
    if align == 0 {
        return value;
    }

    ((value + align - 1) / align) * align
}

/// returns true if value fits into u8 (unsigned 8bits).
pub fn fits_u8(value: i64) -> bool {
    0 <= value && value <= 255
}

/// returns true if value fits into i32 (signed 32bits).
pub fn fits_i32(value: i64) -> bool {
    i32::MIN as i64 <= value && value <= i32::MAX as i64
}

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

    #[test]
    fn test_fits_u8() {
        assert_eq!(true, fits_u8(0));
        assert_eq!(true, fits_u8(255));
        assert_eq!(false, fits_u8(256));
        assert_eq!(false, fits_u8(-1));
    }

    #[test]
    fn test_fits_i32() {
        assert_eq!(true, fits_i32(0));
        assert_eq!(true, fits_i32(i32::MAX as i64));
        assert_eq!(true, fits_i32(i32::MIN as i64));
        assert_eq!(false, fits_i32(i32::MAX as i64 + 1));
        assert_eq!(false, fits_i32(i32::MIN as i64 - 1));
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::path::{Path, PathBuf};
use std::io;
use std::ops::{Deref, DerefMut};

use response::{Response, Responder};
use http::{Status, ContentType};

/// A file with an associated name; responds with the Content-Type based on the
/// file extension.
#[derive(Debug)]
pub struct NamedFile(PathBuf, File);

impl NamedFile {
    /// Attempts to open a file in read-only mode.
    ///
    /// # Errors
    ///
    /// This function will return an error if path does not already exist. Other
    /// errors may also be returned according to
    /// [OpenOptions::open](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open).
    ///
    /// # Examples
    ///
    /// ```rust
    /// use rocket::response::NamedFile;
    ///
    /// let file = NamedFile::open("foo.txt");
    /// ```
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
        let file = File::open(path.as_ref())?;
        Ok(NamedFile(path.as_ref().to_path_buf(), file))
    }

    /// Retrieve the underlying `File`.
    #[inline(always)]
    pub fn file(&self) -> &File {
        &self.1
    }

    /// Take the underlying `File`.
    #[inline(always)]
    pub fn take_file(self) -> File {
        self.1
    }

    /// Retrieve a mutable borrow to the underlying `File`.
    #[inline(always)]
    pub fn file_mut(&mut self) -> &mut File {
        &mut self.1
    }

    /// Retrieve the path of this file.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use std::io;
    /// use rocket::response::NamedFile;
    ///
    /// # fn demo_path() -> io::Result<()> {
    /// let file = NamedFile::open("foo.txt")?;
    /// assert_eq!(file.path().as_os_str(), "foo.txt");
    /// # Ok(())
    /// # }
    /// ```
    #[inline(always)]
    pub fn path(&self) -> &Path {
        self.0.as_path()
    }
}

/// Streams the named file to the client. Sets or overrides the Content-Type in
/// the response according to the file's extension if the extension is
/// recognized. See
/// [ContentType::from_extension](/rocket/http/struct.ContentType.html#method.from_extension)
/// for more information. If you would like to stream a file with a different
/// Content-Type than that implied by its extension, use a `File` directly.
///
/// # Failure
///
/// If reading the file fails permanently at any point during the response, an
/// `Outcome` of `Failure` is returned, and the response is terminated abrubtly.
impl<'r> Responder<'r> for NamedFile {
    fn respond(self) -> Result<Response<'r>, Status> {
        let mut response = Response::new();
        if let Some(ext) = self.path().extension() {
            // TODO: Use Cow for lowercase.
            let ext_string = ext.to_string_lossy().to_lowercase();
            let content_type = ContentType::from_extension(&ext_string);
            if !content_type.is_any() {
                response.set_header(content_type);
            }
        }

        response.set_streamed_body(self.take_file());
        Ok(response)
    }
}

impl Deref for NamedFile {
    type Target = File;

    fn deref(&self) -> &File {
        &self.1
    }
}

impl DerefMut for NamedFile {
    fn deref_mut(&mut self) -> &mut File {
        &mut self.1
    }
}

impl io::Read for NamedFile {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.file().read(buf)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.file().read_to_end(buf)
    }
}

impl io::Write for NamedFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file().write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.file().flush()
    }
}

impl io::Seek for NamedFile {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        self.file().seek(pos)
    }
}

impl<'a> io::Read for &'a NamedFile {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.file().read(buf)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.file().read_to_end(buf)
    }
}

impl<'a> io::Write for &'a NamedFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file().write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.file().flush()
    }
}

impl<'a> io::Seek for &'a NamedFile {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        self.file().seek(pos)
    }
}
<commit_msg>Update NamedFile documentation.<commit_after>use std::fs::File;
use std::path::{Path, PathBuf};
use std::io;
use std::ops::{Deref, DerefMut};

use response::{Response, Responder};
use http::{Status, ContentType};

/// A file with an associated name; responds with the Content-Type based on the
/// file extension.
#[derive(Debug)]
pub struct NamedFile(PathBuf, File);

impl NamedFile {
    /// Attempts to open a file in read-only mode.
    ///
    /// # Errors
    ///
    /// This function will return an error if path does not already exist. Other
    /// errors may also be returned according to
    /// [OpenOptions::open](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open).
    ///
    /// # Examples
    ///
    /// ```rust
    /// use rocket::response::NamedFile;
    ///
    /// let file = NamedFile::open("foo.txt");
    /// ```
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
        let file = File::open(path.as_ref())?;
        Ok(NamedFile(path.as_ref().to_path_buf(), file))
    }

    /// Retrieve the underlying `File`.
    #[inline(always)]
    pub fn file(&self) -> &File {
        &self.1
    }

    /// Take the underlying `File`.
    #[inline(always)]
    pub fn take_file(self) -> File {
        self.1
    }

    /// Retrieve a mutable borrow to the underlying `File`.
    #[inline(always)]
    pub fn file_mut(&mut self) -> &mut File {
        &mut self.1
    }

    /// Retrieve the path of this file.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use std::io;
    /// use rocket::response::NamedFile;
    ///
    /// # fn demo_path() -> io::Result<()> {
    /// let file = NamedFile::open("foo.txt")?;
    /// assert_eq!(file.path().as_os_str(), "foo.txt");
    /// # Ok(())
    /// # }
    /// ```
    #[inline(always)]
    pub fn path(&self) -> &Path {
        self.0.as_path()
    }
}

/// Streams the named file to the client. Sets or overrides the Content-Type in
/// the response according to the file's extension if the extension is
/// recognized. See
/// [ContentType::from_extension](/rocket/http/struct.ContentType.html#method.from_extension)
/// for more information. If you would like to stream a file with a different
/// Content-Type than that implied by its extension, use a `File` directly.
impl<'r> Responder<'r> for NamedFile {
    fn respond(self) -> Result<Response<'r>, Status> {
        let mut response = Response::new();
        if let Some(ext) = self.path().extension() {
            // TODO: Use Cow for lowercase.
            let ext_string = ext.to_string_lossy().to_lowercase();
            let content_type = ContentType::from_extension(&ext_string);
            if !content_type.is_any() {
                response.set_header(content_type);
            }
        }

        response.set_streamed_body(self.take_file());
        Ok(response)
    }
}

impl Deref for NamedFile {
    type Target = File;

    fn deref(&self) -> &File {
        &self.1
    }
}

impl DerefMut for NamedFile {
    fn deref_mut(&mut self) -> &mut File {
        &mut self.1
    }
}

impl io::Read for NamedFile {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.file().read(buf)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.file().read_to_end(buf)
    }
}

impl io::Write for NamedFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file().write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.file().flush()
    }
}

impl io::Seek for NamedFile {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        self.file().seek(pos)
    }
}

impl<'a> io::Read for &'a NamedFile {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.file().read(buf)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.file().read_to_end(buf)
    }
}

impl<'a> io::Write for &'a NamedFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file().write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.file().flush()
    }
}

impl<'a> io::Seek for &'a NamedFile {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        self.file().seek(pos)
    }
}
<|endoftext|>


<commit_before>use std::ops::Deref;
use std::ops::DerefMut;

use itertools::Itertools;

use libimagstore::store::{Entry, EntryHeader, FileLockEntry};
use libimagerror::into::IntoError;

use error::TagErrorKind;
use error::MapErrInto;
use result::Result;
use tag::{Tag, TagSlice};
use util::is_tag;

use toml::Value;

pub trait Tagable {

    fn get_tags(&self) -> Result<Vec<Tag>>;
    fn set_tags(&mut self, ts: &[Tag]) -> Result<()>;

    fn add_tag(&mut self, t: Tag) -> Result<()>;
    fn remove_tag(&mut self, t: Tag) -> Result<()>;

    fn has_tag(&self, t: TagSlice) -> Result<bool>;
    fn has_tags(&self, ts: &[Tag]) -> Result<bool>;

}

impl Tagable for EntryHeader {

    fn get_tags(&self) -> Result<Vec<Tag>> {
        let tags = try!(self.read("imag.tags").map_err_into(TagErrorKind::HeaderReadError));

        match tags {
            Some(Value::Array(tags)) => {
                if !tags.iter().all(|t| is_match!(*t, Value::String(_))) {
                    return Err(TagErrorKind::TagTypeError.into());
                }
                if tags.iter().any(|t| match *t {
                    Value::String(ref s) => !is_tag(s),
                    _ => unreachable!()})
                {
                    return Err(TagErrorKind::NotATag.into());
                }

                Ok(tags.iter()
                    .cloned()
                    .map(|t| {
                        match t {
                           Value::String(s) => s,
                           _ => unreachable!(),
                        }
                    })
                    .collect())
            },
            None => Ok(vec![]),
            _ => Err(TagErrorKind::TagTypeError.into()),
        }
    }

    fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
        if ts.iter().any(|tag| !is_tag(tag)) {
            debug!("Not a tag: '{}'", ts.iter().filter(|t| !is_tag(t)).next().unwrap());
            return Err(TagErrorKind::NotATag.into());
        }

        let a = ts.iter().unique().map(|t| Value::String(t.clone())).collect();
        self.set("imag.tags", Value::Array(a))
            .map(|_| ())
            .map_err(Box::new)
            .map_err(|e| TagErrorKind::HeaderWriteError.into_error_with_cause(e))
    }

    fn add_tag(&mut self, t: Tag) -> Result<()> {
        if !is_tag(&t) {
            debug!("Not a tag: '{}'", t);
            return Err(TagErrorKind::NotATag.into());
        }

        self.get_tags()
            .map(|mut tags| {
                tags.push(t);
                self.set_tags(&tags.into_iter().unique().collect::<Vec<_>>()[..])
            })
            .map(|_| ())
    }

    fn remove_tag(&mut self, t: Tag) -> Result<()> {
        if !is_tag(&t) {
            debug!("Not a tag: '{}'", t);
            return Err(TagErrorKind::NotATag.into());
        }

        self.get_tags()
            .map(|mut tags| {
                tags.retain(|tag| tag.clone() != t);
                self.set_tags(&tags[..])
            })
            .map(|_| ())
    }

    fn has_tag(&self, t: TagSlice) -> Result<bool> {
        let tags = try!(self.read("imag.tags").map_err_into(TagErrorKind::HeaderReadError));

        if !tags.iter().all(|t| is_match!(*t, Value::String(_))) {
            return Err(TagErrorKind::TagTypeError.into());
        }

        Ok(tags
           .iter()
           .any(|tag| {
               match *tag {
                   Value::String(ref s) => { s == t },
                   _ => unreachable!()
               }
           }))
    }

    fn has_tags(&self, tags: &[Tag]) -> Result<bool> {
        let mut result = true;
        for tag in tags {
            let check = self.has_tag(tag);
            if check.is_err() {
                return Err(check.unwrap_err());
            }
            let check = check.unwrap();

            result = result && check;
        }

        Ok(result)
    }

}

impl Tagable for Entry {

    fn get_tags(&self) -> Result<Vec<Tag>> {
        self.get_header().get_tags()
    }

    fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
        self.get_header_mut().set_tags(ts)
    }

    fn add_tag(&mut self, t: Tag) -> Result<()> {
        self.get_header_mut().add_tag(t)
    }

    fn remove_tag(&mut self, t: Tag) -> Result<()> {
        self.get_header_mut().remove_tag(t)
    }

    fn has_tag(&self, t: TagSlice) -> Result<bool> {
        self.get_header().has_tag(t)
    }

    fn has_tags(&self, ts: &[Tag]) -> Result<bool> {
        self.get_header().has_tags(ts)
    }

}

impl<'a> Tagable for FileLockEntry<'a> {

    fn get_tags(&self) -> Result<Vec<Tag>> {
        self.deref().get_tags()
    }

    fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
        self.deref_mut().set_tags(ts)
    }

    fn add_tag(&mut self, t: Tag) -> Result<()> {
        self.deref_mut().add_tag(t)
    }

    fn remove_tag(&mut self, t: Tag) -> Result<()> {
        self.deref_mut().remove_tag(t)
    }

    fn has_tag(&self, t: TagSlice) -> Result<bool> {
        self.deref().has_tag(t)
    }

    fn has_tags(&self, ts: &[Tag]) -> Result<bool> {
        self.deref().has_tags(ts)
    }

}

<commit_msg>Replace unwrap() with try!()<commit_after>use std::ops::Deref;
use std::ops::DerefMut;

use itertools::Itertools;

use libimagstore::store::{Entry, EntryHeader, FileLockEntry};
use libimagerror::into::IntoError;

use error::TagErrorKind;
use error::MapErrInto;
use result::Result;
use tag::{Tag, TagSlice};
use util::is_tag;

use toml::Value;

pub trait Tagable {

    fn get_tags(&self) -> Result<Vec<Tag>>;
    fn set_tags(&mut self, ts: &[Tag]) -> Result<()>;

    fn add_tag(&mut self, t: Tag) -> Result<()>;
    fn remove_tag(&mut self, t: Tag) -> Result<()>;

    fn has_tag(&self, t: TagSlice) -> Result<bool>;
    fn has_tags(&self, ts: &[Tag]) -> Result<bool>;

}

impl Tagable for EntryHeader {

    fn get_tags(&self) -> Result<Vec<Tag>> {
        let tags = try!(self.read("imag.tags").map_err_into(TagErrorKind::HeaderReadError));

        match tags {
            Some(Value::Array(tags)) => {
                if !tags.iter().all(|t| is_match!(*t, Value::String(_))) {
                    return Err(TagErrorKind::TagTypeError.into());
                }
                if tags.iter().any(|t| match *t {
                    Value::String(ref s) => !is_tag(s),
                    _ => unreachable!()})
                {
                    return Err(TagErrorKind::NotATag.into());
                }

                Ok(tags.iter()
                    .cloned()
                    .map(|t| {
                        match t {
                           Value::String(s) => s,
                           _ => unreachable!(),
                        }
                    })
                    .collect())
            },
            None => Ok(vec![]),
            _ => Err(TagErrorKind::TagTypeError.into()),
        }
    }

    fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
        if ts.iter().any(|tag| !is_tag(tag)) {
            debug!("Not a tag: '{}'", ts.iter().filter(|t| !is_tag(t)).next().unwrap());
            return Err(TagErrorKind::NotATag.into());
        }

        let a = ts.iter().unique().map(|t| Value::String(t.clone())).collect();
        self.set("imag.tags", Value::Array(a))
            .map(|_| ())
            .map_err(Box::new)
            .map_err(|e| TagErrorKind::HeaderWriteError.into_error_with_cause(e))
    }

    fn add_tag(&mut self, t: Tag) -> Result<()> {
        if !is_tag(&t) {
            debug!("Not a tag: '{}'", t);
            return Err(TagErrorKind::NotATag.into());
        }

        self.get_tags()
            .map(|mut tags| {
                tags.push(t);
                self.set_tags(&tags.into_iter().unique().collect::<Vec<_>>()[..])
            })
            .map(|_| ())
    }

    fn remove_tag(&mut self, t: Tag) -> Result<()> {
        if !is_tag(&t) {
            debug!("Not a tag: '{}'", t);
            return Err(TagErrorKind::NotATag.into());
        }

        self.get_tags()
            .map(|mut tags| {
                tags.retain(|tag| tag.clone() != t);
                self.set_tags(&tags[..])
            })
            .map(|_| ())
    }

    fn has_tag(&self, t: TagSlice) -> Result<bool> {
        let tags = try!(self.read("imag.tags").map_err_into(TagErrorKind::HeaderReadError));

        if !tags.iter().all(|t| is_match!(*t, Value::String(_))) {
            return Err(TagErrorKind::TagTypeError.into());
        }

        Ok(tags
           .iter()
           .any(|tag| {
               match *tag {
                   Value::String(ref s) => { s == t },
                   _ => unreachable!()
               }
           }))
    }

    fn has_tags(&self, tags: &[Tag]) -> Result<bool> {
        let mut result = true;
        for tag in tags {
            result = result && try!(self.has_tag(tag));
        }

        Ok(result)
    }

}

impl Tagable for Entry {

    fn get_tags(&self) -> Result<Vec<Tag>> {
        self.get_header().get_tags()
    }

    fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
        self.get_header_mut().set_tags(ts)
    }

    fn add_tag(&mut self, t: Tag) -> Result<()> {
        self.get_header_mut().add_tag(t)
    }

    fn remove_tag(&mut self, t: Tag) -> Result<()> {
        self.get_header_mut().remove_tag(t)
    }

    fn has_tag(&self, t: TagSlice) -> Result<bool> {
        self.get_header().has_tag(t)
    }

    fn has_tags(&self, ts: &[Tag]) -> Result<bool> {
        self.get_header().has_tags(ts)
    }

}

impl<'a> Tagable for FileLockEntry<'a> {

    fn get_tags(&self) -> Result<Vec<Tag>> {
        self.deref().get_tags()
    }

    fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
        self.deref_mut().set_tags(ts)
    }

    fn add_tag(&mut self, t: Tag) -> Result<()> {
        self.deref_mut().add_tag(t)
    }

    fn remove_tag(&mut self, t: Tag) -> Result<()> {
        self.deref_mut().remove_tag(t)
    }

    fn has_tag(&self, t: TagSlice) -> Result<bool> {
        self.deref().has_tag(t)
    }

    fn has_tags(&self, ts: &[Tag]) -> Result<bool> {
        self.deref().has_tags(ts)
    }

}

<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::result::Result as RResult;
use std::ops::Deref;

use toml::{Parser, Value};

/**
 * Errors which are related to configuration-file loading
 */
pub mod error {
    use std::error::Error;
    use std::fmt::{Display, Formatter};
    use std::fmt::Error as FmtError;

    /**
     * The kind of an error
     */
    #[derive(Clone, Debug, PartialEq)]
    pub enum ConfigErrorKind {
        ConfigParsingFailed,
        NoConfigFileFound,
    }

    /**
     * Configuration error type
     */
    #[derive(Debug)]
    pub struct ConfigError {
        kind: ConfigErrorKind,
        cause: Option<Box<Error>>,
    }

    impl ConfigError {

        /**
         * Instantiate a new ConfigError, optionally with cause
         */
        pub fn new(kind: ConfigErrorKind, cause: Option<Box<Error>>) -> ConfigError {
            ConfigError {
                kind: kind,
                cause: cause,
            }
        }

        /**
         * get the Kind of the Error
         */
        pub fn kind(&self) -> ConfigErrorKind {
            self.kind.clone()
        }

        /**
         * Get the string, the ConfigError can be described with
         */
        pub fn as_str(e: &ConfigError) -> &'static str {
            match e.kind() {
                ConfigErrorKind::ConfigParsingFailed => "Config parsing failed",
                ConfigErrorKind::NoConfigFileFound   => "No config file found",
            }
        }

    }

    impl Display for ConfigError {

        fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
            try!(write!(fmt, "{}", ConfigError::as_str(self)));
            Ok(())
        }

    }

    impl Error for ConfigError {

        fn description(&self) -> &str {
            ConfigError::as_str(self)
        }

        fn cause(&self) -> Option<&Error> {
            self.cause.as_ref().map(|e| &**e)
        }

    }

}

use self::error::{ConfigError, ConfigErrorKind};

/**
 * Result type of this module. Either T or ConfigError
 */
pub type Result<T> = RResult<T, ConfigError>;

/**
 * Configuration object
 *
 * Holds all config variables which are globally available plus the configuration object from the
 * config parser, which can be accessed.
 */
#[derive(Debug)]
pub struct Configuration {

    /**
     * The plain configuration object for direct access if necessary
     */
    config: Value,

    /**
     * The verbosity the program should run with
     */
    verbosity: bool,

    /**
     * The editor which should be used
     */
    editor: Option<String>,

    /**
     * The options the editor should get when opening some file
     */
    editor_opts: String,
}

impl Configuration {

    /**
     * Get a new configuration object.
     *
     * The passed runtimepath is used for searching the configuration file, whereas several file
     * names are tested. If that does not work, the home directory and the XDG basedir are tested
     * with all variants.
     *
     * If that doesn't work either, an error is returned.
     */
    pub fn new(rtp: &PathBuf) -> Result<Configuration> {
        fetch_config(&rtp).map(|cfg| {
            let verbosity   = get_verbosity(&cfg);
            let editor      = get_editor(&cfg);
            let editor_opts = get_editor_opts(&cfg);

            debug!("Building configuration");
            debug!("  - verbosity  : {:?}", verbosity);
            debug!("  - editor     : {:?}", editor);
            debug!("  - editor-opts: {}", editor_opts);

            Configuration {
                config: cfg,
                verbosity: verbosity,
                editor: editor,
                editor_opts: editor_opts,
            }
        })
    }

    pub fn editor(&self) -> Option<&String> {
        self.editor.as_ref()
    }

    pub fn config(&self) -> &Value {
        &self.config
    }

    pub fn store_config(&self) -> Option<&Value> {
        match &self.config {
            &Value::Table(ref tabl) => tabl.get("store"),
            _ => None,
        }
    }

}

impl Deref for Configuration {
    type Target = Value;

    fn deref(&self) -> &Value {
        &self.config
    }

}

fn get_verbosity(v: &Value) -> bool {
    match v {
        &Value::Table(ref t) => t.get("verbose")
                .map(|v| match v { &Value::Boolean(b) => b, _ => false, })
                .unwrap_or(false),
        _ => false,
    }
}

fn get_editor(v: &Value) -> Option<String> {
    match v {
        &Value::Table(ref t) => t.get("editor")
                .and_then(|v| match v { &Value::String(ref s) => Some(s.clone()), _ => None, }),
        _ => None,
    }
}

fn get_editor_opts(v: &Value) -> String {
    match v {
        &Value::Table(ref t) => t.get("editor-opts")
                .and_then(|v| match v { &Value::String(ref s) => Some(s.clone()), _ => None, })
                .unwrap_or(String::new()),
        _ => String::new(),
    }
}

/**
 * Helper to fetch the config file
 *
 * Tests several variants for the config file path and uses the first one which works.
 */
fn fetch_config(rtp: &PathBuf) -> Result<Value> {
    use std::env;
    use std::fs::File;
    use std::io::Read;
    use std::io::Write;
    use std::io::stderr;

    use xdg_basedir;
    use itertools::Itertools;

    use libimagutil::variants::generate_variants as gen_vars;

    let variants = vec!["config", "config.toml", "imagrc", "imagrc.toml"];
    let modifier = |base: &PathBuf, v: &'static str| {
        let mut base = base.clone();
        base.push(format!("{}", v));
        base
    };

    vec![
        gen_vars(rtp.clone(), variants.clone(), &modifier),

        env::var("HOME").map(|home| gen_vars(PathBuf::from(home), variants.clone(), &modifier))
                        .unwrap_or(vec![]),

        xdg_basedir::get_data_home().map(|data_dir| gen_vars(data_dir, variants.clone(), &modifier))
                                    .unwrap_or(vec![]),
    ].iter()
        .flatten()
        .filter(|path| path.exists() && path.is_file())
        .map(|path| {
            let content = {
                let mut s = String::new();
                let f = File::open(path);
                if f.is_err() {
                }
                let mut f = f.unwrap();
                f.read_to_string(&mut s).ok();
                s
            };
            let mut parser = Parser::new(&content[..]);
            let res = parser.parse();
            if res.is_none() {
                write!(stderr(), "Config file parser error:");
                for error in parser.errors {
                    write!(stderr(), "At [{}][{}] <> {}", error.lo, error.hi, error);
                    write!(stderr(), "in: '{}'", &content[error.lo..error.hi]);
                }
                None
            } else {
                res
            }
        })
        .filter(|loaded| loaded.is_some())
        .nth(0)
        .map(|inner| Value::Table(inner.unwrap()))
        .ok_or(ConfigError::new(ConfigErrorKind::NoConfigFileFound, None))
}

<commit_msg>Remove unused enum variant<commit_after>use std::path::PathBuf;
use std::result::Result as RResult;
use std::ops::Deref;

use toml::{Parser, Value};

/**
 * Errors which are related to configuration-file loading
 */
pub mod error {
    use std::error::Error;
    use std::fmt::{Display, Formatter};
    use std::fmt::Error as FmtError;

    /**
     * The kind of an error
     */
    #[derive(Clone, Debug, PartialEq)]
    pub enum ConfigErrorKind {
        NoConfigFileFound,
    }

    /**
     * Configuration error type
     */
    #[derive(Debug)]
    pub struct ConfigError {
        kind: ConfigErrorKind,
        cause: Option<Box<Error>>,
    }

    impl ConfigError {

        /**
         * Instantiate a new ConfigError, optionally with cause
         */
        pub fn new(kind: ConfigErrorKind, cause: Option<Box<Error>>) -> ConfigError {
            ConfigError {
                kind: kind,
                cause: cause,
            }
        }

        /**
         * get the Kind of the Error
         */
        pub fn kind(&self) -> ConfigErrorKind {
            self.kind.clone()
        }

        /**
         * Get the string, the ConfigError can be described with
         */
        pub fn as_str(e: &ConfigError) -> &'static str {
            match e.kind() {
                ConfigErrorKind::NoConfigFileFound   => "No config file found",
            }
        }

    }

    impl Display for ConfigError {

        fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
            try!(write!(fmt, "{}", ConfigError::as_str(self)));
            Ok(())
        }

    }

    impl Error for ConfigError {

        fn description(&self) -> &str {
            ConfigError::as_str(self)
        }

        fn cause(&self) -> Option<&Error> {
            self.cause.as_ref().map(|e| &**e)
        }

    }

}

use self::error::{ConfigError, ConfigErrorKind};

/**
 * Result type of this module. Either T or ConfigError
 */
pub type Result<T> = RResult<T, ConfigError>;

/**
 * Configuration object
 *
 * Holds all config variables which are globally available plus the configuration object from the
 * config parser, which can be accessed.
 */
#[derive(Debug)]
pub struct Configuration {

    /**
     * The plain configuration object for direct access if necessary
     */
    config: Value,

    /**
     * The verbosity the program should run with
     */
    verbosity: bool,

    /**
     * The editor which should be used
     */
    editor: Option<String>,

    /**
     * The options the editor should get when opening some file
     */
    editor_opts: String,
}

impl Configuration {

    /**
     * Get a new configuration object.
     *
     * The passed runtimepath is used for searching the configuration file, whereas several file
     * names are tested. If that does not work, the home directory and the XDG basedir are tested
     * with all variants.
     *
     * If that doesn't work either, an error is returned.
     */
    pub fn new(rtp: &PathBuf) -> Result<Configuration> {
        fetch_config(&rtp).map(|cfg| {
            let verbosity   = get_verbosity(&cfg);
            let editor      = get_editor(&cfg);
            let editor_opts = get_editor_opts(&cfg);

            debug!("Building configuration");
            debug!("  - verbosity  : {:?}", verbosity);
            debug!("  - editor     : {:?}", editor);
            debug!("  - editor-opts: {}", editor_opts);

            Configuration {
                config: cfg,
                verbosity: verbosity,
                editor: editor,
                editor_opts: editor_opts,
            }
        })
    }

    pub fn editor(&self) -> Option<&String> {
        self.editor.as_ref()
    }

    pub fn config(&self) -> &Value {
        &self.config
    }

    pub fn store_config(&self) -> Option<&Value> {
        match &self.config {
            &Value::Table(ref tabl) => tabl.get("store"),
            _ => None,
        }
    }

}

impl Deref for Configuration {
    type Target = Value;

    fn deref(&self) -> &Value {
        &self.config
    }

}

fn get_verbosity(v: &Value) -> bool {
    match v {
        &Value::Table(ref t) => t.get("verbose")
                .map(|v| match v { &Value::Boolean(b) => b, _ => false, })
                .unwrap_or(false),
        _ => false,
    }
}

fn get_editor(v: &Value) -> Option<String> {
    match v {
        &Value::Table(ref t) => t.get("editor")
                .and_then(|v| match v { &Value::String(ref s) => Some(s.clone()), _ => None, }),
        _ => None,
    }
}

fn get_editor_opts(v: &Value) -> String {
    match v {
        &Value::Table(ref t) => t.get("editor-opts")
                .and_then(|v| match v { &Value::String(ref s) => Some(s.clone()), _ => None, })
                .unwrap_or(String::new()),
        _ => String::new(),
    }
}

/**
 * Helper to fetch the config file
 *
 * Tests several variants for the config file path and uses the first one which works.
 */
fn fetch_config(rtp: &PathBuf) -> Result<Value> {
    use std::env;
    use std::fs::File;
    use std::io::Read;
    use std::io::Write;
    use std::io::stderr;

    use xdg_basedir;
    use itertools::Itertools;

    use libimagutil::variants::generate_variants as gen_vars;

    let variants = vec!["config", "config.toml", "imagrc", "imagrc.toml"];
    let modifier = |base: &PathBuf, v: &'static str| {
        let mut base = base.clone();
        base.push(format!("{}", v));
        base
    };

    vec![
        gen_vars(rtp.clone(), variants.clone(), &modifier),

        env::var("HOME").map(|home| gen_vars(PathBuf::from(home), variants.clone(), &modifier))
                        .unwrap_or(vec![]),

        xdg_basedir::get_data_home().map(|data_dir| gen_vars(data_dir, variants.clone(), &modifier))
                                    .unwrap_or(vec![]),
    ].iter()
        .flatten()
        .filter(|path| path.exists() && path.is_file())
        .map(|path| {
            let content = {
                let mut s = String::new();
                let f = File::open(path);
                if f.is_err() {
                }
                let mut f = f.unwrap();
                f.read_to_string(&mut s).ok();
                s
            };
            let mut parser = Parser::new(&content[..]);
            let res = parser.parse();
            if res.is_none() {
                write!(stderr(), "Config file parser error:");
                for error in parser.errors {
                    write!(stderr(), "At [{}][{}] <> {}", error.lo, error.hi, error);
                    write!(stderr(), "in: '{}'", &content[error.lo..error.hi]);
                }
                None
            } else {
                res
            }
        })
        .filter(|loaded| loaded.is_some())
        .nth(0)
        .map(|inner| Value::Table(inner.unwrap()))
        .ok_or(ConfigError::new(ConfigErrorKind::NoConfigFileFound, None))
}

<|endoftext|>


<commit_before>//! Internal FFI and marshalling things.

use std::default::Default;
use std::ptr;

use glib_sys::{gboolean, GString};

use length::RsvgLength;
use node::RsvgNode;
use filter_context::RsvgFilterContext;

use super::Filter;

// Keep this in sync with
// ../../librsvg/librsvg/filters/common.h:_RsvgFilterPrimitive
/// Required by the C code until all filters are ported to Rust.
#[repr(C)]
pub(super) struct RsvgFilterPrimitive {
    x: RsvgLength,
    y: RsvgLength,
    width: RsvgLength,
    height: RsvgLength,
    x_specified: gboolean,
    y_specified: gboolean,
    width_specified: gboolean,
    height_specified: gboolean,
    in_: *mut GString,
    result: *mut GString,

    render: Option<
        unsafe extern "C" fn(*mut RsvgNode, *mut RsvgFilterPrimitive, *mut RsvgFilterContext),
    >,
}

impl RsvgFilterPrimitive {
    /// Creates a new `RsvgFilterPrimitive` with the proper render callback.
    #[inline]
    pub(super) fn new<T: Filter>() -> RsvgFilterPrimitive {
        RsvgFilterPrimitive {
            x: Default::default(),
            y: Default::default(),
            width: Default::default(),
            height: Default::default(),
            x_specified: Default::default(),
            y_specified: Default::default(),
            width_specified: Default::default(),
            height_specified: Default::default(),
            in_: ptr::null_mut(),
            result: ptr::null_mut(),

            render: Some(render_callback::<T>),
        }
    }
}

/// Calls `Filter::render()` for this filter primitive.
///
/// # Safety
/// `raw_node` and `ctx` must be valid pointers.
unsafe extern "C" fn render_callback<T: Filter>(
    raw_node: *mut RsvgNode,
    _primitive: *mut RsvgFilterPrimitive,
    ctx: *mut RsvgFilterContext,
) {
    assert!(!raw_node.is_null());
    let node: &RsvgNode = &*raw_node;

    node.with_impl(move |filter: &T| filter.render(ctx));
}
<commit_msg>Skip rendering filters if they are in error<commit_after>//! Internal FFI and marshalling things.

use std::default::Default;
use std::ptr;

use glib_sys::{gboolean, GString};

use length::RsvgLength;
use node::RsvgNode;
use filter_context::RsvgFilterContext;

use super::Filter;

// Keep this in sync with
// ../../librsvg/librsvg/filters/common.h:_RsvgFilterPrimitive
/// Required by the C code until all filters are ported to Rust.
#[repr(C)]
pub(super) struct RsvgFilterPrimitive {
    x: RsvgLength,
    y: RsvgLength,
    width: RsvgLength,
    height: RsvgLength,
    x_specified: gboolean,
    y_specified: gboolean,
    width_specified: gboolean,
    height_specified: gboolean,
    in_: *mut GString,
    result: *mut GString,

    render: Option<
        unsafe extern "C" fn(*mut RsvgNode, *mut RsvgFilterPrimitive, *mut RsvgFilterContext),
    >,
}

impl RsvgFilterPrimitive {
    /// Creates a new `RsvgFilterPrimitive` with the proper render callback.
    #[inline]
    pub(super) fn new<T: Filter>() -> RsvgFilterPrimitive {
        RsvgFilterPrimitive {
            x: Default::default(),
            y: Default::default(),
            width: Default::default(),
            height: Default::default(),
            x_specified: Default::default(),
            y_specified: Default::default(),
            width_specified: Default::default(),
            height_specified: Default::default(),
            in_: ptr::null_mut(),
            result: ptr::null_mut(),

            render: Some(render_callback::<T>),
        }
    }
}

/// Calls `Filter::render()` for this filter primitive.
///
/// # Safety
/// `raw_node` and `ctx` must be valid pointers.
unsafe extern "C" fn render_callback<T: Filter>(
    raw_node: *mut RsvgNode,
    _primitive: *mut RsvgFilterPrimitive,
    ctx: *mut RsvgFilterContext,
) {
    assert!(!raw_node.is_null());
    let node: &RsvgNode = &*raw_node;

    // Don't render filters if they are in error.
    if node.is_in_error() {
        return;
    }

    node.with_impl(move |filter: &T| filter.render(ctx));
}
<|endoftext|>


<commit_before>fn make_squares_list(n: i32) -> Vec<i32> {
    let mut re: Vec<i32> = vec![];
    for i in 0..n {
        let temp = i * i;
        if temp > n {
            break;
        } else {
            re.push(temp);
        }
    }

    re
}

fn main() {}
<commit_msg>finish<commit_after>fn make_squares_list(n: i32) -> Vec<i32> {
    let mut re: Vec<i32> = vec![];
    for i in 0..n + 1 {
        let temp = i * i;
        if temp > n {
            break;
        } else {
            re.push(temp);
        }
    }

    re
}

fn sum_list(l1: &Vec<i32>, l2: &Vec<i32>) -> Vec<i32> {
    let mut temp: Vec<Vec<i32>> = l1
        .iter()
        .map(|a| l2.iter().map(|b| b + a).collect())
        .collect();

    let mut re: Vec<i32> = vec![];
    for i in temp.iter_mut() {
        re.append(i);
    }

    re
}

fn gen_all_nums(time: &mut u32, basic: &Vec<i32>) -> Vec<i32> {
    let mut re: Vec<i32> = sum_list(basic, basic);
    while (*time > 2) {
        let temp = re.clone();
        re.append(&mut sum_list(basic, &temp));
        *time -= 1;
        //println!("{:?}", re);
    }
    re
}

fn ps(n: i32) -> i32 {
    let basic_list = make_squares_list(n);

    for i in 2..4 {
        if gen_all_nums(&mut (i as u32), &basic_list).contains(&n) {
            return i;
        }
    }

    0
}

fn main() {
    //println!("{:?}", make_squares_list(5));
    //println!("{:?}", sum_list(&vec![1, 2, 3], &vec![4, 5, 6]));
    //println!("{:?}", gen_all_nums(&mut (2 as u32), &vec![1, 2]));

    println!("{:?}", ps(13)); //=> 2
    println!("{:?}", ps(3)); //=> 3
    println!("{:?}", ps(12)); //=> 3
}
<|endoftext|>


<commit_before>/*
Copyright 2017-2019 Aron Heinecke

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
use chrono;
use csv;
use json;
use log4rs;
use mysql;
use regex;
use reqwest;
use std;
use std::io;
use toml;
use ts3_query;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        Toml(err: toml::de::Error) {
            from()
            description("toml error")
            display("toml error: {}",err)
            cause(err)
        }
        Io(err: io::Error) {
            from()
            description("io error")
            display("I/O error: {}", err)
            cause(err)
        }
        Http(err: reqwest::Error) {
            from()
            description("http error")
            display("http error: {}",err)
            cause(err)
        }
        Json(err: json::Error) {
            from()
            description("json error")
            display("json error: {}",err)
            cause(err)
        }
        Parser(descr: String) {
            description(descr)
            display("Error: {}",descr)
        }
        Regex(err: regex::Error) {
            from()
            description("regex error")
            display("regex error: {}",err)
            cause(err)
        }
        IntParseError(err: std::num::ParseIntError) {
            from()
            description("int parse error")
            display("parse error: {}",err)
            cause(err)
        }
        DateParseError(err: chrono::ParseError) {
            from()
            description(err.description())
            display("parse error: {}",err)
            cause(err)
        }
        Mariadb(err: mysql::Error) {
            from()
            description("mariadb error")
            display("mariadb error: {}",err)
            cause(err)
        }
        RowParse(err: mysql::FromRowError) {
            from()
            description("row parse error")
            display("RowParse: {}",err)
            cause(err)
        }
        ValueParse(err: mysql::FromValueError) {
            from()
            description("row value parse error")
            display("ValueParse: {}",err)
            cause(err)
        }
        Log(err: log4rs::Error) {
            from()
            description("log4rs error")
            display("log4rs error: {}",err)
            cause(err)
        }
        NoValue(descr: &'static str) {
            description(descr)
            display("no value {}",descr)
        }
        CSV(err: csv::Error) {
            from()
            description("csv error")
            display("csv error: {}",err)
            cause(err)
        }
        InvalidDBSetup(descr: String) {
            description(descr)
            display("Error {}", descr)
        }
        Other(descr: &'static str) {
            description(descr)
            display("Error {}", descr)
        }
        TSError(err: ts3_query::Ts3Error) {
            from()
            display("ts3 error")
            description(err.description())
            cause(err)
        }
        MissingKey(key: &'static str) {
            display("Key {} not found in db!",key)
        }
    }
}
<commit_msg>Improve error reporting for ts3error & missingkey<commit_after>/*
Copyright 2017-2019 Aron Heinecke

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
use chrono;
use csv;
use json;
use log4rs;
use mysql;
use regex;
use reqwest;
use std;
use std::io;
use toml;
use ts3_query;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        Toml(err: toml::de::Error) {
            from()
            description("toml error")
            display("toml error: {}",err)
            cause(err)
        }
        Io(err: io::Error) {
            from()
            description("io error")
            display("I/O error: {}", err)
            cause(err)
        }
        Http(err: reqwest::Error) {
            from()
            description("http error")
            display("http error: {}",err)
            cause(err)
        }
        Json(err: json::Error) {
            from()
            description("json error")
            display("json error: {}",err)
            cause(err)
        }
        Parser(descr: String) {
            description(descr)
            display("Error: {}",descr)
        }
        Regex(err: regex::Error) {
            from()
            description("regex error")
            display("regex error: {}",err)
            cause(err)
        }
        IntParseError(err: std::num::ParseIntError) {
            from()
            description("int parse error")
            display("parse error: {}",err)
            cause(err)
        }
        DateParseError(err: chrono::ParseError) {
            from()
            description(err.description())
            display("parse error: {}",err)
            cause(err)
        }
        Mariadb(err: mysql::Error) {
            from()
            description("mariadb error")
            display("mariadb error: {}",err)
            cause(err)
        }
        RowParse(err: mysql::FromRowError) {
            from()
            description("row parse error")
            display("RowParse: {}",err)
            cause(err)
        }
        ValueParse(err: mysql::FromValueError) {
            from()
            description("row value parse error")
            display("ValueParse: {}",err)
            cause(err)
        }
        Log(err: log4rs::Error) {
            from()
            description("log4rs error")
            display("log4rs error: {}",err)
            cause(err)
        }
        NoValue(descr: &'static str) {
            description(descr)
            display("no value {}",descr)
        }
        CSV(err: csv::Error) {
            from()
            description("csv error")
            display("csv error: {}",err)
            cause(err)
        }
        InvalidDBSetup(descr: String) {
            description(descr)
            display("Error {}", descr)
        }
        Other(descr: &'static str) {
            description(descr)
            display("Error {}", descr)
        }
        TSError(err: ts3_query::Ts3Error) {
            from()
            display("ts3 error: {}",err)
            description(err.description())
            cause(err)
        }
        MissingKey(key: &'static str) {
            description("Required settings key not found in db")
            display("Key {} not found in db!",key)
        }
    }
}
<|endoftext|>


<commit_before>fn main() {
    let data: [u8; 1024*1024*1024] = [42; 1024*1024*1024];
    //~^ ERROR: reached the configured maximum execution time
    assert_eq!(data.len(), 1024*1024*1024);
}
<commit_msg>repeat expressions abort due to OOM instead of execution time exhaustion<commit_after>fn main() {
    let data: [u8; 1024*1024*1024] = [42; 1024*1024*1024];
    //~^ ERROR: tried to allocate
    assert_eq!(data.len(), 1024*1024*1024);
}
<|endoftext|>


<commit_before>use support::rustc_host;
use support::{basic_lib_manifest, project};

#[test]
fn pathless_tools() {
    let target = rustc_host();

    let foo = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{}]
            ar = "nonexistent-ar"
            linker = "nonexistent-linker"
        "#,
                target
            ),
        ).build();

    foo.cargo("build --verbose")
        .with_stderr(
            "\
[COMPILING] foo v0.5.0 ([CWD])
[RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
        ).run();
}

#[test]
fn absolute_tools() {
    let target = rustc_host();
    let root = if cfg!(windows) { r#"C:\"# } else { "/" };

    // Escaped as they appear within a TOML config file
    let config = if cfg!(windows) {
        (
            r#"C:\\bogus\\nonexistent-ar"#,
            r#"C:\\bogus\\nonexistent-linker"#,
        )
    } else {
        (r#"/bogus/nonexistent-ar"#, r#"/bogus/nonexistent-linker"#)
    };

    let foo = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{target}]
            ar = "{ar}"
            linker = "{linker}"
        "#,
                target = target,
                ar = config.0,
                linker = config.1
            ),
        ).build();

    foo.cargo("build --verbose").with_stderr(&format!(
            "\
[COMPILING] foo v0.5.0 ([CWD])
[RUNNING] `rustc [..] -C ar={root}bogus/nonexistent-ar -C linker={root}bogus/nonexistent-linker [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
            root = root,
        )).run();
}

#[test]
fn relative_tools() {
    let target = rustc_host();

    // Escaped as they appear within a TOML config file
    let config = if cfg!(windows) {
        (r#".\\nonexistent-ar"#, r#".\\tools\\nonexistent-linker"#)
    } else {
        (r#"./nonexistent-ar"#, r#"./tools/nonexistent-linker"#)
    };

    // Funky directory structure to test that relative tool paths are made absolute
    // by reference to the `.cargo/..` directory and not to (for example) the CWD.
    let p = project()
        .no_manifest()
        .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
        .file("bar/src/lib.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{target}]
            ar = "{ar}"
            linker = "{linker}"
        "#,
                target = target,
                ar = config.0,
                linker = config.1
            ),
        ).build();

    let prefix = p.root().into_os_string().into_string().unwrap();

    p.cargo("build --verbose").cwd(p.root().join("bar")).with_stderr(&format!(
            "\
[COMPILING] bar v0.5.0 ([CWD])
[RUNNING] `rustc [..] -C ar={prefix}/./nonexistent-ar -C linker={prefix}/./tools/nonexistent-linker [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
            prefix = prefix,
        )).run();
}

#[test]
fn custom_runner() {
    let target = rustc_host();

    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file("tests/test.rs", "")
        .file("benches/bench.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{}]
            runner = "nonexistent-runner -r"
        "#,
                target
            ),
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(
            "\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param`
",
        ).run();

    p.cargo("test --test test --verbose -- --param")
        .with_status(101)
        .with_stderr_contains(
            "\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r [..]/target/debug/deps/test-[..][EXE] --param`
",
        ).run();

    p.cargo("bench --bench bench --verbose -- --param")
        .with_status(101)
        .with_stderr_contains(
            "\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc [..]`
[RUNNING] `rustc [..]`
[FINISHED] release [optimized] target(s) in [..]
[RUNNING] `nonexistent-runner -r [..]/target/release/deps/bench-[..][EXE] --param --bench`
",
        ).run();
}

// can set a custom runner via `target.'cfg(..)'.runner`
#[test]
fn custom_runner_cfg() {
    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config",
            r#"
            [target.'cfg(not(target_os = "none"))']
            runner = "nonexistent-runner -r"
            "#,
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(&format!(
            "\
[COMPILING] foo v0.0.1 (CWD)
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param`
",
        )).run();
}

// custom runner set via `target.$triple.runner` have precende over `target.'cfg(..)'.runner`
#[test]
fn custom_runner_cfg_precedence() {
    let target = rustc_host();

    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.'cfg(not(target_os = "none"))']
            runner = "ignored-runner"

            [target.{}]
            runner = "nonexistent-runner -r"
        "#,
                target
            ),
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(&format!(
            "\
            [COMPILING] foo v0.0.1 (CWD)
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param`
",
        )).run();
}

#[test]
fn custom_runner_cfg_collision() {
    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config",
            r#"
            [target.'cfg(not(target_arch = "avr"))']
            runner = "true"

            [target.'cfg(not(target_os = "none"))']
            runner = "false"
            "#,
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(&format!(
            "\
[ERROR] several matching instances of `target.'cfg(..)'.runner` in `.cargo/config`
",
        )).run();
}
<commit_msg>Fixed CWD templates in tool_path tests.<commit_after>use support::rustc_host;
use support::{basic_lib_manifest, project};

#[test]
fn pathless_tools() {
    let target = rustc_host();

    let foo = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{}]
            ar = "nonexistent-ar"
            linker = "nonexistent-linker"
        "#,
                target
            ),
        ).build();

    foo.cargo("build --verbose")
        .with_stderr(
            "\
[COMPILING] foo v0.5.0 ([CWD])
[RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
        ).run();
}

#[test]
fn absolute_tools() {
    let target = rustc_host();
    let root = if cfg!(windows) { r#"C:\"# } else { "/" };

    // Escaped as they appear within a TOML config file
    let config = if cfg!(windows) {
        (
            r#"C:\\bogus\\nonexistent-ar"#,
            r#"C:\\bogus\\nonexistent-linker"#,
        )
    } else {
        (r#"/bogus/nonexistent-ar"#, r#"/bogus/nonexistent-linker"#)
    };

    let foo = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{target}]
            ar = "{ar}"
            linker = "{linker}"
        "#,
                target = target,
                ar = config.0,
                linker = config.1
            ),
        ).build();

    foo.cargo("build --verbose").with_stderr(&format!(
            "\
[COMPILING] foo v0.5.0 ([CWD])
[RUNNING] `rustc [..] -C ar={root}bogus/nonexistent-ar -C linker={root}bogus/nonexistent-linker [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
            root = root,
        )).run();
}

#[test]
fn relative_tools() {
    let target = rustc_host();

    // Escaped as they appear within a TOML config file
    let config = if cfg!(windows) {
        (r#".\\nonexistent-ar"#, r#".\\tools\\nonexistent-linker"#)
    } else {
        (r#"./nonexistent-ar"#, r#"./tools/nonexistent-linker"#)
    };

    // Funky directory structure to test that relative tool paths are made absolute
    // by reference to the `.cargo/..` directory and not to (for example) the CWD.
    let p = project()
        .no_manifest()
        .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
        .file("bar/src/lib.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{target}]
            ar = "{ar}"
            linker = "{linker}"
        "#,
                target = target,
                ar = config.0,
                linker = config.1
            ),
        ).build();

    let prefix = p.root().into_os_string().into_string().unwrap();

    p.cargo("build --verbose").cwd(p.root().join("bar")).with_stderr(&format!(
            "\
[COMPILING] bar v0.5.0 ([CWD])
[RUNNING] `rustc [..] -C ar={prefix}/./nonexistent-ar -C linker={prefix}/./tools/nonexistent-linker [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
            prefix = prefix,
        )).run();
}

#[test]
fn custom_runner() {
    let target = rustc_host();

    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file("tests/test.rs", "")
        .file("benches/bench.rs", "")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.{}]
            runner = "nonexistent-runner -r"
        "#,
                target
            ),
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(
            "\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param`
",
        ).run();

    p.cargo("test --test test --verbose -- --param")
        .with_status(101)
        .with_stderr_contains(
            "\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r [..]/target/debug/deps/test-[..][EXE] --param`
",
        ).run();

    p.cargo("bench --bench bench --verbose -- --param")
        .with_status(101)
        .with_stderr_contains(
            "\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc [..]`
[RUNNING] `rustc [..]`
[FINISHED] release [optimized] target(s) in [..]
[RUNNING] `nonexistent-runner -r [..]/target/release/deps/bench-[..][EXE] --param --bench`
",
        ).run();
}

// can set a custom runner via `target.'cfg(..)'.runner`
#[test]
fn custom_runner_cfg() {
    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config",
            r#"
            [target.'cfg(not(target_os = "none"))']
            runner = "nonexistent-runner -r"
            "#,
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(&format!(
            "\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param`
",
        )).run();
}

// custom runner set via `target.$triple.runner` have precende over `target.'cfg(..)'.runner`
#[test]
fn custom_runner_cfg_precedence() {
    let target = rustc_host();

    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config",
            &format!(
                r#"
            [target.'cfg(not(target_os = "none"))']
            runner = "ignored-runner"

            [target.{}]
            runner = "nonexistent-runner -r"
        "#,
                target
            ),
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(&format!(
            "\
            [COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param`
",
        )).run();
}

#[test]
fn custom_runner_cfg_collision() {
    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config",
            r#"
            [target.'cfg(not(target_arch = "avr"))']
            runner = "true"

            [target.'cfg(not(target_os = "none"))']
            runner = "false"
            "#,
        ).build();

    p.cargo("run -- --param")
        .with_status(101)
        .with_stderr_contains(&format!(
            "\
[ERROR] several matching instances of `target.'cfg(..)'.runner` in `.cargo/config`
",
        )).run();
}
<|endoftext|>


<commit_before>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*===============================================================================================*/

extern crate ion_core;
extern crate sdl2;

use self::ion_core::renderer::traits::WindowBackend;
use self::ion_core::renderer::window::{WindowConfig, WindowState};
use self::ion_core::util::traits::AsAny;
use self::sdl2::event::Event;

use std::any::Any;
use std::os::raw::c_void;

/*===============================================================================================*/
/*------WINDOW BACKEND SDL2 STRUCT---------------------------------------------------------------*/
/*===============================================================================================*/

/// Allows for the creation and handling of a SDL2 window.
pub struct WindowBackendSDL2 {

    // Private
    _window_state:    WindowState,
    _sdl2_context:    Option<sdl2::Sdl>,
    _sdl2_video:      Option<sdl2::VideoSubsystem>,
    _sdl2_window:     Option<sdl2::video::Window>,
    _sdl2_event_pump: Option<sdl2::EventPump>
}

/*===============================================================================================*/
/*------WINDOW BACKEND SDL2 PUBLIC METHODS-------------------------------------------------------*/
/*===============================================================================================*/

impl AsAny for WindowBackendSDL2 {

    fn as_any (&self) -> &Any {
        self
    }
}

/*-----------------------------------------------------------------------------------------------*/

impl WindowBackend for WindowBackendSDL2 {

    fn init (&mut self, config: &WindowConfig) {

        // Initialize sdl and video subsystem
        let sdl2_context = sdl2::init ().unwrap ();
        let sdl2_video   = sdl2_context.video ().unwrap ();

        // Create new sdl2 window builder
        let mut sdl2_window_builder = sdl2_video.window (&config.window_title,
            config.window_size.x as u32,
            config.window_size.y as u32);

        // Enable OpenGL and set window position
        sdl2_window_builder.opengl ()
            .position (config.window_pos.x as i32, config.window_pos.y as i32);

        // Set fullscreen and resizable state
        if config.window_is_fullscreen {sdl2_window_builder.fullscreen ();}
        if config.window_is_resizable  {sdl2_window_builder.resizable  ();}

        // Create the sdl2 window and event pump
        let sdl2_window     = sdl2_window_builder.build ().unwrap ();
        let sdl2_event_pump = sdl2_context.event_pump   ().unwrap ();

        // Set window backend variables
        self._sdl2_context    = Some (sdl2_context);
        self._sdl2_video      = Some (sdl2_video);
        self._sdl2_event_pump = Some (sdl2_event_pump);
        self._sdl2_window     = Some (sdl2_window);
        self._window_state    = WindowState::Active;
    }

/*-----------------------------------------------------------------------------------------------*/

    fn get_window_state (&self) -> WindowState {
        self._window_state
    }

/*-----------------------------------------------------------------------------------------------*/

    fn on_pre_render (&mut self) {

        for event in self._sdl2_event_pump.as_mut ().unwrap ().poll_iter () {

            if let Event::Quit {..} = event {
                self._window_state = WindowState::Closed
            }
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    fn on_render      (&mut self) {}
    fn on_post_render (&mut self) {}

/*-----------------------------------------------------------------------------------------------*/

    unsafe fn get_platform_display (&self) -> Result<*mut c_void, ()> {
        unimplemented! ()
    }

/*-----------------------------------------------------------------------------------------------*/

    unsafe fn get_platform_window (&self) -> Result<*mut c_void, ()> {
        unimplemented! ()
    }
}

/*===============================================================================================*/
/*------WINDOW BACKEND SDL2 PUBLIC STATIC METHODS------------------------------------------------*/
/*===============================================================================================*/

impl WindowBackendSDL2 {

    /// Returns a new `WindowBackendSDL2` instance.
    pub fn new () -> WindowBackendSDL2 {

        WindowBackendSDL2 {

            _window_state:    WindowState::Closed,
            _sdl2_context:    None,
            _sdl2_video:      None,
            _sdl2_event_pump: None,
            _sdl2_window:     None,
        }
    }
}

/*-----------------------------------------------------------------------------------------------*/

impl Default for WindowBackendSDL2 {

    fn default () -> WindowBackendSDL2 {
        WindowBackendSDL2::new ()
    }
}
<commit_msg>Made window variables public<commit_after>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*===============================================================================================*/

extern crate ion_core;
extern crate sdl2;

use self::ion_core::renderer::traits::WindowBackend;
use self::ion_core::renderer::window::{WindowConfig, WindowState};
use self::ion_core::util::traits::AsAny;
use self::sdl2::event::Event;

use std::any::Any;
use std::os::raw::c_void;

/*===============================================================================================*/
/*------WINDOW BACKEND SDL2 STRUCT---------------------------------------------------------------*/
/*===============================================================================================*/

/// Allows for the creation and handling of a SDL2 window.
pub struct WindowBackendSDL2 {

    // Public
    /// Stores the current window state.
    pub window_state:    WindowState,
    /// Stores the sdl2 context.
    pub sdl2_context:    Option<sdl2::Sdl>,
    /// Stores the video subsystem.
    pub sdl2_video:      Option<sdl2::VideoSubsystem>,
    /// Stores the sdl2 window.
    pub sdl2_window:     Option<sdl2::video::Window>,
    /// Stores the sdl2 event pump.
    pub sdl2_event_pump: Option<sdl2::EventPump>
}

/*===============================================================================================*/
/*------WINDOW BACKEND SDL2 PUBLIC METHODS-------------------------------------------------------*/
/*===============================================================================================*/

impl AsAny for WindowBackendSDL2 {

    fn as_any (&self) -> &Any {
        self
    }
}

/*-----------------------------------------------------------------------------------------------*/

impl WindowBackend for WindowBackendSDL2 {

    fn init (&mut self, config: &WindowConfig) {

        // Initialize sdl and video subsystem
        let sdl2_context = sdl2::init ().unwrap ();
        let sdl2_video   = sdl2_context.video ().unwrap ();

        // Create new sdl2 window builder
        let mut sdl2_window_builder = sdl2_video.window (&config.window_title,
            config.window_size.x as u32,
            config.window_size.y as u32);

        // Enable OpenGL and set window position
        sdl2_window_builder.opengl ()
            .position (config.window_pos.x as i32, config.window_pos.y as i32);

        // Set fullscreen and resizable state
        if config.window_is_fullscreen {sdl2_window_builder.fullscreen ();}
        if config.window_is_resizable  {sdl2_window_builder.resizable  ();}

        // Create the sdl2 window and event pump
        let sdl2_window     = sdl2_window_builder.build ().unwrap ();
        let sdl2_event_pump = sdl2_context.event_pump   ().unwrap ();

        // Set window backend variables
        self.sdl2_context    = Some (sdl2_context);
        self.sdl2_video      = Some (sdl2_video);
        self.sdl2_event_pump = Some (sdl2_event_pump);
        self.sdl2_window     = Some (sdl2_window);
        self.window_state    = WindowState::Active;
    }

/*-----------------------------------------------------------------------------------------------*/

    fn get_window_state (&self) -> WindowState {
        self.window_state
    }

/*-----------------------------------------------------------------------------------------------*/

    fn on_pre_render (&mut self) {

        for event in self.sdl2_event_pump.as_mut ().unwrap ().poll_iter () {

            if let Event::Quit {..} = event {
                self.window_state = WindowState::Closed
            }
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    fn on_render      (&mut self) {}
    fn on_post_render (&mut self) {}

/*-----------------------------------------------------------------------------------------------*/

    unsafe fn get_platform_display (&self) -> Result<*mut c_void, ()> {
        unimplemented! ()
    }

/*-----------------------------------------------------------------------------------------------*/

    unsafe fn get_platform_window (&self) -> Result<*mut c_void, ()> {
        unimplemented! ()
    }
}

/*===============================================================================================*/
/*------WINDOW BACKEND SDL2 PUBLIC STATIC METHODS------------------------------------------------*/
/*===============================================================================================*/

impl WindowBackendSDL2 {

    /// Returns a new `WindowBackendSDL2` instance.
    pub fn new () -> WindowBackendSDL2 {

        WindowBackendSDL2 {

            window_state:    WindowState::Closed,
            sdl2_context:    None,
            sdl2_video:      None,
            sdl2_event_pump: None,
            sdl2_window:     None,
        }
    }
}

/*-----------------------------------------------------------------------------------------------*/

impl Default for WindowBackendSDL2 {

    fn default () -> WindowBackendSDL2 {
        WindowBackendSDL2::new ()
    }
}
<|endoftext|>