<commit_before>use std::fmt;
use num::{Zero};
use std::ops::{Add, Sub};
use std::hash::Hash;

extern crate num;
use num::{ToPrimitive, FromPrimitive, CheckedAdd, CheckedSub};

/// Type infrastructure that describes an architecture,
///  with details such as pointer size.
///
/// Useful for specifying the appropriate member types for pointers, etc.
/// That is, when a struct contains an RVA, its 32-bits or 64-bits depending on Arch.
///
/// Example:
///
/// ```
/// use lancelot::arch::{Arch, Arch32};
///
/// struct Section<A: Arch> {
///   addr: A::RVA,
///   buf:  Vec<u8>,
///   name: String,
/// }
///
/// let s: Section::<Arch32> = Section {
///   addr: 0x0,
///   buf: vec![],
///   name: "foo".to_string(),
/// };
/// ```
///
/// see: https://stackoverflow.com/q/55785858/87207
pub trait Arch {
    /// The type used for Virtual Addresses (which are unsigned).
    type VA:
        // trait Ord so that we can compare addresses.
        Ord
        // trait Add so that we can do VA + RVA -> VA
        //  technically, we should constrain Add to Add<RHS=RVA>
        //  but, signed + unsigned addition is not implemented.
        //  atm, we push this down to the user.
        //  TODO: provide helper routines to make this easy.
        + Add<Output=Self::VA>
        + Zero
        + FromPrimitive
        + ToPrimitive
        // trait Copy because this is just a number, so prefer copy semantics.
        + Copy
        ;

    /// The type used for Relative Virtual Addresses (signed).
    type RVA:
        // trait Ord so that we can compare offsets.
        Ord
        + Zero
        + Hash
        + fmt::LowerHex
        // trait Add so that we can do VA + RVA -> VA.
        //  see note above.
        + Add<Output=Self::RVA>
        + Sub<Output=Self::RVA>
        // trait Add so that we can do RVA + RVA -> RVA.
        + Add<Self::RVA, Output=Self::RVA>
        + CheckedAdd<Output=Self::RVA>
        + CheckedSub<Output=Self::RVA>
        // trait FromPrimitive so that we can convert from usize (vec length) to offset.
        + FromPrimitive
        + ToPrimitive
        // trait Copy because this is just a number, so prefer copy semantics.
        + Copy
        ;

    fn get_bits() -> u8;
}

/// 32-bit Intel architecture.
pub struct Arch32;
impl Arch for Arch32 {
    type VA = u32;
    type RVA = i32;
    fn get_bits() -> u8 {
        32
    }
}

impl fmt::Display for Arch32 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "x32")
    }
}

/// 64-bit Intel architecture.
pub struct Arch64;
impl Arch for Arch64 {
    type VA = u64;
    type RVA = i64;
    fn get_bits() -> u8 {
        64
    }
}

impl fmt::Display for Arch64 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "x64")
    }
}

/// Checked arithmetic across RVA and usize.
///
/// We'd like RVA to be trait `Add<usize, Output=RVA>`.
/// However, this cannot be the case when `<RVA=u32>`
///  as we then have `i32 + u32` which can overflow `i32`.
/// So, we have to do checked arithmetic.
///
/// Example:
///
/// ```
/// use lancelot::arch::*;
///
/// // returns Some if the operation does not wrap:
/// assert_eq!(true, rva_add_usize::<Arch32>(0x0, 0x1).is_some());
/// assert_eq!(0x1,  rva_add_usize::<Arch32>(0x0, 0x1).unwrap());
///
/// // returns None if the operation wraps.
/// assert_eq!(true, rva_add_usize::<Arch32>(0x0, 0xFFFFFFFF).is_none());
/// ```
pub fn rva_add_usize<A: Arch>(base: A::RVA, offset: usize) -> Option<A::RVA> {
    if let Some(v) = A::RVA::from_usize(offset) {
        base.checked_add(&v)
    } else {
        None
    }
}

/// Checked arithmetic across RVA and usize.
///
/// We'd like RVA to be trait `Sub<usize, Output=RVA>`.
/// However, this cannot be the case when `<RVA=u32>`
///  as we then have `i32 - u32` which can underflow `i32`.
/// So, we have to do checked arithmetic.
///
/// Example:
///
/// ```
/// use std::i32;
/// use lancelot::arch::*;
///
/// // returns Some if the operation does not wrap:
/// assert_eq!(true, rva_sub_usize::<Arch32>(0x1, 0x0).is_some());
/// assert_eq!(0x1,  rva_sub_usize::<Arch32>(0x1, 0x0).unwrap());
///
/// // returns None if the operation wraps.
/// assert_eq!(true, rva_sub_usize::<Arch32>(std::i32::MAX, 0xFFFFFFFF).is_none());
/// ```
pub fn rva_sub_usize<A: Arch>(base: A::RVA, offset: usize) -> Option<A::RVA> {
    if let Some(v) = A::RVA::from_usize(offset) {
        base.checked_sub(&v)
    } else {
        None
    }
}

<commit_msg>arch: implement further fundametal traits<commit_after>use std::fmt;
use std::hash;
use num::{Zero};
use std::ops::{Add, Sub};
use std::hash::Hash;
use std::fmt::Debug;

extern crate num;
use num::{ToPrimitive, FromPrimitive, CheckedAdd, CheckedSub};

/// Type infrastructure that describes an architecture,
///  with details such as pointer size.
///
/// Useful for specifying the appropriate member types for pointers, etc.
/// That is, when a struct contains an RVA, its 32-bits or 64-bits depending on Arch.
///
/// Example:
///
/// ```
/// use lancelot::arch::{Arch, Arch32};
///
/// struct Section<A: Arch> {
///   addr: A::RVA,
///   buf:  Vec<u8>,
///   name: String,
/// }
///
/// let s: Section::<Arch32> = Section {
///   addr: 0x0,
///   buf: vec![],
///   name: "foo".to_string(),
/// };
/// ```
///
/// see: https://stackoverflow.com/q/55785858/87207
pub trait Arch {
    /// The type used for Virtual Addresses (which are unsigned).
    type VA:
        // trait Ord so that we can compare addresses.
        Ord
        // trait Add so that we can do VA + RVA -> VA
        //  technically, we should constrain Add to Add<RHS=RVA>
        //  but, signed + unsigned addition is not implemented.
        //  atm, we push this down to the user.
        //  TODO: provide helper routines to make this easy.
        + Add<Output=Self::VA>
        + Zero
        + FromPrimitive
        + ToPrimitive
        // trait Copy because this is just a number, so prefer copy semantics.
        + Copy
        + Debug
        ;

    /// The type used for Relative Virtual Addresses (signed).
    type RVA:
        // trait Ord so that we can compare offsets.
        Ord
        + Zero
        + Hash
        + fmt::LowerHex
        // trait Add so that we can do VA + RVA -> VA.
        //  see note above.
        + Add<Output=Self::RVA>
        + Sub<Output=Self::RVA>
        // trait Add so that we can do RVA + RVA -> RVA.
        + Add<Self::RVA, Output=Self::RVA>
        + CheckedAdd<Output=Self::RVA>
        + CheckedSub<Output=Self::RVA>
        // trait FromPrimitive so that we can convert from usize (vec length) to offset.
        + FromPrimitive
        + ToPrimitive
        // trait Copy because this is just a number, so prefer copy semantics.
        + Copy
        + Debug
        ;

    fn get_bits() -> u8;
}

/// 32-bit Intel architecture.
pub struct Arch32;
impl Arch for Arch32 {
    type VA = u32;
    type RVA = i32;
    fn get_bits() -> u8 {
        32
    }
}

impl fmt::Display for Arch32 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "x32")
    }
}

impl fmt::Debug for Arch32 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "x32")
    }
}

impl hash::Hash for Arch32 {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        "x32".hash(state);
    }
}

impl PartialEq for Arch32 {
    fn eq(&self, other: &Arch32) -> bool {
        true
    }
}

impl Eq for Arch32 {}

/// 64-bit Intel architecture.
pub struct Arch64;
impl Arch for Arch64 {
    type VA = u64;
    type RVA = i64;
    fn get_bits() -> u8 {
        64
    }
}

impl fmt::Display for Arch64 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "x64")
    }
}

impl fmt::Debug for Arch64 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "x64")
    }
}

impl hash::Hash for Arch64 {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        "x64".hash(state);
    }
}

impl PartialEq for Arch64 {
    fn eq(&self, other: &Arch64) -> bool {
        true
    }
}

impl Eq for Arch64 {}

/// Checked arithmetic across RVA and usize.
///
/// We'd like RVA to be trait `Add<usize, Output=RVA>`.
/// However, this cannot be the case when `<RVA=u32>`
///  as we then have `i32 + u32` which can overflow `i32`.
/// So, we have to do checked arithmetic.
///
/// Example:
///
/// ```
/// use lancelot::arch::*;
///
/// // returns Some if the operation does not wrap:
/// assert_eq!(true, rva_add_usize::<Arch32>(0x0, 0x1).is_some());
/// assert_eq!(0x1,  rva_add_usize::<Arch32>(0x0, 0x1).unwrap());
///
/// // returns None if the operation wraps.
/// assert_eq!(true, rva_add_usize::<Arch32>(0x0, 0xFFFFFFFF).is_none());
/// ```
pub fn rva_add_usize<A: Arch>(base: A::RVA, offset: usize) -> Option<A::RVA> {
    if let Some(v) = A::RVA::from_usize(offset) {
        base.checked_add(&v)
    } else {
        None
    }
}

/// Checked arithmetic across RVA and usize.
///
/// We'd like RVA to be trait `Sub<usize, Output=RVA>`.
/// However, this cannot be the case when `<RVA=u32>`
///  as we then have `i32 - u32` which can underflow `i32`.
/// So, we have to do checked arithmetic.
///
/// Example:
///
/// ```
/// use std::i32;
/// use lancelot::arch::*;
///
/// // returns Some if the operation does not wrap:
/// assert_eq!(true, rva_sub_usize::<Arch32>(0x1, 0x0).is_some());
/// assert_eq!(0x1,  rva_sub_usize::<Arch32>(0x1, 0x0).unwrap());
///
/// // returns None if the operation wraps.
/// assert_eq!(true, rva_sub_usize::<Arch32>(std::i32::MAX, 0xFFFFFFFF).is_none());
/// ```
pub fn rva_sub_usize<A: Arch>(base: A::RVA, offset: usize) -> Option<A::RVA> {
    if let Some(v) = A::RVA::from_usize(offset) {
        base.checked_sub(&v)
    } else {
        None
    }
}

<|endoftext|>


<commit_before>use std::simd::u64x2;
use std::mem::{size_of, zeroed};

use stack::Stack;

extern "C" {
  #[link_name = "lwt_bootstrap"]
  pub fn bootstrap();
  #[link_name = "lwt_swapcontext"]
  pub fn swapcontext(save: *mut Registers, restore: *mut Registers);
  #[link_name = "lwt_get_sp_limit"]
  pub fn get_sp_limit() -> *const u8;
  #[link_name = "lwt_set_sp_limit"]
  pub fn set_sp_limit(limit: *const u8);
  #[link_name = "lwt_abort"]
  pub fn abort() -> !;
}

#[allow(non_camel_case_types)]
pub type uintptr_t = u64;

#[repr(C)]
#[allow(dead_code)]
pub struct Registers {
  rbx: u64,
  rsp: u64,
  rbp: u64,
  rdi: u64,
  r12: u64,
  r13: u64,
  r14: u64,
  r15: u64,
  ip:  u64,
  xmm0: u64x2,
  xmm1: u64x2,
  xmm2: u64x2,
  xmm3: u64x2,
  xmm4: u64x2,
  xmm5: u64x2,
}

impl Registers {
  pub fn new() -> Registers {
    unsafe {
      Registers {
        ip: abort as u64,
        .. zeroed()
      }
    }
  }
}

pub fn initialise_call_frame(stack: &mut Stack, init: uintptr_t, args: &[uintptr_t]) -> Registers {
  let sp = stack.top() as *mut uintptr_t;
  let sp = align_down_mut(sp, 16);
  let sp = offset_mut(sp, -1);
  unsafe {
    *sp = 0;
  }

  let mut regs = Registers {
    rbp: 0,
    rsp: sp as uintptr_t,
    ip: bootstrap as uintptr_t,
    rbx: init,
    .. Registers::new()
  };

  match into_fields!(regs { rdi, r12, r13, r14, r15 } <- args.iter().cloned()) {
    Some(mut args) => if args.next().is_some() {
      panic!("too many arguments")
    },
    None => {}
  }

  regs
}

#[inline]
fn align_down_mut<T>(sp: *mut T, n: uint) -> *mut T {
  let sp = (sp as uint) & !(n - 1);
  sp as *mut T
}

// ptr::offset_mmut is positive ints only
#[inline]
pub fn offset_mut<T>(ptr: *mut T, count: int) -> *mut T {
  (ptr as int + count * (size_of::<T>() as int)) as *mut T
}
<commit_msg>u64 -> uintptr_t<commit_after>use std::simd::u64x2;
use std::mem::{size_of, zeroed};

use stack::Stack;

extern "C" {
  #[link_name = "lwt_bootstrap"]
  pub fn bootstrap();
  #[link_name = "lwt_swapcontext"]
  pub fn swapcontext(save: *mut Registers, restore: *mut Registers);
  #[link_name = "lwt_get_sp_limit"]
  pub fn get_sp_limit() -> *const u8;
  #[link_name = "lwt_set_sp_limit"]
  pub fn set_sp_limit(limit: *const u8);
  #[link_name = "lwt_abort"]
  pub fn abort() -> !;
}

#[allow(non_camel_case_types)]
pub type uintptr_t = u64;

#[repr(C)]
#[allow(dead_code)]
pub struct Registers {
  rbx: u64,
  rsp: u64,
  rbp: u64,
  rdi: u64,
  r12: u64,
  r13: u64,
  r14: u64,
  r15: u64,
  ip:  u64,
  xmm0: u64x2,
  xmm1: u64x2,
  xmm2: u64x2,
  xmm3: u64x2,
  xmm4: u64x2,
  xmm5: u64x2,
}

impl Registers {
  pub fn new() -> Registers {
    unsafe {
      Registers {
        ip: abort as uintptr_t,
        .. zeroed()
      }
    }
  }
}

pub fn initialise_call_frame(stack: &mut Stack, init: uintptr_t, args: &[uintptr_t]) -> Registers {
  let sp = stack.top() as *mut uintptr_t;
  let sp = align_down_mut(sp, 16);
  let sp = offset_mut(sp, -1);
  unsafe {
    *sp = 0;
  }

  let mut regs = Registers {
    rbp: 0,
    rsp: sp as uintptr_t,
    ip: bootstrap as uintptr_t,
    rbx: init,
    .. Registers::new()
  };

  match into_fields!(regs { rdi, r12, r13, r14, r15 } <- args.iter().cloned()) {
    Some(mut args) => if args.next().is_some() {
      panic!("too many arguments")
    },
    None => {}
  }

  regs
}

#[inline]
fn align_down_mut<T>(sp: *mut T, n: uint) -> *mut T {
  let sp = (sp as uint) & !(n - 1);
  sp as *mut T
}

// ptr::offset_mmut is positive ints only
#[inline]
pub fn offset_mut<T>(ptr: *mut T, count: int) -> *mut T {
  (ptr as int + count * (size_of::<T>() as int)) as *mut T
}
<|endoftext|>


<commit_before>use rustc::ty::{self, Ty};
use syntax::ast::{FloatTy, IntTy, UintTy};

use error::{EvalResult, EvalError};
use eval_context::EvalContext;
use value::PrimVal;

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    pub(super) fn cast_primval(
        &self,
        val: PrimVal,
        src_ty: Ty<'tcx>,
        dest_ty: Ty<'tcx>
    ) -> EvalResult<'tcx, PrimVal> {
        let kind = self.ty_to_primval_kind(src_ty)?;

        use value::PrimValKind::*;
        match kind {
            F32 => self.cast_float(val.to_f32()? as f64, dest_ty),
            F64 => self.cast_float(val.to_f64()?, dest_ty),

            I8 | I16 | I32 | I64 | I128 => {
                if val.is_ptr() {
                    self.cast_ptr(val, dest_ty)
                } else {
                    self.cast_signed_int(val.to_i128()?, dest_ty)
                }
            },

            Bool | Char | U8 | U16 | U32 | U64 | U128 => {
                if val.is_ptr() {
                    self.cast_ptr(val, dest_ty)
                } else {
                    self.cast_int(val.to_u128()?, dest_ty, false)
                }
            },

            FnPtr | Ptr => self.cast_ptr(val, dest_ty),
        }
    }

    fn cast_signed_int(&self, val: i128, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
        self.cast_int(val as u128, ty, val < 0)
    }

    fn cast_int(&self, v: u128, ty: ty::Ty<'tcx>, negative: bool) -> EvalResult<'tcx, PrimVal> {
        use rustc::ty::TypeVariants::*;
        match ty.sty {
            TyBool if v == 0 => Ok(PrimVal::from_bool(false)),
            TyBool if v == 1 => Ok(PrimVal::from_bool(true)),
            TyBool => Err(EvalError::InvalidBool),

            TyInt(IntTy::I8)  => Ok(PrimVal::Bytes(v as i128 as i8  as u128)),
            TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i128 as i16 as u128)),
            TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i128 as i32 as u128)),
            TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i128 as i64 as u128)),
            TyInt(IntTy::I128) => Ok(PrimVal::Bytes(v as u128)),

            TyUint(UintTy::U8)  => Ok(PrimVal::Bytes(v as u8  as u128)),
            TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u128)),
            TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u128)),
            TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v as u64 as u128)),
            TyUint(UintTy::U128) => Ok(PrimVal::Bytes(v)),

            TyInt(IntTy::Is) => {
                let int_ty = self.tcx.sess.target.int_type;
                let ty = self.tcx.mk_mach_int(int_ty);
                self.cast_int(v, ty, negative)
            }

            TyUint(UintTy::Us) => {
                let uint_ty = self.tcx.sess.target.uint_type;
                let ty = self.tcx.mk_mach_uint(uint_ty);
                self.cast_int(v, ty, negative)
            }

            TyFloat(FloatTy::F64) if negative => Ok(PrimVal::from_f64(v as i128 as f64)),
            TyFloat(FloatTy::F64)             => Ok(PrimVal::from_f64(v as f64)),
            TyFloat(FloatTy::F32) if negative => Ok(PrimVal::from_f32(v as i128 as f32)),
            TyFloat(FloatTy::F32)             => Ok(PrimVal::from_f32(v as f32)),

            TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)),
            TyChar => Err(EvalError::InvalidChar(v)),

            // No alignment check needed for raw pointers
            TyRawPtr(_) => Ok(PrimVal::Bytes(v % (1 << self.memory.pointer_size()))),

            _ => Err(EvalError::Unimplemented(format!("int to {:?} cast", ty))),
        }
    }

    fn cast_float(&self, val: f64, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
        use rustc::ty::TypeVariants::*;
        match ty.sty {
            // Casting negative floats to unsigned integers yields zero.
            TyUint(_) if val < 0.0 => self.cast_int(0, ty, false),
            TyInt(_)  if val < 0.0 => self.cast_int(val as i128 as u128, ty, true),

            TyInt(_) | ty::TyUint(_) => self.cast_int(val as u128, ty, false),

            TyFloat(FloatTy::F64) => Ok(PrimVal::from_f64(val)),
            TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(val as f32)),
            _ => Err(EvalError::Unimplemented(format!("float to {:?} cast", ty))),
        }
    }

    fn cast_ptr(&self, ptr: PrimVal, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
        use rustc::ty::TypeVariants::*;
        match ty.sty {
            // Casting to a reference or fn pointer is not permitted by rustc, no need to support it here.
            TyRawPtr(_) | TyInt(IntTy::Is) | TyUint(UintTy::Us) =>
                Ok(ptr),
            TyInt(_) | TyUint(_) => Err(EvalError::ReadPointerAsBytes),
            _ => Err(EvalError::Unimplemented(format!("ptr to {:?} cast", ty))),
        }
    }
}
<commit_msg>Don't pretend that casts to bool are a thing<commit_after>use rustc::ty::{self, Ty};
use syntax::ast::{FloatTy, IntTy, UintTy};

use error::{EvalResult, EvalError};
use eval_context::EvalContext;
use value::PrimVal;

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    pub(super) fn cast_primval(
        &self,
        val: PrimVal,
        src_ty: Ty<'tcx>,
        dest_ty: Ty<'tcx>
    ) -> EvalResult<'tcx, PrimVal> {
        let kind = self.ty_to_primval_kind(src_ty)?;

        use value::PrimValKind::*;
        match kind {
            F32 => self.cast_float(val.to_f32()? as f64, dest_ty),
            F64 => self.cast_float(val.to_f64()?, dest_ty),

            I8 | I16 | I32 | I64 | I128 => {
                if val.is_ptr() {
                    self.cast_ptr(val, dest_ty)
                } else {
                    self.cast_signed_int(val.to_i128()?, dest_ty)
                }
            },

            Bool | Char | U8 | U16 | U32 | U64 | U128 => {
                if val.is_ptr() {
                    self.cast_ptr(val, dest_ty)
                } else {
                    self.cast_int(val.to_u128()?, dest_ty, false)
                }
            },

            FnPtr | Ptr => self.cast_ptr(val, dest_ty),
        }
    }

    fn cast_signed_int(&self, val: i128, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
        self.cast_int(val as u128, ty, val < 0)
    }

    fn cast_int(&self, v: u128, ty: ty::Ty<'tcx>, negative: bool) -> EvalResult<'tcx, PrimVal> {
        use rustc::ty::TypeVariants::*;
        match ty.sty {
            // Casts to bool are not permitted by rustc, no need to handle them here.

            TyInt(IntTy::I8)  => Ok(PrimVal::Bytes(v as i128 as i8  as u128)),
            TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i128 as i16 as u128)),
            TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i128 as i32 as u128)),
            TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i128 as i64 as u128)),
            TyInt(IntTy::I128) => Ok(PrimVal::Bytes(v as u128)),

            TyUint(UintTy::U8)  => Ok(PrimVal::Bytes(v as u8  as u128)),
            TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u128)),
            TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u128)),
            TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v as u64 as u128)),
            TyUint(UintTy::U128) => Ok(PrimVal::Bytes(v)),

            TyInt(IntTy::Is) => {
                let int_ty = self.tcx.sess.target.int_type;
                let ty = self.tcx.mk_mach_int(int_ty);
                self.cast_int(v, ty, negative)
            }

            TyUint(UintTy::Us) => {
                let uint_ty = self.tcx.sess.target.uint_type;
                let ty = self.tcx.mk_mach_uint(uint_ty);
                self.cast_int(v, ty, negative)
            }

            TyFloat(FloatTy::F64) if negative => Ok(PrimVal::from_f64(v as i128 as f64)),
            TyFloat(FloatTy::F64)             => Ok(PrimVal::from_f64(v as f64)),
            TyFloat(FloatTy::F32) if negative => Ok(PrimVal::from_f32(v as i128 as f32)),
            TyFloat(FloatTy::F32)             => Ok(PrimVal::from_f32(v as f32)),

            TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)),
            TyChar => Err(EvalError::InvalidChar(v)),

            // No alignment check needed for raw pointers
            TyRawPtr(_) => Ok(PrimVal::Bytes(v % (1 << self.memory.pointer_size()))),

            _ => Err(EvalError::Unimplemented(format!("int to {:?} cast", ty))),
        }
    }

    fn cast_float(&self, val: f64, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
        use rustc::ty::TypeVariants::*;
        match ty.sty {
            // Casting negative floats to unsigned integers yields zero.
            TyUint(_) if val < 0.0 => self.cast_int(0, ty, false),
            TyInt(_)  if val < 0.0 => self.cast_int(val as i128 as u128, ty, true),

            TyInt(_) | ty::TyUint(_) => self.cast_int(val as u128, ty, false),

            TyFloat(FloatTy::F64) => Ok(PrimVal::from_f64(val)),
            TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(val as f32)),
            _ => Err(EvalError::Unimplemented(format!("float to {:?} cast", ty))),
        }
    }

    fn cast_ptr(&self, ptr: PrimVal, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
        use rustc::ty::TypeVariants::*;
        match ty.sty {
            // Casting to a reference or fn pointer is not permitted by rustc, no need to support it here.
            TyRawPtr(_) | TyInt(IntTy::Is) | TyUint(UintTy::Us) =>
                Ok(ptr),
            TyInt(_) | TyUint(_) => Err(EvalError::ReadPointerAsBytes),
            _ => Err(EvalError::Unimplemented(format!("ptr to {:?} cast", ty))),
        }
    }
}
<|endoftext|>


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

// Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/)

#![cfg(not(test))]
#![cfg(feature="cargo-fmt")]

extern crate getopts;
extern crate rustc_serialize;

use std::path::PathBuf;
use std::process::Command;
use std::env;
use std::str;

use getopts::Options;
use rustc_serialize::json::Json;

fn main() {
    let mut opts = getopts::Options::new();
    opts.optflag("h", "help", "show this message");

    let matches = match opts.parse(env::args().skip(1).take_while(|a| a != "--")) {
        Ok(m) => m,
        Err(e) => {
            print_usage(&opts, &e.to_string());
            return;
        }
    };

    if matches.opt_present("h") {
        print_usage(&opts, "");
    } else {
        format_crate(&opts);
    }
}

fn print_usage(opts: &Options, reason: &str) {
    let msg = format!("{}\nusage: cargo fmt [options]", reason);
    println!("{}\nThis utility formats all bin and lib files of the current crate using rustfmt. \
              Arguments after `--` are passed to rustfmt.",
             opts.usage(&msg));
}

fn format_crate(opts: &Options) {
    let targets = match get_targets() {
        Ok(t) => t,
        Err(e) => {
            print_usage(opts, &e.to_string());
            return;
        }
    };

    // Currently only bin and lib files get formatted
    let files: Vec<_> = targets.into_iter()
                               .filter(|t| t.kind.is_lib() | t.kind.is_bin())
                               .map(|t| t.path)
                               .collect();

    format_files(&files, &get_fmt_args()).unwrap_or_else(|e| print_usage(opts, &e.to_string()));
}

fn get_fmt_args() -> Vec<String> {
    // All arguments after -- are passed to rustfmt
    env::args().skip_while(|a| a != "--").skip(1).collect()
}

#[derive(Debug)]
enum TargetKind {
    Lib, // dylib, staticlib, lib
    Bin, // bin
    Other, // test, plugin,...
}

impl TargetKind {
    fn is_lib(&self) -> bool {
        match self {
            &TargetKind::Lib => true,
            _ => false,
        }
    }

    fn is_bin(&self) -> bool {
        match self {
            &TargetKind::Bin => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
struct Target {
    path: PathBuf,
    kind: TargetKind,
}

// Returns a vector of all compile targets of a crate
fn get_targets() -> Result<Vec<Target>, std::io::Error> {
    let mut targets: Vec<Target> = vec![];
    let output = try!(Command::new("cargo").arg("read-manifest").output());
    if output.status.success() {
        // None of the unwraps should fail if output of `cargo read-manifest` is correct
        let data = &String::from_utf8(output.stdout).unwrap();
        let json = Json::from_str(data).unwrap();
        let jtargets = json.find("targets").unwrap().as_array().unwrap();
        for jtarget in jtargets {
            targets.push(target_from_json(jtarget));
        }

        Ok(targets)
    } else {
        // This happens when cargo-fmt is not used inside a crate
        Err(std::io::Error::new(std::io::ErrorKind::NotFound,
                                str::from_utf8(&output.stderr).unwrap()))
    }
}

fn target_from_json(jtarget: &Json) -> Target {
    let jtarget = jtarget.as_object().unwrap();
    let path = PathBuf::from(jtarget.get("src_path").unwrap().as_string().unwrap());
    let kinds = jtarget.get("kind").unwrap().as_array().unwrap();
    let kind = match kinds[0].as_string().unwrap() {
        "bin" => TargetKind::Bin,
        "lib" | "dylib" | "staticlib" => TargetKind::Lib,
        _ => TargetKind::Other,
    };

    Target {
        path: path,
        kind: kind,
    }
}

fn format_files(files: &Vec<PathBuf>, fmt_args: &Vec<String>) -> Result<(), std::io::Error> {
    let mut command = try!(Command::new("rustfmt")
                               .args(files)
                               .args(fmt_args)
                               .spawn());
    try!(command.wait());

    Ok(())
}
<commit_msg>Add verbose and quiet flags to cargo-fmt<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/)

#![cfg(not(test))]
#![cfg(feature="cargo-fmt")]

extern crate getopts;
extern crate rustc_serialize;

use std::path::PathBuf;
use std::process::Command;
use std::env;
use std::str;

use getopts::Options;
use rustc_serialize::json::Json;

fn main() {
    let mut opts = getopts::Options::new();
    opts.optflag("h", "help", "show this message");
    opts.optflag("q", "quiet", "no output printed to stdout");
    opts.optflag("v", "verbose", "use verbose output");

    let matches = match opts.parse(env::args().skip(1).take_while(|a| a != "--")) {
        Ok(m) => m,
        Err(e) => {
            print_usage(&opts, &e.to_string());
            return;
        }
    };

    let (verbose, quiet) = (matches.opt_present("v"), matches.opt_present("q"));

    if verbose && quiet {
        print_usage(&opts, "quiet mode and verbose mode are not compatible");
        return;
    }

    if matches.opt_present("h") {
        print_usage(&opts, "");
    } else {
        format_crate(&opts, verbose, quiet);
    }
}

fn print_usage(opts: &Options, reason: &str) {
    let msg = format!("{}\nusage: cargo fmt [options]", reason);
    println!("{}\nThis utility formats all bin and lib files of the current crate using rustfmt. \
              Arguments after `--` are passed to rustfmt.",
             opts.usage(&msg));
}

fn format_crate(opts: &Options, verbose: bool, quiet: bool) {
    let targets = match get_targets() {
        Ok(t) => t,
        Err(e) => {
            print_usage(opts, &e.to_string());
            return;
        }
    };

    // Currently only bin and lib files get formatted
    let files: Vec<_> = targets.into_iter()
                               .filter(|t| t.kind.is_lib() | t.kind.is_bin())
                               .inspect(|t| {
                                   if verbose {
                                       println!("[{:?}] {:?}", t.kind, t.path)
                                   }
                               })
                               .map(|t| t.path)
                               .collect();

    format_files(&files, &get_fmt_args(), verbose, quiet)
        .unwrap_or_else(|e| print_usage(opts, &e.to_string()));
}

fn get_fmt_args() -> Vec<String> {
    // All arguments after -- are passed to rustfmt
    env::args().skip_while(|a| a != "--").skip(1).collect()
}

#[derive(Debug)]
enum TargetKind {
    Lib, // dylib, staticlib, lib
    Bin, // bin
    Other, // test, plugin,...
}

impl TargetKind {
    fn is_lib(&self) -> bool {
        match self {
            &TargetKind::Lib => true,
            _ => false,
        }
    }

    fn is_bin(&self) -> bool {
        match self {
            &TargetKind::Bin => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub struct Target {
    path: PathBuf,
    kind: TargetKind,
}

// Returns a vector of all compile targets of a crate
fn get_targets() -> Result<Vec<Target>, std::io::Error> {
    let mut targets: Vec<Target> = vec![];
    let output = try!(Command::new("cargo").arg("read-manifest").output());
    if output.status.success() {
        // None of the unwraps should fail if output of `cargo read-manifest` is correct
        let data = &String::from_utf8(output.stdout).unwrap();
        let json = Json::from_str(data).unwrap();
        let jtargets = json.find("targets").unwrap().as_array().unwrap();
        for jtarget in jtargets {
            targets.push(target_from_json(jtarget));
        }

        Ok(targets)
    } else {
        // This happens when cargo-fmt is not used inside a crate
        Err(std::io::Error::new(std::io::ErrorKind::NotFound,
                                str::from_utf8(&output.stderr).unwrap()))
    }
}

fn target_from_json(jtarget: &Json) -> Target {
    let jtarget = jtarget.as_object().unwrap();
    let path = PathBuf::from(jtarget.get("src_path").unwrap().as_string().unwrap());
    let kinds = jtarget.get("kind").unwrap().as_array().unwrap();
    let kind = match kinds[0].as_string().unwrap() {
        "bin" => TargetKind::Bin,
        "lib" | "dylib" | "staticlib" => TargetKind::Lib,
        _ => TargetKind::Other,
    };

    Target {
        path: path,
        kind: kind,
    }
}

fn format_files(files: &Vec<PathBuf>,
                fmt_args: &Vec<String>,
                verbose: bool,
                quiet: bool)
                -> Result<(), std::io::Error> {
    let stdout = if quiet {
        std::process::Stdio::null()
    } else {
        std::process::Stdio::inherit()
    };
    if verbose {
        print!("rustfmt");
        for a in fmt_args.iter() {
            print!(" {}", a);
        }
        for f in files.iter() {
            print!(" {}", f.display());
        }
        println!("");
    }
    let mut command = try!(Command::new("rustfmt")
                               .stdout(stdout)
                               .args(files)
                               .args(fmt_args)
                               .spawn());
    try!(command.wait());

    Ok(())
}
<|endoftext|>


<commit_before>extern crate tempdir;
extern crate hyper;
extern crate grnenvlib;
extern crate clap;

use clap::{Arg, App, SubCommand};
use grnenvlib::command;

fn main() {
    default_main();
}

fn cli() -> App<'static, 'static> {
    App::new("grnenv-rs")
        .version("0.1.0")
        .author("Hiroshi Hatake <cosmo0920.wp@gmail.com>")
        .about("A tiny tool for obtain and select multiple Groonga.")
        .subcommand(SubCommand::with_name("init").about("Prepare grnenv-rs."))
        .subcommand(SubCommand::with_name("install")
            .about("Install a given Groonga version and arch")
            .arg(Arg::with_name("VERSION").required(true))
            .arg(Arg::with_name("arch")
                .short("a")
                .long("arch")
                .value_name("ARCH")
                .help("Select architectures. e.g.) x86, x64")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("switch")
            .about("Switch Groonga with given version and arch")
            .arg(Arg::with_name("VERSION").required(true))
            .arg(Arg::with_name("arch")
                .short("a")
                .long("arch")
                .value_name("ARCH")
                .help("Select architectures. e.g.) x86, x64")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("versions").about("Display installed Groonga versions"))
        .subcommand(SubCommand::with_name("uninstall")
            .about("Uninstall a given Groonga version and arch")
            .arg(Arg::with_name("VERSION").required(true))
            .arg(Arg::with_name("arch")
                .short("a")
                .long("arch")
                .value_name("ARCH")
                .help("Select architectures. e.g.) x86, x64")
                .takes_value(true)))
}

#[cfg(not(windows))]
fn default_main() {
    let matches = cli().get_matches();
    match matches.subcommand() {
        ("init", _) => command::unix::init(),
        ("install", Some(m)) => command::unix::install(m),
        ("switch", Some(m)) => command::unix::switch(m),
        ("versions", _) => command::common::versions(),
        ("uninstall", Some(m)) => command::unix::uninstall(m),
        (_, _) => unreachable!(),
    }
}

#[cfg(windows)]
fn default_main() {
    let matches = cli().get_matches();
    match matches.subcommand() {
        ("init", _) => command::windows::init(),
        ("install", Some(m)) => command::windows::install(m),
        ("switch", Some(m)) => command::windows::switch(m),
        ("versions", _) => command::common::versions(),
        ("uninstall", Some(m)) => command::windows::uninstall(m),
        (_, _) => unreachable!(),
    }
}
<commit_msg>bin: Obtain crate metadata with macro<commit_after>extern crate tempdir;
extern crate hyper;
extern crate grnenvlib;
#[macro_use]
extern crate clap;

use clap::{Arg, App, SubCommand};
use grnenvlib::command;

fn main() {
    default_main();
}

fn cli() -> App<'static, 'static> {
    App::new("grnenv-rs")
        .version(crate_version!())
        .author(crate_authors!())
        .about("A tiny tool for obtain and select multiple Groonga.")
        .subcommand(SubCommand::with_name("init").about("Prepare grnenv-rs."))
        .subcommand(SubCommand::with_name("install")
            .about("Install a given Groonga version and arch")
            .arg(Arg::with_name("VERSION").required(true))
            .arg(Arg::with_name("arch")
                .short("a")
                .long("arch")
                .value_name("ARCH")
                .help("Select architectures. e.g.) x86, x64")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("switch")
            .about("Switch Groonga with given version and arch")
            .arg(Arg::with_name("VERSION").required(true))
            .arg(Arg::with_name("arch")
                .short("a")
                .long("arch")
                .value_name("ARCH")
                .help("Select architectures. e.g.) x86, x64")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("versions").about("Display installed Groonga versions"))
        .subcommand(SubCommand::with_name("uninstall")
            .about("Uninstall a given Groonga version and arch")
            .arg(Arg::with_name("VERSION").required(true))
            .arg(Arg::with_name("arch")
                .short("a")
                .long("arch")
                .value_name("ARCH")
                .help("Select architectures. e.g.) x86, x64")
                .takes_value(true)))
}

#[cfg(not(windows))]
fn default_main() {
    let matches = cli().get_matches();
    match matches.subcommand() {
        ("init", _) => command::unix::init(),
        ("install", Some(m)) => command::unix::install(m),
        ("switch", Some(m)) => command::unix::switch(m),
        ("versions", _) => command::common::versions(),
        ("uninstall", Some(m)) => command::unix::uninstall(m),
        (_, _) => unreachable!(),
    }
}

#[cfg(windows)]
fn default_main() {
    let matches = cli().get_matches();
    match matches.subcommand() {
        ("init", _) => command::windows::init(),
        ("install", Some(m)) => command::windows::install(m),
        ("switch", Some(m)) => command::windows::switch(m),
        ("versions", _) => command::common::versions(),
        ("uninstall", Some(m)) => command::windows::uninstall(m),
        (_, _) => unreachable!(),
    }
}
<|endoftext|>


<commit_before>extern crate rpizw_rover;
#[macro_use]
extern crate clap;

use rpizw_rover::error::*;

const PWM_CHIP: u32 = 0;
const LEFT_PWM: u32 = 0;
const RIGHT_PWM: u32 = 1;

fn run() -> Result<()> {
    use clap::App;
    use rpizw_rover::Rover;

    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).version(crate_version!()).get_matches();

    let rover = Rover::new(PWM_CHIP, LEFT_PWM, RIGHT_PWM)?;

    if let Some(_) = matches.subcommand_matches("disable") {
        rover.enable(false)
    } else if let Some(_) = matches.subcommand_matches("enable") {
        rover.enable(true)
    } else if let Some(_) = matches.subcommand_matches("stop") {
        rover.stop()
    } else if let Some(matches) = matches.subcommand_matches("speed") {
        let left = matches.value_of("LEFT").unwrap();
        let right = matches.value_of("RIGHT").unwrap_or(left);
        let left: i8 = left.parse::<i8>().chain_err(|| "failed to parse left speed")?;
        let right: i8 = right.parse::<i8>().chain_err(|| "failed to parse right speed")?;

        rover.set_speed(left, right)?;
        if !matches.is_present("dont-enable") {
            rover.enable(true)?;
        }
        Ok(())

    } else if let Some(_) = matches.subcommand_matches("unexport") {
        rover.unexport()
    } else {
        println!("{}", matches.usage());
        Ok(())
    }
}

fn main() {
    if let Err(ref e) = run() {
        use std::io::Write;
        let stderr = &mut ::std::io::stderr();
        let errmsg = "Error writing to stderr";

        writeln!(stderr, "error: {}", e).expect(errmsg);

        for e in e.iter().skip(1) {
            writeln!(stderr, "caused by: {}", e).expect(errmsg);
        }

        if let Some(backtrace) = e.backtrace() {
            writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
        }

        ::std::process::exit(1);
    }
}
<commit_msg>Refactors the cli tool<commit_after>extern crate rpizw_rover;
#[macro_use]
extern crate clap;

use rpizw_rover::error::*;

const PWM_CHIP: u32 = 0;
const LEFT_PWM: u32 = 0;
const RIGHT_PWM: u32 = 1;

fn run() -> Result<()> {
    use clap::App;
    use rpizw_rover::Rover;

    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).version(crate_version!()).get_matches();

    let rover = Rover::new(PWM_CHIP, LEFT_PWM, RIGHT_PWM)?;
    rover.export()?;

    if let Some(_) = matches.subcommand_matches("disable") {
        rover.enable(false)
    } else if let Some(_) = matches.subcommand_matches("enable") {
        rover.enable(true)
    } else if let Some(_) = matches.subcommand_matches("stop") {
        rover.stop()
    } else if let Some(matches) = matches.subcommand_matches("speed") {
        let left = matches.value_of("LEFT").unwrap();
        let right = matches.value_of("RIGHT").unwrap_or(left);
        let left: i8 = left.parse::<i8>().chain_err(|| "failed to parse left speed")?;
        let right: i8 = right.parse::<i8>().chain_err(|| "failed to parse right speed")?;

        rover.set_speed(left, right)?;
        if !matches.is_present("dont-enable") {
            rover.enable(true)?;
        }
        Ok(())

    } else if let Some(_) = matches.subcommand_matches("unexport") {
        rover.enable(false)?;
        rover.unexport()
    } else {
        println!("{}", matches.usage());
        Ok(())
    }
}

fn main() {
    if let Err(ref e) = run() {
        use std::io::Write;
        let stderr = &mut ::std::io::stderr();
        let errmsg = "Error writing to stderr";

        writeln!(stderr, "error: {}", e).expect(errmsg);

        for e in e.iter().skip(1) {
            writeln!(stderr, "caused by: {}", e).expect(errmsg);
        }

        if let Some(backtrace) = e.backtrace() {
            writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
        }

        ::std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

/// The start and end of contiguous range of lines. The range is contained within
/// `start..end`
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct LineRange {
    /// Start of the line range (inclusive)
    start: usize,
    /// End of the line range (exclusive)
    end: usize,
}

impl LineRange {
    /// Returns true if the line is contained within the line range
    pub fn contains(&self, line: usize) -> bool {
        line >= self.start && line < self.end
    }
}

/// Represents possible branches through an execution
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Branches {
    /// Line ranges for each branch
    ranges: Vec<LineRange>,
    /// Whether there is an implicit or empty default branch i.e. missing or empty `else` in an
    /// `if` statement
    implicit_default: bool,
}

/// Coverage context for all the branches
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BranchAnalysis {
    /// Each key is `LineRange` showing a region of the code containing a set of branches with the
    /// value being a `LineRange` for each branch in the code
    /// TODO consider BTreeMap then can order on line range start
    branches: HashMap<LineRange, Branches>,
}

impl BranchAnalysis {
    /// Returns true if the line is part of a branch
    pub fn is_branch(&self, line: usize) -> bool {
        self.branches.iter().any(|(k, _)| k.contains(line))
    }
}
<commit_msg>Added branch context for all files<commit_after>use std::collections::{BTreeMap, HashMap};
use std::path::{Path, PathBuf};

#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BranchContext {
    files: HashMap<PathBuf, BranchAnalysis>,
}

impl BranchContext {
    pub fn is_branch<P: AsRef<Path>>(&self, path: P, line: usize) -> bool {
        if let Some(file) = self.files.get(path.as_ref()) {
            file.is_branch(line)
        } else {
            false
        }
    }
}

/// Coverage context for all the branches
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BranchAnalysis {
    /// Each key is `LineRange` showing a region of the code containing a set of branches with the
    /// value being a `LineRange` for each branch in the code
    /// TODO consider BTreeMap then can order on line range start
    branches: BTreeMap<LineRange, Branches>,
}

impl BranchAnalysis {
    /// Returns true if the line is part of a branch
    pub fn is_branch(&self, line: usize) -> bool {
        self.branches.iter().any(|(k, _)| k.contains(line))
    }
}

/// Represents possible branches through an execution
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Branches {
    /// Line ranges for each branch
    ranges: Vec<LineRange>,
    /// Whether there is an implicit or empty default branch i.e. missing or empty `else` in an
    /// `if` statement
    implicit_default: bool,
}

/// The start and end of contiguous range of lines. The range is contained within
/// `start..end`
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct LineRange {
    /// Start of the line range (inclusive)
    start: usize,
    /// End of the line range (exclusive)
    end: usize,
}

impl LineRange {
    /// Returns true if the line is contained within the line range
    pub fn contains(&self, line: usize) -> bool {
        line >= self.start && line < self.end
    }
}
<|endoftext|>


<commit_before>use cassandra_sys::CassIterator as _CassIterator;
use cassandra_sys::cass_iterator_free;
use cassandra_sys::cass_iterator_next;
use cassandra_sys::cass_iterator_get_column;
use cassandra_sys::CassRow as _Row;
use cassandra_sys::cass_row_get_column;
use cassandra_sys::cass_row_get_column_by_name;
use cassandra_sys::cass_iterator_from_row;
use cassandra_sys::CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS;
use cassandra::util::Protected;
use cassandra::value::Value;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt;
use std::ffi::CString;
use std::iter::IntoIterator;
use std::iter;
use cassandra_sys::cass_true;
use cassandra_sys::cass_false;

use cassandra::error::CassError;
use cassandra::column::Column;

///A collection of column values.
pub struct Row(*const _Row);

impl Protected<*const _Row> for Row {
    fn inner(&self) -> *const _Row {
        self.0
    }
    fn build(inner: *const _Row) -> Self {
        Row(inner)
    }
}

impl Debug for Row {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        for column in self {
            try!(write!(f, "{:?}\t", Value::build(column.inner())));
        }
        Ok(())
    }
}

impl Display for Row {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        for column in self {
            try!(write!(f, "{}\t", Value::build(column.inner())));
        }
        Ok(())
    }
}

///Auto inferencing conversion from c* to rust
pub trait AsRustType<T> {
    ///convert while reading cassandra columns
    fn get_col(&self, index: usize) -> Result<T, CassError>;

    ///convert while reading cassandra columns by name
    fn get_col_by_name<S>(&self, name: S) -> Result<T, CassError>
        where S: Into<String>;
}

impl AsRustType<bool> for Row {
    fn get_col(&self, index: usize) -> Result<bool, CassError> {
        let col = try!(self.get_column(index));
        col.get_bool()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<bool, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_bool()
    }
}

impl AsRustType<String> for Row {
    fn get_col(&self, index: usize) -> Result<String, CassError> {
        let col = try!(self.get_column(index));
        col.get_string()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<String, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_string()
    }
}

impl AsRustType<f64> for Row {
    fn get_col(&self, index: usize) -> Result<f64, CassError> {
        let col = try!(self.get_column(index));
        col.get_double()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<f64, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_double()
    }
}

impl AsRustType<f32> for Row {
    fn get_col(&self, index: usize) -> Result<f32, CassError> {
        let col = try!(self.get_column(index));
        col.get_float()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<f32, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_float()
    }
}

impl AsRustType<i64> for Row {
    fn get_col(&self, index: usize) -> Result<i64, CassError> {
        let col = try!(self.get_column(index));
        col.get_i64()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<i64, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_i64()
    }
}

impl AsRustType<i32> for Row {
    fn get_col(&self, index: usize) -> Result<i32, CassError> {
        let col = try!(self.get_column(index));
        col.get_i32()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<i32, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_i32()
    }
}

impl Row {
    ///Get a particular column by index
    pub fn get_column(&self, index: usize) -> Result<Column, CassError> {
        unsafe {
            let col = cass_row_get_column(self.0, index);
            if col.is_null() {
                Err(CassError::build(CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS))
            } else {
                Ok(Column::build(col))
            }
        }
    }

    ///Get a particular column by name
    pub fn get_column_by_name<S>(&self, name: S) -> Result<Column, CassError>
        where S: Into<String> {
        unsafe {
            let col = cass_row_get_column_by_name(self.0,
                                                  CString::new(name.into()).expect("must be utf8").as_ptr());
            if col.is_null() {
                Err(CassError::build(CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS))
            } else {
                Ok(Column::build(col))
            }
        }
    }
}

///An iterator over the columns in a row
pub struct RowIterator(pub *mut _CassIterator);

impl Drop for RowIterator {
    fn drop(&mut self) {
        unsafe { cass_iterator_free(self.0) }
    }
}

impl iter::Iterator for RowIterator {
    type Item = Column;

    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
        unsafe {
            match cass_iterator_next(self.0) {
                cass_false => None,
                cass_true => Some(Column::build(cass_iterator_get_column(self.0))),
            }
        }
    }
}

impl<'a> Iterator for &'a RowIterator {
    type Item = Column;

    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
        unsafe {
            match cass_iterator_next(self.0) {
                cass_false => None,
                cass_true => Some(Column::build(cass_iterator_get_column(self.0))),
            }
        }
    }
}

impl Display for RowIterator {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        for item in self {
            try!(write!(f, "{}\t", Value::build(item.inner())));
        }
        Ok(())
    }
}

impl IntoIterator for Row {
    type Item = Column;
    type IntoIter = RowIterator;

    ///Creates a new iterator for the specified row. This can be
    ///used to iterate over columns in a row.
    fn into_iter(self) -> Self::IntoIter {
        unsafe { RowIterator(cass_iterator_from_row(self.0)) }
    }
}

impl<'a> IntoIterator for &'a Row {
    type Item = Column;
    type IntoIter = RowIterator;
    fn into_iter(self) -> Self::IntoIter {
        unsafe { RowIterator(cass_iterator_from_row(self.0)) }
    }
}
<commit_msg>Implement AsRustType for Set and Map iterators<commit_after>use cassandra_sys::CassIterator as _CassIterator;
use cassandra_sys::cass_iterator_free;
use cassandra_sys::cass_iterator_next;
use cassandra_sys::cass_iterator_get_column;
use cassandra_sys::CassRow as _Row;
use cassandra_sys::cass_row_get_column;
use cassandra_sys::cass_row_get_column_by_name;
use cassandra_sys::cass_iterator_from_row;
use cassandra_sys::CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS;
use cassandra::util::Protected;
use cassandra::value::Value;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt;
use std::ffi::CString;
use std::iter::IntoIterator;
use std::iter;
use cassandra_sys::cass_true;
use cassandra_sys::cass_false;

use cassandra::error::CassError;
use cassandra::column::Column;
use cassandra::iterator::{SetIterator, MapIterator};

///A collection of column values.
pub struct Row(*const _Row);

impl Protected<*const _Row> for Row {
    fn inner(&self) -> *const _Row {
        self.0
    }
    fn build(inner: *const _Row) -> Self {
        Row(inner)
    }
}

impl Debug for Row {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        for column in self {
            try!(write!(f, "{:?}\t", Value::build(column.inner())));
        }
        Ok(())
    }
}

impl Display for Row {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        for column in self {
            try!(write!(f, "{}\t", Value::build(column.inner())));
        }
        Ok(())
    }
}

///Auto inferencing conversion from c* to rust
pub trait AsRustType<T> {
    ///convert while reading cassandra columns
    fn get_col(&self, index: usize) -> Result<T, CassError>;

    ///convert while reading cassandra columns by name
    fn get_col_by_name<S>(&self, name: S) -> Result<T, CassError>
        where S: Into<String>;
}

impl AsRustType<bool> for Row {
    fn get_col(&self, index: usize) -> Result<bool, CassError> {
        let col = try!(self.get_column(index));
        col.get_bool()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<bool, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_bool()
    }
}

impl AsRustType<String> for Row {
    fn get_col(&self, index: usize) -> Result<String, CassError> {
        let col = try!(self.get_column(index));
        col.get_string()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<String, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_string()
    }
}

impl AsRustType<f64> for Row {
    fn get_col(&self, index: usize) -> Result<f64, CassError> {
        let col = try!(self.get_column(index));
        col.get_double()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<f64, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_double()
    }
}

impl AsRustType<f32> for Row {
    fn get_col(&self, index: usize) -> Result<f32, CassError> {
        let col = try!(self.get_column(index));
        col.get_float()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<f32, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_float()
    }
}

impl AsRustType<i64> for Row {
    fn get_col(&self, index: usize) -> Result<i64, CassError> {
        let col = try!(self.get_column(index));
        col.get_i64()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<i64, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_i64()
    }
}

impl AsRustType<i32> for Row {
    fn get_col(&self, index: usize) -> Result<i32, CassError> {
        let col = try!(self.get_column(index));
        col.get_i32()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<i32, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.get_i32()
    }
}

impl AsRustType<SetIterator> for Row {
    fn get_col(&self, index: usize) -> Result<SetIterator, CassError> {
        let col = try!(self.get_column(index));
        col.set_iter()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<SetIterator, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.set_iter()
    }
}

impl AsRustType<MapIterator> for Row {
    fn get_col(&self, index: usize) -> Result<MapIterator, CassError> {
        let col = try!(self.get_column(index));
        col.map_iter()
    }

    fn get_col_by_name<S>(&self, name: S) -> Result<MapIterator, CassError>
        where S: Into<String> {
        let col = try!(self.get_column_by_name(name));
        col.map_iter()
    }
}

impl Row {
    ///Get a particular column by index
    pub fn get_column(&self, index: usize) -> Result<Column, CassError> {
        unsafe {
            let col = cass_row_get_column(self.0, index);
            if col.is_null() {
                Err(CassError::build(CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS))
            } else {
                Ok(Column::build(col))
            }
        }
    }

    ///Get a particular column by name
    pub fn get_column_by_name<S>(&self, name: S) -> Result<Column, CassError>
        where S: Into<String> {
        unsafe {
            let col = cass_row_get_column_by_name(self.0,
                                                  CString::new(name.into()).expect("must be utf8").as_ptr());
            if col.is_null() {
                Err(CassError::build(CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS))
            } else {
                Ok(Column::build(col))
            }
        }
    }
}

///An iterator over the columns in a row
pub struct RowIterator(pub *mut _CassIterator);

impl Drop for RowIterator {
    fn drop(&mut self) {
        unsafe { cass_iterator_free(self.0) }
    }
}

impl iter::Iterator for RowIterator {
    type Item = Column;

    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
        unsafe {
            match cass_iterator_next(self.0) {
                cass_false => None,
                cass_true => Some(Column::build(cass_iterator_get_column(self.0))),
            }
        }
    }
}

impl<'a> Iterator for &'a RowIterator {
    type Item = Column;

    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
        unsafe {
            match cass_iterator_next(self.0) {
                cass_false => None,
                cass_true => Some(Column::build(cass_iterator_get_column(self.0))),
            }
        }
    }
}

impl Display for RowIterator {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        for item in self {
            try!(write!(f, "{}\t", Value::build(item.inner())));
        }
        Ok(())
    }
}

impl IntoIterator for Row {
    type Item = Column;
    type IntoIter = RowIterator;

    ///Creates a new iterator for the specified row. This can be
    ///used to iterate over columns in a row.
    fn into_iter(self) -> Self::IntoIter {
        unsafe { RowIterator(cass_iterator_from_row(self.0)) }
    }
}

impl<'a> IntoIterator for &'a Row {
    type Item = Column;
    type IntoIter = RowIterator;
    fn into_iter(self) -> Self::IntoIter {
        unsafe { RowIterator(cass_iterator_from_row(self.0)) }
    }
}
<|endoftext|>


<commit_before>#![feature(collections, plugin)]

#[plugin]
#[no_link]
extern crate json_macros;

extern crate "rustc-serialize" as rustc_serialize;

use rustc_serialize::Encodable;
use rustc_serialize::json::{self, Encoder};

#[derive(RustcDecodable, RustcEncodable)]
struct Photo {
    url: String,
    dimensions: (u32, u32),
}

#[derive(RustcDecodable, RustcEncodable)]
struct User {
    name: String,
    post_count: u32,
    likes_burgers: bool,
    avatar: Option<Photo>,
}

fn main() {
    println!("24 days of Rust - json (day 6)");
    println!("{:?}", json::encode(&42));
    println!("{:?}", json::encode(&vec!["to", "be", "or", "not", "to", "be"]));
    println!("{:?}", json::encode(&Some(true)));
    let user = User {
        name: "Zbyszek".to_string(),
        post_count: 100u32,
        likes_burgers: true,
        avatar: Some(Photo {
            url: "http://lorempixel.com/160/160/".to_string(),
            dimensions: (160u32, 160u32),
        }),
    };
    println!("{:?}", json::encode(&user));
    let mut buffer: Vec<u8> = Vec::new();
    {
        let mut encoder = Encoder::new_pretty(&mut buffer);
        user.encode(&mut encoder).ok().expect("JSON encode error");
    }
    let encoded = String::from_utf8(buffer).unwrap();
    println!("{}", encoded);
    let incoming_request = "{\"name\":\"John\",\"post_count\":2,\"likes_burgers\":false,\"avatar\":null}";
    let decoded: User = json::decode(incoming_request).unwrap();
    println!("My name is {} and I {} burgers",
        decoded.name, if decoded.likes_burgers { "love" } else { "don't like" });
    assert!(decoded.avatar.is_none());
    let new_request = "{\"id\":64,\"title\":\"24days\",\"stats\":{\"pageviews\":1500}}";
    if let Ok(request_json) = json::Json::from_str(new_request) {
        if let Some(ref stats) = request_json.find("stats") {
            if let Some(ref pageviews) = stats.find("pageviews") {
                println!("Pageviews: {}", pageviews);
            }
        }
    }
    let config = json!({
        "hostname": "localhost",
        "port": 6543,
        "allowed_methods": ["get", "post"],
        "limits": {
            "bandwidth": (500 * 16),
            "rate": null
        }
    });
    println!("Configuration: {}", config);
    println!("Bandwidth: {}", config.search("bandwidth").unwrap());
}
<commit_msg>Fixed day6.<commit_after>#![feature(collections, plugin)]

#[plugin]
#[no_link]
extern crate json_macros;

extern crate "rustc-serialize" as rustc_serialize;

use rustc_serialize::Encodable;
use rustc_serialize::json::{self, Encoder};

#[derive(RustcDecodable, RustcEncodable)]
struct Photo {
    url: String,
    dimensions: (u32, u32),
}

#[derive(RustcDecodable, RustcEncodable)]
struct User {
    name: String,
    post_count: u32,
    likes_burgers: bool,
    avatar: Option<Photo>,
}

fn main() {
    println!("24 days of Rust - json (day 6)");
    println!("{:?}", json::encode(&42));
    println!("{:?}", json::encode(&vec!["to", "be", "or", "not", "to", "be"]));
    println!("{:?}", json::encode(&Some(true)));
    let user = User {
        name: "Zbyszek".to_string(),
        post_count: 100u32,
        likes_burgers: true,
        avatar: Some(Photo {
            url: "http://lorempixel.com/160/160/".to_string(),
            dimensions: (160u32, 160u32),
        }),
    };
    println!("{:?}", json::encode(&user));
    let mut encoded = String::new();
    {
        let mut encoder = Encoder::new_pretty(&mut encoded);
        user.encode(&mut encoder).ok().expect("JSON encode error");
    }
    println!("{}", encoded);
    let incoming_request = "{\"name\":\"John\",\"post_count\":2,\"likes_burgers\":false,\"avatar\":null}";
    let decoded: User = json::decode(incoming_request).unwrap();
    println!("My name is {} and I {} burgers",
        decoded.name, if decoded.likes_burgers { "love" } else { "don't like" });
    assert!(decoded.avatar.is_none());
    let new_request = "{\"id\":64,\"title\":\"24days\",\"stats\":{\"pageviews\":1500}}";
    if let Ok(request_json) = json::Json::from_str(new_request) {
        if let Some(ref stats) = request_json.find("stats") {
            if let Some(ref pageviews) = stats.find("pageviews") {
                println!("Pageviews: {}", pageviews);
            }
        }
    }
    let config = json!({
        "hostname": "localhost",
        "port": 6543,
        "allowed_methods": ["get", "post"],
        "limits": {
            "bandwidth": (500 * 16),
            "rate": null
        }
    });
    println!("Configuration: {}", config);
    println!("Bandwidth: {}", config.search("bandwidth").unwrap());
}
<|endoftext|>


<commit_before>use std::fmt;
use std::ops::Index;

/// Dim4 is used to store [Array](./struct.Array.html) dimensions
#[derive(Copy, Clone)]
pub struct Dim4 {
    dims: [u64; 4],
}

/// Default trait for Dim4 returns an Array of dimensions [1, 1, 1, 1]
impl Default for Dim4 {
    fn default() -> Dim4 {
        Dim4 { dims:[1, 1, 1, 1] }
    }
}

/// Enables index operation for Dim4
///
/// # Examples
///
/// ```
/// use arrayfire::Dim4;
///
/// let dims = Dim4::new(&[4, 4, 2, 1]);
/// println!("0th Dimension length is {}", dims[0]); // -> 4
/// println!("1th Dimension length is {}", dims[1]); // -> 4
/// println!("2th Dimension length is {}", dims[2]); // -> 2
/// println!("3th Dimension length is {}", dims[3]); // -> 1
/// ```
impl Index<usize> for Dim4 {
    type Output = u64;

    fn index<'a>(&'a self, _index: usize) ->&'a u64 {
        &self.dims[_index]
    }
}

/// Enables use of Dim4 objects for printing it to display
///
/// # Examples
///
/// ```
/// use arrayfire::Dim4;
///
/// let dims = Dim4::new(&[4, 4, 2, 1]);
/// println!("0th Dimension length is {}", dims[0]); // -> 4
/// ```
impl fmt::Display for Dim4 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{} {} {} {}]", self.dims[0], self.dims[1], self.dims[2], self.dims[3])
    }
}

impl Dim4 {
    /// Create Dim4 object
    ///
    /// # Examples
    ///
    /// ```
    /// use arrayfire::Dim4;
    /// let dims = Dim4::new(&[4, 4, 2, 1]);
    /// ```
    pub fn new(dims: &[u64; 4]) -> Dim4 {
        Dim4 { dims: dims.clone(), }
    }

    /// Get the number of elements represented by Dim4 object
    pub fn elements(&self) -> u64 {
        self.dims[0]*self.dims[1]*self.dims[2]*self.dims[3]
    }

    /// Get the number of dimensions of Dim4
    pub fn ndims(&self) -> usize {
        let nelems = self.elements();
        match nelems {
            0 => 0,
            1 => 1,
            _ => {
                if self.dims[3] != 1 { 4 }
                else if self.dims[2] != 1 { 3 }
                else if self.dims[1] != 1 { 2 }
                else { 1 }
            },
        }
    }

    // Get the dimensions as a slice of 4 values
    pub fn get(&self) -> &[u64; 4] {
        &self.dims
    }
}
<commit_msg>Add support for partialeq & debug to dim4<commit_after>use std::fmt;
use std::ops::Index;

/// Dim4 is used to store [Array](./struct.Array.html) dimensions
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Dim4 {
    dims: [u64; 4],
}

/// Default trait for Dim4 returns an Array of dimensions [1, 1, 1, 1]
impl Default for Dim4 {
    fn default() -> Dim4 {
        Dim4 { dims:[1, 1, 1, 1] }
    }
}

/// Enables index operation for Dim4
///
/// # Examples
///
/// ```
/// use arrayfire::Dim4;
///
/// let dims = Dim4::new(&[4, 4, 2, 1]);
/// println!("0th Dimension length is {}", dims[0]); // -> 4
/// println!("1th Dimension length is {}", dims[1]); // -> 4
/// println!("2th Dimension length is {}", dims[2]); // -> 2
/// println!("3th Dimension length is {}", dims[3]); // -> 1
/// ```
impl Index<usize> for Dim4 {
    type Output = u64;

    fn index<'a>(&'a self, _index: usize) ->&'a u64 {
        &self.dims[_index]
    }
}

/// Enables use of Dim4 objects for printing it to display
///
/// # Examples
///
/// ```
/// use arrayfire::Dim4;
///
/// let dims = Dim4::new(&[4, 4, 2, 1]);
/// println!("0th Dimension length is {}", dims[0]); // -> 4
/// ```
impl fmt::Display for Dim4 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{} {} {} {}]", self.dims[0], self.dims[1], self.dims[2], self.dims[3])
    }
}

impl Dim4 {
    /// Create Dim4 object
    ///
    /// # Examples
    ///
    /// ```
    /// use arrayfire::Dim4;
    /// let dims = Dim4::new(&[4, 4, 2, 1]);
    /// ```
    pub fn new(dims: &[u64; 4]) -> Dim4 {
        Dim4 { dims: dims.clone(), }
    }

    /// Get the number of elements represented by Dim4 object
    pub fn elements(&self) -> u64 {
        self.dims[0]*self.dims[1]*self.dims[2]*self.dims[3]
    }

    /// Get the number of dimensions of Dim4
    pub fn ndims(&self) -> usize {
        let nelems = self.elements();
        match nelems {
            0 => 0,
            1 => 1,
            _ => {
                if self.dims[3] != 1 { 4 }
                else if self.dims[2] != 1 { 3 }
                else if self.dims[1] != 1 { 2 }
                else { 1 }
            },
        }
    }

    // Get the dimensions as a slice of 4 values
    pub fn get(&self) -> &[u64; 4] {
        &self.dims
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Yusuke Sasaki
//
// This software is released under the MIT License.
// See http://opensource.org/licenses/mit-license.php or <LICENSE>.

use attr;
use super::{Var, Model};
use error::Result;
use itertools::*;

use std::ops::{Add, Sub, Mul, Neg, AddAssign};
use std::iter::Sum;

/// Linear expression of variables
///
/// A linear expression consists of a constant term plus a list of coefficients and variables.
#[derive(Debug, Clone, Default)]
pub struct LinExpr {
  vars: Vec<Var>,
  coeff: Vec<f64>,
  offset: f64
}

impl<'a> From<&'a Var> for LinExpr {
    fn from(var : &Var) -> LinExpr {
        LinExpr::new() + var
    }
}

impl From<Var> for LinExpr {
    fn from(var : Var) -> LinExpr {
        LinExpr::from(&var)
    }
}

impl Into<(Vec<i32>, Vec<f64>, f64)> for LinExpr {
  fn into(self) -> (Vec<i32>, Vec<f64>, f64) {
    (self.vars.into_iter().map(|e| e.index()).collect(), self.coeff, self.offset)
  }
}

impl LinExpr {
  /// Create an empty linear expression.
  pub fn new() -> Self {
    LinExpr::default()
  }

  /// Add a linear term into the expression.
  pub fn add_term(mut self, coeff: f64, var: Var) -> Self {
    self.coeff.push(coeff);
    self.vars.push(var);
    self
  }

  /// Add a constant into the expression.
  pub fn add_constant(mut self, constant: f64) -> Self {
    self.offset += constant;
    self
  }

  /// Get actual value of the expression.
  pub fn get_value(&self, model: &Model) -> Result<f64> {
    let vars = try!(model.get_values(attr::X, self.vars.as_slice()));

    Ok(Zip::new((vars, self.coeff.iter())).fold(0.0, |acc, (ind, val)| acc + ind * val) + self.offset)
  }
}

/// Quadratic expression of variables
///
/// A quadratic expression consists of a linear expression and a set of
/// variable-variable-coefficient triples to express the quadratic term.
#[derive(Debug, Clone, Default)]
pub struct QuadExpr {
  lind: Vec<Var>,
  lval: Vec<f64>,
  qrow: Vec<Var>,
  qcol: Vec<Var>,
  qval: Vec<f64>,
  offset: f64
}

impl Into<(Vec<i32>, Vec<f64>, Vec<i32>, Vec<i32>, Vec<f64>, f64)> for QuadExpr {
  fn into(self) -> (Vec<i32>, Vec<f64>, Vec<i32>, Vec<i32>, Vec<f64>, f64) {
    (self.lind.into_iter().map(|e| e.index()).collect(),
     self.lval,
     self.qrow.into_iter().map(|e| e.index()).collect(),
     self.qcol.into_iter().map(|e| e.index()).collect(),
     self.qval,
     self.offset)
  }
}

impl QuadExpr {
  pub fn new() -> Self {
    QuadExpr::default()
  }

  /// Add a linear term into the expression.
  pub fn add_term(mut self, coeff: f64, var: Var) -> Self {
    self.lind.push(var);
    self.lval.push(coeff);
    self
  }

  /// Add a quadratic term into the expression.
  pub fn add_qterm(mut self, coeff: f64, row: Var, col: Var) -> Self {
    self.qval.push(coeff);
    self.qrow.push(row);
    self.qcol.push(col);
    self
  }

  /// Add a constant into the expression.
  pub fn add_constant(mut self, constant: f64) -> Self {
    self.offset += constant;
    self
  }

  /// Get actual value of the expression.
  pub fn get_value(&self, model: &Model) -> Result<f64> {
    let lind = try!(model.get_values(attr::X, self.lind.as_slice()));
    let qrow = try!(model.get_values(attr::X, self.qrow.as_slice()));
    let qcol = try!(model.get_values(attr::X, self.qcol.as_slice()));

    Ok(Zip::new((lind, self.lval.iter())).fold(0.0, |acc, (ind, val)| acc + ind * val) +
       Zip::new((qrow, qcol, self.qval.iter())).fold(0.0, |acc, (row, col, val)| acc + row * col * val) +
       self.offset)
  }
}

// Conversion into QuadExpr

impl Into<QuadExpr> for Var {
  fn into(self) -> QuadExpr { QuadExpr::new().add_term(1.0, self) }
}

impl<'a> Into<QuadExpr> for &'a Var {
  fn into(self) -> QuadExpr { QuadExpr::new().add_term(1.0, self.clone()) }
}

impl Into<QuadExpr> for LinExpr {
  fn into(self) -> QuadExpr {
    QuadExpr {
      lind: self.vars,
      lval: self.coeff,
      offset: self.offset,
      qrow: Vec::new(),
      qcol: Vec::new(),
      qval: Vec::new()
    }
  }
}

// /////// Operator definition.

/// `Var` + `Var`  => `LinExpr`
impl Add for Var {
  type Output = LinExpr;
  fn add(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(1.0, rhs) }
}
impl<'a> Add<&'a Var> for Var {
  type Output = LinExpr;
  fn add(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(1.0, rhs.clone()) }
}
impl<'a> Add<Var> for &'a Var {
  type Output = LinExpr;
  fn add(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(1.0, rhs) }
}
impl<'a, 'b> Add<&'b Var> for &'a Var {
  type Output = LinExpr;
  fn add(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(1.0, rhs.clone()) }
}

/// `Var` - `Var` => `LinExpr`
impl Sub for Var {
  type Output = LinExpr;
  fn sub(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(-1.0, rhs) }
}
impl<'a> Sub<&'a Var> for Var {
  type Output = LinExpr;
  fn sub(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(-1.0, rhs.clone()) }
}
impl<'a> Sub<Var> for &'a Var {
  type Output = LinExpr;
  fn sub(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(-1.0, rhs) }
}
impl<'a, 'b> Sub<&'b Var> for &'a Var {
  type Output = LinExpr;
  fn sub(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(-1.0, rhs.clone()) }
}
impl Sub<LinExpr> for Var {
  type Output = LinExpr;
  fn sub(self, expr: LinExpr) -> LinExpr { expr + (-self) }
}

/// -`Var` => `LinExpr`
impl Neg for Var {
  type Output = LinExpr;
  fn neg(self) -> LinExpr { LinExpr::new().add_term(-1.0, self) }
}
impl<'a> Neg for &'a Var {
  type Output = LinExpr;
  fn neg(self) -> LinExpr { LinExpr::new().add_term(-1.0, self.clone()) }
}

/// `Var` * `f64` => `LinExpr`
impl Mul<f64> for Var {
  type Output = LinExpr;
  fn mul(self, rhs: f64) -> Self::Output { LinExpr::new().add_term(rhs, self) }
}
impl<'a> Mul<f64> for &'a Var {
  type Output = LinExpr;
  fn mul(self, rhs: f64) -> Self::Output { LinExpr::new().add_term(rhs, self.clone()) }
}
impl Mul<Var> for f64 {
  type Output = LinExpr;
  fn mul(self, rhs: Var) -> Self::Output { LinExpr::new().add_term(self, rhs) }
}
impl<'a> Mul<&'a Var> for f64 {
  type Output = LinExpr;
  fn mul(self, rhs: &'a Var) -> Self::Output { LinExpr::new().add_term(self, rhs.clone()) }
}

/// `Var` * `Var` => `QuadExpr`
impl Mul for Var {
  type Output = QuadExpr;
  fn mul(self, rhs: Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self, rhs) }
}
impl<'a> Mul<&'a Var> for Var {
  type Output = QuadExpr;
  fn mul(self, rhs: &Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self, rhs.clone()) }
}
impl<'a> Mul<Var> for &'a Var {
  type Output = QuadExpr;
  fn mul(self, rhs: Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self.clone(), rhs) }
}
impl<'a, 'b> Mul<&'b Var> for &'a Var {
  type Output = QuadExpr;
  fn mul(self, rhs: &Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self.clone(), rhs.clone()) }
}

/// `LinExpr` + `Var` => `LinExpr`
impl Add<LinExpr> for Var {
  type Output = LinExpr;
  fn add(self, rhs: LinExpr) -> LinExpr { rhs.add_term(1.0, self) }
}
impl<'a> Add<LinExpr> for &'a Var {
  type Output = LinExpr;
  fn add(self, rhs: LinExpr) -> LinExpr { rhs.add_term(1.0, self.clone()) }
}
impl Add<Var> for LinExpr {
  type Output = LinExpr;
  fn add(self, rhs: Var) -> LinExpr { self.add_term(1.0, rhs) }
}
impl<'a> Add<&'a Var> for LinExpr {
  type Output = LinExpr;
  fn add(self, rhs: &'a Var) -> LinExpr { self.add_term(1.0, rhs.clone()) }
}

/// `LinExpr` + `f64` => `LinExpr`
impl Add<f64> for LinExpr {
  type Output = LinExpr;
  fn add(self, rhs: f64) -> Self::Output { self.add_constant(rhs) }
}
impl Add<LinExpr> for f64 {
  type Output = LinExpr;
  fn add(self, rhs: LinExpr) -> Self::Output { rhs.add_constant(self) }
}

/// `LinExpr` - `f64` => `LinExpr`
impl Sub<f64> for LinExpr {
  type Output = LinExpr;
  fn sub(self, rhs: f64) -> Self::Output { self.add_constant(-rhs) }
}

/// `f64` - `LinExpr` => `LinExpr`
impl Sub<LinExpr> for f64 {
  type Output = LinExpr;
  fn sub(self, mut rhs: LinExpr) -> Self::Output {
    for c in rhs.coeff.iter_mut() {
      *c *= -1.0;
    }
    rhs.add_constant(self)
  }
}

impl Add for LinExpr {
  type Output = LinExpr;
  fn add(mut self, rhs: LinExpr) -> Self::Output {
    self += rhs;
    self
  }
}

impl AddAssign for LinExpr {
    fn add_assign(&mut self, rhs: LinExpr) {
        self.vars.extend(rhs.vars);
        self.coeff.extend(rhs.coeff);
        self.offset += rhs.offset;
    }
}

impl AddAssign<Var> for LinExpr {
    fn add_assign(&mut self, rhs: Var) {
        let expr : LinExpr = rhs.into();
        *self += expr;
    }
}

impl Sub for LinExpr {
  type Output = LinExpr;
  fn sub(mut self, rhs: LinExpr) -> Self::Output {
    self.vars.extend(rhs.vars);
    self.coeff.extend(rhs.coeff.into_iter().map(|c| -c));
    self.offset -= rhs.offset;
    self
  }
}

impl Mul<f64> for LinExpr {
  type Output = LinExpr;
  fn mul(mut self, rhs: f64) -> Self::Output {
    for coeff in &mut self.coeff {
      *coeff *= rhs;
    }
    self.offset *= rhs;
    self
  }
}

impl Mul<LinExpr> for f64 {
  type Output = LinExpr;
  fn mul(self, rhs: LinExpr) -> Self::Output {
      rhs * self
  }
}

impl Mul<f64> for QuadExpr {
  type Output = QuadExpr;
  fn mul(mut self, rhs: f64) -> Self::Output {
    for i in 0..(self.lval.len()) {
      self.lval[i] *= rhs;
    }
    for j in 0..(self.qval.len()) {
      self.qval[j] *= rhs;
    }
    self.offset *= rhs;
    self
  }
}

impl Sum for LinExpr {
    fn sum<I: Iterator<Item=LinExpr>>(iter: I) -> LinExpr {
        iter.fold(LinExpr::new(), |acc, expr| acc + expr)
    }
}

impl Add<LinExpr> for QuadExpr {
  type Output = QuadExpr;
  fn add(mut self, rhs: LinExpr) -> Self::Output {
    self.lind.extend(rhs.vars);
    self.lval.extend(rhs.coeff);
    self.offset += rhs.offset;
    self
  }
}

impl Sub<LinExpr> for QuadExpr {
  type Output = QuadExpr;
  fn sub(mut self, rhs: LinExpr) -> Self::Output {
    self.lind.extend(rhs.vars);
    self.lval.extend(rhs.coeff.into_iter().map(|c| -c));
    self.offset -= rhs.offset;
    self
  }
}

impl Add for QuadExpr {
  type Output = QuadExpr;
  fn add(mut self, rhs: QuadExpr) -> QuadExpr {
    self.lind.extend(rhs.lind);
    self.lval.extend(rhs.lval);
    self.qrow.extend(rhs.qrow);
    self.qcol.extend(rhs.qcol);
    self.qval.extend(rhs.qval);
    self.offset += rhs.offset;
    self
  }
}

impl Sub for QuadExpr {
  type Output = QuadExpr;
  fn sub(mut self, rhs: QuadExpr) -> QuadExpr {
    self.lind.extend(rhs.lind);
    self.lval.extend(rhs.lval.into_iter().map(|c| -c));
    self.qrow.extend(rhs.qrow);
    self.qcol.extend(rhs.qcol);
    self.qval.extend(rhs.qval.into_iter().map(|c| -c));
    self.offset -= rhs.offset;
    self
  }
}
<commit_msg>fix `Sub<LinExpr> for Var` add `Neg for LinExpr` and `Div<f64> for LinExpr`<commit_after>// Copyright (c) 2016 Yusuke Sasaki
//
// This software is released under the MIT License.
// See http://opensource.org/licenses/mit-license.php or <LICENSE>.

use attr;
use super::{Var, Model};
use error::Result;
use itertools::*;

use std::ops::{Add, Sub, Mul, Neg, AddAssign, Div};
use std::iter::Sum;

/// Linear expression of variables
///
/// A linear expression consists of a constant term plus a list of coefficients and variables.
#[derive(Debug, Clone, Default)]
pub struct LinExpr {
  vars: Vec<Var>,
  coeff: Vec<f64>,
  offset: f64
}

impl<'a> From<&'a Var> for LinExpr {
    fn from(var : &Var) -> LinExpr {
        LinExpr::new() + var
    }
}

impl From<Var> for LinExpr {
    fn from(var : Var) -> LinExpr {
        LinExpr::from(&var)
    }
}

impl Into<(Vec<i32>, Vec<f64>, f64)> for LinExpr {
  fn into(self) -> (Vec<i32>, Vec<f64>, f64) {
    (self.vars.into_iter().map(|e| e.index()).collect(), self.coeff, self.offset)
  }
}

impl LinExpr {
  /// Create an empty linear expression.
  pub fn new() -> Self {
    LinExpr::default()
  }

  /// Add a linear term into the expression.
  pub fn add_term(mut self, coeff: f64, var: Var) -> Self {
    self.coeff.push(coeff);
    self.vars.push(var);
    self
  }

  /// Add a constant into the expression.
  pub fn add_constant(mut self, constant: f64) -> Self {
    self.offset += constant;
    self
  }

  /// Get actual value of the expression.
  pub fn get_value(&self, model: &Model) -> Result<f64> {
    let vars = try!(model.get_values(attr::X, self.vars.as_slice()));

    Ok(Zip::new((vars, self.coeff.iter())).fold(0.0, |acc, (ind, val)| acc + ind * val) + self.offset)
  }
}

/// Quadratic expression of variables
///
/// A quadratic expression consists of a linear expression and a set of
/// variable-variable-coefficient triples to express the quadratic term.
#[derive(Debug, Clone, Default)]
pub struct QuadExpr {
  lind: Vec<Var>,
  lval: Vec<f64>,
  qrow: Vec<Var>,
  qcol: Vec<Var>,
  qval: Vec<f64>,
  offset: f64
}

impl Into<(Vec<i32>, Vec<f64>, Vec<i32>, Vec<i32>, Vec<f64>, f64)> for QuadExpr {
  fn into(self) -> (Vec<i32>, Vec<f64>, Vec<i32>, Vec<i32>, Vec<f64>, f64) {
    (self.lind.into_iter().map(|e| e.index()).collect(),
     self.lval,
     self.qrow.into_iter().map(|e| e.index()).collect(),
     self.qcol.into_iter().map(|e| e.index()).collect(),
     self.qval,
     self.offset)
  }
}

impl QuadExpr {
  pub fn new() -> Self {
    QuadExpr::default()
  }

  /// Add a linear term into the expression.
  pub fn add_term(mut self, coeff: f64, var: Var) -> Self {
    self.lind.push(var);
    self.lval.push(coeff);
    self
  }

  /// Add a quadratic term into the expression.
  pub fn add_qterm(mut self, coeff: f64, row: Var, col: Var) -> Self {
    self.qval.push(coeff);
    self.qrow.push(row);
    self.qcol.push(col);
    self
  }

  /// Add a constant into the expression.
  pub fn add_constant(mut self, constant: f64) -> Self {
    self.offset += constant;
    self
  }

  /// Get actual value of the expression.
  pub fn get_value(&self, model: &Model) -> Result<f64> {
    let lind = try!(model.get_values(attr::X, self.lind.as_slice()));
    let qrow = try!(model.get_values(attr::X, self.qrow.as_slice()));
    let qcol = try!(model.get_values(attr::X, self.qcol.as_slice()));

    Ok(Zip::new((lind, self.lval.iter())).fold(0.0, |acc, (ind, val)| acc + ind * val) +
       Zip::new((qrow, qcol, self.qval.iter())).fold(0.0, |acc, (row, col, val)| acc + row * col * val) +
       self.offset)
  }
}

// Conversion into QuadExpr

impl Into<QuadExpr> for Var {
  fn into(self) -> QuadExpr { QuadExpr::new().add_term(1.0, self) }
}

impl<'a> Into<QuadExpr> for &'a Var {
  fn into(self) -> QuadExpr { QuadExpr::new().add_term(1.0, self.clone()) }
}

impl Into<QuadExpr> for LinExpr {
  fn into(self) -> QuadExpr {
    QuadExpr {
      lind: self.vars,
      lval: self.coeff,
      offset: self.offset,
      qrow: Vec::new(),
      qcol: Vec::new(),
      qval: Vec::new()
    }
  }
}

// /////// Operator definition.

/// `Var` + `Var`  => `LinExpr`
impl Add for Var {
  type Output = LinExpr;
  fn add(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(1.0, rhs) }
}
impl<'a> Add<&'a Var> for Var {
  type Output = LinExpr;
  fn add(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(1.0, rhs.clone()) }
}
impl<'a> Add<Var> for &'a Var {
  type Output = LinExpr;
  fn add(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(1.0, rhs) }
}
impl<'a, 'b> Add<&'b Var> for &'a Var {
  type Output = LinExpr;
  fn add(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(1.0, rhs.clone()) }
}

/// `Var` - `Var` => `LinExpr`
impl Sub for Var {
  type Output = LinExpr;
  fn sub(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(-1.0, rhs) }
}
impl<'a> Sub<&'a Var> for Var {
  type Output = LinExpr;
  fn sub(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self).add_term(-1.0, rhs.clone()) }
}
impl<'a> Sub<Var> for &'a Var {
  type Output = LinExpr;
  fn sub(self, rhs: Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(-1.0, rhs) }
}
impl<'a, 'b> Sub<&'b Var> for &'a Var {
  type Output = LinExpr;
  fn sub(self, rhs: &Var) -> LinExpr { LinExpr::new().add_term(1.0, self.clone()).add_term(-1.0, rhs.clone()) }
}
impl Sub<LinExpr> for Var {
  type Output = LinExpr;
  fn sub(self, expr: LinExpr) -> LinExpr {  self + (-expr) }
}

/// -`Var` => `LinExpr`
impl Neg for Var {
  type Output = LinExpr;
  fn neg(self) -> LinExpr { LinExpr::new().add_term(-1.0, self) }
}
impl<'a> Neg for &'a Var {
  type Output = LinExpr;
  fn neg(self) -> LinExpr { LinExpr::new().add_term(-1.0, self.clone()) }
}

/// `Var` * `f64` => `LinExpr`
impl Mul<f64> for Var {
  type Output = LinExpr;
  fn mul(self, rhs: f64) -> Self::Output { LinExpr::new().add_term(rhs, self) }
}
impl<'a> Mul<f64> for &'a Var {
  type Output = LinExpr;
  fn mul(self, rhs: f64) -> Self::Output { LinExpr::new().add_term(rhs, self.clone()) }
}
impl Mul<Var> for f64 {
  type Output = LinExpr;
  fn mul(self, rhs: Var) -> Self::Output { LinExpr::new().add_term(self, rhs) }
}
impl<'a> Mul<&'a Var> for f64 {
  type Output = LinExpr;
  fn mul(self, rhs: &'a Var) -> Self::Output { LinExpr::new().add_term(self, rhs.clone()) }
}

/// `Var` * `Var` => `QuadExpr`
impl Mul for Var {
  type Output = QuadExpr;
  fn mul(self, rhs: Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self, rhs) }
}
impl<'a> Mul<&'a Var> for Var {
  type Output = QuadExpr;
  fn mul(self, rhs: &Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self, rhs.clone()) }
}
impl<'a> Mul<Var> for &'a Var {
  type Output = QuadExpr;
  fn mul(self, rhs: Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self.clone(), rhs) }
}
impl<'a, 'b> Mul<&'b Var> for &'a Var {
  type Output = QuadExpr;
  fn mul(self, rhs: &Var) -> Self::Output { QuadExpr::new().add_qterm(1.0, self.clone(), rhs.clone()) }
}

/// `LinExpr` + `Var` => `LinExpr`
impl Add<LinExpr> for Var {
  type Output = LinExpr;
  fn add(self, rhs: LinExpr) -> LinExpr { rhs.add_term(1.0, self) }
}
impl<'a> Add<LinExpr> for &'a Var {
  type Output = LinExpr;
  fn add(self, rhs: LinExpr) -> LinExpr { rhs.add_term(1.0, self.clone()) }
}
impl Add<Var> for LinExpr {
  type Output = LinExpr;
  fn add(self, rhs: Var) -> LinExpr { self.add_term(1.0, rhs) }
}
impl<'a> Add<&'a Var> for LinExpr {
  type Output = LinExpr;
  fn add(self, rhs: &'a Var) -> LinExpr { self.add_term(1.0, rhs.clone()) }
}

/// `LinExpr` + `f64` => `LinExpr`
impl Add<f64> for LinExpr {
  type Output = LinExpr;
  fn add(self, rhs: f64) -> Self::Output { self.add_constant(rhs) }
}
impl Add<LinExpr> for f64 {
  type Output = LinExpr;
  fn add(self, rhs: LinExpr) -> Self::Output { rhs.add_constant(self) }
}

/// `LinExpr` - `f64` => `LinExpr`
impl Sub<f64> for LinExpr {
  type Output = LinExpr;
  fn sub(self, rhs: f64) -> Self::Output { self.add_constant(-rhs) }
}

/// `f64` - `LinExpr` => `LinExpr`
impl Sub<LinExpr> for f64 {
  type Output = LinExpr;
  fn sub(self, mut rhs: LinExpr) -> Self::Output {
    for c in rhs.coeff.iter_mut() {
      *c *= -1.0;
    }
    rhs.add_constant(self)
  }
}

impl Add for LinExpr {
  type Output = LinExpr;
  fn add(mut self, rhs: LinExpr) -> Self::Output {
    self += rhs;
    self
  }
}

impl Neg for LinExpr {
  type Output = LinExpr;
  fn neg(mut self) -> LinExpr {
      for coeff in &mut self.coeff {
        *coeff = -*coeff;
      }
      self.offset = -self.offset;
      self
  }
}

impl AddAssign for LinExpr {
    fn add_assign(&mut self, rhs: LinExpr) {
        self.vars.extend(rhs.vars);
        self.coeff.extend(rhs.coeff);
        self.offset += rhs.offset;
    }
}

impl AddAssign<Var> for LinExpr {
    fn add_assign(&mut self, rhs: Var) {
        let expr : LinExpr = rhs.into();
        *self += expr;
    }
}

impl Sub for LinExpr {
  type Output = LinExpr;
  fn sub(mut self, rhs: LinExpr) -> Self::Output {
    self.vars.extend(rhs.vars);
    self.coeff.extend(rhs.coeff.into_iter().map(|c| -c));
    self.offset -= rhs.offset;
    self
  }
}

impl Mul<f64> for LinExpr {
  type Output = LinExpr;
  fn mul(mut self, rhs: f64) -> Self::Output {
    for coeff in &mut self.coeff {
      *coeff *= rhs;
    }
    self.offset *= rhs;
    self
  }
}

impl Div<f64> for LinExpr {
  type Output = LinExpr;
  fn div(mut self, rhs: f64) -> Self::Output {
    for coeff in &mut self.coeff {
      *coeff /= rhs;
    }
    self.offset /= rhs;
    self
  }
}

impl Mul<LinExpr> for f64 {
  type Output = LinExpr;
  fn mul(self, rhs: LinExpr) -> Self::Output {
      rhs * self
  }
}

impl Mul<f64> for QuadExpr {
  type Output = QuadExpr;
  fn mul(mut self, rhs: f64) -> Self::Output {
    for i in 0..(self.lval.len()) {
      self.lval[i] *= rhs;
    }
    for j in 0..(self.qval.len()) {
      self.qval[j] *= rhs;
    }
    self.offset *= rhs;
    self
  }
}

impl Sum for LinExpr {
    fn sum<I: Iterator<Item=LinExpr>>(iter: I) -> LinExpr {
        iter.fold(LinExpr::new(), |acc, expr| acc + expr)
    }
}

impl Add<LinExpr> for QuadExpr {
  type Output = QuadExpr;
  fn add(mut self, rhs: LinExpr) -> Self::Output {
    self.lind.extend(rhs.vars);
    self.lval.extend(rhs.coeff);
    self.offset += rhs.offset;
    self
  }
}

impl Sub<LinExpr> for QuadExpr {
  type Output = QuadExpr;
  fn sub(mut self, rhs: LinExpr) -> Self::Output {
    self.lind.extend(rhs.vars);
    self.lval.extend(rhs.coeff.into_iter().map(|c| -c));
    self.offset -= rhs.offset;
    self
  }
}

impl Add for QuadExpr {
  type Output = QuadExpr;
  fn add(mut self, rhs: QuadExpr) -> QuadExpr {
    self.lind.extend(rhs.lind);
    self.lval.extend(rhs.lval);
    self.qrow.extend(rhs.qrow);
    self.qcol.extend(rhs.qcol);
    self.qval.extend(rhs.qval);
    self.offset += rhs.offset;
    self
  }
}

impl Sub for QuadExpr {
  type Output = QuadExpr;
  fn sub(mut self, rhs: QuadExpr) -> QuadExpr {
    self.lind.extend(rhs.lind);
    self.lval.extend(rhs.lval.into_iter().map(|c| -c));
    self.qrow.extend(rhs.qrow);
    self.qcol.extend(rhs.qcol);
    self.qval.extend(rhs.qval.into_iter().map(|c| -c));
    self.offset -= rhs.offset;
    self
  }
}
<|endoftext|>