<commit_before>use cocoa::base::{id, nil};
use cocoa::foundation::{NSUInteger, NSString};
use objc::runtime::{BOOL, NO, YES};
use sys::{MTLCreateSystemDefaultDevice, MTLCopyAllDevices, MTLDevice};
use std::borrow::Cow;
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::ffi::CStr;
use {Size};

pub trait ReadOnlyDevice {
    fn is_headless(&self) -> bool;
    fn is_low_power(&self) -> bool;
    fn max_threads_per_group(&self) -> bool;
    fn get_name(&self) -> Cow<str>;
    fn supports_texture_sample_count(&self, sample_count: usize) -> bool;
}

pub struct Device(id);

impl Device {
    pub fn system_default_device() -> Result<Self, DeviceError> {
        let device = unsafe { MTLCreateSystemDefaultDevice() };
        if device != nil {
            Ok(Device(device))
        } else {
            Err(DeviceError::ConstructionFailed)
        }
    }

    #[allow(unused_mut, unused_variables)]
    pub fn enumerate_all_system_devices() -> Vec<Result<Self, DeviceError>> {
        let all_devices = unsafe { MTLCopyAllDevices() };
        let mut devices_vec = vec![];

        devices_vec
    }

    pub unsafe fn into_raw(self) -> id {
        self.0
    }

    pub unsafe fn from_raw_unchecked(device_ptr: id) -> Self {
        Device(device_ptr)
    }

    pub fn from_raw(device_ptr: id) -> Result<Self, DeviceError> {
        #[link(name = "Foundation", kind = "framework")]
        extern {
            fn NSProtocolFromString(namestr: id) -> id;
        }

        let conforms_to_protocol: BOOL = unsafe {
            let mtl_device_protocol_str = NSString::alloc(nil).init_str("MTLDevice");
            let mtl_device_protocol = NSProtocolFromString(mtl_device_protocol_str);
            msg_send![device_ptr, conformsToProtocol:mtl_device_protocol]
        };

        if device_ptr == nil {
            Err(DeviceError::ConstructedFromNil)
        } else if conforms_to_protocol == NO {
            Err(DeviceError::ConstructedFromWrongPointerType)
        } else {
            Ok(Device(device_ptr))
        }
    }

    pub fn is_headless(&self) -> bool {
        unsafe { self.0.headless() == YES }
    }

    pub fn is_low_power(&self) -> bool {
        unsafe { self.0.lowPower() == YES }
    }

    pub fn max_threads_per_group(&self) -> Size {
        unsafe { self.0.maxThreadsPerGroup().into() }
    }

    pub fn get_name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn supports_texture_sample_count(&self, sample_count: usize) -> bool {
        unsafe { self.0.supportsTextureSampleCount(sample_count as NSUInteger) == YES }
    }
}

/// Internal utility function to get a Device's id without consuming it.
/// Not exported publicly from this crate.
#[doc(hidden)]
pub unsafe fn _device_get_raw(device: &Device) -> id {
    device.0
}

#[derive(Clone, Debug)]
pub enum DeviceError {
    ConstructionFailed,
    ConstructedFromNil,
    ConstructedFromWrongPointerType,
    OtherRuntimeError
}

impl Display for DeviceError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let descr = match *self {
            DeviceError::ConstructionFailed => "DeviceError::ConstructionFailed",
            DeviceError::ConstructedFromNil => "DeviceError::ConstructedFromNil",
            DeviceError::ConstructedFromWrongPointerType => "DeviceError::ConstructedFromWrongPointerType",
            DeviceError::OtherRuntimeError => "DeviceError::OtherRuntimeError"
        };
        write!(f, "{}", descr)
    }
}

impl Error for DeviceError {
    fn description(&self) -> &str {
        match *self {
            DeviceError::ConstructionFailed =>
                "Could not create a default device. Please ensure that you are using at least OSX 10.11 or iOS 8.0",
            DeviceError::ConstructedFromNil => "Attempted to create a device from a nil pointer",
            DeviceError::ConstructedFromWrongPointerType =>
                "Attempted to create a device from a pointer which does not implement MTLDevice",
            DeviceError::OtherRuntimeError => "An error occured in the Objective-C runtime"
        }
    }
}
<commit_msg>Add and implement is_depth24_stencil8_pixel_format_supported for/to ReadOnlyDevice and Device<commit_after>use cocoa::base::{id, nil};
use cocoa::foundation::{NSUInteger, NSString};
use objc::runtime::{BOOL, NO, YES};
use sys::{MTLCreateSystemDefaultDevice, MTLCopyAllDevices, MTLDevice};
use std::borrow::Cow;
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::ffi::CStr;
use {Size};

pub trait ReadOnlyDevice {
    fn is_depth24_stencil8_pixel_format_supported(&self) -> bool;
    fn is_headless(&self) -> bool;
    fn is_low_power(&self) -> bool;
    fn max_threads_per_group(&self) -> bool;
    fn get_name(&self) -> Cow<str>;
    fn supports_texture_sample_count(&self, sample_count: usize) -> bool;
}

pub struct Device(id);

impl Device {
    pub fn system_default_device() -> Result<Self, DeviceError> {
        let device = unsafe { MTLCreateSystemDefaultDevice() };
        if device != nil {
            Ok(Device(device))
        } else {
            Err(DeviceError::ConstructionFailed)
        }
    }

    #[allow(unused_mut, unused_variables)]
    pub fn enumerate_all_system_devices() -> Vec<Result<Self, DeviceError>> {
        let all_devices = unsafe { MTLCopyAllDevices() };
        let mut devices_vec = vec![];

        devices_vec
    }

    pub unsafe fn into_raw(self) -> id {
        self.0
    }

    pub unsafe fn from_raw_unchecked(device_ptr: id) -> Self {
        Device(device_ptr)
    }

    pub fn from_raw(device_ptr: id) -> Result<Self, DeviceError> {
        #[link(name = "Foundation", kind = "framework")]
        extern {
            fn NSProtocolFromString(namestr: id) -> id;
        }

        let conforms_to_protocol: BOOL = unsafe {
            let mtl_device_protocol_str = NSString::alloc(nil).init_str("MTLDevice");
            let mtl_device_protocol = NSProtocolFromString(mtl_device_protocol_str);
            msg_send![device_ptr, conformsToProtocol:mtl_device_protocol]
        };

        if device_ptr == nil {
            Err(DeviceError::ConstructedFromNil)
        } else if conforms_to_protocol == NO {
            Err(DeviceError::ConstructedFromWrongPointerType)
        } else {
            Ok(Device(device_ptr))
        }
    }

    pub fn is_depth24_stencil8_pixel_format_supported(&self) -> bool {
        unsafe { self.0.depth24Stencil8PixelFormatSupported() == YES }
    }

    pub fn is_headless(&self) -> bool {
        unsafe { self.0.headless() == YES }
    }

    pub fn is_low_power(&self) -> bool {
        unsafe { self.0.lowPower() == YES }
    }

    pub fn max_threads_per_group(&self) -> Size {
        unsafe { self.0.maxThreadsPerGroup().into() }
    }

    pub fn get_name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn supports_texture_sample_count(&self, sample_count: usize) -> bool {
        unsafe { self.0.supportsTextureSampleCount(sample_count as NSUInteger) == YES }
    }
}

/// Internal utility function to get a Device's id without consuming it.
/// Not exported publicly from this crate.
#[doc(hidden)]
pub unsafe fn _device_get_raw(device: &Device) -> id {
    device.0
}

#[derive(Clone, Debug)]
pub enum DeviceError {
    ConstructionFailed,
    ConstructedFromNil,
    ConstructedFromWrongPointerType,
    OtherRuntimeError
}

impl Display for DeviceError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let descr = match *self {
            DeviceError::ConstructionFailed => "DeviceError::ConstructionFailed",
            DeviceError::ConstructedFromNil => "DeviceError::ConstructedFromNil",
            DeviceError::ConstructedFromWrongPointerType => "DeviceError::ConstructedFromWrongPointerType",
            DeviceError::OtherRuntimeError => "DeviceError::OtherRuntimeError"
        };
        write!(f, "{}", descr)
    }
}

impl Error for DeviceError {
    fn description(&self) -> &str {
        match *self {
            DeviceError::ConstructionFailed =>
                "Could not create a default device. Please ensure that you are using at least OSX 10.11 or iOS 8.0",
            DeviceError::ConstructedFromNil => "Attempted to create a device from a nil pointer",
            DeviceError::ConstructedFromWrongPointerType =>
                "Attempted to create a device from a pointer which does not implement MTLDevice",
            DeviceError::OtherRuntimeError => "An error occured in the Objective-C runtime"
        }
    }
}
<|endoftext|>


<commit_before>/// The most generic error message in ReQL
#[derive(Debug)]
pub enum Error {
    Compile(CompileError),
    Runtime(RuntimeError),
    Driver(DriverError),
}

impl From<CompileError> for Error {
    fn from(err: CompileError) -> Error {
        Error::Compile(err)
    }
}

impl From<RuntimeError> for Error {
    fn from(err: RuntimeError) -> Error {
        Error::Runtime(err)
    }
}

impl From<DriverError> for Error {
    fn from(err: DriverError) -> Error {
        Error::Driver(err)
    }
}

/// The query cannot be compiled by the server
///
/// This may be due to a syntax error, such as an unrecognized optional argument, or specifying the
/// wrong number of arguments to a command.
#[derive(Debug)]
pub enum CompileError {}

/// The parent class of all runtime errors
///
/// All errors on the server unrelated to compilation. Programs may use this to catch any runtime
/// error, but the server will always return a more specific error class.
#[derive(Debug)]
pub enum RuntimeError {
    QueryLogic(QueryLogicError),
    ResourceLimit(ResourceLimitError),
    User(UserError),
    Internal(InternalError),
    Timeout(TimeoutError),
    Availability(AvailabilityError),
    Permissions(PermissionsError),
}

/// The query contains a logical impossibility, such as adding a number to a string.
#[derive(Debug)]
pub enum QueryLogicError {
    NonExistence(NonExistenceError),
}

/// A `QueryLogicError` that results from accessing a non-existent field or something else that
/// can be handled with the default command.
#[derive(Debug)]
pub enum NonExistenceError {}

/// Query execution caused a resource limit (for example, the array size limit) to be exceeded.
#[derive(Debug)]
pub enum ResourceLimitError {}

/// An error produced by the error command.
#[derive(Debug)]
pub enum UserError {}

/// Query execution stopped due to an internal error, i.e., a server bug.
#[derive(Debug)]
pub enum InternalError {}

/// The query has timed out
///
/// This error happens on the client, not the server. Depending on driver implementation it may
/// derive from a native error class rather than `Error`.
#[derive(Debug)]
pub enum TimeoutError {}

/// A server in the cluster is unavailable
///
/// The parent class of `OpFailedError` and `OpIndeterminateError`. Programs may use this
/// to catch any availability error, but the server will always return one of this class’s
/// children.
#[derive(Debug)]
pub enum AvailabilityError {
    OpFailed(OpFailedError),
    OpIndeterminate(OpIndeterminateError),
}

/// The operation has failed due to cluster state, configuration or table availability.
#[derive(Debug)]
pub enum OpFailedError {}

/// The status of the operation cannot be verified due to cluster state, configuration or table
/// availability.
#[derive(Debug)]
pub enum OpIndeterminateError {}

/// The user account does not have the permissions necessary to execute the query.
#[derive(Debug)]
pub enum PermissionsError {}

/// An error has occurred within the driver
///
/// This may be a driver bug, or it may be an unfulfillable command, such as an unserializable
/// query.
#[derive(Debug)]
pub enum DriverError {
    Auth(AuthError),
}

/// The client failed authentication with the server.
#[derive(Debug)]
pub enum AuthError {}
<commit_msg>Implement errors<commit_after>use std::error::Error as StdError;
use std::fmt;

/// The most generic error message in ReQL
#[derive(Debug)]
pub enum Error {
    Compile(CompileError),
    Runtime(RuntimeError),
    Driver(DriverError),
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Compile(ref err) => err.description(),
            Error::Runtime(ref err) => err.description(),
            Error::Driver(ref err) => err.description(),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Compile(ref err) => err.fmt(f),
            Error::Runtime(ref err) => err.fmt(f),
            Error::Driver(ref err) => err.fmt(f),
        }
    }
}

impl From<CompileError> for Error {
    fn from(err: CompileError) -> Error {
        Error::Compile(err)
    }
}

impl From<RuntimeError> for Error {
    fn from(err: RuntimeError) -> Error {
        Error::Runtime(err)
    }
}

impl From<DriverError> for Error {
    fn from(err: DriverError) -> Error {
        Error::Driver(err)
    }
}

/// The query cannot be compiled by the server
///
/// This may be due to a syntax error, such as an unrecognized optional argument, or specifying the
/// wrong number of arguments to a command.
#[derive(Debug)]
pub struct CompileError;

impl StdError for CompileError {
    fn description(&self) -> &str {
        "The query cannot be compiled by the server"
    }
}

impl fmt::Display for CompileError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "The query cannot be compiled by the server.")
    }
}

/// The parent class of all runtime errors
///
/// All errors on the server unrelated to compilation. Programs may use this to catch any runtime
/// error, but the server will always return a more specific error class.
#[derive(Debug)]
pub enum RuntimeError {
    QueryLogic(QueryLogicError),
    ResourceLimit(ResourceLimitError),
    User(UserError),
    Internal(InternalError),
    Timeout(TimeoutError),
    Availability(AvailabilityError),
    Permissions(PermissionsError),
}

impl StdError for RuntimeError {
    fn description(&self) -> &str {
        match *self {
            RuntimeError::QueryLogic(ref err) => err.description(),
            RuntimeError::ResourceLimit(ref err) => err.description(),
            RuntimeError::User(ref err) => err.description(),
            RuntimeError::Internal(ref err) => err.description(),
            RuntimeError::Timeout(ref err) => err.description(),
            RuntimeError::Availability(ref err) => err.description(),
            RuntimeError::Permissions(ref err) => err.description(),
        }
    }
}

impl fmt::Display for RuntimeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            RuntimeError::QueryLogic(ref err) => err.fmt(f),
            RuntimeError::ResourceLimit(ref err) => err.fmt(f),
            RuntimeError::User(ref err) => err.fmt(f),
            RuntimeError::Internal(ref err) => err.fmt(f),
            RuntimeError::Timeout(ref err) => err.fmt(f),
            RuntimeError::Availability(ref err) => err.fmt(f),
            RuntimeError::Permissions(ref err) => err.fmt(f),
        }
    }
}

impl From<QueryLogicError> for RuntimeError {
    fn from(err: QueryLogicError) -> RuntimeError {
        RuntimeError::QueryLogic(err)
    }
}

impl From<ResourceLimitError> for RuntimeError {
    fn from(err: ResourceLimitError) -> RuntimeError {
        RuntimeError::ResourceLimit(err)
    }
}

impl From<UserError> for RuntimeError {
    fn from(err: UserError) -> RuntimeError {
        RuntimeError::User(err)
    }
}

impl From<InternalError> for RuntimeError {
    fn from(err: InternalError) -> RuntimeError {
        RuntimeError::Internal(err)
    }
}

impl From<TimeoutError> for RuntimeError {
    fn from(err: TimeoutError) -> RuntimeError {
        RuntimeError::Timeout(err)
    }
}

impl From<AvailabilityError> for RuntimeError {
    fn from(err: AvailabilityError) -> RuntimeError {
        RuntimeError::Availability(err)
    }
}

impl From<PermissionsError> for RuntimeError {
    fn from(err: PermissionsError) -> RuntimeError {
        RuntimeError::Permissions(err)
    }
}

/// The query contains a logical impossibility, such as adding a number to a string.
#[derive(Debug)]
pub enum QueryLogicError {
    NonExistence(NonExistenceError),
}

impl StdError for QueryLogicError {
    fn description(&self) -> &str {
        match *self {
            QueryLogicError::NonExistence(ref err) => err.description(),
        }
    }
}

impl fmt::Display for QueryLogicError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            QueryLogicError::NonExistence(ref err) => err.fmt(f),
        }
    }
}

impl From<NonExistenceError> for QueryLogicError {
    fn from(err: NonExistenceError) -> QueryLogicError {
        QueryLogicError::NonExistence(err)
    }
}

/// A `QueryLogicError` that results from accessing a non-existent field or something else that
/// can be handled with the default command.
#[derive(Debug)]
pub struct NonExistenceError;

impl StdError for NonExistenceError {
    fn description(&self) -> &str {
        "Non-existence error"
    }
}

impl fmt::Display for NonExistenceError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Non-existence error.")
    }
}

/// Query execution caused a resource limit (for example, the array size limit) to be exceeded.
#[derive(Debug)]
pub struct ResourceLimitError;

impl StdError for ResourceLimitError {
    fn description(&self) -> &str {
        "Resource limit error"
    }
}

impl fmt::Display for ResourceLimitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Resource limit error.")
    }
}

/// An error produced by the error command.
#[derive(Debug)]
pub struct UserError;

impl StdError for UserError {
    fn description(&self) -> &str {
        "User error"
    }
}

impl fmt::Display for UserError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "User error.")
    }
}

/// Query execution stopped due to an internal error, i.e., a server bug.
#[derive(Debug)]
pub struct InternalError;

impl StdError for InternalError {
    fn description(&self) -> &str {
        "Server error"
    }
}

impl fmt::Display for InternalError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Server error.")
    }
}

/// The query has timed out
///
/// This error happens on the client, not the server. Depending on driver implementation it may
/// derive from a native error class rather than `Error`.
#[derive(Debug)]
pub struct TimeoutError;

impl StdError for TimeoutError {
    fn description(&self) -> &str {
        "Timeout error"
    }
}

impl fmt::Display for TimeoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Timeout error.")
    }
}

/// A server in the cluster is unavailable
///
/// The parent class of `OpFailedError` and `OpIndeterminateError`. Programs may use this
/// to catch any availability error, but the server will always return one of this class’s
/// children.
#[derive(Debug)]
pub enum AvailabilityError {
    OpFailed(OpFailedError),
    OpIndeterminate(OpIndeterminateError),
}

impl StdError for AvailabilityError {
    fn description(&self) -> &str {
        match *self {
            AvailabilityError::OpFailed(ref err) => err.description(),
            AvailabilityError::OpIndeterminate(ref err) => err.description(),
        }
    }
}

impl fmt::Display for AvailabilityError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            AvailabilityError::OpFailed(ref err) => err.fmt(f),
            AvailabilityError::OpIndeterminate(ref err) => err.fmt(f),
        }
    }
}

impl From<OpFailedError> for AvailabilityError {
    fn from(err: OpFailedError) -> AvailabilityError {
        AvailabilityError::OpFailed(err)
    }
}

impl From<OpIndeterminateError> for AvailabilityError {
    fn from(err: OpIndeterminateError) -> AvailabilityError {
        AvailabilityError::OpIndeterminate(err)
    }
}

/// The operation has failed due to cluster state, configuration or table availability.
#[derive(Debug)]
pub struct OpFailedError;

impl StdError for OpFailedError {
    fn description(&self) -> &str {
        "Operation failed error"
    }
}

impl fmt::Display for OpFailedError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Operation failed error.")
    }
}

/// The status of the operation cannot be verified due to cluster state, configuration or table
/// availability.
#[derive(Debug)]
pub struct OpIndeterminateError;

impl StdError for OpIndeterminateError {
    fn description(&self) -> &str {
        "Operation cannot be verified"
    }
}

impl fmt::Display for OpIndeterminateError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Operation cannot be verified.")
    }
}

/// The user account does not have the permissions necessary to execute the query.
#[derive(Debug)]
pub struct PermissionsError;

impl StdError for PermissionsError {
    fn description(&self) -> &str {
        "Permission error"
    }
}

impl fmt::Display for PermissionsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Permission error.")
    }
}

/// An error has occurred within the driver
///
/// This may be a driver bug, or it may be an unfulfillable command, such as an unserializable
/// query.
#[derive(Debug)]
pub enum DriverError {
    Auth(AuthError),
}

impl StdError for DriverError {
    fn description(&self) -> &str {
        match *self {
            DriverError::Auth(ref err) => err.description(),
        }
    }
}

impl fmt::Display for DriverError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            DriverError::Auth(ref err) => err.fmt(f),
        }
    }
}

impl From<AuthError> for DriverError {
    fn from(err: AuthError) -> DriverError {
        DriverError::Auth(err)
    }
}

/// The client failed authentication with the server.
#[derive(Debug)]
pub struct AuthError;

impl StdError for AuthError {
    fn description(&self) -> &str {
        "The client failed authentication with the server"
    }
}

impl fmt::Display for AuthError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "The client failed authentication with the server.")
    }
}

<|endoftext|>


<commit_before>use bit_vec::BitVec;
use std::slice::Iter;
use lfsr;

#[derive(PartialEq, Debug)]
pub struct GaloisLFSR {
    state: BitVec,
    mask: BitVec,
}

impl GaloisLFSR {
    pub fn from_iter(iter: Iter<usize>) -> Self {
        let &len = iter.clone().max().unwrap();

        let state = BitVec::from_elem(len, true);
        let mut mask = BitVec::from_elem(len, false);

        for &t in iter {
            if t < len {
                // Set the _counterpart_ mask index
                mask.set(len - t, true);
            }
        }
        mask.set(0, true);

        GaloisLFSR { state: state, mask: mask, }
    }

    fn shift(&mut self) {
        lfsr::shift(&mut self.state);
    }

    fn feedback(&mut self) {
        for (i, mb) in self.mask.iter().enumerate() {
            let sb = self.state[i];
            self.state.set(i, mb ^ sb);
        }
    }

    pub fn iter(&mut self) -> lfsr::LFSRIter<GaloisLFSR> {
        lfsr::LFSRIter { lfsr: self }
    }
}

impl lfsr::LFSR for GaloisLFSR {
    fn output(&self) -> bool {
        let len = self.state.len();
        self.state[len - 1]
    }

    fn step(&mut self) {
        let output = self.output();

        self.shift();

        if output {
            self.feedback();
        }
    }
}
<commit_msg>Add IntoIterator impls for GaloisLFSR<commit_after>use bit_vec::BitVec;
use std::slice::Iter;
use lfsr;
use lfsr::LFSR;

#[derive(PartialEq, Debug)]
pub struct GaloisLFSR {
    state: BitVec,
    mask: BitVec,
}

impl GaloisLFSR {
    pub fn from_iter(iter: Iter<usize>) -> Self {
        let &len = iter.clone().max().unwrap();

        let state = BitVec::from_elem(len, true);
        let mut mask = BitVec::from_elem(len, false);

        for &t in iter {
            if t < len {
                // Set the _counterpart_ mask index
                mask.set(len - t, true);
            }
        }
        mask.set(0, true);

        GaloisLFSR { state: state, mask: mask, }
    }

    fn shift(&mut self) {
        lfsr::shift(&mut self.state);
    }

    fn feedback(&mut self) {
        for (i, mb) in self.mask.iter().enumerate() {
            let sb = self.state[i];
            self.state.set(i, mb ^ sb);
        }
    }

    pub fn iter(&mut self) -> lfsr::Iter<GaloisLFSR> {
        lfsr::Iter { lfsr: self }
    }
}

impl LFSR for GaloisLFSR {
    fn output(&self) -> bool {
        let len = self.state.len();
        self.state[len - 1]
    }

    fn step(&mut self) {
        let output = self.output();

        self.shift();

        if output {
            self.feedback();
        }
    }
}
impl IntoIterator for GaloisLFSR {
    type Item = bool;
    type IntoIter = lfsr::IntoIter<GaloisLFSR>;

    fn into_iter(self) -> Self::IntoIter {
        lfsr::IntoIter { lfsr: self }
    }
}

impl<'a> IntoIterator for &'a mut GaloisLFSR {
    type Item = bool;
    type IntoIter = lfsr::Iter<'a, GaloisLFSR>;

    fn into_iter(self) -> Self::IntoIter {
        lfsr::Iter { lfsr: self }
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Simple compression

*/

#![crate_id = "flate#0.11.0-pre"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]
#![feature(phase)]
#![deny(deprecated_owned_vector)]

#[cfg(test)] #[phase(syntax, link)] extern crate log;

extern crate libc;

use std::c_vec::CVec;
use libc::{c_void, size_t, c_int};

pub mod rustrt {
    use libc::{c_void, size_t, c_int};
    #[link(name = "miniz", kind = "static")]
    extern {
        pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
                                          src_buf_len: size_t,
                                          pout_len: *mut size_t,
                                          flags: c_int)
                                          -> *mut c_void;

        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
                                            src_buf_len: size_t,
                                            pout_len: *mut size_t,
                                            flags: c_int)
                                            -> *mut c_void;
    }
}

static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum

fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
    unsafe {
        let mut outsz : size_t = 0;
        let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void,
                                                     bytes.len() as size_t,
                                                     &mut outsz,
                                                     flags);
        if !res.is_null() {
            Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)))
        } else {
            None
        }
    }
}

pub fn deflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
    deflate_bytes_internal(bytes, LZ_NORM)
}

pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
}

fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
    unsafe {
        let mut outsz : size_t = 0;
        let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void,
                                                       bytes.len() as size_t,
                                                       &mut outsz,
                                                       flags);
        if !res.is_null() {
            Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)))
        } else {
            None
        }
    }
}

pub fn inflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
    inflate_bytes_internal(bytes, 0)
}

pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

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

    use super::{inflate_bytes, deflate_bytes};
    use self::rand::Rng;

    #[test]
    #[allow(deprecated_owned_vector)]
    fn test_flate_round_trip() {
        let mut r = rand::task_rng();
        let mut words = vec!();
        for _ in range(0, 20) {
            let range = r.gen_range(1u, 10);
            words.push(r.gen_vec::<u8>(range));
        }
        for _ in range(0, 20) {
            let mut input = vec![];
            for _ in range(0, 2000) {
                input.push_all(r.choose(words.as_slice()).as_slice());
            }
            debug!("de/inflate of {} bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(input.as_slice()).expect("deflation failed");
            let out = inflate_bytes(cmp.as_slice()).expect("inflation failed");
            debug!("{} bytes deflated to {} ({:.1f}% size)",
                   input.len(), cmp.len(),
                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
            assert_eq!(input.as_slice(), out.as_slice());
        }
    }

    #[test]
    fn test_zlib_flate() {
        let bytes = vec!(1, 2, 3, 4, 5);
        let deflated = deflate_bytes(bytes.as_slice()).expect("deflation failed");
        let inflated = inflate_bytes(deflated.as_slice()).expect("inflation failed");
        assert_eq!(inflated.as_slice(), bytes.as_slice());
    }
}
<commit_msg>flate: add documentation<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Simple [DEFLATE][def]-based compression. This is a wrapper around the
[`miniz`][mz] library, which is a one-file pure-C implementation of zlib.

[def]: https://en.wikipedia.org/wiki/DEFLATE
[mz]: https://code.google.com/p/miniz/

*/

#![crate_id = "flate#0.11.0-pre"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]
#![feature(phase)]
#![deny(deprecated_owned_vector)]

#[cfg(test)] #[phase(syntax, link)] extern crate log;

extern crate libc;

use std::c_vec::CVec;
use libc::{c_void, size_t, c_int};

#[link(name = "miniz", kind = "static")]
extern {
    /// Raw miniz compression function.
    fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
                                      src_buf_len: size_t,
                                      pout_len: *mut size_t,
                                      flags: c_int)
                                      -> *mut c_void;

    /// Raw miniz decompression function.
    fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
                                        src_buf_len: size_t,
                                        pout_len: *mut size_t,
                                        flags: c_int)
                                        -> *mut c_void;
}

static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum

fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
    unsafe {
        let mut outsz : size_t = 0;
        let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void,
                                                     bytes.len() as size_t,
                                                     &mut outsz,
                                                     flags);
        if !res.is_null() {
            Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)))
        } else {
            None
        }
    }
}

/// Compress a buffer, without writing any sort of header on the output.
pub fn deflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
    deflate_bytes_internal(bytes, LZ_NORM)
}

/// Compress a buffer, using a header that zlib can understand.
pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
}

fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
    unsafe {
        let mut outsz : size_t = 0;
        let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void,
                                                       bytes.len() as size_t,
                                                       &mut outsz,
                                                       flags);
        if !res.is_null() {
            Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)))
        } else {
            None
        }
    }
}

/// Decompress a buffer, without parsing any sort of header on the input.
pub fn inflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
    inflate_bytes_internal(bytes, 0)
}

/// Decompress a buffer that starts with a zlib header.
pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

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

    use super::{inflate_bytes, deflate_bytes};
    use self::rand::Rng;

    #[test]
    #[allow(deprecated_owned_vector)]
    fn test_flate_round_trip() {
        let mut r = rand::task_rng();
        let mut words = vec!();
        for _ in range(0, 20) {
            let range = r.gen_range(1u, 10);
            words.push(r.gen_vec::<u8>(range));
        }
        for _ in range(0, 20) {
            let mut input = vec![];
            for _ in range(0, 2000) {
                input.push_all(r.choose(words.as_slice()).as_slice());
            }
            debug!("de/inflate of {} bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(input.as_slice()).expect("deflation failed");
            let out = inflate_bytes(cmp.as_slice()).expect("inflation failed");
            debug!("{} bytes deflated to {} ({:.1f}% size)",
                   input.len(), cmp.len(),
                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
            assert_eq!(input.as_slice(), out.as_slice());
        }
    }

    #[test]
    fn test_zlib_flate() {
        let bytes = vec!(1, 2, 3, 4, 5);
        let deflated = deflate_bytes(bytes.as_slice()).expect("deflation failed");
        let inflated = inflate_bytes(deflated.as_slice()).expect("inflation failed");
        assert_eq!(inflated.as_slice(), bytes.as_slice());
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// rust - central access to other rust tools
// FIXME #2238 Make commands run and test emit proper file endings on windows
// FIXME #2238 Make run only accept source that emits an executable

#[link(name = "rust",
       vers = "0.8",
       uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
       url = "https://github.com/mozilla/rust/tree/master/src/rust")];

#[license = "MIT/ASL2"];
#[crate_type = "lib"];

extern mod rustpkg;
extern mod rustdoc;
extern mod rusti;
extern mod rustc;

use std::io;
use std::os;
use std::run;
use std::libc::exit;

enum ValidUsage {
    Valid(int), Invalid
}

impl ValidUsage {
    fn is_valid(&self) -> bool {
        match *self {
            Valid(_)   => true,
            Invalid    => false
        }
    }
}

enum Action {
    Call(extern "Rust" fn(args: &[~str]) -> ValidUsage),
    CallMain(&'static str, extern "Rust" fn(&[~str])),
}

enum UsageSource<'self> {
    UsgStr(&'self str),
    UsgCall(extern "Rust" fn()),
}

struct Command<'self> {
    cmd: &'self str,
    action: Action,
    usage_line: &'self str,
    usage_full: UsageSource<'self>,
}

static COMMANDS: &'static [Command<'static>] = &'static [
    Command {
        cmd: "build",
        action: CallMain("rustc", rustc::main_args),
        usage_line: "compile rust source files",
        usage_full: UsgCall(rustc_help),
    },
    Command {
        cmd: "run",
        action: Call(cmd_run),
        usage_line: "build an executable, and run it",
        usage_full: UsgStr(
            "The run command is an shortcut for the command line \n\
             \"rustc <filename> -o <filestem>~ && ./<filestem>~ [<arguments>...]\".\
            \n\nUsage:\trust run <filename> [<arguments>...]"
        )
    },
    Command {
        cmd: "test",
        action: Call(cmd_test),
        usage_line: "build a test executable, and run it",
        usage_full: UsgStr(
            "The test command is an shortcut for the command line \n\
            \"rustc --test <filename> -o <filestem>test~ && \
            ./<filestem>test~ [<arguments>...]\"\
            \n\nUsage:\trust test <filename> [<arguments>...]"
        )
    },
    Command {
        cmd: "doc",
        action: CallMain("rustdoc", rustdoc::main_args),
        usage_line: "generate documentation from doc comments",
        usage_full: UsgCall(rustdoc_help),
    },
    Command {
        cmd: "pkg",
        action: CallMain("rustpkg", rustpkg::main_args),
        usage_line: "download, build, install rust packages",
        usage_full: UsgCall(rustpkg::usage::general),
    },
    Command {
        cmd: "sketch",
        action: CallMain("rusti", rusti::main_args),
        usage_line: "run a rust interpreter",
        usage_full: UsgStr("\nUsage:\trusti"),
    },
    Command {
        cmd: "help",
        action: Call(cmd_help),
        usage_line: "show detailed usage of a command",
        usage_full: UsgStr(
            "The help command displays the usage text of another command.\n\
            The text is either build in, or provided by the corresponding \
            program.\n\nUsage:\trust help <command>"
        )
    }
];

fn rustc_help() {
    rustc::usage(os::args()[0].clone())
}

fn rustdoc_help() {
    rustdoc::usage(os::args()[0].clone())
}

fn find_cmd(command_string: &str) -> Option<Command> {
    do COMMANDS.iter().find |command| {
        command.cmd == command_string
    }.map_move(|x| *x)
}

fn cmd_help(args: &[~str]) -> ValidUsage {
    fn print_usage(command_string: ~str) -> ValidUsage {
        match find_cmd(command_string) {
            Some(command) => {
                match command.action {
                    CallMain(prog, _) => printfln!(
                        "The %s command is an alias for the %s program.",
                        command.cmd, prog),
                    _       => ()
                }
                match command.usage_full {
                    UsgStr(msg) => printfln!("%s\n", msg),
                    UsgCall(f)  => f(),
                }
                Valid(0)
            },
            None => Invalid
        }
    }

    match args {
        [ref command_string] => print_usage((*command_string).clone()),
        _                    => Invalid
    }
}

fn cmd_test(args: &[~str]) -> ValidUsage {
    match args {
        [ref filename, ..prog_args] => {
            let p = Path(*filename);
            let test_exec = p.filestem().unwrap() + "test~";
            invoke("rustc", &[~"--test", filename.to_owned(),
                              ~"-o", test_exec.to_owned()], rustc::main_args);
            let exit_code = run::process_status(~"./" + test_exec, prog_args);
            Valid(exit_code)
        }
        _ => Invalid
    }
}

fn cmd_run(args: &[~str]) -> ValidUsage {
    match args {
        [ref filename, ..prog_args] => {
            let p = Path(*filename);
            let exec = p.filestem().unwrap() + "~";
            invoke("rustc", &[filename.to_owned(), ~"-o", exec.to_owned()],
                   rustc::main_args);
            let exit_code = run::process_status(~"./"+exec, prog_args);
            Valid(exit_code)
        }
        _ => Invalid
    }
}

fn invoke(prog: &str, args: &[~str], f: &fn(&[~str])) {
    let mut osargs = ~[prog.to_owned()];
    osargs.push_all_move(args.to_owned());
    f(osargs);
}

fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
    match command.action {
        Call(f) => f(args),
        CallMain(prog, f) => {
            invoke(prog, args, f);
            Valid(0)
        }
    }
}

fn usage() {
    static INDENT: uint = 8;

    io::print(
        "The rust tool is a convenience for managing rust source code.\n\
        It acts as a shortcut for programs of the rust tool chain.\n\
        \n\
        Usage:\trust <command> [arguments]\n\
        \n\
        The commands are:\n\
        \n"
    );

    for command in COMMANDS.iter() {
        let padding = " ".repeat(INDENT - command.cmd.len());
        printfln!("    %s%s%s", command.cmd, padding, command.usage_line);
    }

    io::print(
        "\n\
        Use \"rust help <command>\" for more information about a command.\n\
        \n"
    );

}

pub fn main() {
    #[fixed_stack_segment]; #[inline(never)];

    let os_args = os::args();

    if (os_args.len() > 1 && (os_args[1] == ~"-v" || os_args[1] == ~"--version")) {
        rustc::version(os_args[0]);
        unsafe { exit(0); }
    }

    let args = os_args.tail();

    if !args.is_empty() {
        let r = find_cmd(*args.head());
        for command in r.iter() {
            let result = do_command(command, args.tail());
            match result {
                Valid(exit_code) => unsafe { exit(exit_code.to_i32()) },
                _                => loop
            }
        }
    }

    usage();
}
<commit_msg>auto merge of #9471 : brson/rust/rustexit, r=thestinger<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// rust - central access to other rust tools
// FIXME #2238 Make commands run and test emit proper file endings on windows
// FIXME #2238 Make run only accept source that emits an executable

#[link(name = "rust",
       vers = "0.8",
       uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
       url = "https://github.com/mozilla/rust/tree/master/src/rust")];

#[license = "MIT/ASL2"];
#[crate_type = "lib"];

extern mod rustpkg;
extern mod rustdoc;
extern mod rusti;
extern mod rustc;

use std::io;
use std::os;
use std::run;

enum ValidUsage {
    Valid(int), Invalid
}

impl ValidUsage {
    fn is_valid(&self) -> bool {
        match *self {
            Valid(_)   => true,
            Invalid    => false
        }
    }
}

enum Action {
    Call(extern "Rust" fn(args: &[~str]) -> ValidUsage),
    CallMain(&'static str, extern "Rust" fn(&[~str])),
}

enum UsageSource<'self> {
    UsgStr(&'self str),
    UsgCall(extern "Rust" fn()),
}

struct Command<'self> {
    cmd: &'self str,
    action: Action,
    usage_line: &'self str,
    usage_full: UsageSource<'self>,
}

static COMMANDS: &'static [Command<'static>] = &'static [
    Command {
        cmd: "build",
        action: CallMain("rustc", rustc::main_args),
        usage_line: "compile rust source files",
        usage_full: UsgCall(rustc_help),
    },
    Command {
        cmd: "run",
        action: Call(cmd_run),
        usage_line: "build an executable, and run it",
        usage_full: UsgStr(
            "The run command is an shortcut for the command line \n\
             \"rustc <filename> -o <filestem>~ && ./<filestem>~ [<arguments>...]\".\
            \n\nUsage:\trust run <filename> [<arguments>...]"
        )
    },
    Command {
        cmd: "test",
        action: Call(cmd_test),
        usage_line: "build a test executable, and run it",
        usage_full: UsgStr(
            "The test command is an shortcut for the command line \n\
            \"rustc --test <filename> -o <filestem>test~ && \
            ./<filestem>test~ [<arguments>...]\"\
            \n\nUsage:\trust test <filename> [<arguments>...]"
        )
    },
    Command {
        cmd: "doc",
        action: CallMain("rustdoc", rustdoc::main_args),
        usage_line: "generate documentation from doc comments",
        usage_full: UsgCall(rustdoc_help),
    },
    Command {
        cmd: "pkg",
        action: CallMain("rustpkg", rustpkg::main_args),
        usage_line: "download, build, install rust packages",
        usage_full: UsgCall(rustpkg::usage::general),
    },
    Command {
        cmd: "sketch",
        action: CallMain("rusti", rusti::main_args),
        usage_line: "run a rust interpreter",
        usage_full: UsgStr("\nUsage:\trusti"),
    },
    Command {
        cmd: "help",
        action: Call(cmd_help),
        usage_line: "show detailed usage of a command",
        usage_full: UsgStr(
            "The help command displays the usage text of another command.\n\
            The text is either build in, or provided by the corresponding \
            program.\n\nUsage:\trust help <command>"
        )
    }
];

fn rustc_help() {
    rustc::usage(os::args()[0].clone())
}

fn rustdoc_help() {
    rustdoc::usage(os::args()[0].clone())
}

fn find_cmd(command_string: &str) -> Option<Command> {
    do COMMANDS.iter().find |command| {
        command.cmd == command_string
    }.map_move(|x| *x)
}

fn cmd_help(args: &[~str]) -> ValidUsage {
    fn print_usage(command_string: ~str) -> ValidUsage {
        match find_cmd(command_string) {
            Some(command) => {
                match command.action {
                    CallMain(prog, _) => printfln!(
                        "The %s command is an alias for the %s program.",
                        command.cmd, prog),
                    _       => ()
                }
                match command.usage_full {
                    UsgStr(msg) => printfln!("%s\n", msg),
                    UsgCall(f)  => f(),
                }
                Valid(0)
            },
            None => Invalid
        }
    }

    match args {
        [ref command_string] => print_usage((*command_string).clone()),
        _                    => Invalid
    }
}

fn cmd_test(args: &[~str]) -> ValidUsage {
    match args {
        [ref filename, ..prog_args] => {
            let p = Path(*filename);
            let test_exec = p.filestem().unwrap() + "test~";
            invoke("rustc", &[~"--test", filename.to_owned(),
                              ~"-o", test_exec.to_owned()], rustc::main_args);
            let exit_code = run::process_status(~"./" + test_exec, prog_args);
            Valid(exit_code)
        }
        _ => Invalid
    }
}

fn cmd_run(args: &[~str]) -> ValidUsage {
    match args {
        [ref filename, ..prog_args] => {
            let p = Path(*filename);
            let exec = p.filestem().unwrap() + "~";
            invoke("rustc", &[filename.to_owned(), ~"-o", exec.to_owned()],
                   rustc::main_args);
            let exit_code = run::process_status(~"./"+exec, prog_args);
            Valid(exit_code)
        }
        _ => Invalid
    }
}

fn invoke(prog: &str, args: &[~str], f: &fn(&[~str])) {
    let mut osargs = ~[prog.to_owned()];
    osargs.push_all_move(args.to_owned());
    f(osargs);
}

fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
    match command.action {
        Call(f) => f(args),
        CallMain(prog, f) => {
            invoke(prog, args, f);
            Valid(0)
        }
    }
}

fn usage() {
    static INDENT: uint = 8;

    io::print(
        "The rust tool is a convenience for managing rust source code.\n\
        It acts as a shortcut for programs of the rust tool chain.\n\
        \n\
        Usage:\trust <command> [arguments]\n\
        \n\
        The commands are:\n\
        \n"
    );

    for command in COMMANDS.iter() {
        let padding = " ".repeat(INDENT - command.cmd.len());
        printfln!("    %s%s%s", command.cmd, padding, command.usage_line);
    }

    io::print(
        "\n\
        Use \"rust help <command>\" for more information about a command.\n\
        \n"
    );

}

pub fn main() {
    #[fixed_stack_segment]; #[inline(never)];

    let os_args = os::args();

    if (os_args.len() > 1 && (os_args[1] == ~"-v" || os_args[1] == ~"--version")) {
        rustc::version(os_args[0]);
        return;
    }

    let args = os_args.tail();

    if !args.is_empty() {
        let r = find_cmd(*args.head());
        for command in r.iter() {
            let result = do_command(command, args.tail());
            match result {
                Valid(exit_code) => {
                    os::set_exit_status(exit_code);
                    return;
                }
                _ => loop
            }
        }
    }

    usage();
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::{CString, OsString};
use std::os::unix::ffi::OsStringExt;
use std::ptr;

use libc;

fn osstring2cstring(s: &OsString) -> CString {
    unsafe { CString::from_vec_unchecked(s.clone().into_vec()) }
}

// Helper wrappers around libc::* API
pub fn fork() -> libc::pid_t {
    unsafe { libc::fork() }
}

pub fn execvp(argv: Vec<&OsString>) {
    let mut args = Vec::new();
    for arg in &argv {
        args.push(osstring2cstring(arg).as_ptr());
    }
    args.push(ptr::null());
    assert!(unsafe { libc::execvp(args[0], args.as_ptr()) } > -1);
}

pub fn dup2(fd1: i32, fd2: i32) {
    assert!(unsafe { libc::dup2(fd1, fd2) } > -1);
}

pub fn close(fd: i32) {
    assert_eq!(unsafe { libc::close(fd) }, 0);
}

pub fn pipe() -> (i32, i32) {
    let mut fds = [0; 2];
    assert_eq!(unsafe { libc::pipe(fds.as_mut_ptr()) }, 0);
    (fds[0], fds[1])
}

fn which(exec: &str) -> Option<OsString> {
    if let Some(path) = env::var_os("PATH") {
        let paths = env::split_paths(&path);
        for path in paths {
            let candidate = path.join(exec);
            if path.join(exec).exists() {
                return Some(candidate.into_os_string());
            }
        }
    }
    None
}

pub fn find_pager(env: &str) -> Option<OsString> {
    let default_pager = || which("more");
    env::var_os(env).or_else(default_pager)
}

#[cfg(test)]
mod tests {
    use super::{find_pager, which};
    use std::ffi::OsString;

#[cfg(target_os = "linux")]
const MORE: &'static str = "/bin/more";

#[cfg(target_os = "macos")]
const MORE: &'static str = "/usr/bin/more";

    #[test]
    fn more_found_in_path() {
        assert!(which("more").is_some())
    }

    #[test]
    fn erom_not_found_in_path() {
        assert!(which("erom").is_none())
    }

    #[test]
    fn which_more() {
        assert_eq!(which("more"), Some(OsString::from(MORE)));
    }

    #[test]
    fn usr_bin_more_default_pager() {
        assert_eq!(find_pager("__RANDOM_NAME"), Some(OsString::from(MORE)));
    }
}
<commit_msg>rustfmt<commit_after>use std::env;
use std::ffi::{CString, OsString};
use std::os::unix::ffi::OsStringExt;
use std::ptr;

use libc;

fn osstring2cstring(s: &OsString) -> CString {
    unsafe { CString::from_vec_unchecked(s.clone().into_vec()) }
}

// Helper wrappers around libc::* API
pub fn fork() -> libc::pid_t {
    unsafe { libc::fork() }
}

pub fn execvp(argv: Vec<&OsString>) {
    let mut args = Vec::new();
    for arg in &argv {
        args.push(osstring2cstring(arg).as_ptr());
    }
    args.push(ptr::null());
    assert!(unsafe { libc::execvp(args[0], args.as_ptr()) } > -1);
}

pub fn dup2(fd1: i32, fd2: i32) {
    assert!(unsafe { libc::dup2(fd1, fd2) } > -1);
}

pub fn close(fd: i32) {
    assert_eq!(unsafe { libc::close(fd) }, 0);
}

pub fn pipe() -> (i32, i32) {
    let mut fds = [0; 2];
    assert_eq!(unsafe { libc::pipe(fds.as_mut_ptr()) }, 0);
    (fds[0], fds[1])
}

fn which(exec: &str) -> Option<OsString> {
    if let Some(path) = env::var_os("PATH") {
        let paths = env::split_paths(&path);
        for path in paths {
            let candidate = path.join(exec);
            if path.join(exec).exists() {
                return Some(candidate.into_os_string());
            }
        }
    }
    None
}

pub fn find_pager(env: &str) -> Option<OsString> {
    let default_pager = || which("more");
    env::var_os(env).or_else(default_pager)
}

#[cfg(test)]
mod tests {
    use super::{find_pager, which};
    use std::ffi::OsString;

    #[cfg(target_os = "linux")]
    const MORE: &'static str = "/bin/more";

    #[cfg(target_os = "macos")]
    const MORE: &'static str = "/usr/bin/more";

    #[test]
    fn more_found_in_path() {
        assert!(which("more").is_some())
    }

    #[test]
    fn erom_not_found_in_path() {
        assert!(which("erom").is_none())
    }

    #[test]
    fn which_more() {
        assert_eq!(which("more"), Some(OsString::from(MORE)));
    }

    #[test]
    fn usr_bin_more_default_pager() {
        assert_eq!(find_pager("__RANDOM_NAME"), Some(OsString::from(MORE)));
    }
}
<|endoftext|>


<commit_before>// Some temporary libuv hacks for servo

#[cfg(target_os = "linux")];
#[cfg(target_os = "macos")];
#[cfg(target_os = "freebsd")];

#[nolink]
native mod rustrt {
    fn rust_uvtmp_create_thread() -> thread;
    fn rust_uvtmp_start_thread(thread: thread);
    fn rust_uvtmp_join_thread(thread: thread);
    fn rust_uvtmp_delete_thread(thread: thread);
    fn rust_uvtmp_connect(
        thread: thread,
        req_id: u32,
        ip: str::sbuf,
        chan: comm::chan<iomsg>) -> connect_data;
    fn rust_uvtmp_close_connection(thread: thread, req_id: u32);
    fn rust_uvtmp_write(
        thread: thread,
        req_id: u32,
        buf: *u8,
        len: ctypes::size_t,
        chan: comm::chan<iomsg>);
    fn rust_uvtmp_read_start(
        thread: thread,
        req_id: u32,
        chan: comm::chan<iomsg>);
    fn rust_uvtmp_delete_buf(buf: *u8);
    fn rust_uvtmp_get_req_id(cd: connect_data) -> u32;
}

type thread = *ctypes::void;

type connect_data = *ctypes::void;

enum iomsg {
    whatever,
    connected(connect_data),
    wrote(connect_data),
    read(connect_data, *u8, ctypes::ssize_t)
}

fn create_thread() -> thread {
    rustrt::rust_uvtmp_create_thread()
}

fn start_thread(thread: thread) {
    rustrt::rust_uvtmp_start_thread(thread)
}

fn join_thread(thread: thread) {
    rustrt::rust_uvtmp_join_thread(thread)
}

fn delete_thread(thread: thread) {
    rustrt::rust_uvtmp_delete_thread(thread)
}

fn connect(thread: thread, req_id: u32,
           ip: str, ch: comm::chan<iomsg>) -> connect_data {
    str::as_buf(ip) {|ipbuf|
        rustrt::rust_uvtmp_connect(thread, req_id, ipbuf, ch)
    }
}

fn close_connection(thread: thread, req_id: u32) {
    rustrt::rust_uvtmp_close_connection(thread, req_id);
}

fn write(thread: thread, req_id: u32, bytes: [u8],
         chan: comm::chan<iomsg>) unsafe {
    rustrt::rust_uvtmp_write(
        thread, req_id, vec::to_ptr(bytes), vec::len(bytes), chan);
}

fn read_start(thread: thread, req_id: u32,
              chan: comm::chan<iomsg>) {
    rustrt::rust_uvtmp_read_start(thread, req_id, chan);
}

fn delete_buf(buf: *u8) {
    rustrt::rust_uvtmp_delete_buf(buf);
}

fn get_req_id(cd: connect_data) -> u32 {
    ret rustrt::rust_uvtmp_get_req_id(cd);
}

#[test]
fn test_start_stop() {
    let thread = create_thread();
    start_thread(thread);
    join_thread(thread);
    delete_thread(thread);
}

#[test]
#[ignore]
fn test_connect() {
    let thread = create_thread();
    start_thread(thread);
    let port = comm::port();
    let chan = comm::chan(port);
    connect(thread, 0u32, "74.125.224.146", chan);
    alt comm::recv(port) {
      connected(cd) {
        close_connection(thread, cd);
      }
    }
    join_thread(thread);
    delete_thread(thread);
}

#[test]
#[ignore]
fn test_http() {
    let thread = create_thread();
    start_thread(thread);
    let port = comm::port();
    let chan = comm::chan(port);
    connect(thread, 0u32, "74.125.224.146", chan);
    alt comm::recv(port) {
      connected(cd) {
        write(thread, cd, str::bytes("GET / HTTP/1.0\n\n"), chan);
        alt comm::recv(port) {
          wrote(cd) {
            read_start(thread, cd, chan);
            let keep_going = true;
            while keep_going {
                alt comm::recv(port) {
                  read(_, buf, -1) {
                    keep_going = false;
                    delete_buf(buf);
                  }
                  read(_, buf, len) {
                    unsafe {
                        log(error, len);
                        let buf = vec::unsafe::from_buf(buf, len as uint);
                        let str = str::unsafe_from_bytes(buf);
                        #error("read something");
                        io::println(str);
                    }
                    delete_buf(buf);
                  }
                }
            }
            close_connection(thread, cd);
          }
        }
      }
    }
    join_thread(thread);
    delete_thread(thread);
}<commit_msg>std: Fix types in uvtmp tests<commit_after>// Some temporary libuv hacks for servo

#[cfg(target_os = "linux")];
#[cfg(target_os = "macos")];
#[cfg(target_os = "freebsd")];

#[nolink]
native mod rustrt {
    fn rust_uvtmp_create_thread() -> thread;
    fn rust_uvtmp_start_thread(thread: thread);
    fn rust_uvtmp_join_thread(thread: thread);
    fn rust_uvtmp_delete_thread(thread: thread);
    fn rust_uvtmp_connect(
        thread: thread,
        req_id: u32,
        ip: str::sbuf,
        chan: comm::chan<iomsg>) -> connect_data;
    fn rust_uvtmp_close_connection(thread: thread, req_id: u32);
    fn rust_uvtmp_write(
        thread: thread,
        req_id: u32,
        buf: *u8,
        len: ctypes::size_t,
        chan: comm::chan<iomsg>);
    fn rust_uvtmp_read_start(
        thread: thread,
        req_id: u32,
        chan: comm::chan<iomsg>);
    fn rust_uvtmp_delete_buf(buf: *u8);
    fn rust_uvtmp_get_req_id(cd: connect_data) -> u32;
}

type thread = *ctypes::void;

type connect_data = *ctypes::void;

enum iomsg {
    whatever,
    connected(connect_data),
    wrote(connect_data),
    read(connect_data, *u8, ctypes::ssize_t)
}

fn create_thread() -> thread {
    rustrt::rust_uvtmp_create_thread()
}

fn start_thread(thread: thread) {
    rustrt::rust_uvtmp_start_thread(thread)
}

fn join_thread(thread: thread) {
    rustrt::rust_uvtmp_join_thread(thread)
}

fn delete_thread(thread: thread) {
    rustrt::rust_uvtmp_delete_thread(thread)
}

fn connect(thread: thread, req_id: u32,
           ip: str, ch: comm::chan<iomsg>) -> connect_data {
    str::as_buf(ip) {|ipbuf|
        rustrt::rust_uvtmp_connect(thread, req_id, ipbuf, ch)
    }
}

fn close_connection(thread: thread, req_id: u32) {
    rustrt::rust_uvtmp_close_connection(thread, req_id);
}

fn write(thread: thread, req_id: u32, bytes: [u8],
         chan: comm::chan<iomsg>) unsafe {
    rustrt::rust_uvtmp_write(
        thread, req_id, vec::to_ptr(bytes), vec::len(bytes), chan);
}

fn read_start(thread: thread, req_id: u32,
              chan: comm::chan<iomsg>) {
    rustrt::rust_uvtmp_read_start(thread, req_id, chan);
}

fn delete_buf(buf: *u8) {
    rustrt::rust_uvtmp_delete_buf(buf);
}

fn get_req_id(cd: connect_data) -> u32 {
    ret rustrt::rust_uvtmp_get_req_id(cd);
}

#[test]
fn test_start_stop() {
    let thread = create_thread();
    start_thread(thread);
    join_thread(thread);
    delete_thread(thread);
}

#[test]
#[ignore]
fn test_connect() {
    let thread = create_thread();
    start_thread(thread);
    let port = comm::port();
    let chan = comm::chan(port);
    connect(thread, 0u32, "74.125.224.146", chan);
    alt comm::recv(port) {
      connected(cd) {
        close_connection(thread, 0u32);
      }
    }
    join_thread(thread);
    delete_thread(thread);
}

#[test]
#[ignore]
fn test_http() {
    let thread = create_thread();
    start_thread(thread);
    let port = comm::port();
    let chan = comm::chan(port);
    connect(thread, 0u32, "74.125.224.146", chan);
    alt comm::recv(port) {
      connected(cd) {
        write(thread, 0u32, str::bytes("GET / HTTP/1.0\n\n"), chan);
        alt comm::recv(port) {
          wrote(cd) {
            read_start(thread, 0u32, chan);
            let keep_going = true;
            while keep_going {
                alt comm::recv(port) {
                  read(_, buf, -1) {
                    keep_going = false;
                    delete_buf(buf);
                  }
                  read(_, buf, len) {
                    unsafe {
                        log(error, len);
                        let buf = vec::unsafe::from_buf(buf, len as uint);
                        let str = str::unsafe_from_bytes(buf);
                        #error("read something");
                        io::println(str);
                    }
                    delete_buf(buf);
                  }
                }
            }
            close_connection(thread, 0u32);
          }
        }
      }
    }
    join_thread(thread);
    delete_thread(thread);
}<|endoftext|>


<commit_before>use pact_consumer::prelude::*;
use pact_consumer::{json_pattern, json_pattern_internal};
use std::{
  io::prelude::*,
  env,
  path::Path,
  fs
};
use expectest::prelude::*;
use expectest::expect;
use reqwest::Client;
use pact_matching::models::Pact;

/// This is supposed to be a doctest in lib.rs, but it's breaking there, so
/// we have an executable copy here.
#[test]
fn mock_server_passing_validation() {
    use expectest::*;

    let _ = env_logger::init();

    let output_dir = Path::new("target/pact_dir");
    fs::remove_dir_all(output_dir).unwrap_or(());

    env::set_var("PACT_OUTPUT_DIR", &output_dir);

    {
      // Define the Pact for the test, specify the names of the consuming
      // application and the provider application.
      let alice_service = PactBuilder::new("Consumer", "Alice Service")
        // Start a new interaction. We can add as many interactions as we want.
        .interaction("a retrieve Mallory request", |i| {
          // Defines a provider state. It is optional.
          i.given("there is some good mallory");
          // Define the request, a GET (default) request to '/mallory'.
          i.request.path("/mallory");
          // Define the response we want returned.
          i.response
            .ok()
            .content_type("text/plain")
            .body("That is some good Mallory.");
        })
        .start_mock_server();

      // You would use your actual client code here.
      let mallory_url = alice_service.path("/mallory");
      let mut response = reqwest::blocking::get(mallory_url).expect("could not fetch URL");
      let mut body = String::new();
      response.read_to_string(&mut body).expect("could not read response body");
      assert_eq!(body, "That is some good Mallory.");
    }

    // When your test has finished running, all verifications will be performed
    // automatically, and an error will be thrown if any have failed.

    env::remove_var("PACT_OUTPUT_DIR");

    let path_file = Path::new("target/pact_dir/Consumer-Alice Service.json");
    expect!(path_file.exists()).to(be_true());
}

#[test]
#[should_panic]
fn mock_server_failing_validation() {
    let _ = env_logger::init();

    let hello_service = PactBuilder::new("Hello CLI", "Hello Server")
        .interaction("request a greeting", |i| {
            i.request.path("/hello");
            i.response.body("Hello!");
        })
        .start_mock_server();
    // Call with the wrong URL, which should lead to a panic at the end of
    // the function.
    let url = hello_service.path("/goodbye");
    let _ = reqwest::blocking::get(url);
}

#[test]
fn duplicate_interactions() {
  let _ = env_logger::init();

  let output_dir = Path::new("/tmp/duplicate_interactions");
  fs::remove_dir_all(output_dir).unwrap_or(());

  env::set_var("PACT_OUTPUT_DIR", &output_dir);

  for _ in 1..3 {
    let mock_service = PactBuilder::new("consumer 1", "provider 1")
      .interaction("tricky test", |interaction| {
        interaction
          .request
          .put()
          .json_body(pact_consumer::json_pattern!({
                          "name": pact_consumer::like!("mai"),
                          "street": pact_consumer::like!("5th"),
                          "state": pact_consumer::like!("VA"),
                      }))
          .path("/rolex.html");
        interaction.response.body("TrixR4Kidz");
      })
      .build()
      .start_mock_server();

    let mock_url = mock_service.url().as_ref();

    assert_eq!(
      Client::new()
        .put(&format!("{}rolex.html", mock_url))
        .json(&serde_json::json!({
                      "name": "mai",
                      "street": "5th",
                      "state": "VA",
                  }))
        .send()
        .unwrap()
        .text()
        .unwrap(),
      "TrixR4Kidz",
    );
  }

  env::remove_var("PACT_OUTPUT_DIR");

  let path = output_dir.join("consumer 1-provider 1.json");
  let written_pact = Pact::read_pact(path.as_path()).unwrap();
  expect!(written_pact.interactions.len()).to(be_equal_to(1));
}
<commit_msg>pact_consumer test: Use blocking reqwest<commit_after>use pact_consumer::prelude::*;
use pact_consumer::{json_pattern, json_pattern_internal};
use std::{
  io::prelude::*,
  env,
  path::Path,
  fs
};
use expectest::prelude::*;
use expectest::expect;
use reqwest::blocking::Client;
use pact_matching::models::Pact;

/// This is supposed to be a doctest in lib.rs, but it's breaking there, so
/// we have an executable copy here.
#[test]
fn mock_server_passing_validation() {
    use expectest::*;

    let _ = env_logger::init();

    let output_dir = Path::new("target/pact_dir");
    fs::remove_dir_all(output_dir).unwrap_or(());

    env::set_var("PACT_OUTPUT_DIR", &output_dir);

    {
      // Define the Pact for the test, specify the names of the consuming
      // application and the provider application.
      let alice_service = PactBuilder::new("Consumer", "Alice Service")
        // Start a new interaction. We can add as many interactions as we want.
        .interaction("a retrieve Mallory request", |i| {
          // Defines a provider state. It is optional.
          i.given("there is some good mallory");
          // Define the request, a GET (default) request to '/mallory'.
          i.request.path("/mallory");
          // Define the response we want returned.
          i.response
            .ok()
            .content_type("text/plain")
            .body("That is some good Mallory.");
        })
        .start_mock_server();

      // You would use your actual client code here.
      let mallory_url = alice_service.path("/mallory");
      let mut response = reqwest::blocking::get(mallory_url).expect("could not fetch URL");
      let mut body = String::new();
      response.read_to_string(&mut body).expect("could not read response body");
      assert_eq!(body, "That is some good Mallory.");
    }

    // When your test has finished running, all verifications will be performed
    // automatically, and an error will be thrown if any have failed.

    env::remove_var("PACT_OUTPUT_DIR");

    let path_file = Path::new("target/pact_dir/Consumer-Alice Service.json");
    expect!(path_file.exists()).to(be_true());
}

#[test]
#[should_panic]
fn mock_server_failing_validation() {
    let _ = env_logger::init();

    let hello_service = PactBuilder::new("Hello CLI", "Hello Server")
        .interaction("request a greeting", |i| {
            i.request.path("/hello");
            i.response.body("Hello!");
        })
        .start_mock_server();
    // Call with the wrong URL, which should lead to a panic at the end of
    // the function.
    let url = hello_service.path("/goodbye");
    let _ = reqwest::blocking::get(url);
}

#[test]
fn duplicate_interactions() {
  let _ = env_logger::init();

  let output_dir = Path::new("/tmp/duplicate_interactions");
  fs::remove_dir_all(output_dir).unwrap_or(());

  env::set_var("PACT_OUTPUT_DIR", &output_dir);

  for _ in 1..3 {
    let mock_service = PactBuilder::new("consumer 1", "provider 1")
      .interaction("tricky test", |interaction| {
        interaction
          .request
          .put()
          .json_body(pact_consumer::json_pattern!({
                          "name": pact_consumer::like!("mai"),
                          "street": pact_consumer::like!("5th"),
                          "state": pact_consumer::like!("VA"),
                      }))
          .path("/rolex.html");
        interaction.response.body("TrixR4Kidz");
      })
      .build()
      .start_mock_server();

    let mock_url = mock_service.url().as_ref();

    assert_eq!(
      Client::new()
        .put(&format!("{}rolex.html", mock_url))
        .json(&serde_json::json!({
                      "name": "mai",
                      "street": "5th",
                      "state": "VA",
                  }))
        .send()
        .unwrap()
        .text()
        .unwrap(),
      "TrixR4Kidz",
    );
  }

  env::remove_var("PACT_OUTPUT_DIR");

  let path = output_dir.join("consumer 1-provider 1.json");
  let written_pact = Pact::read_pact(path.as_path()).unwrap();
  expect!(written_pact.interactions.len()).to(be_equal_to(1));
}
<|endoftext|>


<commit_before>use postgres;
use uuid::Uuid;
use std::fmt;
use chrono::{NaiveDateTime, Utc};

use soundcloud;
use spotify;
use error::Error;
use super::{conn, Model};
use model::provider::Provider;
use model::enclosure::Enclosure;

static PROPS: [&'static str; 9]  = ["id",
                                    "provider",
                                    "identifier",
                                    "url",
                                    "name",
                                    "thumbnail_url",
                                    "artwork_url",
                                    "created_at",
                                    "updated_at"];

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Artist {
    pub id:            Uuid,
    pub provider:      Provider,
    pub identifier:    String,
    pub url:           String,
    pub name:          String,
    pub thumbnail_url: Option<String>,
    pub artwork_url:   Option<String>,
    pub created_at:    NaiveDateTime,
    pub updated_at:    NaiveDateTime,
}

impl fmt::Display for Artist {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}:{}", self.provider, self.identifier)
    }
}

impl<'a> Model<'a> for Artist {
    fn table_name() -> String { "artists".to_string() }
    fn props_str(prefix: &str) -> String {
        PROPS
            .iter()
            .map(|&p| format!("{}{}", prefix, p))
            .collect::<Vec<String>>().join(",")
    }
    fn rows_to_items(rows: postgres::rows::Rows) -> Vec<Artist> {
        let mut artists = Vec::new();
        for row in rows.iter() {
            let artist = Artist {
                id:            row.get(0),
                provider:      Provider::new(row.get(1)),
                identifier:    row.get(2),
                url:           row.get(3),
                name:          row.get(4),
                thumbnail_url: row.get(5),
                artwork_url:   row.get(6),
                created_at:    row.get(7),
                updated_at:    row.get(8),
            };
            artists.push(artist)
        }
        artists
    }

    fn create(&self) -> Result<Artist, Error> {
        let conn = try!(conn());
        let stmt = try!(conn.prepare("INSERT INTO artists (provider, identifier, url, name)
                                 VALUES ($1, $2, $3, $4) RETURNING id"));
        let rows = try!(stmt.query(&[&self.provider.to_string(), &self.identifier, &self.url, &self.name]));
        let mut artist = self.clone();
        for row in rows.iter() {
            artist.id = row.get(0);
        }
        Ok(artist)
    }

    fn save(&mut self) -> Result<(), Error> {
        self.updated_at = Utc::now().naive_utc();
        let conn = conn().unwrap();
        let stmt = conn.prepare("UPDATE artists SET
                                 provider      = $2,
                                 identifier    = $3,
                                 url           = $4,
                                 name          = $5,
                                 thumbnail_url = $6,
                                 artwork_url   = $7,
                                 created_at    = $8,
                                 updated_at    = $9
                                 WHERE id = $1").unwrap();
        let result = stmt.query(&[&self.id,
                                  &self.provider.to_string(),
                                  &self.identifier,
                                  &self.url,
                                  &self.name,
                                  &self.thumbnail_url,
                                  &self.artwork_url,
                                  &self.created_at,
                                  &self.updated_at,
        ]);
        match result {
            Ok(_)  => Ok(()),
            Err(_) => Err(Error::Unexpected),
        }
    }
}

impl<'a> Enclosure<'a> for Artist {
    fn new(provider: Provider, identifier: String) -> Artist {
        Artist {
            id:            Uuid::new_v4(),
            provider:      provider,
            identifier:    identifier,
            url:           "".to_string(),
            name:          "".to_string(),
            thumbnail_url: None,
            artwork_url:   None,
            created_at:    Utc::now().naive_utc(),
            updated_at:    Utc::now().naive_utc(),
        }
    }

    fn set_url(&mut self, url: String) -> &mut Artist {
        self.url = url;
        self
    }

    fn set_owner_id(&mut self, _owner_id: Option<String>) -> &mut Artist {
        self
    }

    fn fetch_props(&mut self) -> Result<(), Error> {
        Err(Error::NotFound)
    }

    fn find_by_entry_id(_entry_id: Uuid) -> Vec<Artist> {
        vec![]
    }
}

impl Artist {
    fn find_by(provider: &Provider, identifier: &str) -> Result<Artist, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare(
            &format!("SELECT {} FROM {}
                     WHERE provider = $1 AND identifier = $2
                     ORDER BY updated_at DESC",
                     Artist::props_str(""), Artist::table_name())).unwrap();
        let rows = stmt.query(&[&(*provider).to_string(), &identifier]).unwrap();
        let items = Artist::rows_to_items(rows);
        if items.len() > 0 {
            return Ok(items[0].clone());
        }
        return Err(Error::NotFound)
    }
    pub fn find_or_create(provider: Provider, identifier: String) -> Result<Artist, Error> {
        return match Artist::find_by(&provider, &identifier) {
            Ok(item) => Ok(item),
            Err(_)   => Artist::new(provider, identifier).create()
        }
    }
    pub fn from_yt_channel(channel_id: &str, channel_title: &str) -> Artist {
        let mut artist = Artist::new(Provider::YouTube, channel_id.to_string());
        artist.name = channel_title.to_string();
        artist.clone()
    }
    pub fn from_sp_artist(artist: &spotify::Artist) -> Artist {
        Artist::new(Provider::Spotify, (*artist).id.to_string())
            .update_with_sp_artist(artist)
            .clone()
    }

    pub fn from_sc_user(playlist: &soundcloud::User) -> Artist {
        Artist::new(Provider::SoundCloud, (*playlist).id.to_string())
            .update_with_sc_user(playlist)
            .clone()
    }

    pub fn from_am_artist(artist: &str) -> Artist {
        let mut artist = Artist::new(Provider::AppleMusic, artist.to_string());
        artist.name = artist.to_string();
        artist.clone()
    }

    pub fn update_with_sp_artist(&mut self, artist: &spotify::Artist) -> &mut Artist {
        self.provider       = Provider::Spotify;
        self.identifier     = artist.id.to_string();
        self.url            = artist.uri.clone();
        self.name           = artist.name.clone();
        if let Some(ref images) = artist.images {
            if images.len() > 0 {
                self.artwork_url   = Some(images[0].url.clone());
                self.thumbnail_url = Some(images[0].url.clone());
            }
            if images.len() > 1 {
                self.thumbnail_url = Some(images[1].url.clone());
            }
        }
        self
    }

    pub fn update_with_sc_user(&mut self, user: &soundcloud::User) -> &mut Artist {
        self.provider      = Provider::SoundCloud;
        self.identifier    = user.id.to_string();
        self.url           = user.permalink.to_string();
        self.name          = user.username.to_string();
        self.thumbnail_url = Some(user.avatar_url.clone());
        self.artwork_url   = Some(user.avatar_url.clone());
        self
    }
}

#[cfg(test)]
mod test {
    use model::Model;
    use model::enclosure::Enclosure;
    use super::Artist;
    use Provider;
    #[test]
    fn test_new() {
        let artist = Artist::new(Provider::Spotify, "4tZwfgrHOc3mvqYlEYSvVi".to_string());
        assert_eq!(artist.provider, Provider::Spotify);
        assert_eq!(&artist.identifier, "4tZwfgrHOc3mvqYlEYSvVi");
    }
    #[test]
    fn test_find_of_create() {
        let identifier = "4tZwfgrHOc3mvqYlEYSvVi".to_string();
        let result     = Artist::find_or_create(Provider::Spotify, identifier);
        assert!(result.is_ok());
    }
    #[test]
    fn test_save() {
        let id = "test_save";
        let mut artist = Artist::find_or_create(Provider::Spotify, id.to_string()).unwrap();
        artist.name   = "name".to_string();
        let result    = artist.save();
        assert!(result.is_ok());
        let artist = Artist::find_or_create(Provider::Spotify, id.to_string()).unwrap();
        assert_eq!(&artist.name, "name");
    }
}
<commit_msg>Implement Artist::update_am_artist<commit_after>use postgres;
use uuid::Uuid;
use std::fmt;
use chrono::{NaiveDateTime, Utc};

use soundcloud;
use spotify;
use apple_music;
use error::Error;
use super::{conn, Model};
use model::provider::Provider;
use model::enclosure::Enclosure;

static PROPS: [&'static str; 9]  = ["id",
                                    "provider",
                                    "identifier",
                                    "url",
                                    "name",
                                    "thumbnail_url",
                                    "artwork_url",
                                    "created_at",
                                    "updated_at"];

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Artist {
    pub id:            Uuid,
    pub provider:      Provider,
    pub identifier:    String,
    pub url:           String,
    pub name:          String,
    pub thumbnail_url: Option<String>,
    pub artwork_url:   Option<String>,
    pub created_at:    NaiveDateTime,
    pub updated_at:    NaiveDateTime,
}

impl fmt::Display for Artist {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}:{}", self.provider, self.identifier)
    }
}

impl<'a> Model<'a> for Artist {
    fn table_name() -> String { "artists".to_string() }
    fn props_str(prefix: &str) -> String {
        PROPS
            .iter()
            .map(|&p| format!("{}{}", prefix, p))
            .collect::<Vec<String>>().join(",")
    }
    fn rows_to_items(rows: postgres::rows::Rows) -> Vec<Artist> {
        let mut artists = Vec::new();
        for row in rows.iter() {
            let artist = Artist {
                id:            row.get(0),
                provider:      Provider::new(row.get(1)),
                identifier:    row.get(2),
                url:           row.get(3),
                name:          row.get(4),
                thumbnail_url: row.get(5),
                artwork_url:   row.get(6),
                created_at:    row.get(7),
                updated_at:    row.get(8),
            };
            artists.push(artist)
        }
        artists
    }

    fn create(&self) -> Result<Artist, Error> {
        let conn = try!(conn());
        let stmt = try!(conn.prepare("INSERT INTO artists (provider, identifier, url, name)
                                 VALUES ($1, $2, $3, $4) RETURNING id"));
        let rows = try!(stmt.query(&[&self.provider.to_string(), &self.identifier, &self.url, &self.name]));
        let mut artist = self.clone();
        for row in rows.iter() {
            artist.id = row.get(0);
        }
        Ok(artist)
    }

    fn save(&mut self) -> Result<(), Error> {
        self.updated_at = Utc::now().naive_utc();
        let conn = conn().unwrap();
        let stmt = conn.prepare("UPDATE artists SET
                                 provider      = $2,
                                 identifier    = $3,
                                 url           = $4,
                                 name          = $5,
                                 thumbnail_url = $6,
                                 artwork_url   = $7,
                                 created_at    = $8,
                                 updated_at    = $9
                                 WHERE id = $1").unwrap();
        let result = stmt.query(&[&self.id,
                                  &self.provider.to_string(),
                                  &self.identifier,
                                  &self.url,
                                  &self.name,
                                  &self.thumbnail_url,
                                  &self.artwork_url,
                                  &self.created_at,
                                  &self.updated_at,
        ]);
        match result {
            Ok(_)  => Ok(()),
            Err(_) => Err(Error::Unexpected),
        }
    }
}

impl<'a> Enclosure<'a> for Artist {
    fn new(provider: Provider, identifier: String) -> Artist {
        Artist {
            id:            Uuid::new_v4(),
            provider:      provider,
            identifier:    identifier,
            url:           "".to_string(),
            name:          "".to_string(),
            thumbnail_url: None,
            artwork_url:   None,
            created_at:    Utc::now().naive_utc(),
            updated_at:    Utc::now().naive_utc(),
        }
    }

    fn set_url(&mut self, url: String) -> &mut Artist {
        self.url = url;
        self
    }

    fn set_owner_id(&mut self, _owner_id: Option<String>) -> &mut Artist {
        self
    }

    fn fetch_props(&mut self) -> Result<(), Error> {
        match self.provider {
            Provider::AppleMusic => {
                let country = apple_music::country(&self.url);
                match apple_music::fetch_artist(&country, &self.identifier) {
                    Ok(artist) => self.update_with_am_artist(&artist),
                    Err(_)     => self,
                }
            },
            Provider::Spotify => match spotify::fetch_artist(&self.identifier) {
                Ok(artist) => self.update_with_sp_artist(&artist),
                Err(_)     => self,
            },
            _ => self,
        };
        Ok(())
    }

    fn find_by_entry_id(_entry_id: Uuid) -> Vec<Artist> {
        vec![]
    }
}

impl Artist {
    fn find_by(provider: &Provider, identifier: &str) -> Result<Artist, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare(
            &format!("SELECT {} FROM {}
                     WHERE provider = $1 AND identifier = $2
                     ORDER BY updated_at DESC",
                     Artist::props_str(""), Artist::table_name())).unwrap();
        let rows = stmt.query(&[&(*provider).to_string(), &identifier]).unwrap();
        let items = Artist::rows_to_items(rows);
        if items.len() > 0 {
            return Ok(items[0].clone());
        }
        return Err(Error::NotFound)
    }
    pub fn find_or_create(provider: Provider, identifier: String) -> Result<Artist, Error> {
        return match Artist::find_by(&provider, &identifier) {
            Ok(item) => Ok(item),
            Err(_)   => Artist::new(provider, identifier).create()
        }
    }
    pub fn from_yt_channel(channel_id: &str, channel_title: &str) -> Artist {
        let mut artist = Artist::new(Provider::YouTube, channel_id.to_string());
        artist.name = channel_title.to_string();
        artist.clone()
    }
    pub fn from_sp_artist(artist: &spotify::Artist) -> Artist {
        Artist::new(Provider::Spotify, (*artist).id.to_string())
            .update_with_sp_artist(artist)
            .clone()
    }

    pub fn from_sc_user(playlist: &soundcloud::User) -> Artist {
        Artist::new(Provider::SoundCloud, (*playlist).id.to_string())
            .update_with_sc_user(playlist)
            .clone()
    }

    pub fn from_am_artist(artist: &str) -> Artist {
        let mut artist = Artist::new(Provider::AppleMusic, artist.to_string());
        artist.name = artist.to_string();
        artist.clone()
    }

    pub fn update_with_sp_artist(&mut self, artist: &spotify::Artist) -> &mut Artist {
        self.provider       = Provider::Spotify;
        self.identifier     = artist.id.to_string();
        self.url            = artist.uri.clone();
        self.name           = artist.name.clone();
        if let Some(ref images) = artist.images {
            if images.len() > 0 {
                self.artwork_url   = Some(images[0].url.clone());
                self.thumbnail_url = Some(images[0].url.clone());
            }
            if images.len() > 1 {
                self.thumbnail_url = Some(images[1].url.clone());
            }
        }
        self
    }

    pub fn update_with_am_artist(&mut self, artist: &apple_music::Artist) -> &mut Artist {
        self.provider      = Provider::AppleMusic;
        self.identifier    = artist.id.to_string();
        self.url           = artist.attributes.url.to_string();
        self.name          = artist.attributes.name.to_string();
        if let Some(album) = artist.clone().relationships
            .and_then(|r| r.albums.data.first().map(|a| a.clone())) {
                self.thumbnail_url = Some(album.attributes.artwork.url.to_string());
                self.artwork_url   = Some(album.attributes.artwork.url.to_string());
            }
        self
    }

    pub fn update_with_sc_user(&mut self, user: &soundcloud::User) -> &mut Artist {
        self.provider      = Provider::SoundCloud;
        self.identifier    = user.id.to_string();
        self.url           = user.permalink.to_string();
        self.name          = user.username.to_string();
        self.thumbnail_url = Some(user.avatar_url.clone());
        self.artwork_url   = Some(user.avatar_url.clone());
        self
    }
}

#[cfg(test)]
mod test {
    use model::Model;
    use model::enclosure::Enclosure;
    use super::Artist;
    use Provider;
    #[test]
    fn test_new() {
        let artist = Artist::new(Provider::Spotify, "4tZwfgrHOc3mvqYlEYSvVi".to_string());
        assert_eq!(artist.provider, Provider::Spotify);
        assert_eq!(&artist.identifier, "4tZwfgrHOc3mvqYlEYSvVi");
    }
    #[test]
    fn test_find_of_create() {
        let identifier = "4tZwfgrHOc3mvqYlEYSvVi".to_string();
        let result     = Artist::find_or_create(Provider::Spotify, identifier);
        assert!(result.is_ok());
    }
    #[test]
    fn test_save() {
        let id = "test_save";
        let mut artist = Artist::find_or_create(Provider::Spotify, id.to_string()).unwrap();
        artist.name   = "name".to_string();
        let result    = artist.save();
        assert!(result.is_ok());
        let artist = Artist::find_or_create(Provider::Spotify, id.to_string()).unwrap();
        assert_eq!(&artist.name, "name");
    }
}
<|endoftext|>


<commit_before>use tcod::colors::{Color};

use traits::{Renderable, Movable, Position};
use point::Point;

#[derive(Debug)]
pub struct Item {
    name: String,
    glyph: char,
    color: Color,
    position: Point<i16>,
}

impl Item {
    pub fn new(name: &str, glyph: char, colour: Color, pos: Point<i16>) -> Item {
        Item {
            name: name,
            glyph: glyph,
            color: color,
            position: pos,
        }
    }
}

impl Position for Unit {
    fn get_x(&self) -> i16 {
        self.position.x
    }

    fn get_y(&self) -> i16 {
        self.position.y
    }
}

impl Renderable for Unit {
    fn get_color(&self) -> Color {
        self.color
    }

    fn get_glyph(&self) -> char {
        self.glyph
    }
}<commit_msg>Fixed impls for wrong type, color parameter name, convert &str to String.<commit_after>use tcod::colors::{Color};

use traits::{Renderable, Movable, Position};
use point::Point;

#[derive(Debug)]
pub struct Item {
    name: String,
    glyph: char,
    color: Color,
    position: Point<i16>,
}

impl Item {
    pub fn new(name: &str, glyph: char, color: Color, pos: Point<i16>) -> Item {
        Item {
            name: name.into(),
            glyph: glyph,
            color: color,
            position: pos,
        }
    }
}

impl Position for Item {
    fn get_x(&self) -> i16 {
        self.position.x
    }

    fn get_y(&self) -> i16 {
        self.position.y
    }
}

impl Renderable for Item {
    fn get_color(&self) -> Color {
        self.color
    }

    fn get_glyph(&self) -> char {
        self.glyph
    }
}<|endoftext|>