<commit_before>//Elliptic Curve Crypto
//https://en.wikipedia.org/wiki/Elliptic_curve_cryptography

use super::super::math;
use math::Mod;

struct ECC {
    //equation of the form `y^2 = x^3 + a*x + b`
    a: f64,
    b: f64,
    p: u64,

}

impl ECC {
    fn new(a: f64, b: f64, p: u64) -> ECC {
        //modular exp?
        assert!(4.0 * a.pow(3) + 27.0 * b.pow(2) != 0);
        ECC {
            a: a,
            b: b,
            p: p,
        }

    }

}

<commit_msg>Scrap float implementation and use ratios instead?<commit_after>//Elliptic Curve Crypto
//https://en.wikipedia.org/wiki/Elliptic_curve_cryptography

use super::super::math;
use math::Mod;
use num::rational::Rational64;

#[derive(PartialEq)]
pub struct Point {
    //TODO: is float equality going to be a problem?
    x: f64,
    y: f64,
}

impl Point {
    pub fn new(x: f64, y: f64) -> Point {
        Point{ x: x, y: y }
    }
}

pub struct ECC {
    //equation of the form `y^2 = x^3 + a*x + b`
    a: f64,
    b: f64,
    p: u64,

}

impl ECC {
    pub fn new(a: f64, b: f64, p: u64) -> ECC {
        //modular exp?
        assert!(4.0 * a.powi(3) + 27.0 * b.powi(2) != 0.0);
        ECC {
            a: a,
            b: b,
            p: p,
        }

    }

    fn contains(&self, p: Point) -> bool {
        p.y.powi(2) == p.x.powi(3) + self.a*p.x + self.b
    }
}

<|endoftext|>


<commit_before>use std::mem;

/// Binding to C++ `std::vector<T>`.
///
/// # Invariants
///
/// As an invariant of this API and the static analysis of the cxx::bridge
/// macro, in Rust code we can never obtain a `CxxVector` by value. Instead in
/// Rust code we will only ever look at a vector behind a reference or smart
/// pointer, as in `&CxxVector<T>` or `UniquePtr<CxxVector<T>>`.
#[repr(C, packed)]
pub struct CxxVector<T> {
    _private: [T; 0],
}

impl<T: VectorElement> CxxVector<T> {
    /// Returns the length of the vector in bytes.
    pub fn len(&self) -> usize {
        T::__vector_length(self)
    }

    pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
        T::__get_unchecked(self, pos)
    }

    /// Returns true if `self` has a length of zero bytes.
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn get(&self, pos: usize) -> Option<&T> {
        if pos < self.len() {
            Some(unsafe { T::__get_unchecked(self, pos) })
        } else {
            None
        }
    }

    pub fn push_back(&mut self, item: &T) {
        T::__push_back(self, item);
    }
}

pub struct VectorIntoIterator<'a, T> {
    v: &'a CxxVector<T>,
    index: usize,
}

impl<'a, T: VectorElement> IntoIterator for &'a CxxVector<T> {
    type Item = &'a T;
    type IntoIter = VectorIntoIterator<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        VectorIntoIterator { v: self, index: 0 }
    }
}

impl<'a, T: VectorElement> Iterator for VectorIntoIterator<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.index = self.index + 1;
        self.v.get(self.index - 1)
    }
}

// Methods are private; not intended to be implemented outside of cxxbridge
// codebase.
#[doc(hidden)]
pub unsafe trait VectorElement: Sized {
    unsafe fn __get_unchecked(v: &CxxVector<Self>, pos: usize) -> &Self;
    fn __vector_length(v: &CxxVector<Self>) -> usize;
    fn __push_back(v: &CxxVector<Self>, item: &Self);
}

cxxbridge_macro::vector_builtin!(u8);
cxxbridge_macro::vector_builtin!(u16);
cxxbridge_macro::vector_builtin!(u32);
cxxbridge_macro::vector_builtin!(u64);
cxxbridge_macro::vector_builtin!(usize);
cxxbridge_macro::vector_builtin!(i8);
cxxbridge_macro::vector_builtin!(i16);
cxxbridge_macro::vector_builtin!(i32);
cxxbridge_macro::vector_builtin!(i64);
cxxbridge_macro::vector_builtin!(isize);
cxxbridge_macro::vector_builtin!(f32);
cxxbridge_macro::vector_builtin!(f64);

const_assert_eq!(1, mem::align_of::<CxxVector<usize>>());
<commit_msg>Document CxxVector associated methods<commit_after>use std::mem;

/// Binding to C++ `std::vector<T>`.
///
/// # Invariants
///
/// As an invariant of this API and the static analysis of the cxx::bridge
/// macro, in Rust code we can never obtain a `CxxVector` by value. Instead in
/// Rust code we will only ever look at a vector behind a reference or smart
/// pointer, as in `&CxxVector<T>` or `UniquePtr<CxxVector<T>>`.
#[repr(C, packed)]
pub struct CxxVector<T> {
    _private: [T; 0],
}

impl<T: VectorElement> CxxVector<T> {
    /// Returns the number of elements in the vector.
    pub fn len(&self) -> usize {
        T::__vector_length(self)
    }

    /// Returns a reference to an element without doing bounds checking.
    ///
    /// This is generally not recommended, use with caution! Calling this method
    /// with an out-of-bounds index is undefined behavior even if the resulting
    /// reference is not used.
    pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
        T::__get_unchecked(self, pos)
    }

    /// Returns true if the vector contains no elements.
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns a reference to an element at the given position, or `None` if
    /// out of bounds.
    pub fn get(&self, pos: usize) -> Option<&T> {
        if pos < self.len() {
            Some(unsafe { T::__get_unchecked(self, pos) })
        } else {
            None
        }
    }

    /// Appends an element to the back of the vector.
    pub fn push_back(&mut self, item: &T) {
        T::__push_back(self, item);
    }
}

pub struct VectorIntoIterator<'a, T> {
    v: &'a CxxVector<T>,
    index: usize,
}

impl<'a, T: VectorElement> IntoIterator for &'a CxxVector<T> {
    type Item = &'a T;
    type IntoIter = VectorIntoIterator<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        VectorIntoIterator { v: self, index: 0 }
    }
}

impl<'a, T: VectorElement> Iterator for VectorIntoIterator<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.index = self.index + 1;
        self.v.get(self.index - 1)
    }
}

// Methods are private; not intended to be implemented outside of cxxbridge
// codebase.
#[doc(hidden)]
pub unsafe trait VectorElement: Sized {
    unsafe fn __get_unchecked(v: &CxxVector<Self>, pos: usize) -> &Self;
    fn __vector_length(v: &CxxVector<Self>) -> usize;
    fn __push_back(v: &CxxVector<Self>, item: &Self);
}

cxxbridge_macro::vector_builtin!(u8);
cxxbridge_macro::vector_builtin!(u16);
cxxbridge_macro::vector_builtin!(u32);
cxxbridge_macro::vector_builtin!(u64);
cxxbridge_macro::vector_builtin!(usize);
cxxbridge_macro::vector_builtin!(i8);
cxxbridge_macro::vector_builtin!(i16);
cxxbridge_macro::vector_builtin!(i32);
cxxbridge_macro::vector_builtin!(i64);
cxxbridge_macro::vector_builtin!(isize);
cxxbridge_macro::vector_builtin!(f32);
cxxbridge_macro::vector_builtin!(f64);

const_assert_eq!(1, mem::align_of::<CxxVector<usize>>());
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

use libc::{c_long, c_ulong};
use std::num::Bounded;

pub type Boolean = u8;

pub type CFIndex = c_long;

pub trait CFIndexConvertible {
    /// Always use this method to construct a `CFIndex` value. It performs bounds checking to
    /// ensure the value is in range.
    fn to_CFIndex(self) -> CFIndex;
}

impl CFIndexConvertible for uint {
    #[inline]
    fn to_CFIndex(self) -> CFIndex {
        let max_CFIndex: CFIndex = Bounded::max_value();
        if self > (max_CFIndex as uint) {
            panic!("value out of range")
        }
        self as CFIndex
    }
}

pub type CFOptionFlags = u32;

#[allow(dead_code)]
#[repr(C)]
pub struct CFRange {
    location: CFIndex,
    length: CFIndex
}

impl CFRange {
    pub fn init(offset: CFIndex, length: CFIndex) -> CFRange {
        CFRange {
            location: offset,
            length: length,
        }
    }
}

#[repr(C)]
struct __CFAllocator;

pub type CFAllocatorRef = *const __CFAllocator;

#[repr(C)]
struct __CFNull;

pub type CFNullRef = *const __CFNull;

pub type CFHashCode = c_ulong;

pub type CFTypeID = c_ulong;

#[repr(C)]
struct __CFType;

pub type CFTypeRef = *const __CFType;

/// Superclass of all Core Foundation objects.
pub struct CFType {
    obj: CFTypeRef,
}

impl Clone for CFType {
    #[inline]
    fn clone(&self) -> CFType {
        unsafe {
            TCFType::wrap_under_get_rule(self.obj)
        }
    }
}

impl Drop for CFType {
    fn drop(&mut self) {
        unsafe {
            CFRelease(self.obj)
        }
    }
}

/// All Core Foundation types implement this trait. The type parameter `TypeRef` specifies the
/// associated Core Foundation type: e.g. for `CFType` this is `CFTypeRef`; for `CFArray` this is
/// `CFArrayRef`.
pub trait TCFType<ConcreteTypeRef> {
    /// Returns the object as its concrete TypeRef.
    fn as_concrete_TypeRef(&self) -> ConcreteTypeRef;

    /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this
    /// when following Core Foundation's "Create Rule". The reference count is *not* bumped.
    unsafe fn wrap_under_create_rule(obj: ConcreteTypeRef) -> Self;

    /// Returns the type ID for this class.
    ///
    /// FIXME(pcwalton): The dummy parameter is there to work around the current inexpressivity of
    /// the Rust language.
    fn type_id(dummy: Option<Self>) -> CFTypeID;

    /// Returns the object as a wrapped `CFType`. The reference count is incremented by one.
    #[inline]
    fn as_CFType(&self) -> CFType {
        unsafe {
            TCFType::wrap_under_get_rule(self.as_CFTypeRef())
        }
    }

    /// Returns the object as a raw `CFTypeRef`. The reference count is not adjusted.
    fn as_CFTypeRef(&self) -> CFTypeRef;

    /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this
    /// when following Core Foundation's "Get Rule". The reference count *is* bumped.
    unsafe fn wrap_under_get_rule(reference: ConcreteTypeRef) -> Self;

    /// Returns the reference count of the object. It is unwise to do anything other than test
    /// whether the return value of this method is greater than zero.
    #[inline]
    fn retain_count(&self) -> CFIndex {
        unsafe {
            CFGetRetainCount(self.as_CFTypeRef())
        }
    }

    /// Returns the type ID of this object.
    #[inline]
    fn type_of(&self) -> CFTypeID {
        unsafe {
            CFGetTypeID(self.as_CFTypeRef())
        }
    }

    /// Writes a debugging version of this object on standard error.
    fn show(&self) {
        unsafe {
            CFShow(self.as_CFTypeRef())
        }
    }

    /// Returns true if this value is an instance of another type.
    #[inline]
    fn instance_of<OtherConcreteTypeRef,OtherCFType:TCFType<OtherConcreteTypeRef>>(&self) -> bool {
        let dummy: Option<OtherCFType> = None;
        self.type_of() == TCFType::type_id(dummy)
    }
}

impl TCFType<CFTypeRef> for CFType {
    #[inline]
    fn as_concrete_TypeRef(&self) -> CFTypeRef {
        self.obj
    }

    #[inline]
    unsafe fn wrap_under_get_rule(reference: CFTypeRef) -> CFType {
        let reference: CFTypeRef = CFRetain(reference);
        TCFType::wrap_under_create_rule(reference)
    }

    #[inline]
    fn as_CFTypeRef(&self) -> CFTypeRef {
        self.as_concrete_TypeRef()
    }

    #[inline]
    unsafe fn wrap_under_create_rule(obj: CFTypeRef) -> CFType {
        CFType {
            obj: obj,
        }
    }

    #[inline]
    fn type_id(_: Option<CFType>) -> CFTypeID {
        // FIXME(pcwalton): Is this right?
        0
    }

    #[inline]
    fn instance_of<OtherConcreteTypeRef,OtherCFType:TCFType<OtherConcreteTypeRef>>(&self) -> bool {
        // Since this is the root of the type hierarchy, we always answer yes.
        true
    }
}

#[link(name = "CoreFoundation", kind = "framework")]
extern {
    /*
     * CFBase.h
     */

    /* CFAllocator Reference */
    // N.B. Many CFAllocator functions and constants are omitted here.
    pub static kCFAllocatorDefault: CFAllocatorRef;
    pub static kCFAllocatorSystemDefault: CFAllocatorRef;
    pub static kCFAllocatorMalloc: CFAllocatorRef;
    pub static kCFAllocatorMallocZone: CFAllocatorRef;
    pub static kCFAllocatorNull: CFAllocatorRef;
    pub static kCFAllocatorUseContext: CFAllocatorRef;

    /* CFNull Reference */

    pub static kCFNull: CFNullRef;

    /* CFType Reference */

    //fn CFCopyDescription
    //fn CFCopyTypeIDDescription
    //fn CFEqual
    //fn CFGetAllocator
    pub fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex;
    pub fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID;
    pub fn CFHash(cf: CFTypeRef) -> CFHashCode;
    //fn CFMakeCollectable
    pub fn CFRelease(cf: CFTypeRef);
    pub fn CFRetain(cf: CFTypeRef) -> CFTypeRef;
    pub fn CFShow(obj: CFTypeRef);

    /* Base Utilities Reference */
    // N.B. Some things missing here.
}

<commit_msg>Make CFRange derive Copy<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

use libc::{c_long, c_ulong};
use std::num::Bounded;

pub type Boolean = u8;

pub type CFIndex = c_long;

pub trait CFIndexConvertible {
    /// Always use this method to construct a `CFIndex` value. It performs bounds checking to
    /// ensure the value is in range.
    fn to_CFIndex(self) -> CFIndex;
}

impl CFIndexConvertible for uint {
    #[inline]
    fn to_CFIndex(self) -> CFIndex {
        let max_CFIndex: CFIndex = Bounded::max_value();
        if self > (max_CFIndex as uint) {
            panic!("value out of range")
        }
        self as CFIndex
    }
}

pub type CFOptionFlags = u32;

#[allow(dead_code)]
#[repr(C)]
#[deriving(Copy)]
pub struct CFRange {
    location: CFIndex,
    length: CFIndex
}

impl CFRange {
    pub fn init(offset: CFIndex, length: CFIndex) -> CFRange {
        CFRange {
            location: offset,
            length: length,
        }
    }
}

#[repr(C)]
struct __CFAllocator;

pub type CFAllocatorRef = *const __CFAllocator;

#[repr(C)]
struct __CFNull;

pub type CFNullRef = *const __CFNull;

pub type CFHashCode = c_ulong;

pub type CFTypeID = c_ulong;

#[repr(C)]
struct __CFType;

pub type CFTypeRef = *const __CFType;

/// Superclass of all Core Foundation objects.
pub struct CFType {
    obj: CFTypeRef,
}

impl Clone for CFType {
    #[inline]
    fn clone(&self) -> CFType {
        unsafe {
            TCFType::wrap_under_get_rule(self.obj)
        }
    }
}

impl Drop for CFType {
    fn drop(&mut self) {
        unsafe {
            CFRelease(self.obj)
        }
    }
}

/// All Core Foundation types implement this trait. The type parameter `TypeRef` specifies the
/// associated Core Foundation type: e.g. for `CFType` this is `CFTypeRef`; for `CFArray` this is
/// `CFArrayRef`.
pub trait TCFType<ConcreteTypeRef> {
    /// Returns the object as its concrete TypeRef.
    fn as_concrete_TypeRef(&self) -> ConcreteTypeRef;

    /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this
    /// when following Core Foundation's "Create Rule". The reference count is *not* bumped.
    unsafe fn wrap_under_create_rule(obj: ConcreteTypeRef) -> Self;

    /// Returns the type ID for this class.
    ///
    /// FIXME(pcwalton): The dummy parameter is there to work around the current inexpressivity of
    /// the Rust language.
    fn type_id(dummy: Option<Self>) -> CFTypeID;

    /// Returns the object as a wrapped `CFType`. The reference count is incremented by one.
    #[inline]
    fn as_CFType(&self) -> CFType {
        unsafe {
            TCFType::wrap_under_get_rule(self.as_CFTypeRef())
        }
    }

    /// Returns the object as a raw `CFTypeRef`. The reference count is not adjusted.
    fn as_CFTypeRef(&self) -> CFTypeRef;

    /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this
    /// when following Core Foundation's "Get Rule". The reference count *is* bumped.
    unsafe fn wrap_under_get_rule(reference: ConcreteTypeRef) -> Self;

    /// Returns the reference count of the object. It is unwise to do anything other than test
    /// whether the return value of this method is greater than zero.
    #[inline]
    fn retain_count(&self) -> CFIndex {
        unsafe {
            CFGetRetainCount(self.as_CFTypeRef())
        }
    }

    /// Returns the type ID of this object.
    #[inline]
    fn type_of(&self) -> CFTypeID {
        unsafe {
            CFGetTypeID(self.as_CFTypeRef())
        }
    }

    /// Writes a debugging version of this object on standard error.
    fn show(&self) {
        unsafe {
            CFShow(self.as_CFTypeRef())
        }
    }

    /// Returns true if this value is an instance of another type.
    #[inline]
    fn instance_of<OtherConcreteTypeRef,OtherCFType:TCFType<OtherConcreteTypeRef>>(&self) -> bool {
        let dummy: Option<OtherCFType> = None;
        self.type_of() == TCFType::type_id(dummy)
    }
}

impl TCFType<CFTypeRef> for CFType {
    #[inline]
    fn as_concrete_TypeRef(&self) -> CFTypeRef {
        self.obj
    }

    #[inline]
    unsafe fn wrap_under_get_rule(reference: CFTypeRef) -> CFType {
        let reference: CFTypeRef = CFRetain(reference);
        TCFType::wrap_under_create_rule(reference)
    }

    #[inline]
    fn as_CFTypeRef(&self) -> CFTypeRef {
        self.as_concrete_TypeRef()
    }

    #[inline]
    unsafe fn wrap_under_create_rule(obj: CFTypeRef) -> CFType {
        CFType {
            obj: obj,
        }
    }

    #[inline]
    fn type_id(_: Option<CFType>) -> CFTypeID {
        // FIXME(pcwalton): Is this right?
        0
    }

    #[inline]
    fn instance_of<OtherConcreteTypeRef,OtherCFType:TCFType<OtherConcreteTypeRef>>(&self) -> bool {
        // Since this is the root of the type hierarchy, we always answer yes.
        true
    }
}

#[link(name = "CoreFoundation", kind = "framework")]
extern {
    /*
     * CFBase.h
     */

    /* CFAllocator Reference */
    // N.B. Many CFAllocator functions and constants are omitted here.
    pub static kCFAllocatorDefault: CFAllocatorRef;
    pub static kCFAllocatorSystemDefault: CFAllocatorRef;
    pub static kCFAllocatorMalloc: CFAllocatorRef;
    pub static kCFAllocatorMallocZone: CFAllocatorRef;
    pub static kCFAllocatorNull: CFAllocatorRef;
    pub static kCFAllocatorUseContext: CFAllocatorRef;

    /* CFNull Reference */

    pub static kCFNull: CFNullRef;

    /* CFType Reference */

    //fn CFCopyDescription
    //fn CFCopyTypeIDDescription
    //fn CFEqual
    //fn CFGetAllocator
    pub fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex;
    pub fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID;
    pub fn CFHash(cf: CFTypeRef) -> CFHashCode;
    //fn CFMakeCollectable
    pub fn CFRelease(cf: CFTypeRef);
    pub fn CFRetain(cf: CFTypeRef) -> CFTypeRef;
    pub fn CFShow(obj: CFTypeRef);

    /* Base Utilities Reference */
    // N.B. Some things missing here.
}

<|endoftext|>


<commit_before>//! # C API for rav1e
//!
//! [rav1e](https://github.com/xiph/rav1e/) is an [AV1](https://aomediacodec.github.io/av1-spec/)
//! encoder written in [Rust](https://rust-lang.org)
//!
//! This is the C-compatible API

extern crate rav1e;
extern crate libc;

use std::slice;
use std::sync::Arc;

use std::ffi::CStr;
use std::ffi::CString;
use std::os::raw::c_char;
use std::os::raw::c_int;

use libc::size_t;
use libc::ptrdiff_t;

/// Raw video Frame
///
/// It can be allocated throught rav1e_frame_new(), populated using rav1e_frame_fill_plane()
/// and freed using rav1e_frame_unref().
pub struct Frame(Arc<rav1e::Frame<u16>>);

type EncoderStatus=rav1e::EncoderStatus;

/// Encoder configuration
///
/// Instantiate it using rav1e_config_default() and fine-tune it using
/// rav1e_config_parse().
///
/// Use rav1e_config_unref() to free its memory.
pub struct Config {
    cfg: rav1e::Config,
    last_err: Option<EncoderStatus>,
}

/// Encoder context
///
/// Contains the encoding state, it is created by rav1e_context_new() using an
/// Encoder configuration.
///
/// Use rav1e_context_unref() to free its memory.
pub struct Context {
    ctx: rav1e::Context<u16>,
    last_err: Option<EncoderStatus>,
}

type FrameType = rav1e::FrameType;

/// Encoded Packet
///
/// The encoded packets are retrieved using rav1e_receive_packet().
///
/// Use rav1e_packet_unref() to free its memory.
#[repr(C)]
pub struct Packet {
    /// Encoded data buffer
    pub data: *const u8,
    /// Encoded data buffer size
    pub len: size_t,
    /// Frame sequence number
    pub number: u64,
    /// Frame type
    pub frame_type: FrameType,
}

type ChromaSamplePosition=rav1e::ChromaSamplePosition;
type ChromaSampling=rav1e::ChromaSampling;
type MatrixCoefficients=rav1e::MatrixCoefficients;
type ColorPrimaries=rav1e::ColorPrimaries;
type TransferCharacteristics=rav1e::TransferCharacteristics;
type Rational=rav1e::Rational;

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_default() -> *mut Config {
    let cfg = rav1e::Config {
        enc: rav1e::EncoderConfig::default(),
        threads: 0,
    };

    let c = Box::new(Config {
        cfg,
        last_err: None,
    });

    Box::into_raw(c)
}

/// Set color properties of the stream.
///
/// Supported values are defined by the enum types
/// RaMatrixCoefficients, RaColorPrimaries, and RaTransferCharacteristics
/// respectively.
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_set_color_description(cfg: *mut Config,
                                                            matrix: MatrixCoefficients,
                                                            primaries: ColorPrimaries,
                                                            transfer: TransferCharacteristics
) -> c_int {
    (*cfg).cfg.enc.color_description = Some(rav1e::ColorDescription {
        matrix_coefficients: matrix,
        color_primaries: primaries,
        transfer_characteristics: transfer,
    });

    if (*cfg).cfg.enc.color_description.is_some() { 0 } else { -1 }
}

/// Set the content light level information for HDR10 streams.
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_set_content_light(cfg: *mut Config,
                                                        max_content_light_level: u16,
                                                        max_frame_average_light_level: u16
) -> c_int {
    (*cfg).cfg.enc.content_light = Some(rav1e::ContentLight {
        max_content_light_level,
        max_frame_average_light_level,
    });

    if (*cfg).cfg.enc.content_light.is_some() { 0 } else { -1 }
}

/// Set the mastering display information for HDR10 streams.
///
/// primaries and white_point arguments are RaPoint, containing 0.16 fixed point values.
/// max_luminance is a 24.8 fixed point value.
/// min_luminance is a 18.14 fixed point value.
///
/// Returns a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_set_mastering_display(cfg: *mut Config,
                                                            primaries: [rav1e::Point; 3],
                                                            white_point: rav1e::Point,
                                                            max_luminance: u32,
                                                            min_luminance: u32
) -> c_int {
    (*cfg).cfg.enc.mastering_display = Some(rav1e::MasteringDisplay {
        primaries,
        white_point,
        max_luminance,
        min_luminance,
    });

    if (*cfg).cfg.enc.mastering_display.is_some() { 0 } else { -1 }
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_unref(cfg: *mut Config) {
    if !cfg.is_null() {
        let _ = Box::from_raw(cfg);
    }
}

unsafe fn option_match(
    cfg: *mut Config,
    key: *const c_char,
    value: *const c_char
) -> Result<(), ()> {
    let key = CStr::from_ptr(key).to_str().map_err(|_| ())?;
    let value = CStr::from_ptr(value).to_str().map_err(|_| ())?;
    let enc = &mut(*cfg).cfg.enc;

    match key {
        "width" => enc.width = value.parse().map_err(|_| ())?,
        "height" => enc.height = value.parse().map_err(|_| ())?,
        "speed" => enc.speed_settings = rav1e::SpeedSettings::from_preset(value.parse().map_err(|_| ())?),

        "threads" => (*cfg).cfg.threads = value.parse().map_err(|_| ())?,

        "tune" => enc.tune = value.parse().map_err(|_| ())?,
        "quantizer" => enc.quantizer = value.parse().map_err(|_| ())?,

        "key_frame_interval" => enc.max_key_frame_interval = value.parse().map_err(|_| ())?,
        "min_key_frame_interval" => enc.min_key_frame_interval = value.parse().map_err(|_| ())?,
        "low_latency" => enc.low_latency = value.parse().map_err(|_| ())?,

        _ => return Err(())
    }

    Ok(())
}

/// Set a configuration parameter using its key and value as string.
///
/// Available keys and values
/// - "quantizer": 0-255, default 100
/// - "speed": 0-10, default 3
/// - "tune": "psnr"-"psychovisual", default "psnr"
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_parse(
    cfg: *mut Config,
    key: *const c_char,
    value: *const c_char,
) -> c_int {
    if option_match(cfg, key, value) == Ok(()) { 0 } else { -1 }
}

/// Set a configuration parameter using its key and value as integer.
///
/// Available keys and values are the same as rav1e_config_parse()
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_parse_int(
    cfg: *mut Config,
    key: *const c_char,
    value: c_int,
) -> c_int {
    let val = CString::new(value.to_string()).unwrap();
    if option_match(cfg, key, val.as_ptr()) == Ok(()) { 0 } else { -1 }
}

/// Generate a new encoding context from a populated encoder configuration
///
/// Multiple contexts can be generated through it.
#[no_mangle]
pub unsafe extern "C" fn rav1e_context_new(cfg: *const Config) -> *mut Context {
    let ctx = Context {
        ctx: (*cfg).cfg.new_context(),
        last_err: None,
    };

    Box::into_raw(Box::new(ctx))
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_context_unref(ctx: *mut Context) {
    if !ctx.is_null() {
        let _ = Box::from_raw(ctx);
    }
}

/// Produce a new frame from the encoding context
///
/// It must be populated using rav1e_frame_fill_plane().
///
/// The frame is reference counted and must be released passing it to rav1e_frame_unref(),
/// see rav1e_send_frame().
#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_new(ctx: *const Context) -> *mut Frame {
    let f = (*ctx).ctx.new_frame();
    let frame = Box::new(Frame(f));

    Box::into_raw(frame)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_unref(frame: *mut Frame) {
    if !frame.is_null() {
        let _ = Box::from_raw(frame);
    }
}

/// Send the frame for encoding
///
/// The function increases the frame internal reference count and it can be passed multiple
/// times to different rav1e_send_frame().
///
/// Returns:
/// - `0` on success,
/// - `> 0` if the input queue is full
/// - `< 0` on unrecoverable failure
#[no_mangle]
pub unsafe extern "C" fn rav1e_send_frame(ctx: *mut Context, frame: *const Frame) -> c_int {
    let frame = if frame.is_null() {
        None
    } else {
        Some((*frame).0.clone())
    };

    (*ctx)
        .ctx
        .send_frame(frame)
        .map(|_v| {
            (*ctx).last_err = None;
            0
        }).unwrap_or_else(|e| {
            use rav1e::EncoderStatus::*;
            (*ctx).last_err = Some(e);
            match e {
                EnoughData => 1,
                NeedMoreData | NeedMoreFrames => unreachable!(),
                _ => -1,
            }
        })
}

/// Receive encoded data
///
/// Returns:
/// - `0` on success
/// - `> 0` if additional frame data is required
/// - `< 0` on unrecoverable failure
#[no_mangle]
pub unsafe extern "C" fn rav1e_receive_packet(
    ctx: *mut Context,
    pkt: *mut *mut Packet,
) -> c_int {
    (*ctx)
        .ctx
        .receive_packet()
        .map(|p| {
            (*ctx).last_err = None;
            let rav1e::Packet { data, number, frame_type, .. } = p;
            let len  = data.len();
            let data = Box::into_raw(data.into_boxed_slice()) as *const u8;
            let packet = Packet {
                data,
                len,
                number,
                frame_type,
            };
            *pkt = Box::into_raw(Box::new(packet));
            0
        }).unwrap_or_else(|e| {
            use rav1e::EncoderStatus::*;
            (*ctx).last_err = Some(e);
            match e {
                NeedMoreData |
                    NeedMoreFrames => 1,
                EnoughData => unreachable!(),
                _ => -1,
            }
        })
}

#[no_mangle]
pub unsafe extern fn rav1e_packet_unref(pkt: *mut Packet) {
    if !pkt.is_null() {
        let pkt = Box::from_raw(pkt);
        let _ = Box::from_raw(pkt.data as *mut u8);
    }
}

/// Produce a sequence header matching the current encoding context
///
/// Its format is compatible with the AV1 Matroska and ISOBMFF specification.
///
/// Use rav1e_container_sequence_header_unref() to free it.
#[no_mangle]
pub unsafe extern fn rav1e_container_sequence_header(ctx: *mut Context, buf_size: *mut size_t) -> *mut u8 {
    let buf = (*ctx).ctx.container_sequence_header();

    *buf_size = buf.len();
    Box::into_raw(buf.into_boxed_slice()) as *mut u8
}

#[no_mangle]
pub unsafe extern fn rav1e_container_sequence_header_unref(sequence: *mut u8) {
    if !sequence.is_null() {
        let _ = Box::from_raw(sequence);
    }
}

/// Fill a frame plane
///
/// Currently the frame contains 3 planes, the first is luminance followed by
/// chrominance.
///
/// The data is copied and this function has to be called for each plane.
///
/// frame: A frame provided by rav1e_frame_new()
/// plane: The index of the plane starting from 0
/// data: The data to be copied
/// data_len: Lenght of the buffer
/// stride: Plane line in bytes, including padding
/// bytewidth: Number of bytes per component, either 1 or 2
#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_fill_plane(
    frame: *mut Frame,
    plane: c_int,
    data: *const u8,
    data_len: size_t,
    stride: ptrdiff_t,
    bytewidth: c_int,
) {
    let input = Arc::get_mut(&mut (*frame).0).unwrap();
    let data_slice = slice::from_raw_parts(data, data_len as usize);

    input.planes[plane as usize].copy_from_raw_u8(data_slice, stride as usize, bytewidth as usize);
}
<commit_msg>crav1e: Use make_mut in rav1e_frame_fill_plane<commit_after>//! # C API for rav1e
//!
//! [rav1e](https://github.com/xiph/rav1e/) is an [AV1](https://aomediacodec.github.io/av1-spec/)
//! encoder written in [Rust](https://rust-lang.org)
//!
//! This is the C-compatible API

extern crate rav1e;
extern crate libc;

use std::slice;
use std::sync::Arc;

use std::ffi::CStr;
use std::ffi::CString;
use std::os::raw::c_char;
use std::os::raw::c_int;

use libc::size_t;
use libc::ptrdiff_t;

/// Raw video Frame
///
/// It can be allocated throught rav1e_frame_new(), populated using rav1e_frame_fill_plane()
/// and freed using rav1e_frame_unref().
pub struct Frame(Arc<rav1e::Frame<u16>>);

type EncoderStatus=rav1e::EncoderStatus;

/// Encoder configuration
///
/// Instantiate it using rav1e_config_default() and fine-tune it using
/// rav1e_config_parse().
///
/// Use rav1e_config_unref() to free its memory.
pub struct Config {
    cfg: rav1e::Config,
    last_err: Option<EncoderStatus>,
}

/// Encoder context
///
/// Contains the encoding state, it is created by rav1e_context_new() using an
/// Encoder configuration.
///
/// Use rav1e_context_unref() to free its memory.
pub struct Context {
    ctx: rav1e::Context<u16>,
    last_err: Option<EncoderStatus>,
}

type FrameType = rav1e::FrameType;

/// Encoded Packet
///
/// The encoded packets are retrieved using rav1e_receive_packet().
///
/// Use rav1e_packet_unref() to free its memory.
#[repr(C)]
pub struct Packet {
    /// Encoded data buffer
    pub data: *const u8,
    /// Encoded data buffer size
    pub len: size_t,
    /// Frame sequence number
    pub number: u64,
    /// Frame type
    pub frame_type: FrameType,
}

type ChromaSamplePosition=rav1e::ChromaSamplePosition;
type ChromaSampling=rav1e::ChromaSampling;
type MatrixCoefficients=rav1e::MatrixCoefficients;
type ColorPrimaries=rav1e::ColorPrimaries;
type TransferCharacteristics=rav1e::TransferCharacteristics;
type Rational=rav1e::Rational;

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_default() -> *mut Config {
    let cfg = rav1e::Config {
        enc: rav1e::EncoderConfig::default(),
        threads: 0,
    };

    let c = Box::new(Config {
        cfg,
        last_err: None,
    });

    Box::into_raw(c)
}

/// Set color properties of the stream.
///
/// Supported values are defined by the enum types
/// RaMatrixCoefficients, RaColorPrimaries, and RaTransferCharacteristics
/// respectively.
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_set_color_description(cfg: *mut Config,
                                                            matrix: MatrixCoefficients,
                                                            primaries: ColorPrimaries,
                                                            transfer: TransferCharacteristics
) -> c_int {
    (*cfg).cfg.enc.color_description = Some(rav1e::ColorDescription {
        matrix_coefficients: matrix,
        color_primaries: primaries,
        transfer_characteristics: transfer,
    });

    if (*cfg).cfg.enc.color_description.is_some() { 0 } else { -1 }
}

/// Set the content light level information for HDR10 streams.
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_set_content_light(cfg: *mut Config,
                                                        max_content_light_level: u16,
                                                        max_frame_average_light_level: u16
) -> c_int {
    (*cfg).cfg.enc.content_light = Some(rav1e::ContentLight {
        max_content_light_level,
        max_frame_average_light_level,
    });

    if (*cfg).cfg.enc.content_light.is_some() { 0 } else { -1 }
}

/// Set the mastering display information for HDR10 streams.
///
/// primaries and white_point arguments are RaPoint, containing 0.16 fixed point values.
/// max_luminance is a 24.8 fixed point value.
/// min_luminance is a 18.14 fixed point value.
///
/// Returns a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_set_mastering_display(cfg: *mut Config,
                                                            primaries: [rav1e::Point; 3],
                                                            white_point: rav1e::Point,
                                                            max_luminance: u32,
                                                            min_luminance: u32
) -> c_int {
    (*cfg).cfg.enc.mastering_display = Some(rav1e::MasteringDisplay {
        primaries,
        white_point,
        max_luminance,
        min_luminance,
    });

    if (*cfg).cfg.enc.mastering_display.is_some() { 0 } else { -1 }
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_config_unref(cfg: *mut Config) {
    if !cfg.is_null() {
        let _ = Box::from_raw(cfg);
    }
}

unsafe fn option_match(
    cfg: *mut Config,
    key: *const c_char,
    value: *const c_char
) -> Result<(), ()> {
    let key = CStr::from_ptr(key).to_str().map_err(|_| ())?;
    let value = CStr::from_ptr(value).to_str().map_err(|_| ())?;
    let enc = &mut(*cfg).cfg.enc;

    match key {
        "width" => enc.width = value.parse().map_err(|_| ())?,
        "height" => enc.height = value.parse().map_err(|_| ())?,
        "speed" => enc.speed_settings = rav1e::SpeedSettings::from_preset(value.parse().map_err(|_| ())?),

        "threads" => (*cfg).cfg.threads = value.parse().map_err(|_| ())?,

        "tune" => enc.tune = value.parse().map_err(|_| ())?,
        "quantizer" => enc.quantizer = value.parse().map_err(|_| ())?,

        "key_frame_interval" => enc.max_key_frame_interval = value.parse().map_err(|_| ())?,
        "min_key_frame_interval" => enc.min_key_frame_interval = value.parse().map_err(|_| ())?,
        "low_latency" => enc.low_latency = value.parse().map_err(|_| ())?,

        _ => return Err(())
    }

    Ok(())
}

/// Set a configuration parameter using its key and value as string.
///
/// Available keys and values
/// - "quantizer": 0-255, default 100
/// - "speed": 0-10, default 3
/// - "tune": "psnr"-"psychovisual", default "psnr"
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_parse(
    cfg: *mut Config,
    key: *const c_char,
    value: *const c_char,
) -> c_int {
    if option_match(cfg, key, value) == Ok(()) { 0 } else { -1 }
}

/// Set a configuration parameter using its key and value as integer.
///
/// Available keys and values are the same as rav1e_config_parse()
///
/// Return a negative value on error or 0.
#[no_mangle]
pub unsafe extern "C" fn rav1e_config_parse_int(
    cfg: *mut Config,
    key: *const c_char,
    value: c_int,
) -> c_int {
    let val = CString::new(value.to_string()).unwrap();
    if option_match(cfg, key, val.as_ptr()) == Ok(()) { 0 } else { -1 }
}

/// Generate a new encoding context from a populated encoder configuration
///
/// Multiple contexts can be generated through it.
#[no_mangle]
pub unsafe extern "C" fn rav1e_context_new(cfg: *const Config) -> *mut Context {
    let ctx = Context {
        ctx: (*cfg).cfg.new_context(),
        last_err: None,
    };

    Box::into_raw(Box::new(ctx))
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_context_unref(ctx: *mut Context) {
    if !ctx.is_null() {
        let _ = Box::from_raw(ctx);
    }
}

/// Produce a new frame from the encoding context
///
/// It must be populated using rav1e_frame_fill_plane().
///
/// The frame is reference counted and must be released passing it to rav1e_frame_unref(),
/// see rav1e_send_frame().
#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_new(ctx: *const Context) -> *mut Frame {
    let f = (*ctx).ctx.new_frame();
    let frame = Box::new(Frame(f));

    Box::into_raw(frame)
}

#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_unref(frame: *mut Frame) {
    if !frame.is_null() {
        let _ = Box::from_raw(frame);
    }
}

/// Send the frame for encoding
///
/// The function increases the frame internal reference count and it can be passed multiple
/// times to different rav1e_send_frame().
///
/// Returns:
/// - `0` on success,
/// - `> 0` if the input queue is full
/// - `< 0` on unrecoverable failure
#[no_mangle]
pub unsafe extern "C" fn rav1e_send_frame(ctx: *mut Context, frame: *const Frame) -> c_int {
    let frame = if frame.is_null() {
        None
    } else {
        Some((*frame).0.clone())
    };

    (*ctx)
        .ctx
        .send_frame(frame)
        .map(|_v| {
            (*ctx).last_err = None;
            0
        }).unwrap_or_else(|e| {
            use rav1e::EncoderStatus::*;
            (*ctx).last_err = Some(e);
            match e {
                EnoughData => 1,
                NeedMoreData | NeedMoreFrames => unreachable!(),
                _ => -1,
            }
        })
}

/// Receive encoded data
///
/// Returns:
/// - `0` on success
/// - `> 0` if additional frame data is required
/// - `< 0` on unrecoverable failure
#[no_mangle]
pub unsafe extern "C" fn rav1e_receive_packet(
    ctx: *mut Context,
    pkt: *mut *mut Packet,
) -> c_int {
    (*ctx)
        .ctx
        .receive_packet()
        .map(|p| {
            (*ctx).last_err = None;
            let rav1e::Packet { data, number, frame_type, .. } = p;
            let len  = data.len();
            let data = Box::into_raw(data.into_boxed_slice()) as *const u8;
            let packet = Packet {
                data,
                len,
                number,
                frame_type,
            };
            *pkt = Box::into_raw(Box::new(packet));
            0
        }).unwrap_or_else(|e| {
            use rav1e::EncoderStatus::*;
            (*ctx).last_err = Some(e);
            match e {
                NeedMoreData |
                    NeedMoreFrames => 1,
                EnoughData => unreachable!(),
                _ => -1,
            }
        })
}

#[no_mangle]
pub unsafe extern fn rav1e_packet_unref(pkt: *mut Packet) {
    if !pkt.is_null() {
        let pkt = Box::from_raw(pkt);
        let _ = Box::from_raw(pkt.data as *mut u8);
    }
}

/// Produce a sequence header matching the current encoding context
///
/// Its format is compatible with the AV1 Matroska and ISOBMFF specification.
///
/// Use rav1e_container_sequence_header_unref() to free it.
#[no_mangle]
pub unsafe extern fn rav1e_container_sequence_header(ctx: *mut Context, buf_size: *mut size_t) -> *mut u8 {
    let buf = (*ctx).ctx.container_sequence_header();

    *buf_size = buf.len();
    Box::into_raw(buf.into_boxed_slice()) as *mut u8
}

#[no_mangle]
pub unsafe extern fn rav1e_container_sequence_header_unref(sequence: *mut u8) {
    if !sequence.is_null() {
        let _ = Box::from_raw(sequence);
    }
}

/// Fill a frame plane
///
/// Currently the frame contains 3 planes, the first is luminance followed by
/// chrominance.
///
/// The data is copied and this function has to be called for each plane.
///
/// frame: A frame provided by rav1e_frame_new()
/// plane: The index of the plane starting from 0
/// data: The data to be copied
/// data_len: Lenght of the buffer
/// stride: Plane line in bytes, including padding
/// bytewidth: Number of bytes per component, either 1 or 2
#[no_mangle]
pub unsafe extern "C" fn rav1e_frame_fill_plane(
    frame: *mut Frame,
    plane: c_int,
    data: *const u8,
    data_len: size_t,
    stride: ptrdiff_t,
    bytewidth: c_int,
) {
    let f = &mut (*frame).0;
    let input = Arc::make_mut(f);
    let data_slice = slice::from_raw_parts(data, data_len as usize);

    input.planes[plane as usize].copy_from_raw_u8(data_slice, stride as usize, bytewidth as usize);
}
<|endoftext|>


<commit_before>#[test]
fn num_cards() {
    let deck = super::Deck::new();
    assert_eq!(deck.cards.len(), 52);
}

#[test]
fn draw_card() {
    let mut deck = super::Deck::new();
    let _card = deck.draw();
    assert_eq!(deck.cards.len(), 51);
}
<commit_msg>Addded checks for the removed card for draw test<commit_after>#[test]
fn num_cards() {
    let deck = super::Deck::new();
    assert_eq!(deck.cards.len(), 52);
}

#[test]
fn draw_card() {
    let mut deck = super::Deck::new();
    let top_card_value = deck.cards.get(51).unwrap().value.clone();
    let top_card_suit = deck.cards.get(51).unwrap().suit.clone();
    let card = deck.draw();
    assert_eq!(deck.cards.len(), 51);

    assert!(card.value != ::card::Value::None);
    assert!(card.suit != ::card::Suit::None);

    assert_eq!(card.value, top_card_value);
    assert_eq!(card.suit, top_card_suit);
}
<|endoftext|>


<commit_before>// Copyright 2014 The Gfx-rs Developers.
//
// 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.

#![crate_id = "github.com/bjz/gfx-rs#device:0.1"]
#![comment = "A lightweight graphics device manager for Rust"]
#![license = "ASL2"]
#![crate_type = "lib"]

#![feature(phase)]

#[phase(plugin, link)] extern crate log;
extern crate libc;
extern crate comm;

#[cfg(gl)] pub use gl::GlBackEnd;
#[cfg(gl)] pub use dev = self::gl;
// #[cfg(d3d11)] ... // TODO

use std::kinds::marker;

pub mod attrib;
pub mod shade;
pub mod target;
#[cfg(gl)] mod gl;

#[deriving(Show)]
pub struct Capabilities {
    shader_model: shade::ShaderModel,
    max_draw_buffers : uint,
    max_texture_size : uint,
    max_vertex_attributes: uint,
}

pub type VertexCount = u16;
pub type IndexCount = u16;
pub type AttributeSlot = u8;
pub type UniformBufferSlot = u8;
pub type TextureSlot = u8;

#[deriving(Show)]
pub enum BufferUsage {
    UsageStatic,
    UsageDynamic,
    UsageStream,
}

#[deriving(Show)]
pub enum Request {
    // Requests that require a reply:
    CallNewVertexBuffer(Vec<f32>),
    CallNewIndexBuffer(Vec<u16>),
    CallNewRawBuffer,
    CallNewArrayBuffer,
    CallNewShader(shade::Stage, shade::ShaderSource),
    CallNewProgram(Vec<dev::Shader>),
    CallNewFrameBuffer,
    // Requests that don't expect a reply:
    CastClear(target::ClearData),
    CastBindProgram(dev::Program),
    CastBindArrayBuffer(dev::ArrayBuffer),
    CastBindAttribute(AttributeSlot, dev::Buffer, attrib::Count,
        attrib::Type, attrib::Stride, attrib::Offset),
    CastBindIndex(dev::Buffer),
    CastBindFrameBuffer(dev::FrameBuffer),
    CastBindTarget(target::Target, target::Plane),
    CastBindUniformBlock(dev::Program, u8, UniformBufferSlot, dev::Buffer),
    CastBindUniform(shade::Location, shade::UniformValue),
    //CastBindTexture(TextureSlot, dev::Texture, dev::Sampler),    //TODO
    CastUpdateBuffer(dev::Buffer, Vec<f32>),
    CastDraw(VertexCount, VertexCount),
    CastDrawIndexed(IndexCount, IndexCount),
    CastSwapBuffers,
}

#[deriving(Show)]
pub enum Reply {
    ReplyNewBuffer(dev::Buffer),
    ReplyNewArrayBuffer(dev::ArrayBuffer),
    ReplyNewShader(Result<dev::Shader, shade::CreateShaderError>),
    ReplyNewProgram(Result<shade::ProgramMeta, ()>),
    ReplyNewFrameBuffer(dev::FrameBuffer),
}

pub trait ApiBackEnd {
    fn get_capabilities<'a>(&'a self) -> &'a Capabilities;
    // calls
    fn create_buffer(&mut self) -> dev::Buffer;
    fn create_array_buffer(&mut self) -> dev::ArrayBuffer;
    fn create_shader(&mut self, shade::Stage, code: shade::ShaderSource) -> Result<dev::Shader, shade::CreateShaderError>;
    fn create_program(&mut self, shaders: &[dev::Shader]) -> Result<shade::ProgramMeta, ()>;
    fn create_frame_buffer(&mut self) -> dev::FrameBuffer;
    // helpers
    fn update_buffer<T>(&mut self, dev::Buffer, data: &[T], BufferUsage);
    // casts
    fn process(&mut self, Request);
}

pub struct Ack;

pub struct Device<P, I> {
    no_share: marker::NoShare,
    request_rx: Receiver<Request>,
    reply_tx: Sender<Reply>,
    graphics_context: P,
    back_end: I,
    swap_ack: Sender<Ack>,
    close: comm::Close,
}

impl<Api, P: GraphicsContext<Api>, I: ApiBackEnd> Device<P, I> {
    pub fn close(&self) {
        self.close.now()
    }

    pub fn make_current(&self) {
        self.graphics_context.make_current();
    }

    /// Update the platform. The client must manually update this on the main
    /// thread.
    pub fn update(&mut self) {
        // Get updates from the renderer and pass on results
        loop {
            match self.request_rx.recv_opt() {
                Ok(CastSwapBuffers) => {
                    self.graphics_context.swap_buffers();
                    self.swap_ack.send(Ack);
                    break;
                },
                Ok(CallNewVertexBuffer(data)) => {
                    let name = self.back_end.create_buffer();
                    self.back_end.update_buffer(name, data.as_slice(), UsageStatic);
                    self.reply_tx.send(ReplyNewBuffer(name));
                },
                Ok(CallNewIndexBuffer(data)) => {
                    let name = self.back_end.create_buffer();
                    self.back_end.update_buffer(name, data.as_slice(), UsageStatic);
                    self.reply_tx.send(ReplyNewBuffer(name));
                },
                Ok(CallNewRawBuffer) => {
                    let name = self.back_end.create_buffer();
                    self.reply_tx.send(ReplyNewBuffer(name));
                },
                Ok(CallNewArrayBuffer) => {
                    let name = self.back_end.create_array_buffer();
                    self.reply_tx.send(ReplyNewArrayBuffer(name));
                },
                Ok(CallNewShader(stage, code)) => {
                    let name = self.back_end.create_shader(stage, code);
                    self.reply_tx.send(ReplyNewShader(name));
                },
                Ok(CallNewProgram(code)) => {
                    let name = self.back_end.create_program(code.as_slice());
                    self.reply_tx.send(ReplyNewProgram(name));
                },
                Ok(CallNewFrameBuffer) => {
                    let name = self.back_end.create_frame_buffer();
                    self.reply_tx.send(ReplyNewFrameBuffer(name));
                },
                Ok(request) => self.back_end.process(request),
                Err(()) => return,
            }
        }
    }
}

pub trait GraphicsContext<Api> {
    fn swap_buffers(&self);
    fn make_current(&self);
}

pub trait GlProvider {
    fn get_proc_address(&self, &str) -> *const ::libc::c_void;
    fn is_extension_supported(&self, &str) -> bool;
}

#[deriving(Show)]
pub enum InitError {}

pub type QueueSize = u8;
pub struct Options<T>(pub T, pub QueueSize);

#[allow(visible_private_types)]
pub fn init<Api, P: GraphicsContext<Api>, T: GlProvider>(graphics_context: P, options: Options<T>)
        -> Result<(Sender<Request>, Receiver<Reply>, Device<P, GlBackEnd>, Receiver<Ack>, comm::ShouldClose), InitError> {
    let (request_tx, request_rx) = channel();
    let (reply_tx, reply_rx) = channel();
    let (swap_tx, swap_rx) = channel();
    let (close, should_close) = comm::close_stream();

    let Options(provider, queue_size) = options;
    for _ in range(0, queue_size) {
        swap_tx.send(Ack);
    }

    let gl = GlBackEnd::new(&provider); // TODO: Generalise for different back-ends
    let device = Device {
        no_share: marker::NoShare,
        request_rx: request_rx,
        reply_tx: reply_tx,
        graphics_context: graphics_context,
        back_end: gl,
        swap_ack: swap_tx,
        close: close,
    };

    Ok((request_tx, reply_rx, device, swap_rx, should_close))
}
<commit_msg>Add some documentation<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// 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.

#![crate_id = "github.com/bjz/gfx-rs#device:0.1"]
#![comment = "A lightweight graphics device manager for Rust"]
#![license = "ASL2"]
#![crate_type = "lib"]

#![feature(phase)]

#[phase(plugin, link)] extern crate log;
extern crate libc;
extern crate comm;

#[cfg(gl)] pub use gl::GlBackEnd;
#[cfg(gl)] pub use dev = self::gl;
// #[cfg(d3d11)] ... // TODO

use std::kinds::marker;

pub mod attrib;
pub mod shade;
pub mod target;
#[cfg(gl)] mod gl;

#[deriving(Show)]
pub struct Capabilities {
    shader_model: shade::ShaderModel,
    max_draw_buffers : uint,
    max_texture_size : uint,
    max_vertex_attributes: uint,
}

pub type VertexCount = u16;
pub type IndexCount = u16;
pub type AttributeSlot = u8;
pub type UniformBufferSlot = u8;
pub type TextureSlot = u8;

#[deriving(Show)]
pub enum BufferUsage {
    UsageStatic,
    UsageDynamic,
    UsageStream,
}

#[deriving(Show)]
pub enum Request {
    // Requests that require a reply:
    CallNewVertexBuffer(Vec<f32>),
    CallNewIndexBuffer(Vec<u16>),
    CallNewRawBuffer,
    CallNewArrayBuffer,
    CallNewShader(shade::Stage, shade::ShaderSource),
    CallNewProgram(Vec<dev::Shader>),
    CallNewFrameBuffer,
    // Requests that don't expect a reply:
    CastClear(target::ClearData),
    CastBindProgram(dev::Program),
    CastBindArrayBuffer(dev::ArrayBuffer),
    CastBindAttribute(AttributeSlot, dev::Buffer, attrib::Count,
        attrib::Type, attrib::Stride, attrib::Offset),
    CastBindIndex(dev::Buffer),
    CastBindFrameBuffer(dev::FrameBuffer),
    CastBindTarget(target::Target, target::Plane),
    CastBindUniformBlock(dev::Program, u8, UniformBufferSlot, dev::Buffer),
    CastBindUniform(shade::Location, shade::UniformValue),
    //CastBindTexture(TextureSlot, dev::Texture, dev::Sampler),    //TODO
    CastUpdateBuffer(dev::Buffer, Vec<f32>),
    CastDraw(VertexCount, VertexCount),
    CastDrawIndexed(IndexCount, IndexCount),
    CastSwapBuffers,
}

#[deriving(Show)]
pub enum Reply {
    ReplyNewBuffer(dev::Buffer),
    ReplyNewArrayBuffer(dev::ArrayBuffer),
    ReplyNewShader(Result<dev::Shader, shade::CreateShaderError>),
    ReplyNewProgram(Result<shade::ProgramMeta, ()>),
    ReplyNewFrameBuffer(dev::FrameBuffer),
}

/// An interface for performing draw calls using a specific graphics API
pub trait ApiBackEnd {
    fn get_capabilities<'a>(&'a self) -> &'a Capabilities;
    // calls
    fn create_buffer(&mut self) -> dev::Buffer;
    fn create_array_buffer(&mut self) -> dev::ArrayBuffer;
    fn create_shader(&mut self, shade::Stage, code: shade::ShaderSource) -> Result<dev::Shader, shade::CreateShaderError>;
    fn create_program(&mut self, shaders: &[dev::Shader]) -> Result<shade::ProgramMeta, ()>;
    fn create_frame_buffer(&mut self) -> dev::FrameBuffer;
    // helpers
    fn update_buffer<T>(&mut self, dev::Buffer, data: &[T], BufferUsage);
    // casts
    fn process(&mut self, Request);
}

pub struct Ack;

/// An API-agnostic device that manages incoming draw calls
pub struct Device<P, I> {
    no_share: marker::NoShare,
    request_rx: Receiver<Request>,
    reply_tx: Sender<Reply>,
    graphics_context: P,
    back_end: I,
    swap_ack: Sender<Ack>,
    close: comm::Close,
}

impl<Api, P: GraphicsContext<Api>, I: ApiBackEnd> Device<P, I> {
    pub fn close(&self) {
        self.close.now()
    }

    pub fn make_current(&self) {
        self.graphics_context.make_current();
    }

    /// Update the platform. The client must manually update this on the main
    /// thread.
    pub fn update(&mut self) {
        // Get updates from the renderer and pass on results
        loop {
            match self.request_rx.recv_opt() {
                Ok(CastSwapBuffers) => {
                    self.graphics_context.swap_buffers();
                    self.swap_ack.send(Ack);
                    break;
                },
                Ok(CallNewVertexBuffer(data)) => {
                    let name = self.back_end.create_buffer();
                    self.back_end.update_buffer(name, data.as_slice(), UsageStatic);
                    self.reply_tx.send(ReplyNewBuffer(name));
                },
                Ok(CallNewIndexBuffer(data)) => {
                    let name = self.back_end.create_buffer();
                    self.back_end.update_buffer(name, data.as_slice(), UsageStatic);
                    self.reply_tx.send(ReplyNewBuffer(name));
                },
                Ok(CallNewRawBuffer) => {
                    let name = self.back_end.create_buffer();
                    self.reply_tx.send(ReplyNewBuffer(name));
                },
                Ok(CallNewArrayBuffer) => {
                    let name = self.back_end.create_array_buffer();
                    self.reply_tx.send(ReplyNewArrayBuffer(name));
                },
                Ok(CallNewShader(stage, code)) => {
                    let name = self.back_end.create_shader(stage, code);
                    self.reply_tx.send(ReplyNewShader(name));
                },
                Ok(CallNewProgram(code)) => {
                    let name = self.back_end.create_program(code.as_slice());
                    self.reply_tx.send(ReplyNewProgram(name));
                },
                Ok(CallNewFrameBuffer) => {
                    let name = self.back_end.create_frame_buffer();
                    self.reply_tx.send(ReplyNewFrameBuffer(name));
                },
                Ok(request) => self.back_end.process(request),
                Err(()) => return,
            }
        }
    }
}

pub trait GraphicsContext<Api> {
    fn swap_buffers(&self);
    fn make_current(&self);
}

pub trait GlProvider {
    fn get_proc_address(&self, &str) -> *const ::libc::c_void;
    fn is_extension_supported(&self, &str) -> bool;
}

#[deriving(Show)]
pub enum InitError {}

pub type QueueSize = u8;
pub struct Options<T>(pub T, pub QueueSize);

#[allow(visible_private_types)]
pub fn init<Api, P: GraphicsContext<Api>, T: GlProvider>(graphics_context: P, options: Options<T>)
        -> Result<(Sender<Request>, Receiver<Reply>, Device<P, GlBackEnd>, Receiver<Ack>, comm::ShouldClose), InitError> {
    let (request_tx, request_rx) = channel();
    let (reply_tx, reply_rx) = channel();
    let (swap_tx, swap_rx) = channel();
    let (close, should_close) = comm::close_stream();

    let Options(provider, queue_size) = options;
    for _ in range(0, queue_size) {
        swap_tx.send(Ack);
    }

    let gl = GlBackEnd::new(&provider); // TODO: Generalise for different back-ends
    let device = Device {
        no_share: marker::NoShare,
        request_rx: request_rx,
        reply_tx: reply_tx,
        graphics_context: graphics_context,
        back_end: gl,
        swap_ack: swap_tx,
        close: close,
    };

    Ok((request_tx, reply_rx, device, swap_rx, should_close))
}
<|endoftext|>


<commit_before>use super::*;
use delimited::Delimited;

ast_struct! {
    /// An enum variant.
    pub struct Variant {
        /// Attributes tagged on the variant.
        pub attrs: Vec<Attribute>,

        /// Name of the variant.
        pub ident: Ident,

        /// Type of variant.
        pub data: VariantData,

        /// Explicit discriminant, e.g. `Foo = 1`
        pub discriminant: Option<(Token![=], Expr)>,
    }
}

ast_enum! {
    /// Data stored within an enum variant or struct.
    pub enum VariantData {
        /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
        Struct(token::Brace, Delimited<Field, Token![,]>),

        /// Tuple variant, e.g. `Some(T)`.
        Tuple(token::Paren, Delimited<Field, Token![,]>),

        /// Unit variant, e.g. `None`.
        Unit,
    }
}

impl VariantData {
    // TODO: expose this?
    // /// Slice containing the fields stored in the variant.
    // pub fn fields(&self) -> &Delimited<Field, token::Comma> {
    //     match *self {
    //         VariantData::Struct(_, ref fields) |
    //         VariantData::Tuple(_, ref fields) => fields,
    //         VariantData::Unit => &[],
    //     }
    // }
    //
    // /// Mutable slice containing the fields stored in the variant.
    // pub fn fields_mut(&mut self) -> &mut Delimited<Field, token::Comma> {
    //     match *self {
    //         VariantData::Struct(ref mut fields, _) |
    //         VariantData::Tuple(ref mut fields, _) => fields,
    //         VariantData::Unit => &mut [],
    //     }
    // }
}

ast_struct! {
    /// A field of a struct or enum variant.
    pub struct Field {
        /// Attributes tagged on the field.
        pub attrs: Vec<Attribute>,

        /// Visibility of the field.
        pub vis: Visibility,

        /// Name of the field, if any.
        ///
        /// Fields of tuple structs have no names.
        pub ident: Option<Ident>,

        pub colon_token: Option<Token![:]>,

        /// Type of the field.
        pub ty: Type,
    }
}

ast_enum_of_structs! {
    /// Visibility level of an item.
    pub enum Visibility {
        /// Public, i.e. `pub`.
        pub Public(VisPublic {
            pub pub_token: Token![pub],
        }),

        /// Crate-visible, i.e. `pub(crate)`.
        pub Crate(VisCrate {
            pub pub_token: Token![pub],
            pub paren_token: token::Paren,
            pub crate_token: Token![crate],
        }),

        /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
        pub Restricted(VisRestricted {
            pub pub_token: Token![pub],
            pub paren_token: token::Paren,
            pub in_token: Option<Token![in]>,
            pub path: Box<Path>,
        }),

        /// Inherited, i.e. private.
        pub Inherited,
    }
}

#[cfg(feature = "parsing")]
pub mod parsing {
    use super::*;

    use synom::Synom;

    impl Field {
        named!(pub parse_struct -> Self, do_parse!(
            attrs: many0!(Attribute::parse_outer) >>
            vis: syn!(Visibility) >>
            id: syn!(Ident) >>
            colon: punct!(:) >>
            ty: syn!(Type) >>
            (Field {
                ident: Some(id),
                vis: vis,
                attrs: attrs,
                ty: ty,
                colon_token: Some(colon),
            })
        ));

        named!(pub parse_tuple -> Self, do_parse!(
            attrs: many0!(Attribute::parse_outer) >>
            vis: syn!(Visibility) >>
            ty: syn!(Type) >>
            (Field {
                ident: None,
                colon_token: None,
                vis: vis,
                attrs: attrs,
                ty: ty,
            })
        ));
    }

    impl Synom for Visibility {
        named!(parse -> Self, alt!(
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(keyword!(crate)) >>
                (Visibility::Crate(VisCrate {
                    pub_token: pub_token,
                    paren_token: other.0,
                    crate_token: other.1,
                }))
            )
            |
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(keyword!(self)) >>
                (Visibility::Restricted(VisRestricted {
                    pub_token: pub_token,
                    paren_token: other.0,
                    in_token: None,
                    path: Box::new(other.1.into()),
                }))
            )
            |
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(keyword!(super)) >>
                (Visibility::Restricted(VisRestricted {
                    pub_token: pub_token,
                    paren_token: other.0,
                    in_token: None,
                    path: Box::new(other.1.into()),
                }))
            )
            |
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(do_parse!(
                    in_tok: keyword!(in) >>
                    restricted: call!(Path::parse_mod_style) >>
                    (in_tok, restricted)
                )) >>
                (Visibility::Restricted(VisRestricted {
                    pub_token: pub_token,
                    paren_token: other.0,
                    in_token: Some((other.1).0),
                    path: Box::new((other.1).1),
                }))
            )
            |
            keyword!(pub) => { |tok| {
                Visibility::Public(VisPublic {
                    pub_token: tok,
                })
            } }
            |
            epsilon!() => { |_| Visibility::Inherited }
        ));

        fn description() -> Option<&'static str> {
            Some("visibility qualifier, e.g. `pub`")
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use quote::{ToTokens, Tokens};

    impl ToTokens for Variant {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append_all(&self.attrs);
            self.ident.to_tokens(tokens);
            self.data.to_tokens(tokens);
            if let Some((ref eq_token, ref disc)) = self.discriminant {
                eq_token.to_tokens(tokens);
                disc.to_tokens(tokens);
            }
        }
    }

    impl ToTokens for VariantData {
        fn to_tokens(&self, tokens: &mut Tokens) {
            match *self {
                VariantData::Struct(ref brace, ref fields) => {
                    brace.surround(tokens, |tokens| {
                        fields.to_tokens(tokens);
                    });
                }
                VariantData::Tuple(ref paren, ref fields) => {
                    paren.surround(tokens, |tokens| {
                        fields.to_tokens(tokens);
                    });
                }
                VariantData::Unit => {}
            }
        }
    }

    impl ToTokens for Field {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append_all(&self.attrs);
            self.vis.to_tokens(tokens);
            if let Some(ref ident) = self.ident {
                ident.to_tokens(tokens);
                TokensOrDefault(&self.colon_token).to_tokens(tokens);
            }
            self.ty.to_tokens(tokens);
        }
    }

    impl ToTokens for VisPublic {
        fn to_tokens(&self, tokens: &mut Tokens) {
            self.pub_token.to_tokens(tokens)
        }
    }

    impl ToTokens for VisCrate {
        fn to_tokens(&self, tokens: &mut Tokens) {
            self.pub_token.to_tokens(tokens);
            self.paren_token.surround(tokens, |tokens| {
                self.crate_token.to_tokens(tokens);
            })
        }
    }

    impl ToTokens for VisRestricted {
        fn to_tokens(&self, tokens: &mut Tokens) {
            self.pub_token.to_tokens(tokens);
            self.paren_token.surround(tokens, |tokens| {
                // XXX: If we have a path which is not "self" or "super",
                // automatically add the "in" token.
                self.in_token.to_tokens(tokens);
                self.path.to_tokens(tokens);
            });
        }
    }
}
<commit_msg>Remove commented code<commit_after>use super::*;
use delimited::Delimited;

ast_struct! {
    /// An enum variant.
    pub struct Variant {
        /// Attributes tagged on the variant.
        pub attrs: Vec<Attribute>,

        /// Name of the variant.
        pub ident: Ident,

        /// Type of variant.
        pub data: VariantData,

        /// Explicit discriminant, e.g. `Foo = 1`
        pub discriminant: Option<(Token![=], Expr)>,
    }
}

ast_enum! {
    /// Data stored within an enum variant or struct.
    pub enum VariantData {
        /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
        Struct(token::Brace, Delimited<Field, Token![,]>),

        /// Tuple variant, e.g. `Some(T)`.
        Tuple(token::Paren, Delimited<Field, Token![,]>),

        /// Unit variant, e.g. `None`.
        Unit,
    }
}

ast_struct! {
    /// A field of a struct or enum variant.
    pub struct Field {
        /// Attributes tagged on the field.
        pub attrs: Vec<Attribute>,

        /// Visibility of the field.
        pub vis: Visibility,

        /// Name of the field, if any.
        ///
        /// Fields of tuple structs have no names.
        pub ident: Option<Ident>,

        pub colon_token: Option<Token![:]>,

        /// Type of the field.
        pub ty: Type,
    }
}

ast_enum_of_structs! {
    /// Visibility level of an item.
    pub enum Visibility {
        /// Public, i.e. `pub`.
        pub Public(VisPublic {
            pub pub_token: Token![pub],
        }),

        /// Crate-visible, i.e. `pub(crate)`.
        pub Crate(VisCrate {
            pub pub_token: Token![pub],
            pub paren_token: token::Paren,
            pub crate_token: Token![crate],
        }),

        /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
        pub Restricted(VisRestricted {
            pub pub_token: Token![pub],
            pub paren_token: token::Paren,
            pub in_token: Option<Token![in]>,
            pub path: Box<Path>,
        }),

        /// Inherited, i.e. private.
        pub Inherited,
    }
}

#[cfg(feature = "parsing")]
pub mod parsing {
    use super::*;

    use synom::Synom;

    impl Field {
        named!(pub parse_struct -> Self, do_parse!(
            attrs: many0!(Attribute::parse_outer) >>
            vis: syn!(Visibility) >>
            id: syn!(Ident) >>
            colon: punct!(:) >>
            ty: syn!(Type) >>
            (Field {
                ident: Some(id),
                vis: vis,
                attrs: attrs,
                ty: ty,
                colon_token: Some(colon),
            })
        ));

        named!(pub parse_tuple -> Self, do_parse!(
            attrs: many0!(Attribute::parse_outer) >>
            vis: syn!(Visibility) >>
            ty: syn!(Type) >>
            (Field {
                ident: None,
                colon_token: None,
                vis: vis,
                attrs: attrs,
                ty: ty,
            })
        ));
    }

    impl Synom for Visibility {
        named!(parse -> Self, alt!(
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(keyword!(crate)) >>
                (Visibility::Crate(VisCrate {
                    pub_token: pub_token,
                    paren_token: other.0,
                    crate_token: other.1,
                }))
            )
            |
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(keyword!(self)) >>
                (Visibility::Restricted(VisRestricted {
                    pub_token: pub_token,
                    paren_token: other.0,
                    in_token: None,
                    path: Box::new(other.1.into()),
                }))
            )
            |
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(keyword!(super)) >>
                (Visibility::Restricted(VisRestricted {
                    pub_token: pub_token,
                    paren_token: other.0,
                    in_token: None,
                    path: Box::new(other.1.into()),
                }))
            )
            |
            do_parse!(
                pub_token: keyword!(pub) >>
                other: parens!(do_parse!(
                    in_tok: keyword!(in) >>
                    restricted: call!(Path::parse_mod_style) >>
                    (in_tok, restricted)
                )) >>
                (Visibility::Restricted(VisRestricted {
                    pub_token: pub_token,
                    paren_token: other.0,
                    in_token: Some((other.1).0),
                    path: Box::new((other.1).1),
                }))
            )
            |
            keyword!(pub) => { |tok| {
                Visibility::Public(VisPublic {
                    pub_token: tok,
                })
            } }
            |
            epsilon!() => { |_| Visibility::Inherited }
        ));

        fn description() -> Option<&'static str> {
            Some("visibility qualifier, e.g. `pub`")
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use quote::{ToTokens, Tokens};

    impl ToTokens for Variant {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append_all(&self.attrs);
            self.ident.to_tokens(tokens);
            self.data.to_tokens(tokens);
            if let Some((ref eq_token, ref disc)) = self.discriminant {
                eq_token.to_tokens(tokens);
                disc.to_tokens(tokens);
            }
        }
    }

    impl ToTokens for VariantData {
        fn to_tokens(&self, tokens: &mut Tokens) {
            match *self {
                VariantData::Struct(ref brace, ref fields) => {
                    brace.surround(tokens, |tokens| {
                        fields.to_tokens(tokens);
                    });
                }
                VariantData::Tuple(ref paren, ref fields) => {
                    paren.surround(tokens, |tokens| {
                        fields.to_tokens(tokens);
                    });
                }
                VariantData::Unit => {}
            }
        }
    }

    impl ToTokens for Field {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append_all(&self.attrs);
            self.vis.to_tokens(tokens);
            if let Some(ref ident) = self.ident {
                ident.to_tokens(tokens);
                TokensOrDefault(&self.colon_token).to_tokens(tokens);
            }
            self.ty.to_tokens(tokens);
        }
    }

    impl ToTokens for VisPublic {
        fn to_tokens(&self, tokens: &mut Tokens) {
            self.pub_token.to_tokens(tokens)
        }
    }

    impl ToTokens for VisCrate {
        fn to_tokens(&self, tokens: &mut Tokens) {
            self.pub_token.to_tokens(tokens);
            self.paren_token.surround(tokens, |tokens| {
                self.crate_token.to_tokens(tokens);
            })
        }
    }

    impl ToTokens for VisRestricted {
        fn to_tokens(&self, tokens: &mut Tokens) {
            self.pub_token.to_tokens(tokens);
            self.paren_token.surround(tokens, |tokens| {
                // XXX: If we have a path which is not "self" or "super",
                // automatically add the "in" token.
                self.in_token.to_tokens(tokens);
                self.path.to_tokens(tokens);
            });
        }
    }
}
<|endoftext|>


<commit_before>use super::structure::{Program,Condition,Command,Expression,Sensor};

/// `SensorData` represents the information that is available for programs to decide what `ast::structure::Command`
/// to execute when it is evaluated.
///
/// # Examples
///
/// ```
/// let data = ast::data::SensorData { x: 37.0, y: 51.0, vx: 1.0, vy: 0.0, o: 0.0, w: 0.0 };
/// ```
#[derive(Copy,Clone)]
pub struct SensorData {
	pub x:  f32,
	pub y:  f32,
	pub vx: f32,
	pub vy: f32,
	pub o:  f32,
	pub w:  f32
}

/// `Evaluate` returns a specific `ast::structure::Command` to execute, depending on `ast::data::SensorData`
pub trait Evaluate {
	fn evaluate(&self, sensor_data: SensorData) -> Box<&Command>;
}

impl Evaluate for Program {
	fn evaluate(&self, sensor_data: SensorData) -> Box<&Command> {
		match *self {
			Program::If(ref condition, ref true_program, ref false_program) => {
				if (*condition).value(sensor_data) {
					Box::new(*true_program.evaluate(sensor_data))
				} else {
					Box::new(*false_program.evaluate(sensor_data))
				}
			},
			Program::Command(ref command) => Box::new(command),
		}
	}
}

/// The numeric value of an `ast::structure::Expression`
pub trait NumericValue {
	fn value(&self, sensor_data: SensorData) -> f32;
}

impl NumericValue for Expression {
	fn value(&self, sensor_data: SensorData) -> f32 {
		match *self {
			Expression::Constant(value)               => value,
			Expression::Sensor(ref sensor)            => sensor.value(sensor_data),
			Expression::Plus(ref left, ref right)     => left.value(sensor_data) + right.value(sensor_data),
			Expression::Minus(ref left, ref right)    => left.value(sensor_data) - right.value(sensor_data),
			Expression::Multiply(ref left, ref right) => left.value(sensor_data) * right.value(sensor_data),
			Expression::Divide(ref left, ref right)   => left.value(sensor_data) / right.value(sensor_data)
		}
	}
}

impl NumericValue for Sensor {
	fn value(&self, sensor_data: SensorData) -> f32 {
		match *self {
			Sensor::X  => sensor_data.x,
			Sensor::Y  => sensor_data.y,
			Sensor::Vx => sensor_data.vx,
			Sensor::Vy => sensor_data.vy,
			Sensor::O  => sensor_data.o,
			Sensor::W  => sensor_data.w,
		}
	}
}

/// The truth value of an `ast::structure::Condition`
pub trait BooleanValue {
	fn value(&self, sensor_data: SensorData) -> bool;
}

impl BooleanValue for Condition {
	fn value(&self, sensor_data: SensorData) -> bool {
		match *self {
			Condition::True                              => true,
			Condition::False                             => false,
			Condition::Not(ref condition)                => !(*condition).value(sensor_data),
			Condition::Or(ref left, ref right)           => (*left).value(sensor_data) || (*right).value(sensor_data),
			Condition::And(ref left, ref right)          => (*left).value(sensor_data) && (*right).value(sensor_data),
			Condition::Less(ref left, ref right)         => (*left).value(sensor_data) <  (*right).value(sensor_data),
			Condition::LessEqual(ref left, ref right)    => (*left).value(sensor_data) <= (*right).value(sensor_data),
			Condition::Equal(ref left, ref right)        => (*left).value(sensor_data) == (*right).value(sensor_data),
			Condition::GreaterEqual(ref left, ref right) => (*left).value(sensor_data) >= (*right).value(sensor_data),
			Condition::Greater(ref left, ref right)      => (*left).value(sensor_data) >  (*right).value(sensor_data),
		}
	}
}<commit_msg>Module documentation for data<commit_after>//! The `data` model is responsible for creation and evaluation of data in the
//! moon lander domain.
//!
//! The center piece is [`ast::data::SensorData`](struct.SensorData.html) that
//! gets evaluated by a
//! [`ast::structure::Program`](../structure/enum.Program.html) to produce a
//! [`ast::structure::Command`](../structure/enum.Command.html).

use super::structure::{Program,Condition,Command,Expression,Sensor};

/// `SensorData` represents the information that is available for programs to decide what `ast::structure::Command`
/// to execute when it is evaluated.
///
/// # Examples
///
/// ```
/// let data = ast::data::SensorData { x: 37.0, y: 51.0, vx: 1.0, vy: 0.0, o: 0.0, w: 0.0 };
/// ```
#[derive(Copy,Clone)]
pub struct SensorData {
	pub x:  f32,
	pub y:  f32,
	pub vx: f32,
	pub vy: f32,
	pub o:  f32,
	pub w:  f32
}

/// `Evaluate` returns a specific `ast::structure::Command` to execute, depending on `ast::data::SensorData`
pub trait Evaluate {
	fn evaluate(&self, sensor_data: SensorData) -> Box<&Command>;
}

impl Evaluate for Program {
	fn evaluate(&self, sensor_data: SensorData) -> Box<&Command> {
		match *self {
			Program::If(ref condition, ref true_program, ref false_program) => {
				if (*condition).value(sensor_data) {
					Box::new(*true_program.evaluate(sensor_data))
				} else {
					Box::new(*false_program.evaluate(sensor_data))
				}
			},
			Program::Command(ref command) => Box::new(command),
		}
	}
}

/// The numeric value of an `ast::structure::Expression`
pub trait NumericValue {
	fn value(&self, sensor_data: SensorData) -> f32;
}

impl NumericValue for Expression {
	fn value(&self, sensor_data: SensorData) -> f32 {
		match *self {
			Expression::Constant(value)               => value,
			Expression::Sensor(ref sensor)            => sensor.value(sensor_data),
			Expression::Plus(ref left, ref right)     => left.value(sensor_data) + right.value(sensor_data),
			Expression::Minus(ref left, ref right)    => left.value(sensor_data) - right.value(sensor_data),
			Expression::Multiply(ref left, ref right) => left.value(sensor_data) * right.value(sensor_data),
			Expression::Divide(ref left, ref right)   => left.value(sensor_data) / right.value(sensor_data)
		}
	}
}

impl NumericValue for Sensor {
	fn value(&self, sensor_data: SensorData) -> f32 {
		match *self {
			Sensor::X  => sensor_data.x,
			Sensor::Y  => sensor_data.y,
			Sensor::Vx => sensor_data.vx,
			Sensor::Vy => sensor_data.vy,
			Sensor::O  => sensor_data.o,
			Sensor::W  => sensor_data.w,
		}
	}
}

/// The truth value of an `ast::structure::Condition`
pub trait BooleanValue {
	fn value(&self, sensor_data: SensorData) -> bool;
}

impl BooleanValue for Condition {
	fn value(&self, sensor_data: SensorData) -> bool {
		match *self {
			Condition::True                              => true,
			Condition::False                             => false,
			Condition::Not(ref condition)                => !(*condition).value(sensor_data),
			Condition::Or(ref left, ref right)           => (*left).value(sensor_data) || (*right).value(sensor_data),
			Condition::And(ref left, ref right)          => (*left).value(sensor_data) && (*right).value(sensor_data),
			Condition::Less(ref left, ref right)         => (*left).value(sensor_data) <  (*right).value(sensor_data),
			Condition::LessEqual(ref left, ref right)    => (*left).value(sensor_data) <= (*right).value(sensor_data),
			Condition::Equal(ref left, ref right)        => (*left).value(sensor_data) == (*right).value(sensor_data),
			Condition::GreaterEqual(ref left, ref right) => (*left).value(sensor_data) >= (*right).value(sensor_data),
			Condition::Greater(ref left, ref right)      => (*left).value(sensor_data) >  (*right).value(sensor_data),
		}
	}
}
<|endoftext|>


<commit_before>use engine::Tile;
use util::units::{Size, AsTuple};

use std::iter::repeat;

pub struct Map {
    tiles: Vec<Vec<Tile>>,
    size: Size,
}

impl Map {

    pub fn new(size: Size) -> Map {

        let (width, height) = size.as_tuple();

        // TODO: use range syntax
        let tiles: Vec<Vec<Tile>> = range(0, height).map(|_| repeat(Tile::Empty).take(width).collect()).collect();

        Map {
            tiles: tiles,
            size: size
        }
    }

}
<commit_msg>Added size(), at(), and set_tile() to Map<commit_after>use engine::Tile;
use util::units::{AsTuple, Size, Point};

use std::iter::repeat;

pub struct Map {
    tiles: Vec<Vec<Tile>>,
    size: Size,
}

impl Map {

    pub fn new(size: Size) -> Map {

        let (width, height) = size.as_tuple();

        // TODO: use range syntax
        let tiles: Vec<Vec<Tile>> = range(0, height).map(|_| repeat(Tile::Empty).take(width).collect()).collect();

        Map {
            tiles: tiles,
            size: size
        }
    }

    pub fn size(&self) -> Size {
        self.size
    }

    pub fn at(&self, loc: Point) -> Tile {
        self.tiles[loc.y as uint][loc.x as uint]
    }

    pub fn set_tile(&mut self, loc: Point, tile: Tile) {
        self.tiles[loc.y as uint][loc.x as uint] = tile;
    }

}
<|endoftext|>


<commit_before>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use crate::diagonal::*;
use crate::error::*;
use crate::layout::*;
use crate::operator::LinearOperator;
use crate::types::*;
use crate::UPLO;
use std::iter::FromIterator;

/// Eigenvalue decomposition of Hermite matrix reference
pub trait Eigh {
    type EigVal;
    type EigVec;
    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)>;
}

/// Eigenvalue decomposition of mutable reference of Hermite matrix
pub trait EighInplace {
    type EigVal;
    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighInto: Sized {
    type EigVal;
    fn eigh_into(self, uplo: UPLO) -> Result<(Self::EigVal, Self)>;
}

impl<A, S> EighInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> EighInto for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> Eigh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = Array2<A>;

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let a = self.to_owned();
        a.eigh_into(uplo)
    }
}

impl<A, S> Eigh for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = Array2<A>;

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let (a,b) = (self.0.to_owned(), self.1.to_owned());
        (a,b).eigh_into(uplo).map(|x| (x.0, (x.1).0))
    }
}

impl<A, S> EighInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok((ArrayBase::from(s), self))
    }
}

impl<A, S> EighInplace for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.0.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.0.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let layout = self.1.square_layout()?;
        match layout {
            MatrixLayout::C(_) => self.1.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let s = unsafe { A::eigh_generalized(true, self.0.square_layout()?, uplo, self.0.as_allocated_mut()?, self.1.as_allocated_mut()?)? };

        Ok((ArrayBase::from(s), self))
    }
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValsh {
    type EigVal;
    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInto {
    type EigVal;
    fn eigvalsh_into(self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInplace {
    type EigVal;
    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal>;
}

impl<A, S> EigValshInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_into(mut self, uplo: UPLO) -> Result<Self::EigVal> {
        self.eigvalsh_inplace(uplo)
    }
}

impl<A, S> EigValsh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal> {
        let a = self.to_owned();
        a.eigvalsh_into(uplo)
    }
}

impl<A, S> EigValshInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal> {
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok(ArrayBase::from(s))
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrt {
    type Output;
    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrt for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output> {
        let a = self.to_owned();
        a.ssqrt_into(uplo)
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrtInto {
    type Output;
    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrtInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A> + DataOwned,
{
    type Output = Array2<A>;

    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output> {
        let (e, v) = self.eigh_into(uplo)?;
        let e_sqrt = Array::from_iter(e.iter().map(|r| Scalar::from_real(r.sqrt())));
        let ev = e_sqrt.into_diagonal().apply2(&v.t());
        Ok(v.apply2(&ev))
    }
}
<commit_msg>Unify return types for EighInplace, EighInto, Eigh<commit_after>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use crate::diagonal::*;
use crate::error::*;
use crate::layout::*;
use crate::operator::LinearOperator;
use crate::types::*;
use crate::UPLO;
use std::iter::FromIterator;

/// Eigenvalue decomposition of Hermite matrix reference
pub trait Eigh {
    type EigVal;
    type EigVec;
    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)>;
}

/// Eigenvalue decomposition of mutable reference of Hermite matrix
pub trait EighInplace {
    type EigVal;
    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighInto: Sized {
    type EigVal;
    fn eigh_into(self, uplo: UPLO) -> Result<(Self::EigVal, Self)>;
}

impl<A, S> EighInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> EighInto for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> Eigh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = Array2<A>;

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let a = self.to_owned();
        a.eigh_into(uplo)
    }
}

impl<A, S> Eigh for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = (Array2<A>, Array2<A>);

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let (a,b) = (self.0.to_owned(), self.1.to_owned());
        (a,b).eigh_into(uplo)
    }
}

impl<A, S> EighInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok((ArrayBase::from(s), self))
    }
}

impl<A, S> EighInplace for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.0.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.0.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let layout = self.1.square_layout()?;
        match layout {
            MatrixLayout::C(_) => self.1.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let s = unsafe { A::eigh_generalized(true, self.0.square_layout()?, uplo, self.0.as_allocated_mut()?, self.1.as_allocated_mut()?)? };

        Ok((ArrayBase::from(s), self))
    }
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValsh {
    type EigVal;
    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInto {
    type EigVal;
    fn eigvalsh_into(self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInplace {
    type EigVal;
    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal>;
}

impl<A, S> EigValshInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_into(mut self, uplo: UPLO) -> Result<Self::EigVal> {
        self.eigvalsh_inplace(uplo)
    }
}

impl<A, S> EigValsh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal> {
        let a = self.to_owned();
        a.eigvalsh_into(uplo)
    }
}

impl<A, S> EigValshInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal> {
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok(ArrayBase::from(s))
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrt {
    type Output;
    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrt for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output> {
        let a = self.to_owned();
        a.ssqrt_into(uplo)
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrtInto {
    type Output;
    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrtInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A> + DataOwned,
{
    type Output = Array2<A>;

    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output> {
        let (e, v) = self.eigh_into(uplo)?;
        let e_sqrt = Array::from_iter(e.iter().map(|r| Scalar::from_real(r.sqrt())));
        let ev = e_sqrt.into_diagonal().apply2(&v.t());
        Ok(v.apply2(&ev))
    }
}
<|endoftext|>


<commit_before>pub enum ExitCode {
    Success,
    GeneralError,
    KilledBySigint,
}

impl Into<i32> for ExitCode {
    fn into(self) -> i32 {
        match self {
            Self::Success => 0,
            Self::GeneralError => 1,
            Self::KilledBySigint => 130,
        }
    }
}

impl ExitCode {
    pub fn error_if_any_error(results: Vec<Self>) -> Self {
        if results.iter().any(|s| match s {
            Self::GeneralError => true,
            _ => false,
        }) {
            return Self::GeneralError;
        }
        Self::Success
    }
}
<commit_msg>Switch back from Self to ExitCode<commit_after>pub enum ExitCode {
    Success,
    GeneralError,
    KilledBySigint,
}

impl Into<i32> for ExitCode {
    fn into(self) -> i32 {
        match self {
            ExitCode::Success => 0,
            ExitCode::GeneralError => 1,
            ExitCode::KilledBySigint => 130,
        }
    }
}

impl ExitCode {
    pub fn error_if_any_error(results: Vec<Self>) -> Self {
        if results.iter().any(|s| match s {
            ExitCode::GeneralError => true,
            _ => false,
        }) {
            return ExitCode::GeneralError;
        }
        ExitCode::Success
    }
}
<|endoftext|>