<commit_before>use matrix::{Scalar,Mat,ColumnPanelMatrix,RowPanelMatrix,Matrix};
use core::marker::{PhantomData};
use pack::{Copier,Packer};

use std::time::{Duration,Instant};

extern crate core;

pub trait GemmNode<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c: &mut Ct ) -> ();
}

pub struct PackAcp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, ColumnPanelMatrix<T>, Bt, Ct>> {
    child: S,
    panel_width: usize,
    packer: Packer<T, At, ColumnPanelMatrix<T>>,
    a_pack: ColumnPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, ColumnPanelMatrix<T>, Bt, Ct>>
    PackAcp <T,At,Bt,Ct,S> {
    #[inline(always)]
    pub fn new( panel_width: usize, child: S ) -> PackAcp<T, At, Bt, Ct, S>{
        let matrix = ColumnPanelMatrix::new( 0, 0, panel_width );
        let packer = Packer::new();
        PackAcp{ panel_width: panel_width, child: child, a_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, ColumnPanelMatrix<T>, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PackAcp<T, At, Bt, Ct, S> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.a_pack.resize( a.height(), a.width() );
        self.packer.pack( a, &mut self.a_pack );
        self.child.run(&mut self.a_pack, b, c);
    }
}

pub struct PackBcp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, ColumnPanelMatrix<T>, Ct>> {
    child: S,
    panel_width: usize,
    packer: Packer<T, Bt, ColumnPanelMatrix<T>>,
    b_pack: ColumnPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, ColumnPanelMatrix<T>, Ct>>
    PackBcp <T,At,Bt,Ct,S> {
    #[inline(always)]
    pub fn new( panel_width: usize, child: S ) -> PackBcp<T, At, Bt, Ct, S>{
        let matrix = ColumnPanelMatrix::new( 0, 0, panel_width );
        let packer = Packer::new();
        PackBcp{ panel_width: panel_width, child: child, b_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, ColumnPanelMatrix<T>, Ct>>
    GemmNode<T, At, Bt, Ct> for PackBcp<T, At, Bt, Ct, S> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.b_pack.resize( b.height(), b.width() );
        self.packer.pack( b, &mut self.b_pack );
        self.child.run(a, &mut self.b_pack, c);
    }
}
pub struct PackArp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, RowPanelMatrix<T>, Bt, Ct>> {
    child: S,
    panel_height: usize,
    packer: Packer<T, At, RowPanelMatrix<T>>,
    a_pack: RowPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, RowPanelMatrix<T>, Bt, Ct>>
    PackArp <T,At,Bt,Ct,S> {
    #[inline(always)]
    pub fn new( panel_height: usize, child: S ) -> PackArp<T, At, Bt, Ct, S>{
        let matrix = RowPanelMatrix::new( 0, 0, panel_height );
        let packer = Packer::new();
        PackArp{ panel_height: panel_height, child: child, a_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, RowPanelMatrix<T>, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PackArp<T, At, Bt, Ct, S> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.a_pack.resize( a.height(), a.width() );
        self.packer.pack( a, &mut self.a_pack );
        self.child.run(&mut self.a_pack, b, c);
    }
}

pub struct PackBrp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, RowPanelMatrix<T>, Ct>> {
    child: S,
    panel_height: usize,
    packer: Packer<T, Bt, RowPanelMatrix<T>>,
    b_pack: RowPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, RowPanelMatrix<T>, Ct>>
    PackBrp <T,At,Bt,Ct,S> {
    pub fn new( panel_height: usize, child: S ) -> PackBrp<T, At, Bt, Ct, S>{
        let matrix = RowPanelMatrix::new( 0, 0, panel_height );
        let packer = Packer::new();
        PackBrp{ panel_height: panel_height, child: child, b_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, RowPanelMatrix<T>, Ct>>
    GemmNode<T, At, Bt, Ct> for PackBrp<T, At, Bt, Ct, S> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.b_pack.resize( b.height(), b.width() );
        self.packer.pack( b, &mut self.b_pack );
        self.child.run(a, &mut self.b_pack, c);
    }
}

pub struct PartM<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> {
    bsz: usize,
    iota: usize,
    child: S,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> PartM<T,At,Bt,Ct,S> {
    pub fn new( bsz: usize, iota: usize, child: S ) -> PartM<T, At, Bt, Ct,S>{
            PartM{ bsz: bsz, iota: iota, child: child,
                   _t: PhantomData, _at: PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PartM<T,At,Bt,Ct,S> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        let m_save = c.height();
        let ay_off_save = a.off_y();
        let cy_off_save = c.off_y();

        let mut i = 0;
        while i < m_save  {
            let bsz_step = core::cmp::min( self.bsz, m_save - i );
            a.set_height( bsz_step );
            a.set_off_y( ay_off_save + i );
            c.set_height( bsz_step );
            c.set_off_y( cy_off_save + i );

            self.child.run(a, b, c);
            i += bsz_step;
        }
        a.set_height( m_save );
        a.set_off_y( ay_off_save );
        c.set_height( m_save );
        c.set_off_y( cy_off_save );
    }
}

pub struct PartN<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> {
    bsz: usize,
    iota: usize,
    child: S,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> PartN<T,At,Bt,Ct,S> {
    pub fn new( bsz: usize, iota: usize, child: S ) -> PartN<T, At, Bt, Ct, S>{
            PartN{ bsz: bsz, iota: iota, child: child,
                   _t: PhantomData, _at: PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PartN<T,At,Bt,Ct,S> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        let n_save = c.width();
        let bx_off_save = b.off_x();
        let cx_off_save = c.off_x();

        let mut i = 0;
        while i < n_save  {
            let bsz_step = core::cmp::min( self.bsz, n_save - i );
            b.set_width( bsz_step );
            b.set_off_x( bx_off_save + i );
            c.set_width( bsz_step );
            c.set_off_x( cx_off_save + i );

            self.child.run(a, b, c);
            i += bsz_step;
        }
        b.set_width( n_save );
        b.set_off_x( bx_off_save );
        c.set_width( n_save );
        c.set_off_x( cx_off_save );
    }
}

pub struct PartK<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> {
    bsz: usize,
    iota: usize,
    child: S,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> PartK<T,At,Bt,Ct,S> {
    pub fn new( bsz: usize, iota: usize, child: S ) -> PartK<T, At, Bt, Ct, S>{
        PartK{ bsz: bsz, iota: iota, child: child,
               _t: PhantomData, _at: PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PartK<T,At,Bt,Ct,S> {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        let k_save = a.width();
        let ax_off_save = a.off_x();
        let by_off_save = b.off_y();

        let mut i = 0;
        while i < k_save  {
            let bsz_step = core::cmp::min( self.bsz, k_save - i );
            a.set_width( bsz_step );
            a.set_off_x( ax_off_save + i );
            b.set_height( bsz_step );
            b.set_off_y( by_off_save + i );

            self.child.run(a, b, c);
            i += bsz_step;
        }
        a.set_width( k_save );
        a.set_off_x( ax_off_save );
        b.set_height( k_save );
        b.set_off_y( by_off_save );
    }
}

pub struct TripleLoopKernel{}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>>
    GemmNode<T, At, Bt, Ct> for TripleLoopKernel {
    #[inline(always)]
    fn run( &mut self, a: &mut At, b: &mut Bt, c: &mut Ct ) -> () {
        //For now, let's do an axpy based gemm
        for x in 0..c.width() {
            for z in 0..a.width() {
                for y in 0..c.height() {
                    let t = a.get(y,z) * b.get(z,x) + c.get(y,x);
                    c.set( y, x, t );
                }
            }
        }
    }
}
impl TripleLoopKernel {
    pub fn new() -> TripleLoopKernel {
        TripleLoopKernel{}
    }
}
<commit_msg>Mark gemm nodes as unsafe<commit_after>use matrix::{Scalar,Mat,ColumnPanelMatrix,RowPanelMatrix,Matrix};
use core::marker::{PhantomData};
use pack::{Copier,Packer};

use std::time::{Duration,Instant};

extern crate core;

pub trait GemmNode<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c: &mut Ct ) -> ();
}

pub struct PackAcp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, ColumnPanelMatrix<T>, Bt, Ct>> {
    child: S,
    panel_width: usize,
    packer: Packer<T, At, ColumnPanelMatrix<T>>,
    a_pack: ColumnPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, ColumnPanelMatrix<T>, Bt, Ct>>
    PackAcp <T,At,Bt,Ct,S> {
    #[inline(always)]
    pub fn new( panel_width: usize, child: S ) -> PackAcp<T, At, Bt, Ct, S>{
        let matrix = ColumnPanelMatrix::new( 0, 0, panel_width );
        let packer = Packer::new();
        PackAcp{ panel_width: panel_width, child: child, a_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, ColumnPanelMatrix<T>, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PackAcp<T, At, Bt, Ct, S> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.a_pack.resize( a.height(), a.width() );
        self.packer.pack( a, &mut self.a_pack );
        self.child.run(&mut self.a_pack, b, c);
    }
}

pub struct PackBcp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, ColumnPanelMatrix<T>, Ct>> {
    child: S,
    panel_width: usize,
    packer: Packer<T, Bt, ColumnPanelMatrix<T>>,
    b_pack: ColumnPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, ColumnPanelMatrix<T>, Ct>>
    PackBcp <T,At,Bt,Ct,S> {
    #[inline(always)]
    pub fn new( panel_width: usize, child: S ) -> PackBcp<T, At, Bt, Ct, S>{
        let matrix = ColumnPanelMatrix::new( 0, 0, panel_width );
        let packer = Packer::new();
        PackBcp{ panel_width: panel_width, child: child, b_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, ColumnPanelMatrix<T>, Ct>>
    GemmNode<T, At, Bt, Ct> for PackBcp<T, At, Bt, Ct, S> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.b_pack.resize( b.height(), b.width() );
        self.packer.pack( b, &mut self.b_pack );
        self.child.run(a, &mut self.b_pack, c);
    }
}
pub struct PackArp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, RowPanelMatrix<T>, Bt, Ct>> {
    child: S,
    panel_height: usize,
    packer: Packer<T, At, RowPanelMatrix<T>>,
    a_pack: RowPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, RowPanelMatrix<T>, Bt, Ct>>
    PackArp <T,At,Bt,Ct,S> {
    #[inline(always)]
    pub fn new( panel_height: usize, child: S ) -> PackArp<T, At, Bt, Ct, S>{
        let matrix = RowPanelMatrix::new( 0, 0, panel_height );
        let packer = Packer::new();
        PackArp{ panel_height: panel_height, child: child, a_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, RowPanelMatrix<T>, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PackArp<T, At, Bt, Ct, S> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.a_pack.resize( a.height(), a.width() );
        self.packer.pack( a, &mut self.a_pack );
        self.child.run(&mut self.a_pack, b, c);
    }
}

pub struct PackBrp<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, RowPanelMatrix<T>, Ct>> {
    child: S,
    panel_height: usize,
    packer: Packer<T, Bt, RowPanelMatrix<T>>,
    b_pack: RowPanelMatrix<T>,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar,At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, RowPanelMatrix<T>, Ct>>
    PackBrp <T,At,Bt,Ct,S> {
    pub fn new( panel_height: usize, child: S ) -> PackBrp<T, At, Bt, Ct, S>{
        let matrix = RowPanelMatrix::new( 0, 0, panel_height );
        let packer = Packer::new();
        PackBrp{ panel_height: panel_height, child: child, b_pack: matrix, packer: packer,
                 _t: PhantomData, _at:PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, RowPanelMatrix<T>, Ct>>
    GemmNode<T, At, Bt, Ct> for PackBrp<T, At, Bt, Ct, S> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        self.b_pack.resize( b.height(), b.width() );
        self.packer.pack( b, &mut self.b_pack );
        self.child.run(a, &mut self.b_pack, c);
    }
}

pub struct PartM<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> {
    bsz: usize,
    iota: usize,
    child: S,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> PartM<T,At,Bt,Ct,S> {
    pub fn new( bsz: usize, iota: usize, child: S ) -> PartM<T, At, Bt, Ct,S>{
            PartM{ bsz: bsz, iota: iota, child: child,
                   _t: PhantomData, _at: PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PartM<T,At,Bt,Ct,S> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        let m_save = c.height();
        let ay_off_save = a.off_y();
        let cy_off_save = c.off_y();

        let mut i = 0;
        while i < m_save  {
            let bsz_step = core::cmp::min( self.bsz, m_save - i );
            a.set_height( bsz_step );
            a.set_off_y( ay_off_save + i );
            c.set_height( bsz_step );
            c.set_off_y( cy_off_save + i );

            self.child.run(a, b, c);
            i += bsz_step;
        }
        a.set_height( m_save );
        a.set_off_y( ay_off_save );
        c.set_height( m_save );
        c.set_off_y( cy_off_save );
    }
}

pub struct PartN<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> {
    bsz: usize,
    iota: usize,
    child: S,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> PartN<T,At,Bt,Ct,S> {
    pub fn new( bsz: usize, iota: usize, child: S ) -> PartN<T, At, Bt, Ct, S>{
            PartN{ bsz: bsz, iota: iota, child: child,
                   _t: PhantomData, _at: PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PartN<T,At,Bt,Ct,S> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        let n_save = c.width();
        let bx_off_save = b.off_x();
        let cx_off_save = c.off_x();

        let mut i = 0;
        while i < n_save  {
            let bsz_step = core::cmp::min( self.bsz, n_save - i );
            b.set_width( bsz_step );
            b.set_off_x( bx_off_save + i );
            c.set_width( bsz_step );
            c.set_off_x( cx_off_save + i );

            self.child.run(a, b, c);
            i += bsz_step;
        }
        b.set_width( n_save );
        b.set_off_x( bx_off_save );
        c.set_width( n_save );
        c.set_off_x( cx_off_save );
    }
}

pub struct PartK<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> {
    bsz: usize,
    iota: usize,
    child: S,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>> PartK<T,At,Bt,Ct,S> {
    pub fn new( bsz: usize, iota: usize, child: S ) -> PartK<T, At, Bt, Ct, S>{
        PartK{ bsz: bsz, iota: iota, child: child,
               _t: PhantomData, _at: PhantomData, _bt: PhantomData, _ct: PhantomData }
    }
}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>, S: GemmNode<T, At, Bt, Ct>>
    GemmNode<T, At, Bt, Ct> for PartK<T,At,Bt,Ct,S> {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c:&mut Ct ) -> () {
        let k_save = a.width();
        let ax_off_save = a.off_x();
        let by_off_save = b.off_y();

        let mut i = 0;
        while i < k_save  {
            let bsz_step = core::cmp::min( self.bsz, k_save - i );
            a.set_width( bsz_step );
            a.set_off_x( ax_off_save + i );
            b.set_height( bsz_step );
            b.set_off_y( by_off_save + i );

            self.child.run(a, b, c);
            i += bsz_step;
        }
        a.set_width( k_save );
        a.set_off_x( ax_off_save );
        b.set_height( k_save );
        b.set_off_y( by_off_save );
    }
}

pub struct TripleLoopKernel{}
impl<T: Scalar, At: Mat<T>, Bt: Mat<T>, Ct: Mat<T>>
    GemmNode<T, At, Bt, Ct> for TripleLoopKernel {
    #[inline(always)]
    unsafe fn run( &mut self, a: &mut At, b: &mut Bt, c: &mut Ct ) -> () {
        //For now, let's do an axpy based gemm
        for x in 0..c.width() {
            for z in 0..a.width() {
                for y in 0..c.height() {
                    let t = a.get(y,z) * b.get(z,x) + c.get(y,x);
                    c.set( y, x, t );
                }
            }
        }
    }
}
impl TripleLoopKernel {
    pub fn new() -> TripleLoopKernel {
        TripleLoopKernel{}
    }
}
<|endoftext|>


<commit_before>use std::str::CharIndices;
use std::io::Result as IoResult;
use std::io::Write;

use super::action::{IFlagAction, ParseResult};
use super::action::ParseResult::Help;

pub struct HelpAction;

impl IFlagAction for HelpAction {
    fn parse_flag(&self) -> ParseResult {
        return Help;
    }
}

struct WordsIter<'a> {
    data: &'a str,
    iter: CharIndices<'a>,
}

impl<'a> WordsIter<'a> {
    fn new(data: &'a str) -> WordsIter<'a> {
        return WordsIter {
            data: data,
            iter: data.char_indices(),
            };
    }
}

impl<'a> Iterator for WordsIter<'a> {
    type Item = &'a str;
    fn next(&mut self) -> Option<&'a str> {
        let word_start;
        loop {
            let (idx, ch) = match self.iter.next() {
                None => return None,
                Some((idx, ch)) => ((idx, ch)),
            };
            match ch {
                ' ' | '\t' | '\r' | '\n' => continue,
                _ => {
                    word_start = idx;
                    break;
                }
            }
        }
        loop {
            let (idx, ch) = match self.iter.next() {
                None => break,
                Some((idx, ch)) => ((idx, ch)),
            };
            match ch {
                ' ' | '\t' | '\r' | '\n' => {
                    return Some(&self.data[word_start..idx]);
                }
                _ => continue,
            }
        }
        return Some(&self.data[word_start..self.data.len()]);
    }
}

pub fn wrap_text(buf: &mut Write, data: &str, width: usize, indent: usize)
    -> IoResult<()>
{
    let mut witer = WordsIter::new(data);
    let mut off = indent;
    match witer.next() {
        None => {
            return Ok(());
        }
        Some(word) => {
            try!(buf.write_all(word.as_bytes()));
            off += word.len();
        }
    }
    for word in witer {
        if off + word.len() + 1 > width {
            try!(buf.write_all(b"\n"));
            for _ in 0..indent {
                try!(buf.write_all(b" "));
            }
            off = indent;
        } else {
            try!(buf.write_all(b" "));
            off += 1;
        }
        try!(buf.write_all(word.as_bytes()));
        off += word.len();
    }
    return Ok(());
}
<commit_msg>Fix clippy reported problems of double_parens lint<commit_after>use std::str::CharIndices;
use std::io::Result as IoResult;
use std::io::Write;

use super::action::{IFlagAction, ParseResult};
use super::action::ParseResult::Help;

pub struct HelpAction;

impl IFlagAction for HelpAction {
    fn parse_flag(&self) -> ParseResult {
        return Help;
    }
}

struct WordsIter<'a> {
    data: &'a str,
    iter: CharIndices<'a>,
}

impl<'a> WordsIter<'a> {
    fn new(data: &'a str) -> WordsIter<'a> {
        return WordsIter {
            data: data,
            iter: data.char_indices(),
            };
    }
}

impl<'a> Iterator for WordsIter<'a> {
    type Item = &'a str;
    fn next(&mut self) -> Option<&'a str> {
        let word_start;
        loop {
            let (idx, ch) = match self.iter.next() {
                None => return None,
                Some((idx, ch)) => (idx, ch),
            };
            match ch {
                ' ' | '\t' | '\r' | '\n' => continue,
                _ => {
                    word_start = idx;
                    break;
                }
            }
        }
        loop {
            let (idx, ch) = match self.iter.next() {
                None => break,
                Some((idx, ch)) => (idx, ch),
            };
            match ch {
                ' ' | '\t' | '\r' | '\n' => {
                    return Some(&self.data[word_start..idx]);
                }
                _ => continue,
            }
        }
        return Some(&self.data[word_start..self.data.len()]);
    }
}

pub fn wrap_text(buf: &mut Write, data: &str, width: usize, indent: usize)
    -> IoResult<()>
{
    let mut witer = WordsIter::new(data);
    let mut off = indent;
    match witer.next() {
        None => {
            return Ok(());
        }
        Some(word) => {
            try!(buf.write_all(word.as_bytes()));
            off += word.len();
        }
    }
    for word in witer {
        if off + word.len() + 1 > width {
            try!(buf.write_all(b"\n"));
            for _ in 0..indent {
                try!(buf.write_all(b" "));
            }
            off = indent;
        } else {
            try!(buf.write_all(b" "));
            off += 1;
        }
        try!(buf.write_all(word.as_bytes()));
        off += word.len();
    }
    return Ok(());
}
<|endoftext|>


<commit_before>use std::net::IpAddr;

use c_ares;

/// An owned version of `c_ares::HostResults`.
#[derive(Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub struct HostResults{
    hostname: String,
    addresses: Vec<IpAddr>,
    aliases: Vec<String>,
}

impl<'a> From<c_ares::HostResults<'a>> for HostResults {
    fn from(results: c_ares::HostResults) -> Self {
        HostResults {
            hostname: results.hostname().to_owned(),
            addresses: results.addresses().collect(),
            aliases: results.aliases().map(|s| s.to_owned()).collect(),
        }
    }
}
<commit_msg>Contents of HostResults need to be public<commit_after>use std::net::IpAddr;

use c_ares;

/// An owned version of `c_ares::HostResults`.
#[derive(Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub struct HostResults{
    /// The hostname returned by the lookup.
    pub hostname: String,

    /// The IP addresses returned by the lookup.
    pub addresses: Vec<IpAddr>,

    /// The aliases returned by the lookup.
    pub aliases: Vec<String>,
}

impl<'a> From<c_ares::HostResults<'a>> for HostResults {
    fn from(results: c_ares::HostResults) -> Self {
        HostResults {
            hostname: results.hostname().to_owned(),
            addresses: results.addresses().collect(),
            aliases: results.aliases().map(|s| s.to_owned()).collect(),
        }
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate js_types;
extern crate jsrs_common;
extern crate jsrs_parser;
extern crate french_press;
extern crate test;

extern crate rustyline;

mod bench;
mod coerce;
mod eval;

use std::env;
use std::io::prelude::*;
use std::process::exit;
use std::io::{self, BufReader};
use std::path::Path;
use std::fs::{File, metadata};

use rustyline::error::ReadlineError;
use rustyline::Editor;

use french_press::{init_gc, ScopeManager};

use eval::eval_string;

fn eval_file(filename: String, debug: bool, mut scope_manager: &mut ScopeManager) {
    println!("Reading from \"{}\"", filename);
    let path = Path::new(&filename);
    let file = File::open(&path)
        .expect(&format!("Cannot open \"{}\": no such file or directory", filename));
    let file_buffer = BufReader::new(file);

    for line in file_buffer.lines() {
        let mut input = String::from(line.unwrap().trim());

        if debug {
            println!(">> {:?}", input);
        }

        // insert semicolon if necessary
        if !input.ends_with(";") && !input.ends_with("}") {
            input.push_str(";");
        }

        if debug {
            println!("=> {:?}", eval_string(&input, &mut scope_manager));
            //println!("** {:?}", state);
        }
    }
}

fn repl(mut scope_manager: &mut ScopeManager) -> i32 {
    let mut rl = Editor::new();
    let mut stderr = io::stderr();

    scope_manager.push_scope();

    if metadata(".history").is_ok() && rl.load_history(".history").is_err() {
        writeln!(stderr, "Error: unable to load history on startup").unwrap();
    }

    loop {
        // prompt
        let readline = rl.readline(">> ");

        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                let mut input = String::from(line.trim());

                // ignore if only whitespace
                if input.len() == 0 {
                    continue;
                }

                rl.add_history_entry(&input);

                // insert semicolon if necessary
                if !input.ends_with(";") && !input.ends_with("}") {
                    input.push_str(";");
                }

                // eval
                println!("=> {:?}", eval_string(&input, &mut scope_manager).t);
                //println!("** {:?}", state);
            },
            Err(ReadlineError::Interrupted) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 1;
            },
            Err(ReadlineError::Eof) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);

                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 3;
            }
        }
    }
    0
}

fn main() {
    let mut scope_manager = init_gc();

    let args = env::args();
    if args.len() > 1 {
        for file in args.skip(1) {
            eval_file(file, false, &mut scope_manager);
        }
    } else {
        let ret = repl(&mut scope_manager);
        exit(ret)
    }
}
<commit_msg>Print from eval_string.<commit_after>#![feature(test)]

extern crate js_types;
extern crate jsrs_common;
extern crate jsrs_parser;
extern crate french_press;
extern crate test;

extern crate rustyline;

mod bench;
mod coerce;
mod eval;

use std::env;
use std::io::prelude::*;
use std::process::exit;
use std::io::{self, BufReader};
use std::path::Path;
use std::fs::{File, metadata};

use rustyline::error::ReadlineError;
use rustyline::Editor;

use french_press::{init_gc, ScopeManager};
use js_types::js_var::JsType::JsUndef;

use eval::eval_string;

fn eval_file(filename: String, debug: bool, mut scope_manager: &mut ScopeManager) {
    println!("Reading from \"{}\"", filename);
    let path = Path::new(&filename);
    let file = File::open(&path)
        .expect(&format!("Cannot open \"{}\": no such file or directory", filename));
    let file_buffer = BufReader::new(file);

    for line in file_buffer.lines() {
        let mut input = String::from(line.unwrap().trim());

        if debug {
            println!(">> {:?}", input);
        }

        // insert semicolon if necessary
        if !input.ends_with(";") && !input.ends_with("}") {
            input.push_str(";");
        }

        if debug {
            println!("=> {:?}", eval_string(&input, &mut scope_manager));
            //println!("** {:?}", state);
        }
    }
}

fn repl(mut scope_manager: &mut ScopeManager) -> i32 {
    let mut rl = Editor::new();
    let mut stderr = io::stderr();

    scope_manager.push_scope();

    if metadata(".history").is_ok() && rl.load_history(".history").is_err() {
        writeln!(stderr, "Error: unable to load history on startup").unwrap();
    }

    loop {
        // prompt
        let readline = rl.readline(">> ");

        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                let mut input = String::from(line.trim());

                // ignore if only whitespace
                if input.len() == 0 {
                    continue;
                }

                rl.add_history_entry(&input);

                // insert semicolon if necessary
                if !input.ends_with(";") && !input.ends_with("}") {
                    input.push_str(";");
                }

                // eval
                let ret_type = match eval_string(&input, &mut scope_manager) {
                    Some(var) => var.t,
                    None => JsUndef,
                };

                println!("=> {:?}", ret_type);
            },
            Err(ReadlineError::Interrupted) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 1;
            },
            Err(ReadlineError::Eof) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);

                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 3;
            }
        }
    }
    0
}

fn main() {
    let mut scope_manager = init_gc();

    let args = env::args();
    if args.len() > 1 {
        for file in args.skip(1) {
            eval_file(file, false, &mut scope_manager);
        }
    } else {
        let ret = repl(&mut scope_manager);
        exit(ret)
    }
}
<|endoftext|>


<commit_before>pub mod api;
pub mod db;
pub mod indexer;
pub mod model;
pub mod opening;
pub mod util;

use std::{mem, net::SocketAddr, path::PathBuf, sync::Arc, time::Duration};

use axum::{
    extract::{Extension, Path, Query},
    handler::get,
    http::StatusCode,
    AddExtensionLayer, Router,
};
use clap::Clap;
use futures_util::stream::Stream;
use shakmaty::{fen::Fen, variant::VariantPosition, zobrist::Zobrist, CastlingMode};
use tokio::sync::oneshot;

use crate::{
    api::{
        Error, GameRow, GameRowWithUci, PersonalMoveRow, PersonalQuery, PersonalQueryFilter,
        PersonalResponse,
    },
    db::Database,
    indexer::{IndexerOpt, IndexerStub},
    model::{PersonalKeyBuilder, PersonalKeyPrefix},
    opening::{Opening, Openings},
    util::NdJson,
};

#[derive(Clap)]
struct Opt {
    #[clap(long = "bind", default_value = "127.0.0.1:9000")]
    bind: SocketAddr,
    #[clap(long = "db", default_value = "_db")]
    db: PathBuf,
    #[clap(flatten)]
    indexer: IndexerOpt,
}

#[tokio::main]
async fn main() {
    env_logger::init_from_env(
        env_logger::Env::new()
            .filter("EXPLORER_LOG")
            .write_style("EXPLORER_LOG_STYLE"),
    );

    let opt = Opt::parse();

    let openings: &'static Openings = Box::leak(Box::new(Openings::build_table()));
    let db = Arc::new(Database::open(opt.db).expect("db"));
    let (indexer, join_handles) = IndexerStub::spawn(db.clone(), opt.indexer);

    let app = Router::new()
        .route("/admin/:prop", get(db_property))
        .route("/admin/game/:prop", get(game_property))
        .route("/admin/personal/:prop", get(personal_property))
        .route("/personal", get(personal))
        .layer(AddExtensionLayer::new(openings))
        .layer(AddExtensionLayer::new(db))
        .layer(AddExtensionLayer::new(indexer));

    axum::Server::bind(&opt.bind)
        .serve(app.into_make_service())
        .with_graceful_shutdown(async {
            tokio::signal::ctrl_c().await.expect("wait for ctrl-c");
        })
        .await
        .expect("bind");

    for join_handle in join_handles {
        join_handle.await.expect("indexer");
    }
}

async fn db_property(
    Extension(db): Extension<Arc<Database>>,
    Path(prop): Path<String>,
) -> Result<String, StatusCode> {
    db.queryable()
        .db_property(&prop)
        .expect("get property")
        .ok_or(StatusCode::NOT_FOUND)
}

async fn game_property(
    Extension(db): Extension<Arc<Database>>,
    Path(prop): Path<String>,
) -> Result<String, StatusCode> {
    db.queryable()
        .game_property(&prop)
        .expect("get property")
        .ok_or(StatusCode::NOT_FOUND)
}

async fn personal_property(
    Extension(db): Extension<Arc<Database>>,
    Path(prop): Path<String>,
) -> Result<String, StatusCode> {
    db.queryable()
        .personal_property(&prop)
        .expect("get property")
        .ok_or(StatusCode::NOT_FOUND)
}

struct PersonalStreamState {
    indexing: Option<oneshot::Receiver<()>>,
    key: PersonalKeyPrefix,
    db: Arc<Database>,
    filter: PersonalQueryFilter,
    pos: VariantPosition,
    opening: Option<&'static Opening>,
    first: bool,
    done: bool,
}

async fn personal(
    Extension(openings): Extension<&'static Openings>,
    Extension(db): Extension<Arc<Database>>,
    Extension(indexer): Extension<IndexerStub>,
    Query(query): Query<PersonalQuery>,
) -> Result<NdJson<impl Stream<Item = PersonalResponse>>, Error> {
    let indexing = if query.update {
        Some(indexer.index_player(query.player.clone()).await)
    } else {
        None
    };

    let variant = query.variant.into();

    let mut pos = Zobrist::new(match query.fen {
        Some(fen) => VariantPosition::from_setup(variant, &Fen::from(fen), CastlingMode::Chess960)?,
        None => VariantPosition::new(variant),
    });

    let opening = openings.classify_and_play(&mut pos, query.play)?;

    let key = PersonalKeyBuilder::with_user_pov(&query.player.into(), query.color)
        .with_zobrist(variant, pos.zobrist_hash());

    let state = PersonalStreamState {
        filter: query.filter,
        db,
        indexing,
        opening,
        key,
        pos: pos.into_inner(),
        first: true,
        done: false,
    };

    Ok(NdJson::new(futures_util::stream::unfold(
        state,
        |mut state| async move {
            if state.done {
                return None;
            }

            let first = mem::replace(&mut state.first, false);
            state.done = match state.indexing {
                Some(ref mut indexing) => {
                    tokio::select! {
                        _ = indexing => true,
                        _ = tokio::time::sleep(Duration::from_millis(if first { 200 } else { 5000 })) => false,
                    }
                }
                None => true,
            };
            let queryable = state.db.queryable();
            let filtered = queryable
                .get_personal(&state.key, state.filter.since, state.filter.until)
                .expect("get personal")
                .prepare(&state.pos, &state.filter);

            Some((
                PersonalResponse {
                    total: filtered.total,
                    moves: filtered
                        .moves
                        .into_iter()
                        .map(|row| PersonalMoveRow {
                            uci: row.uci,
                            san: row.san,
                            stats: row.stats,
                            game: row.game.and_then(|id| {
                                queryable
                                    .get_game_info(id)
                                    .expect("get game")
                                    .map(|info| GameRow { id, info })
                            }),
                        })
                        .collect(),
                    recent_games: filtered
                        .recent_games
                        .into_iter()
                        .flat_map(|(uci, id)| {
                            queryable.get_game_info(id).expect("get game").map(|info| {
                                GameRowWithUci {
                                    uci,
                                    row: GameRow { id, info },
                                }
                            })
                        })
                        .collect(),
                    opening: state.opening,
                },
                state,
            ))
        },
    )))
}
<commit_msg>poll stream every second<commit_after>pub mod api;
pub mod db;
pub mod indexer;
pub mod model;
pub mod opening;
pub mod util;

use std::{mem, net::SocketAddr, path::PathBuf, sync::Arc, time::Duration};

use axum::{
    extract::{Extension, Path, Query},
    handler::get,
    http::StatusCode,
    AddExtensionLayer, Router,
};
use clap::Clap;
use futures_util::stream::Stream;
use shakmaty::{fen::Fen, variant::VariantPosition, zobrist::Zobrist, CastlingMode};
use tokio::sync::oneshot;

use crate::{
    api::{
        Error, GameRow, GameRowWithUci, PersonalMoveRow, PersonalQuery, PersonalQueryFilter,
        PersonalResponse,
    },
    db::Database,
    indexer::{IndexerOpt, IndexerStub},
    model::{PersonalKeyBuilder, PersonalKeyPrefix},
    opening::{Opening, Openings},
    util::NdJson,
};

#[derive(Clap)]
struct Opt {
    #[clap(long = "bind", default_value = "127.0.0.1:9000")]
    bind: SocketAddr,
    #[clap(long = "db", default_value = "_db")]
    db: PathBuf,
    #[clap(flatten)]
    indexer: IndexerOpt,
}

#[tokio::main]
async fn main() {
    env_logger::init_from_env(
        env_logger::Env::new()
            .filter("EXPLORER_LOG")
            .write_style("EXPLORER_LOG_STYLE"),
    );

    let opt = Opt::parse();

    let openings: &'static Openings = Box::leak(Box::new(Openings::build_table()));
    let db = Arc::new(Database::open(opt.db).expect("db"));
    let (indexer, join_handles) = IndexerStub::spawn(db.clone(), opt.indexer);

    let app = Router::new()
        .route("/admin/:prop", get(db_property))
        .route("/admin/game/:prop", get(game_property))
        .route("/admin/personal/:prop", get(personal_property))
        .route("/personal", get(personal))
        .layer(AddExtensionLayer::new(openings))
        .layer(AddExtensionLayer::new(db))
        .layer(AddExtensionLayer::new(indexer));

    axum::Server::bind(&opt.bind)
        .serve(app.into_make_service())
        .with_graceful_shutdown(async {
            tokio::signal::ctrl_c().await.expect("wait for ctrl-c");
        })
        .await
        .expect("bind");

    for join_handle in join_handles {
        join_handle.await.expect("indexer");
    }
}

async fn db_property(
    Extension(db): Extension<Arc<Database>>,
    Path(prop): Path<String>,
) -> Result<String, StatusCode> {
    db.queryable()
        .db_property(&prop)
        .expect("get property")
        .ok_or(StatusCode::NOT_FOUND)
}

async fn game_property(
    Extension(db): Extension<Arc<Database>>,
    Path(prop): Path<String>,
) -> Result<String, StatusCode> {
    db.queryable()
        .game_property(&prop)
        .expect("get property")
        .ok_or(StatusCode::NOT_FOUND)
}

async fn personal_property(
    Extension(db): Extension<Arc<Database>>,
    Path(prop): Path<String>,
) -> Result<String, StatusCode> {
    db.queryable()
        .personal_property(&prop)
        .expect("get property")
        .ok_or(StatusCode::NOT_FOUND)
}

struct PersonalStreamState {
    indexing: Option<oneshot::Receiver<()>>,
    key: PersonalKeyPrefix,
    db: Arc<Database>,
    filter: PersonalQueryFilter,
    pos: VariantPosition,
    opening: Option<&'static Opening>,
    first: bool,
    done: bool,
}

async fn personal(
    Extension(openings): Extension<&'static Openings>,
    Extension(db): Extension<Arc<Database>>,
    Extension(indexer): Extension<IndexerStub>,
    Query(query): Query<PersonalQuery>,
) -> Result<NdJson<impl Stream<Item = PersonalResponse>>, Error> {
    let indexing = if query.update {
        Some(indexer.index_player(query.player.clone()).await)
    } else {
        None
    };

    let variant = query.variant.into();

    let mut pos = Zobrist::new(match query.fen {
        Some(fen) => VariantPosition::from_setup(variant, &Fen::from(fen), CastlingMode::Chess960)?,
        None => VariantPosition::new(variant),
    });

    let opening = openings.classify_and_play(&mut pos, query.play)?;

    let key = PersonalKeyBuilder::with_user_pov(&query.player.into(), query.color)
        .with_zobrist(variant, pos.zobrist_hash());

    let state = PersonalStreamState {
        filter: query.filter,
        db,
        indexing,
        opening,
        key,
        pos: pos.into_inner(),
        first: true,
        done: false,
    };

    Ok(NdJson::new(futures_util::stream::unfold(
        state,
        |mut state| async move {
            if state.done {
                return None;
            }

            let first = mem::replace(&mut state.first, false);
            state.done = match state.indexing {
                Some(ref mut indexing) => {
                    tokio::select! {
                        _ = indexing => true,
                        _ = tokio::time::sleep(Duration::from_millis(if first { 200 } else { 1000 })) => false,
                    }
                }
                None => true,
            };
            let queryable = state.db.queryable();
            let filtered = queryable
                .get_personal(&state.key, state.filter.since, state.filter.until)
                .expect("get personal")
                .prepare(&state.pos, &state.filter);

            Some((
                PersonalResponse {
                    total: filtered.total,
                    moves: filtered
                        .moves
                        .into_iter()
                        .map(|row| PersonalMoveRow {
                            uci: row.uci,
                            san: row.san,
                            stats: row.stats,
                            game: row.game.and_then(|id| {
                                queryable
                                    .get_game_info(id)
                                    .expect("get game")
                                    .map(|info| GameRow { id, info })
                            }),
                        })
                        .collect(),
                    recent_games: filtered
                        .recent_games
                        .into_iter()
                        .flat_map(|(uci, id)| {
                            queryable.get_game_info(id).expect("get game").map(|info| {
                                GameRowWithUci {
                                    uci,
                                    row: GameRow { id, info },
                                }
                            })
                        })
                        .collect(),
                    opening: state.opening,
                },
                state,
            ))
        },
    )))
}
<|endoftext|>


<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::Command;
use syntax::ast;

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      cfg: &ast::CrateConfig,
                      descriptions: &rustc_errors::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                cfg: &ast::CrateConfig,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &rustc_errors::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     cfg: &ast::CrateConfig,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.default.late_callback(matches, sess, cfg, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed").span);
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           mir_passes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.mir_passes.borrow_mut().extend(mir_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
        format!("{}/toolchains/{}", home, toolchain)
    } else {
        option_env!("SYSROOT")
            .map(|s| s.to_owned())
            .or(Command::new("rustc")
                .arg("--print")
                .arg("sysroot")
                .output()
                .ok()
                .and_then(|out| String::from_utf8(out.stdout).ok())
                .map(|s| s.trim().to_owned()))
            .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
    };

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`
        let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));

        let mut metadata = cargo::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)).expect("could not obtain cargo metadata");
        assert_eq!(metadata.version, 1);

        let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));

        let current_dir = std::env::current_dir();

        let package_index = metadata.packages.iter()
            .position(|package| {
                let package_manifest_path = Path::new(&package.manifest_path);
                if let Some(ref manifest_path) = manifest_path {
                    package_manifest_path == manifest_path
                } else if let Ok(ref current_dir) = current_dir {
                    let package_manifest_directory = package_manifest_path.parent().expect("could not find parent directory of package manifest");
                    package_manifest_directory == current_dir
                } else {
                    panic!("could not read current directory")
                }
            })
            .expect("could not find matching package");
        let package = metadata.packages.remove(package_index);
        for target in package.targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    if let Err(code) = process(vec![format!("--{}", first), target.name].into_iter().chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
        // without having to pass --sysroot or anything
        let args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };
        // this check ensures that dependencies are built but not linted and the final crate is
        // linted but not built
        let mut ccc = ClippyCompilerCalls::new(env::args().any(|s| s == "-Zno-trans"));
        let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P, sysroot: &str) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push(String::from("--sysroot"));
    args.push(sysroot.to_owned());
    args.push("-Zno-trans".to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>Use .expect() for extracting the current_dir.<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::Command;
use syntax::ast;

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      cfg: &ast::CrateConfig,
                      descriptions: &rustc_errors::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                cfg: &ast::CrateConfig,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &rustc_errors::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     cfg: &ast::CrateConfig,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.default.late_callback(matches, sess, cfg, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed").span);
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           mir_passes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.mir_passes.borrow_mut().extend(mir_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
        format!("{}/toolchains/{}", home, toolchain)
    } else {
        option_env!("SYSROOT")
            .map(|s| s.to_owned())
            .or(Command::new("rustc")
                .arg("--print")
                .arg("sysroot")
                .output()
                .ok()
                .and_then(|out| String::from_utf8(out.stdout).ok())
                .map(|s| s.trim().to_owned()))
            .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
    };

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`
        let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));

        let mut metadata = cargo::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)).expect("could not obtain cargo metadata");
        assert_eq!(metadata.version, 1);

        let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));

        let current_dir = std::env::current_dir();

        let package_index = metadata.packages.iter()
            .position(|package| {
                let package_manifest_path = Path::new(&package.manifest_path);
                if let Some(ref manifest_path) = manifest_path {
                    package_manifest_path == manifest_path
                } else {
                    let current_dir = current_dir.as_ref().expect("could not read current directory");
                    let package_manifest_directory = package_manifest_path.parent().expect("could not find parent directory of package manifest");
                    package_manifest_directory == current_dir
                }
            })
            .expect("could not find matching package");
        let package = metadata.packages.remove(package_index);
        for target in package.targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    if let Err(code) = process(vec![format!("--{}", first), target.name].into_iter().chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
        // without having to pass --sysroot or anything
        let args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };
        // this check ensures that dependencies are built but not linted and the final crate is
        // linted but not built
        let mut ccc = ClippyCompilerCalls::new(env::args().any(|s| s == "-Zno-trans"));
        let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P, sysroot: &str) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push(String::from("--sysroot"));
    args.push(sysroot.to_owned());
    args.push("-Zno-trans".to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate time;

mod radio;
mod util;

use std::fs;
use std::thread;
use std::time::Duration;

use radio::Radio;
use radio::data::RADIOSTATIONS;
use util::logger::log;

fn main() {
    // Create log directory in case it doesn't exist
    let _ = fs::create_dir("log");
    log("Start Analyzing Radio stations");
    for station in RADIOSTATIONS {
        thread::spawn(move || {
            let mut last_song = String::new();
            loop {
                // TODO: Save song in hash-map
                // TODO: Serialize hash-map
                let song = station.get_current_song();
                match song {
                    Some(song) => {
                        if  last_song != song {
                            log(&format!("{}: Song changed", station.name));
                            println!("{}: {}", station.name, song);
                            last_song = song;
                        }
                    },
                    None => {},
                }
                thread::sleep(Duration::from_secs(30));
            }
        });
    }
    println!("-- Press any key to end program --");
    // stdin blocks mains thread, so we don't need to join the other threads
    std::io::stdin()
                .read_line(&mut String::new())
                .expect("something went seriously wrong :O");
    log("Stop Analyzing Radio stations");
}

pub fn radio_antenne(html: &str) -> Option<String> {
    if html.contains("\"total\":1") {
        return None;
    }
    // General suffix for all fields
    let suffix = "\",";
    // Response contains two results, songs is saved in type PE_E
    // It is not ensured that the PE_E is the always the first/second part of the response
    let type_ident = "\"type\":\"PE_E\"";
    let (_, html) = html.split_at(html.find(type_ident).unwrap() + type_ident.len());
    // Artist
    let artist_prefix = "\"artistName\":\"";
    let a_pos = html.find(artist_prefix).unwrap();
    let (_, artist) = html.split_at(a_pos + artist_prefix.len());
    let a_pos = artist.find(suffix).unwrap();
    let (artist , _) = artist.split_at(a_pos);
    // Song
    let song_prefix = "\"name\":\"";
    let s_pos = html.find(song_prefix).unwrap();
    let (_, song) = html.split_at(s_pos + song_prefix.len());
    let s_pos = song.find(suffix).unwrap();
    let (song , _) = song.split_at(s_pos);
    Some(format!("{} - {}", artist, song))
}
<commit_msg>Remove unused fn in main<commit_after>extern crate hyper;
extern crate time;

mod radio;
mod util;

use std::fs;
use std::thread;
use std::time::Duration;

use radio::Radio;
use radio::data::RADIOSTATIONS;
use util::logger::log;

fn main() {
    // Create log directory in case it doesn't exist
    let _ = fs::create_dir("log");
    log("Start Analyzing Radio stations");
    for station in RADIOSTATIONS {
        thread::spawn(move || {
            let mut last_song = String::new();
            loop {
                // TODO: Save song in hash-map
                // TODO: Serialize hash-map
                let song = station.get_current_song();
                match song {
                    Some(song) => {
                        if  last_song != song {
                            log(&format!("{}: Song changed", station.name));
                            println!("{}: {}", station.name, song);
                            last_song = song;
                        }
                    },
                    None => {},
                }
                thread::sleep(Duration::from_secs(30));
            }
        });
    }
    println!("-- Press any key to end program --");
    // stdin blocks mains thread, so we don't need to join the other threads
    std::io::stdin()
                .read_line(&mut String::new())
                .expect("something went seriously wrong :O");
    log("Stop Analyzing Radio stations");
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate x11;
extern crate getopts;

mod matches;
mod ui;

use ui::UI;
use matches::simple_match;
use matches::fuzzy_match;
use matches::dmenu_match;
use std::str::FromStr;
use std::io::BufRead;
use std::io::BufReader;
use std::fs::File;
use std::env;
use std::iter::Iterator;

use getopts::Options;

const VERSION: &'static str = "0.0.1";

pub struct Settings {
    topbar: bool,
    fast: bool,
    casesensitive: bool,
    lines: u32,
    prompt: String,
    font: String,
    normbgcolor: String,
    normfgcolor: String,
    selbgcolor: String,
    selfgcolor: String,
    cache_file: String,
    matcher: String,
}

impl Settings {
    fn new() -> Settings{
        Settings {
            topbar: false,
            fast: false,
            casesensitive: true,
            lines: 0,
            prompt: String::new(),
            font: "fixed".to_string(),
            normbgcolor: "rgb:22/22/22".to_string(),
            normfgcolor: "rgb:bb/bb/bb".to_string(),
            selbgcolor: "rgb:00/55/77".to_string(),
            selfgcolor: "rgb:ee/ee/ee".to_string(),
            cache_file: "-".to_string(),
            matcher: "simple".to_string(),
        }
    }
}

struct Status {
    text: String,
    matches: Vec<String>,
    items: Vec<String>,
    selected: String,
    page: u32,
    settings: Settings,
}

fn readitems(settings: &Settings) -> Vec<String> {
    let mut items = vec![];
    let mut input_items: Vec<_>;

    if settings.cache_file == "-" {
        let stdin = std::io::stdin();
        input_items = stdin.lock().lines().collect();
    } else {
        input_items = match File::open(settings.cache_file.clone()) {
            Ok(file) => BufReader::new(file).lines().collect(),
            Err(e) => panic!("{}", e)
        }
    }
    for item in input_items {
        items.push(item.unwrap())
    }
    items
}

fn main () {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut settings = Settings::new();

    let mut opts = Options::new();
    opts.optflag("v", "version", "show version");
    opts.optflag("b", "topbar", "show topbar");
    opts.optflag("f", "fast", "fast start");
    opts.optflag("h", "help", "show help");
    opts.optflag("i", "caseinsensitive", "activate case insensitive");

    opts.optopt("l", "lines", "lines of vertical list", "LINES");
    opts.optopt("c", "cache", "cache file with available commands", "CACHE_FILE");
    opts.optopt("p", "prompt", "add prompt to left of input field", "PROMPT");
    opts.optopt("m", "matcher", "select matcher function", "simple|dmenu|fuzzy");
    opts.optopt("", "font", "font or font set", "FONT");
    opts.optopt("", "background", "normal background color", "NBG");
    opts.optopt("", "foreground", "normal foreground color", "NFG");
    opts.optopt("", "sbackground", "selected background color", "SBG");
    opts.optopt("", "sforeground", "selected foreground color", "SFG");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("v") {
        println!("rumenu-{}, © 2015 Jesús Espino, see LICENSE for details", VERSION);
        return;
    }

    if matches.opt_present("h") {
        let brief = format!("Usage: {} [options]", program);
        print!("{}", opts.usage(&brief));
        return;
    }

    settings.topbar = matches.opt_present("b");
    settings.fast = matches.opt_present("f");
    settings.casesensitive = !matches.opt_present("i");

    match matches.opt_str("l") {
        Some(lines_str) => {
            match u32::from_str(lines_str.trim()) {
                Ok(l) => { settings.lines = l }
                Err(f) => { println!("{}", f.to_string()); return }
            }
        }
        None => {
            settings.lines = 0
        }
    }

    settings.prompt =  matches.opt_str("p").unwrap_or(String::new());
    settings.matcher =  matches.opt_str("m").unwrap_or("simple".to_string());
    settings.font = matches.opt_str("font").unwrap_or("fixed".to_string());
    settings.normbgcolor = matches.opt_str("background").unwrap_or("rgb:22/22/22".to_string());
    settings.normfgcolor = matches.opt_str("foreground").unwrap_or("rgb:bb/bb/bb".to_string());
    settings.selbgcolor = matches.opt_str("sbackground").unwrap_or("rgb:00/55/77".to_string());
    settings.selfgcolor = matches.opt_str("sforeground").unwrap_or("rgb:ee/ee/ee".to_string());
    settings.cache_file = matches.opt_str("cache").unwrap_or("-".to_string());

    let mut ui = UI::new(&settings);

    let items = readitems(&settings);

    let mut status = Status {
        text: "".to_string(),
        matches: vec![],
        items: items,
        selected: "".to_string(),
        page: 0,
        settings: settings,
    };

    if status.settings.matcher == "fuzzy" {
        status.matches = fuzzy_match(&status.text, &status.items);
    } else if status.settings.matcher == "dmenu" {
        status.matches = dmenu_match(&status.text, &status.items);
    } else {
        status.matches = simple_match(&status.text, &status.items);
    }

    status.selected = status.matches.first().unwrap_or(&"".to_string()).clone();
    ui.run(status);
}
<commit_msg>A bit of refactoring main.rs<commit_after>extern crate libc;
extern crate x11;
extern crate getopts;

mod matches;
mod ui;

use ui::UI;
use matches::simple_match;
use matches::fuzzy_match;
use matches::dmenu_match;
use std::str::FromStr;
use std::io::BufRead;
use std::io::BufReader;
use std::fs::File;
use std::env;
use std::iter::Iterator;

use getopts::Options;

const VERSION: &'static str = "0.0.1";

pub struct Settings {
    topbar: bool,
    casesensitive: bool,
    lines: u32,
    prompt: String,
    font: String,
    normbgcolor: String,
    normfgcolor: String,
    selbgcolor: String,
    selfgcolor: String,
    cache_file: String,
    matcher: String,
}

struct Status {
    text: String,
    matches: Vec<String>,
    items: Vec<String>,
    selected: String,
    page: u32,
    settings: Settings,
}

fn readitems(settings: &Settings) -> Vec<String> {
    let mut items = vec![];
    let mut input_items: Vec<_>;

    if settings.cache_file == "-" {
        let stdin = std::io::stdin();
        input_items = stdin.lock().lines().collect();
    } else {
        input_items = match File::open(settings.cache_file.clone()) {
            Ok(file) => BufReader::new(file).lines().collect(),
            Err(e) => panic!("{}", e)
        }
    }
    for item in input_items {
        items.push(item.unwrap())
    }
    items
}

fn parse_args(args: Vec<String>) -> (bool, Settings) {
    let mut opts = Options::new();
    opts.optflag("v", "version", "show version");
    opts.optflag("b", "topbar", "show topbar");
    opts.optflag("h", "help", "show help");
    opts.optflag("i", "caseinsensitive", "activate case insensitive");

    opts.optopt("l", "lines", "lines of vertical list", "LINES");
    opts.optopt("c", "cache", "cache file with available commands", "CACHE_FILE");
    opts.optopt("p", "prompt", "add prompt to left of input field", "PROMPT");
    opts.optopt("m", "matcher", "select matcher function", "simple|dmenu|fuzzy");
    opts.optopt("", "font", "font or font set", "FONT");
    opts.optopt("", "background", "normal background color", "NBG");
    opts.optopt("", "foreground", "normal foreground color", "NFG");
    opts.optopt("", "sbackground", "selected background color", "SBG");
    opts.optopt("", "sforeground", "selected foreground color", "SFG");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    let lines = match matches.opt_str("l") {
        Some(lines_str) => {
            u32::from_str(lines_str.trim()).unwrap_or(0)
        },
        None => 0
    };

    let settings = Settings {
        topbar: matches.opt_present("b"),
        casesensitive: !matches.opt_present("i"),
        lines: lines,
        prompt:  matches.opt_str("p").unwrap_or(String::new()),
        matcher:  matches.opt_str("m").unwrap_or("simple".to_string()),
        font: matches.opt_str("font").unwrap_or("fixed".to_string()),
        normbgcolor: matches.opt_str("background").unwrap_or("rgb:22/22/22".to_string()),
        normfgcolor: matches.opt_str("foreground").unwrap_or("rgb:bb/bb/bb".to_string()),
        selbgcolor: matches.opt_str("sbackground").unwrap_or("rgb:00/55/77".to_string()),
        selfgcolor: matches.opt_str("sforeground").unwrap_or("rgb:ee/ee/ee".to_string()),
        cache_file: matches.opt_str("cache").unwrap_or("-".to_string()),
    };

    let mut exit = false;
    if matches.opt_present("v") {
        println!("rumenu-{}, © 2015 Jesús Espino, see LICENSE for details", VERSION);
        exit = true;
    }
    if matches.opt_present("h") {
        let brief = format!("Usage: {} [options]", args[0].clone());
        print!("{}", opts.usage(&brief));
        exit = true
    }
    (exit, settings)
}

fn main () {
    let args: Vec<String> = env::args().collect();

    let (exit, settings) = parse_args(args);
    if exit { return; }

    let mut ui = UI::new(&settings);

    let items = readitems(&settings);

    let mut status = Status {
        text: "".to_string(),
        matches: vec![],
        items: items,
        selected: "".to_string(),
        page: 0,
        settings: settings,
    };

    if status.settings.matcher == "fuzzy" {
        status.matches = fuzzy_match(&status.text, &status.items);
    } else if status.settings.matcher == "dmenu" {
        status.matches = dmenu_match(&status.text, &status.items);
    } else {
        status.matches = simple_match(&status.text, &status.items);
    }

    status.selected = status.matches.first().unwrap_or(&"".to_string()).clone();
    ui.run(status);
}
<|endoftext|>