<commit_before>use std::collections::HashMap;
use std::fmt;
use std::io::IoError;
use serialize;

use super::{Data, Str, Bool, Vec, Map};

pub struct Encoder<'a> {
    pub data: Vec<Data<'a>>,
}

impl<'a> Encoder<'a> {
    pub fn new() -> Encoder<'a> {
        Encoder { data: Vec::new() }
    }
}

#[deriving(PartialEq)]
pub enum Error {
    UnsupportedType,
    InvalidStr,
    MissingElements,
    KeyIsNotString,
    IoError(IoError),
}

impl fmt::Show for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            UnsupportedType => "unsupported type".fmt(f),
            InvalidStr => "invalid str".fmt(f),
            MissingElements => "no elements in value".fmt(f),
            KeyIsNotString => "key is not a string".fmt(f),
            IoError(ref err) => err.fmt(f),
        }
    }
}

pub type EncoderResult = Result<(), Error>;

impl<'a> serialize::Encoder<Error> for Encoder<'a> {
    fn emit_nil(&mut self) -> EncoderResult { Err(UnsupportedType) }

    fn emit_uint(&mut self, v: uint) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u64(&mut self, v: u64) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u32(&mut self, v: u32) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u16(&mut self, v: u16) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u8(&mut self, v: u8) -> EncoderResult     { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_int(&mut self, v: int) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i64(&mut self, v: i64) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i32(&mut self, v: i32) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i16(&mut self, v: i16) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i8(&mut self, v: i8) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_bool(&mut self, v: bool) -> EncoderResult { self.data.push(Bool(v)); Ok(()) }

    fn emit_f64(&mut self, v: f64) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_f32(&mut self, v: f32) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_char(&mut self, v: char) -> EncoderResult {
        self.data.push(Str(String::from_char(1, v)));
        Ok(())
    }
    fn emit_str(&mut self, v: &str) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_enum(&mut self, _name: &str, _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_variant(&mut self,
                         _name: &str,
                         _id: uint,
                         _len: uint,
                         _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_variant_arg(&mut self,
                             _a_idx: uint,
                             _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_struct_variant(&mut self,
                                _v_name: &str,
                                _v_id: uint,
                                _len: uint,
                                _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_struct_variant_field(&mut self,
                                      _f_name: &str,
                                      _f_idx: uint,
                                      _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_struct(&mut self,
                   _name: &str,
                   _len: uint,
                   f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.data.push(Map(HashMap::new()));
        f(self)
    }

    fn emit_struct_field(&mut self,
                         name: &str,
                         _idx: uint,
                         f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        let mut m = match self.data.pop() {
            Some(Map(m)) => m,
            _ => { return Err(UnsupportedType); }
        };
        try!(f(self));
        let data = match self.data.pop() {
            Some(d) => d,
            _ => { return Err(UnsupportedType); }
        };
        m.insert(name.to_string(), data);
        self.data.push(Map(m));
        Ok(())
    }

    fn emit_tuple(&mut self,
                  len: uint,
                  f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq(len, f)
    }

    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq_elt(idx, f)
    }

    fn emit_tuple_struct(&mut self,
                         _name: &str,
                         len: uint,
                         f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq(len, f)
    }

    fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq_elt(idx, f)
    }

    // Specialized types:
    fn emit_option(&mut self, _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_option_none(&mut self) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_option_some(&mut self, _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.data.push(Vec(Vec::new()));
        f(self)
    }

    fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        let mut v = match self.data.pop() {
            Some(Vec(v)) => v,
            _ => { return Err(UnsupportedType); }
        };
        try!(f(self));
        let data = match self.data.pop() {
            Some(d) => d,
            _ => { return Err(UnsupportedType); }
        };
        v.push(data);
        self.data.push(Vec(v));
        Ok(())
    }

    fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.data.push(Map(HashMap::new()));
        f(self)
    }

    fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        try!(f(self));
        let last = match self.data.last() {
            Some(d) => d,
            None => { return Err(MissingElements); }
        };
        match *last {
            Str(_) => Ok(()),
            _ => Err(KeyIsNotString),
        }
    }

    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        let k = match self.data.pop() {
            Some(Str(s)) => s,
            _ => { return Err(KeyIsNotString); }
        };
        let mut m = match self.data.pop() {
            Some(Map(m)) => m,
            _ => panic!("Expected a map"),
        };
        try!(f(self));
        let popped = match self.data.pop() {
            Some(p) => p,
            None => panic!("Error: Nothing to pop!"),
        };
        m.insert(k, popped);
        self.data.push(Map(m));
        Ok(())
    }
}

pub fn encode<'a, T: serialize::Encodable<Encoder<'a>, Error>>(data: &T) -> Result<Data<'a>, Error> {
    let mut encoder = Encoder::new();
    try!(data.encode(&mut encoder))
    assert_eq!(encoder.data.len(), 1);
    match encoder.data.pop() {
        Some(data) => Ok(data),
        None => panic!("Error: Nothing to pop!"),
    }
}
<commit_msg>Rename global import to avoid problems.<commit_after>use std::collections::HashMap;
use std::fmt;
use std::io::IoError as StdIoError;
use serialize;

use super::{Data, Str, Bool, Vec, Map};

pub struct Encoder<'a> {
    pub data: Vec<Data<'a>>,
}

impl<'a> Encoder<'a> {
    pub fn new() -> Encoder<'a> {
        Encoder { data: Vec::new() }
    }
}

#[deriving(PartialEq)]
pub enum Error {
    UnsupportedType,
    InvalidStr,
    MissingElements,
    KeyIsNotString,
    IoError(StdIoError),
}

impl fmt::Show for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            UnsupportedType => "unsupported type".fmt(f),
            InvalidStr => "invalid str".fmt(f),
            MissingElements => "no elements in value".fmt(f),
            KeyIsNotString => "key is not a string".fmt(f),
            IoError(ref err) => err.fmt(f),
        }
    }
}

pub type EncoderResult = Result<(), Error>;

impl<'a> serialize::Encoder<Error> for Encoder<'a> {
    fn emit_nil(&mut self) -> EncoderResult { Err(UnsupportedType) }

    fn emit_uint(&mut self, v: uint) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u64(&mut self, v: u64) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u32(&mut self, v: u32) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u16(&mut self, v: u16) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_u8(&mut self, v: u8) -> EncoderResult     { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_int(&mut self, v: int) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i64(&mut self, v: i64) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i32(&mut self, v: i32) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i16(&mut self, v: i16) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_i8(&mut self, v: i8) -> EncoderResult   { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_bool(&mut self, v: bool) -> EncoderResult { self.data.push(Bool(v)); Ok(()) }

    fn emit_f64(&mut self, v: f64) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }
    fn emit_f32(&mut self, v: f32) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_char(&mut self, v: char) -> EncoderResult {
        self.data.push(Str(String::from_char(1, v)));
        Ok(())
    }
    fn emit_str(&mut self, v: &str) -> EncoderResult { self.data.push(Str(v.to_string())); Ok(()) }

    fn emit_enum(&mut self, _name: &str, _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_variant(&mut self,
                         _name: &str,
                         _id: uint,
                         _len: uint,
                         _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_variant_arg(&mut self,
                             _a_idx: uint,
                             _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_struct_variant(&mut self,
                                _v_name: &str,
                                _v_id: uint,
                                _len: uint,
                                _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_enum_struct_variant_field(&mut self,
                                      _f_name: &str,
                                      _f_idx: uint,
                                      _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_struct(&mut self,
                   _name: &str,
                   _len: uint,
                   f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.data.push(Map(HashMap::new()));
        f(self)
    }

    fn emit_struct_field(&mut self,
                         name: &str,
                         _idx: uint,
                         f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        let mut m = match self.data.pop() {
            Some(Map(m)) => m,
            _ => { return Err(UnsupportedType); }
        };
        try!(f(self));
        let data = match self.data.pop() {
            Some(d) => d,
            _ => { return Err(UnsupportedType); }
        };
        m.insert(name.to_string(), data);
        self.data.push(Map(m));
        Ok(())
    }

    fn emit_tuple(&mut self,
                  len: uint,
                  f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq(len, f)
    }

    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq_elt(idx, f)
    }

    fn emit_tuple_struct(&mut self,
                         _name: &str,
                         len: uint,
                         f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq(len, f)
    }

    fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.emit_seq_elt(idx, f)
    }

    // Specialized types:
    fn emit_option(&mut self, _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_option_none(&mut self) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_option_some(&mut self, _f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        Err(UnsupportedType)
    }

    fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.data.push(Vec(Vec::new()));
        f(self)
    }

    fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        let mut v = match self.data.pop() {
            Some(Vec(v)) => v,
            _ => { return Err(UnsupportedType); }
        };
        try!(f(self));
        let data = match self.data.pop() {
            Some(d) => d,
            _ => { return Err(UnsupportedType); }
        };
        v.push(data);
        self.data.push(Vec(v));
        Ok(())
    }

    fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        self.data.push(Map(HashMap::new()));
        f(self)
    }

    fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        try!(f(self));
        let last = match self.data.last() {
            Some(d) => d,
            None => { return Err(MissingElements); }
        };
        match *last {
            Str(_) => Ok(()),
            _ => Err(KeyIsNotString),
        }
    }

    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>| -> EncoderResult) -> EncoderResult {
        let k = match self.data.pop() {
            Some(Str(s)) => s,
            _ => { return Err(KeyIsNotString); }
        };
        let mut m = match self.data.pop() {
            Some(Map(m)) => m,
            _ => panic!("Expected a map"),
        };
        try!(f(self));
        let popped = match self.data.pop() {
            Some(p) => p,
            None => panic!("Error: Nothing to pop!"),
        };
        m.insert(k, popped);
        self.data.push(Map(m));
        Ok(())
    }
}

pub fn encode<'a, T: serialize::Encodable<Encoder<'a>, Error>>(data: &T) -> Result<Data<'a>, Error> {
    let mut encoder = Encoder::new();
    try!(data.encode(&mut encoder))
    assert_eq!(encoder.data.len(), 1);
    match encoder.data.pop() {
        Some(data) => Ok(data),
        None => panic!("Error: Nothing to pop!"),
    }
}
<|endoftext|>


<commit_before>use std;

/// GcLeaf can be used to embed just about anything in a GC heap type.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct GcLeaf<T: Clone + 'static> {
    // This private field has an underscore in the hopes that it is
    // less likely to collide with useful features of T.
    value_: T,
}

impl<T: Clone + 'static> GcLeaf<T> {
    /// Create a new GcLeaf wrapping a given value.
    pub fn new(value: T) -> GcLeaf<T> {
        GcLeaf { value_: value }
    }
}

impl<T: Clone + 'static> std::ops::Deref for GcLeaf<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.value_
    }
}

impl<T: Clone + 'static> std::ops::DerefMut for GcLeaf<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.value_
    }
}
<commit_msg>Add method to unwrap GcLeaf values.<commit_after>use std;

/// GcLeaf can be used to embed just about anything in a GC heap type.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct GcLeaf<T: Clone + 'static> {
    // This private field has an underscore in the hopes that it is
    // less likely to collide with useful features of T.
    value_: T,
}

impl<T: Clone + 'static> GcLeaf<T> {
    /// Create a new GcLeaf wrapping a given value.
    pub fn new(value: T) -> GcLeaf<T> {
        GcLeaf { value_: value }
    }

    pub fn unwrap(self) -> T {
        self.value_
    }
}

impl<T: Clone + 'static> std::ops::Deref for GcLeaf<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.value_
    }
}

impl<T: Clone + 'static> std::ops::DerefMut for GcLeaf<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.value_
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2016 bluss and ndarray developers.
//
// 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.

//! Methods for two-dimensional arrays.
use imp_prelude::*;

impl<A, S> ArrayBase<S, (Ix, Ix)>
    where S: Data<Elem=A>,
{
    /// Return an array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row(&self, index: Ix) -> ArrayView<A, Ix>
    {
        self.subview(Axis(0), index)
    }

    /// Return a mutable array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row_mut(&mut self, index: Ix) -> ArrayViewMut<A, Ix>
        where S: DataMut
    {
        self.subview_mut(Axis(0), index)
    }

    /// Return the number of rows (length of `Axis(0)`) in the two-dimensional array.
    pub fn rows(&self) -> Ix {
        self.shape().axis(Axis(0))
    }

    /// Return an array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column(&self, index: Ix) -> ArrayView<A, Ix>
    {
        self.subview(Axis(1), index)
    }

    /// Return a mutable array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column_mut(&mut self, index: Ix) -> ArrayViewMut<A, Ix>
        where S: DataMut
    {
        self.subview_mut(Axis(1), index)
    }

    /// Return the number of columns (length of `Axis(1)`) in the two-dimensional array.
    pub fn cols(&self) -> Ix {
        self.shape().axis(Axis(1))
    }
}

<commit_msg>rows/cols now return  instead of<commit_after>// Copyright 2014-2016 bluss and ndarray developers.
//
// 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.

//! Methods for two-dimensional arrays.
use imp_prelude::*;

impl<A, S> ArrayBase<S, (Ix, Ix)>
    where S: Data<Elem=A>,
{
    /// Return an array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row(&self, index: Ix) -> ArrayView<A, Ix>
    {
        self.subview(Axis(0), index)
    }

    /// Return a mutable array view of row `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn row_mut(&mut self, index: Ix) -> ArrayViewMut<A, Ix>
        where S: DataMut
    {
        self.subview_mut(Axis(0), index)
    }

    /// Return the number of rows (length of `Axis(0)`) in the two-dimensional array.
    pub fn rows(&self) -> usize {
        self.shape().axis(Axis(0))
    }

    /// Return an array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column(&self, index: Ix) -> ArrayView<A, Ix>
    {
        self.subview(Axis(1), index)
    }

    /// Return a mutable array view of column `index`.
    ///
    /// **Panics** if `index` is out of bounds.
    pub fn column_mut(&mut self, index: Ix) -> ArrayViewMut<A, Ix>
        where S: DataMut
    {
        self.subview_mut(Axis(1), index)
    }

    /// Return the number of columns (length of `Axis(1)`) in the two-dimensional array.
    pub fn cols(&self) -> usize {
        self.shape().axis(Axis(1))
    }
}

<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::{HashMap, VecDeque};
use std::vec::Vec;
use autograd::variable::*;
use tensor::*;
use ::*;

thread_local! {
    pub static FUNC_TABLE: RefCell<VecDeque<FuncImpl>> = RefCell::new(VecDeque::new());
}
pub type FuncId = i32;
pub enum RootKind {
    RootVar(VarKind),
    RootFunc(Function),
}
impl RootKind {
    pub fn requires_grad(&self) -> bool {
        match *self {
            RootKind::RootVar(ref v) => v.requires_grad(),
            RootKind::RootFunc(ref f) => f.requires_grad(),
        }
    }
}

impl_func!(FuncStub);
impl FuncIntf for FuncStub {
    #[allow(unused_variables)]
    fn forward(&mut self, input: &mut TensorKindList) -> TensorKindList {
        unreachable!()
    }
    fn backward(&mut self, input: &mut OptTensorKindList) -> OptTensorKindList {
        unreachable!()
    }
}
pub struct FuncImpl {
    previous_functions: Vec<(RootKind, i32)>,
    saved_variables: Vec<VarId>,
    needs_input_grad: Vec<bool>,
    non_differentiable: Vec<TensorId>,
    dirty_tensors: Vec<TensorKind>,
    output_ids: HashMap<VarId, usize>,
    to_save: Vec<TensorId>,
    requires_grad: bool,
    owner: RcMut<FuncIntf>,
}
impl Default for FuncImpl {
    fn default() -> Self {
        FuncImpl {
            previous_functions: Vec::new(),
            saved_variables: Vec::new(),
            needs_input_grad: Vec::new(),
            dirty_tensors: Vec::new(),
            non_differentiable: Vec::new(),
            output_ids: HashMap::new(),
            to_save: Vec::new(),
            requires_grad: false,
            owner: FuncStub::new().value,
        }
    }
}

impl FuncImpl {
    fn _call_hooks(&self, input: &TensorKindList, output: &TensorKindList) {
        unimplemented!();
    }
    fn init(&mut self, intf: RcMut<FuncIntf>) {
        self.owner = intf;
    }
}

#[derive(Clone)]
pub struct Function {
    pub id: FuncId,
}

impl Default for Function {
    fn default() -> Self {
        Function { id: -1 }
    }
}

pub struct FIWrap<T> {
    value: RcMut<T>,
}
impl<T: 'static + FuncIntf> FIWrap<T> {
    pub fn new(arg: T) -> Self {
        let t = FIWrap { value: RcMutNew(arg) };
        t.value.borrow_mut().delegate().init(t.value.clone());
        t
    }
    pub fn f(&mut self, mut input_: &mut VarKindList) -> VarKindList {
        self.value.borrow_mut().f(input_)
    }
}

impl Function {
    pub fn new() -> Self {
        use std::usize;
        let mut id = usize::MAX;
        FUNC_TABLE.with(|f| {
                            let mut table = f.borrow_mut();
                            id = table.len();
                            table.push_back(FuncImpl::default());
                        });
        Function { id: id as i32 }
    }
    pub fn init(&self, intf: RcMut<FuncIntf>) {
        //FUNC_INTF_TABLE.with(|m| m.borrow_mut().insert(self.id, intf));
        self.access().init(intf)
    }
    pub fn previous_functions(&self) -> &Vec<(RootKind, i32)> {
        &self.access().previous_functions
    }
    pub fn output_ids(&self) -> &HashMap<VarId, usize> {
        &self.access().output_ids
    }
    pub fn requires_grad(&self) -> bool {
        self.access().requires_grad
    }
    pub fn needs_input_grad(&self) -> &Vec<bool> {
        &self.access().needs_input_grad
    }
    pub fn mark_dirty(&mut self, input: &TensorKindList) {
        self.access().dirty_tensors = input.iter().map(|t| t.clone()).collect();
    }
    pub fn mark_non_differentiable(&mut self, input: &TensorKindList) {
        self.access().non_differentiable = input.iter().map(|t| t.id()).collect();
    }
    fn access(&self) -> &mut FuncImpl {
        let vecp = FUNC_TABLE.with(|f| f.as_ptr());
        let vec = unsafe { &mut *vecp };
        &mut vec[self.id as usize]
    }
    pub fn from(id: FuncId) -> Self {
        Function { id: id }
    }
    pub fn saved_tensors(&mut self) -> TensorKindList {
        // XXX see if we can't avoid the clone
        self.access()
            .saved_variables
            .iter()
            .map(|v| VarKind::from(*v).data())
            .collect()
    }
    pub fn saved_variables(&mut self) -> VarKindList {
        // XXX see if we can't avoid the clone
        self.access()
            .saved_variables
            .iter()
            .map(|v| VarKind::from(*v))
            .collect()
    }
    pub fn save_for_backward(&mut self, input: &TensorKindList) {
        self.access().to_save = input.iter().map(|t| t.id()).collect();
    }
    pub fn _do_backward(&mut self,
                        grad_output: &mut OptVarKindList,
                        retain_variables: bool)
                        -> OptVarKindList {
        let inner = self.access();
        if inner.saved_variables.is_empty() {
            panic!("Trying to backward through the graph second \
                    time, but the buffers have already been freed. Please \
                    specify retain_variables=True when calling backward for \
                    the first time.");
        };
        let grad_input = inner.owner.borrow_mut().backward_var(grad_output);
        //inner._call_hooks(&grad_input, grad_output);
        if !retain_variables {
            inner.saved_variables.clear();
        };
        grad_input
    }
}

pub trait FuncDelegate {
    fn delegate(&mut self) -> &mut Function;
}

fn ovkl2otkl(input: &mut OptVarKindList) -> OptTensorKindList {
    input
        .iter_mut()
        .map(|ov| match *ov {
                 Some(ref mut v) => Some(v.data().clone()),
                 None => None,
             })
        .collect()
}
fn otkl2ovkl(input: &mut OptTensorKindList) -> OptVarKindList {
    input
        .iter()
        .map(|ov| match ov {
                 &Some(ref v) => Some(v.clone().into()),
                 &None => None,
             })
        .collect()
}

pub trait FuncIntf: FuncDelegate {
    fn forward(&mut self, input: &mut TensorKindList) -> TensorKindList;
    fn backward(&mut self, input: &mut OptTensorKindList) -> OptTensorKindList;

    fn backward_var(&mut self, input: &mut OptVarKindList) -> OptVarKindList {
        let mut input = ovkl2otkl(input);
        let mut output = self.backward(&mut input);
        otkl2ovkl(&mut output)
    }

    fn save_for_backward(&mut self, input: &TensorKindList) {
        self.delegate().save_for_backward(input)
    }
    fn saved_variables(&mut self) -> VarKindList {
        self.delegate().saved_variables()
    }
    fn saved_tensors(&mut self) -> TensorKindList {
        self.delegate().saved_tensors()
    }
    fn needs_input_grad(&mut self) -> &Vec<bool> {
        self.delegate().needs_input_grad()
    }
    fn mark_dirty(&mut self, input: &TensorKindList) {
        self.delegate().mark_dirty(input)
    }
    fn mark_non_differentiable(&mut self, input: &TensorKindList) {
        self.delegate().mark_non_differentiable(input)
    }

    fn f(&mut self, mut input_: &mut VarKindList) -> VarKindList {
        let is_volatile = input_.iter().any(|v| v.is_volatile());
        {
            // do start graph stuff with f
            let f = self.delegate();
            let mut inner = f.access();
            if !is_volatile {
                inner.previous_functions = input_
                    .iter()
                    .map(|v| if let Some(grad_fn) = v.grad_fn() {
                             (RootKind::RootFunc(grad_fn), v.varid())
                         } else {
                             (RootKind::RootVar(v.clone()), v.varid())
                         })
                    .collect();
                inner.needs_input_grad = input_.iter().map(|v| v.requires_grad()).collect();
                inner.requires_grad = inner.needs_input_grad.iter().any(|v| *v);
            }
        }
        let v;
        {
            let mut input_tensors = input_.iter_mut().map(|v| v.data()).collect();
            v = self.forward(&mut input_tensors);
        }
        let f = self.delegate();
        let mut inner = f.access();
        let output = if is_volatile {
            let args = VariableArgs::build().volatile(true).done();
            v.into_iter().map(|t| VarKind::new_args(t, &args)).collect()
        } else {
            let args = VariableArgs::build()
                .creator(Some(f.clone()))
                .requires_grad(inner.requires_grad)
                .done();
            let mut output: VarKindList =
                v.into_iter().map(|t| VarKind::new_args(t, &args)).collect();
            for (i, v) in output.iter().enumerate() {
                inner.output_ids.insert(v.varid(), i);
            }
            if !inner.to_save.is_empty() {
                /* if a tensor was modified in place replace the old variable with the new one */
                let mut t2v = HashMap::new();
                for ref mut var in input_.iter_mut() {
                    t2v.insert(var.tid(), var.varid());
                }
                for ref mut var in &mut output.iter_mut() {
                    t2v.insert(var.tid(), var.varid());
                }
                for t in inner.to_save.iter() {
                    inner.saved_variables.push(t2v[t]);
                }
                inner.to_save.clear();
            };
            if !inner.non_differentiable.is_empty() {
                for ref mut var in &mut output {
                    if inner.non_differentiable.contains(&var.tid()) {
                        var.requires_nograd()
                    }
                }
                inner.non_differentiable.clear();
            };
            output
        };
        output
    }
}
<commit_msg>fix recursion in Function::new()<commit_after>use std::cell::RefCell;
use std::collections::{HashMap, VecDeque};
use std::vec::Vec;
use autograd::variable::*;
use tensor::*;
use ::*;

thread_local! {
    pub static FUNC_TABLE: RefCell<VecDeque<FuncImpl>> = RefCell::new(VecDeque::new());
}
pub type FuncId = i32;
pub enum RootKind {
    RootVar(VarKind),
    RootFunc(Function),
}
impl RootKind {
    pub fn requires_grad(&self) -> bool {
        match *self {
            RootKind::RootVar(ref v) => v.requires_grad(),
            RootKind::RootFunc(ref f) => f.requires_grad(),
        }
    }
}

pub struct FuncImpl {
    previous_functions: Vec<(RootKind, i32)>,
    saved_variables: Vec<VarId>,
    needs_input_grad: Vec<bool>,
    non_differentiable: Vec<TensorId>,
    dirty_tensors: Vec<TensorKind>,
    output_ids: HashMap<VarId, usize>,
    to_save: Vec<TensorId>,
    requires_grad: bool,
    owner: Option<RcMut<FuncIntf>>,
}
impl Default for FuncImpl {
    fn default() -> Self {
        FuncImpl {
            previous_functions: Vec::new(),
            saved_variables: Vec::new(),
            needs_input_grad: Vec::new(),
            dirty_tensors: Vec::new(),
            non_differentiable: Vec::new(),
            output_ids: HashMap::new(),
            to_save: Vec::new(),
            requires_grad: false,
            owner: None,
        }
    }
}

impl FuncImpl {
    fn _call_hooks(&self, input: &TensorKindList, output: &TensorKindList) {
        unimplemented!();
    }
    fn init(&mut self, intf: RcMut<FuncIntf>) {
        self.owner = Some(intf);
    }
}

#[derive(Clone)]
pub struct Function {
    pub id: FuncId,
}

impl Default for Function {
    fn default() -> Self {
        Function { id: -1 }
    }
}

pub struct FIWrap<T> {
    value: RcMut<T>,
}
impl<T: 'static + FuncIntf> FIWrap<T> {
    pub fn new(arg: T) -> Self {
        let t = FIWrap { value: RcMutNew(arg) };
        t.value.borrow_mut().delegate().init(t.value.clone());
        t
    }
    pub fn f(&mut self, mut input_: &mut VarKindList) -> VarKindList {
        self.value.borrow_mut().f(input_)
    }
}

impl Function {
    pub fn new() -> Self {
        use std::usize;
        let mut id = usize::MAX;
        FUNC_TABLE.with(|f| {
                            let mut table = f.borrow_mut();
                            id = table.len();
                            table.push_back(FuncImpl::default());
                        });
        Function { id: id as i32 }
    }
    pub fn init(&self, intf: RcMut<FuncIntf>) {
        //FUNC_INTF_TABLE.with(|m| m.borrow_mut().insert(self.id, intf));
        self.access().init(intf)
    }
    pub fn previous_functions(&self) -> &Vec<(RootKind, i32)> {
        &self.access().previous_functions
    }
    pub fn output_ids(&self) -> &HashMap<VarId, usize> {
        &self.access().output_ids
    }
    pub fn requires_grad(&self) -> bool {
        self.access().requires_grad
    }
    pub fn needs_input_grad(&self) -> &Vec<bool> {
        &self.access().needs_input_grad
    }
    pub fn mark_dirty(&mut self, input: &TensorKindList) {
        self.access().dirty_tensors = input.iter().map(|t| t.clone()).collect();
    }
    pub fn mark_non_differentiable(&mut self, input: &TensorKindList) {
        self.access().non_differentiable = input.iter().map(|t| t.id()).collect();
    }
    fn access(&self) -> &mut FuncImpl {
        let vecp = FUNC_TABLE.with(|f| f.as_ptr());
        let vec = unsafe { &mut *vecp };
        &mut vec[self.id as usize]
    }
    pub fn from(id: FuncId) -> Self {
        Function { id: id }
    }
    pub fn saved_tensors(&mut self) -> TensorKindList {
        // XXX see if we can't avoid the clone
        self.access()
            .saved_variables
            .iter()
            .map(|v| VarKind::from(*v).data())
            .collect()
    }
    pub fn saved_variables(&mut self) -> VarKindList {
        // XXX see if we can't avoid the clone
        self.access()
            .saved_variables
            .iter()
            .map(|v| VarKind::from(*v))
            .collect()
    }
    pub fn save_for_backward(&mut self, input: &TensorKindList) {
        self.access().to_save = input.iter().map(|t| t.id()).collect();
    }
    pub fn _do_backward(&mut self,
                        grad_output: &mut OptVarKindList,
                        retain_variables: bool)
                        -> OptVarKindList {
        let inner = self.access();
        if inner.saved_variables.is_empty() {
            panic!("Trying to backward through the graph second \
                    time, but the buffers have already been freed. Please \
                    specify retain_variables=True when calling backward for \
                    the first time.");
        };

        let grad_input = if let Some(ref owner) = inner.owner {
            owner.borrow_mut().backward_var(grad_output)
        } else {
            panic!("owner not set")
        };
        //inner._call_hooks(&grad_input, grad_output);
        if !retain_variables {
            inner.saved_variables.clear();
        };
        grad_input
    }
}

pub trait FuncDelegate {
    fn delegate(&mut self) -> &mut Function;
}

fn ovkl2otkl(input: &mut OptVarKindList) -> OptTensorKindList {
    input
        .iter_mut()
        .map(|ov| match *ov {
                 Some(ref mut v) => Some(v.data().clone()),
                 None => None,
             })
        .collect()
}
fn otkl2ovkl(input: &mut OptTensorKindList) -> OptVarKindList {
    input
        .iter()
        .map(|ov| match ov {
                 &Some(ref v) => Some(v.clone().into()),
                 &None => None,
             })
        .collect()
}

pub trait FuncIntf: FuncDelegate {
    fn forward(&mut self, input: &mut TensorKindList) -> TensorKindList;
    fn backward(&mut self, input: &mut OptTensorKindList) -> OptTensorKindList;

    fn backward_var(&mut self, input: &mut OptVarKindList) -> OptVarKindList {
        let mut input = ovkl2otkl(input);
        let mut output = self.backward(&mut input);
        otkl2ovkl(&mut output)
    }

    fn save_for_backward(&mut self, input: &TensorKindList) {
        self.delegate().save_for_backward(input)
    }
    fn saved_variables(&mut self) -> VarKindList {
        self.delegate().saved_variables()
    }
    fn saved_tensors(&mut self) -> TensorKindList {
        self.delegate().saved_tensors()
    }
    fn needs_input_grad(&mut self) -> &Vec<bool> {
        self.delegate().needs_input_grad()
    }
    fn mark_dirty(&mut self, input: &TensorKindList) {
        self.delegate().mark_dirty(input)
    }
    fn mark_non_differentiable(&mut self, input: &TensorKindList) {
        self.delegate().mark_non_differentiable(input)
    }

    fn f(&mut self, mut input_: &mut VarKindList) -> VarKindList {
        let is_volatile = input_.iter().any(|v| v.is_volatile());
        {
            // do start graph stuff with f
            let f = self.delegate();
            let mut inner = f.access();
            if !is_volatile {
                inner.previous_functions = input_
                    .iter()
                    .map(|v| if let Some(grad_fn) = v.grad_fn() {
                             (RootKind::RootFunc(grad_fn), v.varid())
                         } else {
                             (RootKind::RootVar(v.clone()), v.varid())
                         })
                    .collect();
                inner.needs_input_grad = input_.iter().map(|v| v.requires_grad()).collect();
                inner.requires_grad = inner.needs_input_grad.iter().any(|v| *v);
            }
        }
        let v;
        {
            let mut input_tensors = input_.iter_mut().map(|v| v.data()).collect();
            v = self.forward(&mut input_tensors);
        }
        let f = self.delegate();
        let mut inner = f.access();
        let output = if is_volatile {
            let args = VariableArgs::build().volatile(true).done();
            v.into_iter().map(|t| VarKind::new_args(t, &args)).collect()
        } else {
            let args = VariableArgs::build()
                .creator(Some(f.clone()))
                .requires_grad(inner.requires_grad)
                .done();
            let mut output: VarKindList =
                v.into_iter().map(|t| VarKind::new_args(t, &args)).collect();
            for (i, v) in output.iter().enumerate() {
                inner.output_ids.insert(v.varid(), i);
            }
            if !inner.to_save.is_empty() {
                /* if a tensor was modified in place replace the old variable with the new one */
                let mut t2v = HashMap::new();
                for ref mut var in input_.iter_mut() {
                    t2v.insert(var.tid(), var.varid());
                }
                for ref mut var in &mut output.iter_mut() {
                    t2v.insert(var.tid(), var.varid());
                }
                for t in inner.to_save.iter() {
                    inner.saved_variables.push(t2v[t]);
                }
                inner.to_save.clear();
            };
            if !inner.non_differentiable.is_empty() {
                for ref mut var in &mut output {
                    if inner.non_differentiable.contains(&var.tid()) {
                        var.requires_nograd()
                    }
                }
                inner.non_differentiable.clear();
            };
            output
        };
        output
    }
}
<|endoftext|>


<commit_before>
use {
    AddBevel,
    AddColor,
    AddImage,
    AddRound,
    BevelRectangleContext,
    Borrowed,
    Field,
    Image,
    ImageRectangleContext,
    RectangleColorContext,
    RoundRectangleContext,
    Value,
};
use internal::{
    CanRectangle,
    CanTransform,
    CanViewTransform,
    ColorComponent,
    HasRectangle,
    HasTransform,
    HasViewTransform,
    Matrix2d,
    Radius,
    Rectangle,
};

/// A rectangle context.
pub struct RectangleContext<'a> {
    /// View transformation.
    pub view: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
}

impl<'a> Clone for RectangleContext<'a> {
    #[inline(always)]
    fn clone(&self) -> RectangleContext<'static> {
        RectangleContext {
            view: Value(*self.view.get()),
            transform: Value(*self.transform.get()),
            rect: Value(*self.rect.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for RectangleContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, RectangleContext<'a>, Matrix2d> for RectangleContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> RectangleContext<'a> {
        RectangleContext {
            view: Borrowed(self.view.get()),
            transform: Value(value),
            rect: Borrowed(self.rect.get()),
        }
    }
}

impl<'a> HasViewTransform<'a, Matrix2d> for RectangleContext<'a> {
    #[inline(always)]
    fn get_view_transform(&'a self) -> &'a Matrix2d {
        self.view.get()
    }
}

impl<'a> CanViewTransform<'a, RectangleContext<'a>, Matrix2d>
for RectangleContext<'a> {
    #[inline(always)]
    fn view_transform(&'a self, value: Matrix2d) -> RectangleContext<'a> {
        RectangleContext {
            view: Value(value),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
        }
    }
}

impl<'a> HasRectangle<'a, Rectangle> for RectangleContext<'a> {
    #[inline(always)]
    fn get_rectangle(&'a self) -> &'a Rectangle {
        self.rect.get()
    }
}

impl<'a> CanRectangle<'a, RectangleContext<'a>, Rectangle> for RectangleContext<'a> {
    #[inline(always)]
    fn rectangle(&'a self, rect: Rectangle) -> RectangleContext<'a> {
        RectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Value(rect),
        }
    }
}

impl<'a> AddColor<'a, RectangleColorContext<'a>> for RectangleContext<'a> {
    /// Creates a RectangleColorContext.
    #[inline(always)]
    fn rgba(
        &'a self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> RectangleColorContext<'a> {
        RectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            color: Value([r, g, b, a]),
            rect: Borrowed(self.rect.get()),
        }
    }
}

#[test]
fn test_rgba() {
    use {Context, AddRectangle};

    let c = Context::new();
    let d = c.rect(0.0, 0.0, 100.0, 100.0);
    let e = d.rgba(1.0, 0.0, 0.0, 1.0);
    let color = e.color.get();
    assert_eq!(color[0], 1.0);
}

impl<'a> AddRound<'a, RoundRectangleContext<'a>> for RectangleContext<'a> {
    #[inline(always)]
    fn round(&'a self, radius: Radius) -> RoundRectangleContext<'a> {
        RoundRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            round_radius: Value(radius),
        }
    }
}

impl<'a> AddBevel<'a, BevelRectangleContext<'a>> for RectangleContext<'a> {
    #[inline(always)]
    fn bevel(&'a self, radius: Radius) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Value(radius),
        }
    }
}

impl<'a, 'b, I: Image> AddImage<'a, 'b, ImageRectangleContext<'a, 'b, I>, I> for RectangleContext<'a> {
    fn image(&'a self, image: &'b I) -> ImageRectangleContext<'a, 'b, I> {
        let (w, h) = image.get_size();
        ImageRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            image: Value(image),
            source_rect: Value([0, 0, w as i32, h as i32]),
        }
    }
}

<commit_msg>Implement `AddBorder` for `RectangleBorderContext`<commit_after>
use {
    AddBevel,
    AddBorder,
    AddColor,
    AddImage,
    AddRound,
    BevelRectangleContext,
    Borrowed,
    Field,
    Image,
    ImageRectangleContext,
    RectangleBorderContext,
    RectangleColorContext,
    RoundRectangleContext,
    Value,
};
use internal::{
    CanRectangle,
    CanTransform,
    CanViewTransform,
    ColorComponent,
    HasRectangle,
    HasTransform,
    HasViewTransform,
    Matrix2d,
    Radius,
    Rectangle,
};

/// A rectangle context.
pub struct RectangleContext<'a> {
    /// View transformation.
    pub view: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
}

impl<'a> Clone for RectangleContext<'a> {
    #[inline(always)]
    fn clone(&self) -> RectangleContext<'static> {
        RectangleContext {
            view: Value(*self.view.get()),
            transform: Value(*self.transform.get()),
            rect: Value(*self.rect.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for RectangleContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, RectangleContext<'a>, Matrix2d> for RectangleContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> RectangleContext<'a> {
        RectangleContext {
            view: Borrowed(self.view.get()),
            transform: Value(value),
            rect: Borrowed(self.rect.get()),
        }
    }
}

impl<'a> HasViewTransform<'a, Matrix2d> for RectangleContext<'a> {
    #[inline(always)]
    fn get_view_transform(&'a self) -> &'a Matrix2d {
        self.view.get()
    }
}

impl<'a> CanViewTransform<'a, RectangleContext<'a>, Matrix2d>
for RectangleContext<'a> {
    #[inline(always)]
    fn view_transform(&'a self, value: Matrix2d) -> RectangleContext<'a> {
        RectangleContext {
            view: Value(value),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
        }
    }
}

impl<'a> HasRectangle<'a, Rectangle> for RectangleContext<'a> {
    #[inline(always)]
    fn get_rectangle(&'a self) -> &'a Rectangle {
        self.rect.get()
    }
}

impl<'a> CanRectangle<'a, RectangleContext<'a>, Rectangle> for RectangleContext<'a> {
    #[inline(always)]
    fn rectangle(&'a self, rect: Rectangle) -> RectangleContext<'a> {
        RectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Value(rect),
        }
    }
}

impl<'a> AddColor<'a, RectangleColorContext<'a>> for RectangleContext<'a> {
    /// Creates a RectangleColorContext.
    #[inline(always)]
    fn rgba(
        &'a self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> RectangleColorContext<'a> {
        RectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            color: Value([r, g, b, a]),
            rect: Borrowed(self.rect.get()),
        }
    }
}

#[test]
fn test_rgba() {
    use {Context, AddRectangle};

    let c = Context::new();
    let d = c.rect(0.0, 0.0, 100.0, 100.0);
    let e = d.rgba(1.0, 0.0, 0.0, 1.0);
    let color = e.color.get();
    assert_eq!(color[0], 1.0);
}

impl<'a> AddRound<'a, RoundRectangleContext<'a>> for RectangleContext<'a> {
    #[inline(always)]
    fn round(&'a self, radius: Radius) -> RoundRectangleContext<'a> {
        RoundRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            round_radius: Value(radius),
        }
    }
}

impl<'a> AddBevel<'a, BevelRectangleContext<'a>> for RectangleContext<'a> {
    #[inline(always)]
    fn bevel(&'a self, radius: Radius) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Value(radius),
        }
    }
}

impl<'a, 'b, I: Image> AddImage<'a, 'b, ImageRectangleContext<'a, 'b, I>, I> for RectangleContext<'a> {
    fn image(&'a self, image: &'b I) -> ImageRectangleContext<'a, 'b, I> {
        let (w, h) = image.get_size();
        ImageRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            image: Value(image),
            source_rect: Value([0, 0, w as i32, h as i32]),
        }
    }
}

impl<'a> AddBorder<'a, RectangleBorderContext<'a>> for RectangleContext<'a> {
    #[inline(always)]
    fn border_radius(&'a self, radius: f64) -> RectangleBorderContext<'a> {
        RectangleBorderContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            border: Value(radius),
        }
    }
}

<|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.

use std::fmt;
use std::from_str::FromStr;
use std::gc::Gc;
use syntax::{ast, ext};
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic;
use syntax::{attr, codemap};
use syntax::parse::token;

/// A component modifier.
#[deriving(PartialEq)]
enum Modifier {
    /// Corresponds to the `#[normalized]` attribute.
    ///
    /// Normalizes the component at runtime. Unsigned integers are normalized to
    /// `[0, 1]`. Signed integers are normalized to `[-1, 1]`.
    Normalized,
    /// Corresponds to the `#[as_float]` attribute.
    ///
    /// Casts the component to a float precision floating-point number at runtime.
    AsFloat,
    /// Corresponds to the `#[as_double]` attribute.
    ///
    /// Specifies a high-precision float.
    AsDouble,
}

impl fmt::Show for Modifier {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Normalized => write!(f, "normalized"),
            AsFloat => write!(f, "as_float"),
            AsDouble => write!(f, "as_double"),
        }
    }
}

impl FromStr for Modifier {
    fn from_str(src: &str) -> Option<Modifier> {
        match src {
            "normalized" => Some(Normalized),
            "as_float" => Some(AsFloat),
            "as_double" => Some(AsDouble),
            _ => None,
        }
    }
}

/// Scan through the field's attributes and extract a relevant modifier. If
/// multiple modifier attributes are found, use the first modifier and emit a
/// warning.
fn find_modifier(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                 attributes: &[ast::Attribute]) -> Option<Modifier> {
    attributes.iter().fold(None, |modifier, attribute| {
        match attribute.node.value.node {
            ast::MetaWord(ref word) => {
                from_str(word.get()).and_then(|new_modifier| {
                    attr::mark_used(attribute);
                    modifier.map_or(Some(new_modifier), |modifier| {
                        cx.span_warn(span, format!(
                            "Extra attribute modifier detected: `#[{}]` - \
                            ignoring in favour of `#[{}]`.", new_modifier, modifier
                        ).as_slice());
                        None
                    })
                }).or(modifier)
            },
            _ => modifier,
        }
    })
}

/// Scan through attributes to find the instance rate, if specified
fn get_instance_rate(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                     attributes: &[ast::Attribute]) -> Gc<ast::Expr> {
    for attribute in attributes.iter() {
        match attribute.node.value.node {
            ast::MetaNameValue(ref name, ref value) => match (name.get(), &value.node) {
                ("instance_rate", &ast::LitInt(value, _)) => {
                    attr::mark_used(attribute);
                    return cx.expr_u8(span, value as u8);
                },
                ("instance_rate", &ast::LitStr(ref value_str, _)) => {
                    match from_str(value_str.get()) {
                        Some(value) => {
                            attr::mark_used(attribute);
                            return cx.expr_u8(span, value);
                        },
                        None => {
                            cx.span_err(span, "Invalid argument for #[instance_rate = ...]");
                        },
                    }
                },
                _ => (),
            },
            _ => ()
        }
    }
    cx.expr_u8(span, 0)
}

/// Find a `gfx::attrib::Type` that describes the given type identifier.
fn decode_type(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
               ty_ident: &ast::Ident, modifier: Option<Modifier>,
               path_root: ast::Ident) -> Gc<ast::Expr> {
    let ty_str = ty_ident.name.as_str();
    match ty_str {
        "f32" | "f64" => {
            let kind = cx.ident_of(match modifier {
                None | Some(AsFloat) => "FloatDefault",
                Some(AsDouble) => "FloatPrecision",
                Some(Normalized) => {
                    cx.span_warn(span, format!(
                        "Incompatible float modifier attribute: `#[{}]`", modifier
                    ).as_slice());
                    ""
                }
            });
            let sub_type = cx.ident_of(format!("F{}", ty_str.slice_from(1)).as_slice());
            quote_expr!(cx, $path_root::gfx::attrib::Float($path_root::gfx::attrib::$kind,
                                                           $path_root::gfx::attrib::$sub_type))
        },
        "u8" | "u16" | "u32" | "u64" |
        "i8" | "i16" | "i32" | "i64" => {
            let sign = cx.ident_of({
                if ty_str.starts_with("i") { "Signed" } else { "Unsigned" }
            });
            let kind = cx.ident_of(match modifier {
                None => "IntRaw",
                Some(Normalized) => "IntNormalized",
                Some(AsFloat) => "IntAsFloat",
                Some(AsDouble) => {
                    cx.span_warn(span, format!(
                        "Incompatible int modifier attribute: `#[{}]`", modifier
                    ).as_slice());
                    ""
                }
            });
            let sub_type = cx.ident_of(format!("U{}", ty_str.slice_from(1)).as_slice());
            quote_expr!(cx, $path_root::gfx::attrib::Int($path_root::gfx::attrib::$kind,
                                                         $path_root::gfx::attrib::$sub_type,
                                                         $path_root::gfx::attrib::$sign))
        },
        "uint" | "int" => {
            cx.span_err(span, format!("Pointer-sized integer components are \
                                      not supported, but found: `{}`. Use an \
                                      integer component with an explicit size \
                                      instead.", ty_str).as_slice());
            cx.expr_lit(span, ast::LitNil)
        },
        ty_str => {
            cx.span_err(span, format!("Unrecognized component type: `{}`",
                                      ty_str).as_slice());
            cx.expr_lit(span, ast::LitNil)
        },
    }
}

fn decode_count_and_type(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                         field: &ast::StructField,
                         path_root: ast::Ident) -> (Gc<ast::Expr>, Gc<ast::Expr>) {
    let modifier = find_modifier(cx, span, field.node.attrs.as_slice());
    match field.node.ty.node {
        ast::TyPath(ref p, _, _) => (
            cx.expr_lit(span, ast::LitInt(1, ast::UnsuffixedIntLit(ast::Plus))),
            decode_type(cx, span, &p.segments[0].identifier, modifier, path_root),
        ),
        ast::TyFixedLengthVec(pty, expr) => (expr, match pty.node {
            ast::TyPath(ref p, _, _) => {
                decode_type(cx, span, &p.segments[0].identifier, modifier, path_root)
            },
            _ => {
                cx.span_err(span, format!("Unsupported fixed vector sub-type: \
                                          `{}`",pty.node).as_slice());
                cx.expr_lit(span, ast::LitNil)
            },
        }),
        _ => {
            cx.span_err(span, format!("Unsupported attribute type: `{}`",
                                      field.node.ty.node).as_slice());
            (cx.expr_lit(span, ast::LitNil), cx.expr_lit(span, ast::LitNil))
        },
    }
}

/// Generates the the method body for `gfx::VertexFormat::generate`.
fn method_body(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                   substr: &generic::Substructure,
                   path_root: ast::Ident) -> Gc<ast::Expr> {
    match *substr.fields {
        generic::StaticStruct(ref definition, generic::Named(ref fields)) => {
            let attribute_pushes = definition.fields.iter().zip(fields.iter())
                .map(|(def, &(ident, _))| {
                    let struct_ident = substr.type_ident;
                    let buffer_expr = substr.nonself_args[1];
                    let (count_expr, type_expr) = decode_count_and_type(cx, span, def, path_root);
                    let ident_str = match super::find_name(cx, span, def.node.attrs.as_slice()) {
                        Some(name) => name,
                        None => token::get_ident(ident),
                    };
                    let ident_str = ident_str.get();
                    let instance_expr = get_instance_rate(cx, span, def.node.attrs.as_slice());
                    super::ugh(cx, |cx| quote_expr!(cx, {
                        attributes.push($path_root::gfx::Attribute {
                            buffer: $buffer_expr,
                            elem_count: $count_expr,
                            elem_type: $type_expr,
                            offset: unsafe {
                                &(*(0u as *const $struct_ident)).$ident as *const _ as $path_root::gfx::attrib::Offset
                            },
                            stride: { use std::mem; mem::size_of::<$struct_ident>() as $path_root::gfx::attrib::Stride },
                            name: $ident_str.to_string(),
                            instance_rate: $instance_expr,
                        });
                    }))
                }).collect::<Vec<Gc<ast::Expr>>>();
            let capacity = fields.len();
            super::ugh(cx, |cx| quote_expr!(cx, {
                let mut attributes = Vec::with_capacity($capacity);
                $attribute_pushes;
                attributes
            }))
        },
        _ => {
            cx.span_err(span, "Unable to implement `gfx::VertexFormat::generate` \
                              on a non-structure");
            cx.expr_lit(span, ast::LitNil)
        }
    }
}

/// Derive a `gfx::VertexFormat` implementation for the `struct`
pub fn expand(context: &mut ext::base::ExtCtxt, span: codemap::Span,
              meta_item: Gc<ast::MetaItem>, item: Gc<ast::Item>,
              push: |Gc<ast::Item>|) {
    // Insert the `gfx` reexport module
    let path_root = super::extern_crate_hack(context, span, |i| push(i));
    let fixup = |item| {
        push(super::fixup_extern_crate_paths(item, path_root))
    };

    // `impl gfx::VertexFormat for $item`
    generic::TraitDef {
        span: span,
        attributes: Vec::new(),
        path: generic::ty::Path {
            path: vec![super::EXTERN_CRATE_HACK, "gfx", "VertexFormat"],
            lifetime: None,
            params: Vec::new(),
            global: true,
        },
        additional_bounds: Vec::new(),
        generics: generic::ty::LifetimeBounds::empty(),
        methods: vec![
            // `fn generate(Option<Self>, gfx::RawBufferHandle) -> Vec<gfx::Attribute>`
            generic::MethodDef {
                name: "generate",
                generics: generic::ty::LifetimeBounds::empty(),
                explicit_self: None,
                args: vec![
                    generic::ty::Literal(generic::ty::Path {
                        path: vec!["Option"],
                        lifetime: None,
                        params: vec![box generic::ty::Self],
                        global: false,
                    }),
                    generic::ty::Literal(generic::ty::Path::new(
                        vec![super::EXTERN_CRATE_HACK, "gfx", "RawBufferHandle"]
                    )),
                ],
                ret_ty: generic::ty::Literal(
                    generic::ty::Path {
                        path: vec!["Vec"],
                        lifetime: None,
                        params: vec![
                            box generic::ty::Literal(generic::ty::Path::new(
                                vec![super::EXTERN_CRATE_HACK, "gfx", "Attribute"])),
                        ],
                        global: false,
                    },
                ),
                attributes: Vec::new(),
                // generate the method body
                combine_substructure: generic::combine_substructure(
                    |c, s, ss| method_body(c, s, ss, path_root)),
            },
        ],
    }.expand(context, meta_item, item, fixup);
}
<commit_msg>Remove undefined behavior in offset computation<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.

use std::fmt;
use std::from_str::FromStr;
use std::gc::Gc;
use syntax::{ast, ext};
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic;
use syntax::{attr, codemap};
use syntax::parse::token;

/// A component modifier.
#[deriving(PartialEq)]
enum Modifier {
    /// Corresponds to the `#[normalized]` attribute.
    ///
    /// Normalizes the component at runtime. Unsigned integers are normalized to
    /// `[0, 1]`. Signed integers are normalized to `[-1, 1]`.
    Normalized,
    /// Corresponds to the `#[as_float]` attribute.
    ///
    /// Casts the component to a float precision floating-point number at runtime.
    AsFloat,
    /// Corresponds to the `#[as_double]` attribute.
    ///
    /// Specifies a high-precision float.
    AsDouble,
}

impl fmt::Show for Modifier {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Normalized => write!(f, "normalized"),
            AsFloat => write!(f, "as_float"),
            AsDouble => write!(f, "as_double"),
        }
    }
}

impl FromStr for Modifier {
    fn from_str(src: &str) -> Option<Modifier> {
        match src {
            "normalized" => Some(Normalized),
            "as_float" => Some(AsFloat),
            "as_double" => Some(AsDouble),
            _ => None,
        }
    }
}

/// Scan through the field's attributes and extract a relevant modifier. If
/// multiple modifier attributes are found, use the first modifier and emit a
/// warning.
fn find_modifier(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                 attributes: &[ast::Attribute]) -> Option<Modifier> {
    attributes.iter().fold(None, |modifier, attribute| {
        match attribute.node.value.node {
            ast::MetaWord(ref word) => {
                from_str(word.get()).and_then(|new_modifier| {
                    attr::mark_used(attribute);
                    modifier.map_or(Some(new_modifier), |modifier| {
                        cx.span_warn(span, format!(
                            "Extra attribute modifier detected: `#[{}]` - \
                            ignoring in favour of `#[{}]`.", new_modifier, modifier
                        ).as_slice());
                        None
                    })
                }).or(modifier)
            },
            _ => modifier,
        }
    })
}

/// Scan through attributes to find the instance rate, if specified
fn get_instance_rate(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                     attributes: &[ast::Attribute]) -> Gc<ast::Expr> {
    for attribute in attributes.iter() {
        match attribute.node.value.node {
            ast::MetaNameValue(ref name, ref value) => match (name.get(), &value.node) {
                ("instance_rate", &ast::LitInt(value, _)) => {
                    attr::mark_used(attribute);
                    return cx.expr_u8(span, value as u8);
                },
                ("instance_rate", &ast::LitStr(ref value_str, _)) => {
                    match from_str(value_str.get()) {
                        Some(value) => {
                            attr::mark_used(attribute);
                            return cx.expr_u8(span, value);
                        },
                        None => {
                            cx.span_err(span, "Invalid argument for #[instance_rate = ...]");
                        },
                    }
                },
                _ => (),
            },
            _ => ()
        }
    }
    cx.expr_u8(span, 0)
}

/// Find a `gfx::attrib::Type` that describes the given type identifier.
fn decode_type(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
               ty_ident: &ast::Ident, modifier: Option<Modifier>,
               path_root: ast::Ident) -> Gc<ast::Expr> {
    let ty_str = ty_ident.name.as_str();
    match ty_str {
        "f32" | "f64" => {
            let kind = cx.ident_of(match modifier {
                None | Some(AsFloat) => "FloatDefault",
                Some(AsDouble) => "FloatPrecision",
                Some(Normalized) => {
                    cx.span_warn(span, format!(
                        "Incompatible float modifier attribute: `#[{}]`", modifier
                    ).as_slice());
                    ""
                }
            });
            let sub_type = cx.ident_of(format!("F{}", ty_str.slice_from(1)).as_slice());
            quote_expr!(cx, $path_root::gfx::attrib::Float($path_root::gfx::attrib::$kind,
                                                           $path_root::gfx::attrib::$sub_type))
        },
        "u8" | "u16" | "u32" | "u64" |
        "i8" | "i16" | "i32" | "i64" => {
            let sign = cx.ident_of({
                if ty_str.starts_with("i") { "Signed" } else { "Unsigned" }
            });
            let kind = cx.ident_of(match modifier {
                None => "IntRaw",
                Some(Normalized) => "IntNormalized",
                Some(AsFloat) => "IntAsFloat",
                Some(AsDouble) => {
                    cx.span_warn(span, format!(
                        "Incompatible int modifier attribute: `#[{}]`", modifier
                    ).as_slice());
                    ""
                }
            });
            let sub_type = cx.ident_of(format!("U{}", ty_str.slice_from(1)).as_slice());
            quote_expr!(cx, $path_root::gfx::attrib::Int($path_root::gfx::attrib::$kind,
                                                         $path_root::gfx::attrib::$sub_type,
                                                         $path_root::gfx::attrib::$sign))
        },
        "uint" | "int" => {
            cx.span_err(span, format!("Pointer-sized integer components are \
                                      not supported, but found: `{}`. Use an \
                                      integer component with an explicit size \
                                      instead.", ty_str).as_slice());
            cx.expr_lit(span, ast::LitNil)
        },
        ty_str => {
            cx.span_err(span, format!("Unrecognized component type: `{}`",
                                      ty_str).as_slice());
            cx.expr_lit(span, ast::LitNil)
        },
    }
}

fn decode_count_and_type(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                         field: &ast::StructField,
                         path_root: ast::Ident) -> (Gc<ast::Expr>, Gc<ast::Expr>) {
    let modifier = find_modifier(cx, span, field.node.attrs.as_slice());
    match field.node.ty.node {
        ast::TyPath(ref p, _, _) => (
            cx.expr_lit(span, ast::LitInt(1, ast::UnsuffixedIntLit(ast::Plus))),
            decode_type(cx, span, &p.segments[0].identifier, modifier, path_root),
        ),
        ast::TyFixedLengthVec(pty, expr) => (expr, match pty.node {
            ast::TyPath(ref p, _, _) => {
                decode_type(cx, span, &p.segments[0].identifier, modifier, path_root)
            },
            _ => {
                cx.span_err(span, format!("Unsupported fixed vector sub-type: \
                                          `{}`",pty.node).as_slice());
                cx.expr_lit(span, ast::LitNil)
            },
        }),
        _ => {
            cx.span_err(span, format!("Unsupported attribute type: `{}`",
                                      field.node.ty.node).as_slice());
            (cx.expr_lit(span, ast::LitNil), cx.expr_lit(span, ast::LitNil))
        },
    }
}

/// Generates the the method body for `gfx::VertexFormat::generate`.
fn method_body(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
                   substr: &generic::Substructure,
                   path_root: ast::Ident) -> Gc<ast::Expr> {
    match *substr.fields {
        generic::StaticStruct(ref definition, generic::Named(ref fields)) => {
            let attribute_pushes = definition.fields.iter().zip(fields.iter())
                .map(|(def, &(ident, _))| {
                    let struct_ident = substr.type_ident;
                    let buffer_expr = substr.nonself_args[1];
                    let (count_expr, type_expr) = decode_count_and_type(cx, span, def, path_root);
                    let ident_str = match super::find_name(cx, span, def.node.attrs.as_slice()) {
                        Some(name) => name,
                        None => token::get_ident(ident),
                    };
                    let ident_str = ident_str.get();
                    let instance_expr = get_instance_rate(cx, span, def.node.attrs.as_slice());
                    super::ugh(cx, |cx| quote_expr!(cx, {
                        attributes.push($path_root::gfx::Attribute {
                            buffer: $buffer_expr,
                            elem_count: $count_expr,
                            elem_type: $type_expr,
                            offset: unsafe {
                                let x: $struct_ident = ::std::mem::uninitialized();
                                let offset = (&x.$ident as *const _ as uint) - (&x as *const _ as uint);
                                ::std::mem::forget(x);
                                offset as $path_root::gfx::attrib::Offset
                            },
                            stride: { use std::mem; mem::size_of::<$struct_ident>() as $path_root::gfx::attrib::Stride },
                            name: $ident_str.to_string(),
                            instance_rate: $instance_expr,
                        });
                    }))
                }).collect::<Vec<Gc<ast::Expr>>>();
            let capacity = fields.len();
            super::ugh(cx, |cx| quote_expr!(cx, {
                let mut attributes = Vec::with_capacity($capacity);
                $attribute_pushes;
                attributes
            }))
        },
        _ => {
            cx.span_err(span, "Unable to implement `gfx::VertexFormat::generate` \
                              on a non-structure");
            cx.expr_lit(span, ast::LitNil)
        }
    }
}

/// Derive a `gfx::VertexFormat` implementation for the `struct`
pub fn expand(context: &mut ext::base::ExtCtxt, span: codemap::Span,
              meta_item: Gc<ast::MetaItem>, item: Gc<ast::Item>,
              push: |Gc<ast::Item>|) {
    // Insert the `gfx` reexport module
    let path_root = super::extern_crate_hack(context, span, |i| push(i));
    let fixup = |item| {
        push(super::fixup_extern_crate_paths(item, path_root))
    };

    // `impl gfx::VertexFormat for $item`
    generic::TraitDef {
        span: span,
        attributes: Vec::new(),
        path: generic::ty::Path {
            path: vec![super::EXTERN_CRATE_HACK, "gfx", "VertexFormat"],
            lifetime: None,
            params: Vec::new(),
            global: true,
        },
        additional_bounds: Vec::new(),
        generics: generic::ty::LifetimeBounds::empty(),
        methods: vec![
            // `fn generate(Option<Self>, gfx::RawBufferHandle) -> Vec<gfx::Attribute>`
            generic::MethodDef {
                name: "generate",
                generics: generic::ty::LifetimeBounds::empty(),
                explicit_self: None,
                args: vec![
                    generic::ty::Literal(generic::ty::Path {
                        path: vec!["Option"],
                        lifetime: None,
                        params: vec![box generic::ty::Self],
                        global: false,
                    }),
                    generic::ty::Literal(generic::ty::Path::new(
                        vec![super::EXTERN_CRATE_HACK, "gfx", "RawBufferHandle"]
                    )),
                ],
                ret_ty: generic::ty::Literal(
                    generic::ty::Path {
                        path: vec!["Vec"],
                        lifetime: None,
                        params: vec![
                            box generic::ty::Literal(generic::ty::Path::new(
                                vec![super::EXTERN_CRATE_HACK, "gfx", "Attribute"])),
                        ],
                        global: false,
                    },
                ),
                attributes: Vec::new(),
                // generate the method body
                combine_substructure: generic::combine_substructure(
                    |c, s, ss| method_body(c, s, ss, path_root)),
            },
        ],
    }.expand(context, meta_item, item, fixup);
}
<|endoftext|>


<commit_before>use std::io;

use codespan::CodeMap;

use termcolor::{Color, ColorSpec, WriteColor};

use Diagnostic;

pub fn emit<W>(mut writer: W, codemap: &CodeMap, diagnostic: &Diagnostic) -> io::Result<()>
where
    W: WriteColor,
{
    let supports_color = writer.supports_color();
    let line_location_color = ColorSpec::new().set_fg(Some(Color::Cyan)).clone();
    let diagnostic_color = ColorSpec::new()
        .set_fg(Some(diagnostic.severity.color()))
        .clone();

    writer.set_color(&diagnostic_color)?;
    write!(writer, "{}", diagnostic.severity)?;
    writer.reset()?;
    writeln!(writer, ": {}", diagnostic.message)?;
    for label in &diagnostic.labels {
        match codemap.find_file(label.span.start()) {
            None => if let Some(ref message) = label.message {
                writeln!(writer, "- {}", message)?
            },
            Some(file) => {
                let (line, col) = file.location(label.span.start()).expect("location");
                writeln!(
                    writer,
                    "- {}:{}:{}",
                    file.name(),
                    line.number(),
                    col.number()
                )?;

                let line_span = file.line_span(line).expect("line_span");

                let line_prefix = file.src_slice(line_span.with_end(label.span.start()))
                    .expect("line_prefix");
                let line_marked = file.src_slice(label.span).expect("line_marked");
                let line_suffix = file.src_slice(line_span.with_start(label.span.end()))
                    .expect("line_suffix")
                    .trim_right_matches(|c: char| c == '\r' || c == '\n');

                writer.set_color(&line_location_color)?;
                let line_string = line.number().to_string();
                let line_location_prefix = format!("{:prefix$} | ", "", prefix = line_string.len());
                write!(writer, "{} | ", line_string)?;
                writer.reset()?;

                write!(writer, "{}", line_prefix)?;
                writer.set_color(&diagnostic_color)?;
                write!(writer, "{}", line_marked)?;
                writer.reset()?;
                writeln!(writer, "{}", line_suffix)?;

                if !supports_color || label.message.is_some() {
                    writer.set_color(&line_location_color)?;
                    write!(writer, "{}", line_location_prefix)?;
                    writer.reset()?;

                    writer.set_color(&diagnostic_color)?;
                    write!(
                        writer,
                        "{:prefix$}{:^>marked$}",
                        prefix = line_prefix.len(),
                        marked = line_marked.len()
                    )?;
                    writer.reset()?;

                    if label.message.is_none() {
                        writeln!(writer)?;
                    }
                }

                match label.message {
                    None => (),
                    Some(ref label) => {
                        writer.set_color(&diagnostic_color)?;
                        writeln!(writer, " {}", label)?;
                        writer.reset()?;
                    },
                }
            },
        }
    }
    Ok(())
}
<commit_msg>Fix padding<commit_after>use codespan::CodeMap;
use std::{fmt, io};
use termcolor::{Color, ColorSpec, WriteColor};

use Diagnostic;

struct Pad<T>(T, usize);

impl<T: fmt::Display> fmt::Display for Pad<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for _ in 0..(self.1) {
            self.0.fmt(f)?;
        }
        Ok(())
    }
}

pub fn emit<W>(mut writer: W, codemap: &CodeMap, diagnostic: &Diagnostic) -> io::Result<()>
where
    W: WriteColor,
{
    let supports_color = writer.supports_color();
    let line_location_color = ColorSpec::new().set_fg(Some(Color::Cyan)).clone();
    let diagnostic_color = ColorSpec::new()
        .set_fg(Some(diagnostic.severity.color()))
        .clone();

    writer.set_color(&diagnostic_color)?;
    write!(writer, "{}", diagnostic.severity)?;
    writer.reset()?;
    writeln!(writer, ": {}", diagnostic.message)?;
    for label in &diagnostic.labels {
        match codemap.find_file(label.span.start()) {
            None => if let Some(ref message) = label.message {
                writeln!(writer, "- {}", message)?
            },
            Some(file) => {
                let (line, col) = file.location(label.span.start()).expect("location");
                writeln!(
                    writer,
                    "- {}:{}:{}",
                    file.name(),
                    line.number(),
                    col.number()
                )?;

                let line_span = file.line_span(line).expect("line_span");

                let line_prefix = file.src_slice(line_span.with_end(label.span.start()))
                    .expect("line_prefix");
                let line_marked = file.src_slice(label.span).expect("line_marked");
                let line_suffix = file.src_slice(line_span.with_start(label.span.end()))
                    .expect("line_suffix")
                    .trim_right_matches(|c: char| c == '\r' || c == '\n');

                writer.set_color(&line_location_color)?;
                let line_string = line.number().to_string();
                let line_location_prefix = format!("{} | ", Pad(' ', line_string.len()));
                write!(writer, "{} | ", line_string)?;
                writer.reset()?;

                write!(writer, "{}", line_prefix)?;
                writer.set_color(&diagnostic_color)?;
                write!(writer, "{}", line_marked)?;
                writer.reset()?;
                writeln!(writer, "{}", line_suffix)?;

                if !supports_color || label.message.is_some() {
                    writer.set_color(&line_location_color)?;
                    write!(writer, "{}", line_location_prefix)?;
                    writer.reset()?;

                    writer.set_color(&diagnostic_color)?;
                    write!(
                        writer,
                        "{}{}",
                        Pad(' ', line_prefix.len()),
                        Pad('^', line_marked.len()),
                    )?;
                    writer.reset()?;

                    if label.message.is_none() {
                        writeln!(writer)?;
                    }
                }

                match label.message {
                    None => (),
                    Some(ref label) => {
                        writer.set_color(&diagnostic_color)?;
                        writeln!(writer, " {}", label)?;
                        writer.reset()?;
                    },
                }
            },
        }
    }
    Ok(())
}
<|endoftext|>


<commit_before>use clap::Arg;
use clap::App;
use clap::ArgMatches;
use autoconf;

pub fn cli_clap(number: &u32) -> ArgMatches {
    let application = App::new(autoconf::package())
        .about("Parses an input file to do awesome things")
        .version(autoconf::version_cli())
        .author("Owen Synge <osynge@googlemail.com>")
        .arg(
            Arg::with_name("verbose")
                .help("Increase log output.")
                .short("v")
                .multiple(true)
                .long("verbose"),
        )
        .arg(
            Arg::with_name("quiet")
                .help("Decrease log output.")
                .short("q")
                .multiple(true)
                .long("quiet"),
        )
        .arg(
            Arg::with_name("rdbms")
                .long("rdbms")
                .value_name("FILE_RDBMS")
                .help("sqlite rdbms file.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("env")
                .short("e")
                .long("env")
                .value_name("ENVIROMENT_VARIABLE")
                .help("Which enviroment variables to process")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("dir-jobs")
                .long("dir-jobs")
                .value_name("DIR_JOB")
                .help("directory storing json jobs.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("dir-sh")
                .long("dir-sh")
                .value_name("DIR_SHELL")
                .help("directory storing jobs shell scripts.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("dir-py")
                .long("dir-py")
                .value_name("DIR_PYTHON")
                .help("directory storing jobs python scripts.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("config")
                .short("c")
                .long("config")
                .value_name("FILE")
                .help("Sets a custom config file")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("target")
                .short("t")
                .long("target")
                .value_name("TARGET")
                .help("Sets the provider to be selected.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("list-provides")
                .long("list-provides")
                .help("list-provides"),
        )
        .arg(
            Arg::with_name("list-target")
                .long("list-target")
                .help("list all targets"),
        )
        .arg(Arg::with_name("session").long("session").help("session"));
    let matches = application.get_matches();
    return matches;
}
<commit_msg>Improve help<commit_after>use autoconf;
use clap::App;
use clap::Arg;
use clap::ArgMatches;

pub fn cli_clap(number: &u32) -> ArgMatches {
    let application = App::new(autoconf::package())
        .about("Parses an input file to do awesome things")
        .version(autoconf::version_cli())
        .author("Owen Synge <osynge@googlemail.com>")
        .arg(
            Arg::with_name("verbose")
                .help("Increase log output.")
                .short("v")
                .multiple(true)
                .long("verbose"),
        )
        .arg(
            Arg::with_name("quiet")
                .help("Decrease log output.")
                .short("q")
                .multiple(true)
                .long("quiet"),
        )
        .arg(
            Arg::with_name("rdbms")
                .long("rdbms")
                .value_name("FILE_RDBMS")
                .help("sqlite rdbms file.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("env")
                .short("e")
                .long("env")
                .value_name("ENVIROMENT_VARIABLE")
                .help("Which enviroment variables to process")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("dir-jobs")
                .long("dir-jobs")
                .value_name("DIR_JOB")
                .help("directory storing json jobs.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("dir-sh")
                .long("dir-sh")
                .value_name("DIR_SHELL")
                .help("directory storing jobs shell scripts.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("dir-py")
                .long("dir-py")
                .value_name("DIR_PYTHON")
                .help("directory storing jobs python scripts.")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("config")
                .short("c")
                .long("config")
                .value_name("FILE")
                .help("Sets a custom config file")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("target")
                .short("t")
                .long("target")
                .value_name("TARGET")
                .help("Sets the target to be selected, so jobs can be matched to provides. Defaults to 'execution'.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("list-provides")
                .long("list-provides")
                .help("List all jobs sorted by the functions they provide."),
        )
        .arg(
            Arg::with_name("list-target")
                .long("list-target")
                .help("List jobs by the target they provide. Not all jobs have a target."),
        )
        .arg(Arg::with_name("session").long("session").help("session"));
    let matches = application.get_matches();
    return matches;
}
<|endoftext|>