<commit_before>use std::hash::{hash,Hash};
use std::collections::HashMap;
use std::thunk::Invoke;
use std::mem::replace;
use std::sync::Arc;
use std::cell::RefCell;

// "One big memo table" design

pub trait Adapton {
    fn new () -> Self ;

    // Names
    fn name_of_string (self:&mut Self, String) -> Name ;
    fn name_of_u64 (self:&mut Self, u64) -> Name ;
    fn name_pair (self: &Self, Name, Name) -> Name ;
    fn name_fork (self:&mut Self, Name) -> (Name, Name) ;

    fn ns<T,F> (self: &mut Self, Name,
                 body:F) -> T where F:FnOnce(&mut Self) -> T;

    fn put<T:Eq> (self:&mut Self, T) -> Art<T> ;

    // Mutable cells
    fn cell<T:Eq> (self:&mut Self, ArtId, T) -> MutArt<T> ;
    fn set<T:Eq> (self:&mut Self, MutArt<T>) ;

    fn thunk<Arg:Eq+Hash,T:Eq>
        (self:&mut Self, id:ArtId,
         fn_body:Box<Invoke<Arg, T> + 'static>, arg:Arg) -> Art<T> ;

    fn force<T:Eq> (self:&mut Self, Art<T>) -> T ;
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum Lineage {
    Unknown, Structural,
    Root,
    Pair(Arc<Lineage>,Arc<Lineage>),
    ForkL(Arc<Lineage>),
    ForkR(Arc<Lineage>),
    String(String),
    U64(u64),
    Arc(Arc<Lineage>),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum Path {
    Empty,
    Child(Arc<Path>,Name),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub struct Name {
    hash : u64,
    lineage : Arc<Lineage>,
    path : Arc<Path>,
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum ArtId {
    None,
    Structural(u64),
    Nominal(Name),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum Art<T> {
    Box(Box<T>),
    Node(Arc<Name>),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum MutArt<T> {
    MutArt(Art<T>)
}

enum Node<T> {
    Pure(PureNode<T>),
    Mut(MutNode<T>),
    Compute(ComputeNode<T>),
}

struct PureNode<T> {
    name : Name,
    val : T,
}

struct MutNode<T> {
    name : Name,
    dem_precs : Vec<DemPrec>,
    val : RefCell<T>,
}

trait Body<T> {
    fn run (self:&Self, st:&mut AdaptonState) -> T ;
}

struct ComputeNode<T> {
    name : Name,
    dem_precs : Vec<DemPrec>,
    dem_succs : Vec<DemSucc>,
    body : Box<Body<T> + 'static>, // Trait in Type: Need lifetime.
    val  : RefCell<Option<T>>,
}

struct DemPrec {
    name : Name,
}

struct DemSucc {
    name : Name,
    dirty : RefCell<bool>
}

pub struct AdaptonState {
    memo_table : HashMap<ArtId, *mut ()>, // memo table
    curr_path : Arc<Path>, // current_namespace
    curr_name : Arc<Name>, // current articulation point
}

impl Adapton for AdaptonState {
    fn new () -> AdaptonState {
        let empty = Arc::new(Path::Empty);
        let root = Arc::new(Name{hash:0, lineage:Arc::new(Lineage::Root), path:empty.clone()});
        AdaptonState {
            memo_table : HashMap::new (),
            curr_path : empty,
            curr_name : root,
        }
    }
    fn name_of_string (self:&mut AdaptonState, sym:String) -> Name {
        let h = hash::<_>(&sym) ;
        let s = Lineage::String(sym) ;
        Name{ hash:h, lineage:Arc::new(s), path:self.curr_path.clone() }
    }
    fn name_of_u64 (self:&mut AdaptonState, sym:u64) -> Name {
        let h = hash::<_>(&sym) ;
        let s = Lineage::U64(sym) ;
        Name{ hash:h, lineage:Arc::new(s), path:self.curr_path.clone() }
    }
    fn name_pair (self: &AdaptonState, fst: Name, snd: Name) -> Name {
        let h = hash::<_>( &(fst.hash,snd.hash) ) ;
        let p = Lineage::Pair(fst.lineage, snd.lineage) ;
        Name{ hash:h, lineage:Arc::new(p), path:self.curr_path.clone() }
    }
    fn name_fork (self:&mut AdaptonState, nm:Name) -> (Name, Name) {
        let h1 = hash::<_>( &(&nm, 11111111) ) ; // TODO: make this hashing better.
        let h2 = hash::<_>( &(&nm, 22222222) ) ;
        ( Name{ hash:h1,
                lineage:Arc::new(Lineage::ForkL(nm.lineage.clone())),
                path:self.curr_path.clone() } ,
          Name{ hash:h2,
                lineage:Arc::new(Lineage::ForkR(nm.lineage)),
                path:self.curr_path.clone() } )
    }
    fn ns<T,F> (self: &mut Self, nm:Name, body:F) -> T where F:FnOnce(&mut Self) -> T {
        let path_body = Arc::new(Path::Child(self.curr_path.clone(), nm)) ;
        let path_pre = replace(&mut self.curr_path, path_body ) ;
        let x = body(self) ;
        let path_body = replace(&mut self.curr_path, path_pre) ;
        drop(path_body);
        x
    }
    fn put<T:Eq> (self:&mut AdaptonState, x:T) -> Art<T> {
        Art::Box(box x)
    }
    fn cell<T:Eq> (self:&mut AdaptonState, id:ArtId, x:T) -> MutArt<T> {
        panic!("")
    }
    fn set<T:Eq> (self:&mut Self, cell:MutArt<T>) {
        panic!("")
    }
    fn thunk<Arg:Eq+Hash,T:Eq>
        (self:&mut AdaptonState,
         id:ArtId, fn_body:Box<Invoke<Arg,T>+'static>, arg:Arg) -> Art<T>
    {
        panic!("")
    }
    fn force<T:Eq> (self:&mut AdaptonState, art:Art<T>) -> T {
        match art {
            Art::Box(b) => *b,
            Art::Node(nm) => panic!(""),
        }
    }
}

pub fn main () {

}
<commit_msg>fixing name and path semantics; Loc := (Name, Path)<commit_after>use std::hash::{hash,Hash};
use std::collections::HashMap;
use std::thunk::Invoke;
use std::mem::replace;
use std::sync::Arc;
use std::cell::RefCell;

// "One big memo table" design

pub trait Adapton {
    fn new () -> Self ;

    // Names
    fn name_of_string (self:&mut Self, String) -> Name ;
    fn name_of_u64 (self:&mut Self, u64) -> Name ;
    fn name_pair (self: &Self, Name, Name) -> Name ;
    fn name_fork (self:&mut Self, Name) -> (Name, Name) ;

    fn ns<T,F> (self: &mut Self, Name,
                 body:F) -> T where F:FnOnce(&mut Self) -> T;

    fn put<T:Eq> (self:&mut Self, T) -> Art<T> ;

    // Mutable cells
    fn cell<T:Eq> (self:&mut Self, ArtId, T) -> MutArt<T> ;
    fn set<T:Eq> (self:&mut Self, MutArt<T>) ;

    fn thunk<Arg:Eq+Hash,T:Eq>
        (self:&mut Self, id:ArtId,
         fn_body:Box<Invoke<Arg, T> + 'static>, arg:Arg) -> Art<T> ;

    fn force<T:Eq> (self:&mut Self, Art<T>) -> T ;
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum Lineage {
    Unknown, Structural,
    Root,
    Pair(Arc<Lineage>,Arc<Lineage>),
    ForkL(Arc<Lineage>),
    ForkR(Arc<Lineage>),
    String(String),
    U64(u64),
    Arc(Arc<Lineage>),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum Path {
    Empty,
    Child(Arc<Path>,Name),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub struct Name {
    hash : u64,
    lineage : Arc<Lineage>,
}

#[derive(Hash,Show,PartialEq,Eq)]
pub struct Loc {
    hash : u64,
    name : Arc<Name>,
    path : Arc<Path>
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum ArtId {
    None,
    Structural(u64),
    Nominal(Name),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum Art<T> {
    Box(Box<T>),
    Node(Arc<Loc>),
}

#[derive(Hash,Show,PartialEq,Eq)]
pub enum MutArt<T> {
    MutArt(Art<T>)
}

enum Node<T> {
    Pure(PureNode<T>),
    Mut(MutNode<T>),
    Compute(ComputeNode<T>),
}

struct PureNode<T> {
    name : Name,
    val : T,
}

struct MutNode<T> {
    name : Name,
    dem_precs : Vec<DemPrec>,
    val : RefCell<T>,
}

trait Body<T> {
    fn run (self:&Self, st:&mut AdaptonState) -> T ;
}

struct ComputeNode<T> {
    name : Name,
    dem_precs : Vec<DemPrec>,
    dem_succs : Vec<DemSucc>,
    body : Box<Body<T> + 'static>, // Trait in Type: Need lifetime.
    val  : RefCell<Option<T>>,
}

struct DemPrec {
    name : Name,
}

struct DemSucc {
    name : Name,
    dirty : RefCell<bool>
}

pub struct AdaptonState {
    memo_table : HashMap<ArtId, *mut ()>, // memo table
    curr_path : Arc<Path>, // current_namespace
    curr_name : Arc<Name>, // current articulation point
}

impl Adapton for AdaptonState {
    fn new () -> AdaptonState {
        let empty = Arc::new(Path::Empty);
        let root = Arc::new(Name{hash:0, lineage:Arc::new(Lineage::Root) });
        AdaptonState {
            memo_table : HashMap::new (),
            curr_path : empty,
            curr_name : root,
        }
    }
    fn name_of_string (self:&mut AdaptonState, sym:String) -> Name {
        let h = hash::<_>(&sym) ;
        let s = Lineage::String(sym) ;
        Name{ hash:h, lineage:Arc::new(s) }
    }
    fn name_of_u64 (self:&mut AdaptonState, sym:u64) -> Name {
        let h = hash::<_>(&sym) ;
        let s = Lineage::U64(sym) ;
        Name{ hash:h, lineage:Arc::new(s) }
    }
    fn name_pair (self: &AdaptonState, fst: Name, snd: Name) -> Name {
        let h = hash::<_>( &(fst.hash,snd.hash) ) ;
        let p = Lineage::Pair(fst.lineage, snd.lineage) ;
        Name{ hash:h, lineage:Arc::new(p) }
    }
    fn name_fork (self:&mut AdaptonState, nm:Name) -> (Name, Name) {
        let h1 = hash::<_>( &(&nm, 11111111) ) ; // TODO: make this hashing better.
        let h2 = hash::<_>( &(&nm, 22222222) ) ;
        ( Name{ hash:h1,
                lineage:Arc::new(Lineage::ForkL(nm.lineage.clone())) } ,
          Name{ hash:h2,
                lineage:Arc::new(Lineage::ForkR(nm.lineage)) } )
    }
    fn ns<T,F> (self: &mut Self, nm:Name, body:F) -> T where F:FnOnce(&mut Self) -> T {
        let path_body = Arc::new(Path::Child(self.curr_path.clone(), nm)) ;
        let path_pre = replace(&mut self.curr_path, path_body ) ;
        let x = body(self) ;
        let path_body = replace(&mut self.curr_path, path_pre) ;
        drop(path_body);
        x
    }
    fn put<T:Eq> (self:&mut AdaptonState, x:T) -> Art<T> {
        Art::Box(box x)
    }
    fn cell<T:Eq> (self:&mut AdaptonState, id:ArtId, x:T) -> MutArt<T> {
        panic!("")
    }
    fn set<T:Eq> (self:&mut Self, cell:MutArt<T>) {
        panic!("")
    }
    fn thunk<Arg:Eq+Hash,T:Eq>
        (self:&mut AdaptonState,
         id:ArtId, fn_body:Box<Invoke<Arg,T>+'static>, arg:Arg) -> Art<T>
    {
        panic!("")
    }
    fn force<T:Eq> (self:&mut AdaptonState, art:Art<T>) -> T {
        match art {
            Art::Box(b) => *b,
            Art::Node(nm) => panic!(""),
        }
    }
}

pub fn main () {

}
<|endoftext|>


<commit_before>extern crate polydraw;

use polydraw::geom::point::Point;
use polydraw::draw::RGB;

struct Poly {
   points: Vec<Point>,
   color: RGB,
}

struct Scene {
   background: RGB,
   polys: Vec<Poly>,
}

impl Scene {
   #[inline]
   fn new(background: RGB) -> Self {
      Scene {
         background: background,
         polys: Vec::new(),
      }
   }

   #[inline]
   pub fn push(&mut self, poly: Poly) {
      self.polys.push(poly);
   }
}

fn main() {
   let mut scene = Scene::new(RGB::new(0, 0, 0));

   let poly_a = Poly {
      points: vec![Point::new(10, 10), Point::new(30, 20), Point::new(20, 30)],
      color: RGB::new(34, 78, 29),
   };

   let poly_b = Poly {
      points: vec![Point::new(40, 40), Point::new(5, 20), Point::new(50, 0)],
      color: RGB::new(128, 59, 89),
   };

   scene.push(poly_a);
   scene.push(poly_b);

   println!("{:?}", scene.background);

   for poly in scene.polys {
      println!("{:?} - {:?}", poly.points, poly.color);
   }
}

<commit_msg>DevRenderer implementation started<commit_after>extern crate polydraw;

use polydraw::{Application, Renderer, Frame};
use polydraw::geom::point::Point;
use polydraw::draw::RGB;

struct Poly {
   points: Vec<Point>,
   color: RGB,
}

struct Scene {
   polys: Vec<Poly>,
}

impl Scene {
   #[inline]
   fn new() -> Self {
      Scene {
         polys: Vec::new(),
      }
   }

   #[inline]
   pub fn push(&mut self, poly: Poly) {
      self.polys.push(poly);
   }
}

struct DevRenderer {
   scene: Scene,
}

impl DevRenderer {
   fn new(scene: Scene) -> Self {
      DevRenderer {
         scene: scene,
      }
   }
}

impl Renderer for DevRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      let white = RGB::new(255, 255, 255);

      for poly in self.scene.polys.iter() {
         for point in poly.points.iter() {
            frame.put_pixel(point.x as i32, point.y as i32, &white)
         }
      }
   }
}

fn main() {
   let mut scene = Scene::new();

   let poly_a = Poly {
      points: vec![
         Point::new(200, 200),
         Point::new(1100, 400),
         Point::new(500, 700),
      ],
      color: RGB::new(34, 78, 29),
   };

   let poly_b = Poly {
      points: vec![
         Point::new(900, 200),
         Point::new(900, 1000),
         Point::new(100, 500),
         Point::new(700, 100),
      ],
      color: RGB::new(128, 59, 89),
   };

   scene.push(poly_a);
   scene.push(poly_b);

   let mut renderer = DevRenderer::new(scene);

   Application::new()
      .renderer(&mut renderer)
      .title("Dev Rasterizer")
      .run();
}

<|endoftext|>


<commit_before><commit_msg>Add test for u8 iterators<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use mpv::*;
use sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

use std::env;
use std::panic::AssertUnwindSafe;
use std::rc::Rc;
use std::sync::Mutex;
use std::time::Duration;

struct Draw{}

pub fn exec() {
    let path = env::args().nth(1).expect("Expected path to media as argument, found nil.");

    // Check for driver availability
    let driver_index = if let Some(i) = sdl2::render::drivers().position(|e| e.name == "opengl") {
        i
    } else {
        panic!("OpenGl driver not found!")
    };

    // Create SDL state
    let sdl = sdl2::init().unwrap();
    let video_subsystem = Rc::new(Mutex::new(sdl.video().unwrap()));
    let vs = video_subsystem.clone();
    let window = vs.lock().unwrap().window("mpv-rs sdl2 example", 1280, 720)
        .resizable()
        .position_centered()
        .opengl()
        .build()
        .unwrap();
    let renderer = window.renderer()
        .index(driver_index as _)
        .build()
        .expect("Failed to create renderer with given parameters");
    let wref = renderer.window().unwrap();
    let mut event_pump = sdl.event_pump().unwrap();
    let events = sdl.event().unwrap();
    events.register_custom_event::<Draw>().unwrap();

    // Create mpv state
    let mpv = Parent::with_options(false,
                                   &[("vo", "opengl-cb".into()),
                                     ("cache-initial", 1.into()),
                                     ("volume", 30.into()),
                                     ("ytdl", true.into())])
            .unwrap();
    let vs = video_subsystem.clone();
    let mut mpv_ogl = mpv.create_opengl_context(move |name| (*vs.lock().unwrap()).gl_get_proc_address(name)).unwrap();
    unsafe { mpv_ogl.set_update_callback(AssertUnwindSafe(events), gl_update_callback) };

    // Load specified file
    mpv.playlist_load_files(&[(&path, FileState::AppendPlay, None)]).unwrap();

    // Setup event handling
    'main: loop {
        for event in event_pump.wait_iter() {
            if event.is_user_event() {
                // The only user event is `Draw`, we don't have to check.
                let (width, height) = wref.size();
                unsafe {
                    mpv_ogl.draw(0, width as _, -(height as isize)).unwrap();
                }
                wref.gl_swap_window();
                continue;
            }

            match event {
                Event::Quit { .. } |
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
                Event::KeyDown { keycode: Some(Keycode::Q), .. } => {
                    break 'main;
                }
                Event::KeyDown { keycode: Some(Keycode::Space), repeat: false, .. } => {
                    if let Data::Flag(true) = mpv.get_property("pause", Format::Flag)
                           .unwrap() {
                        mpv.unpause().unwrap();
                    } else {
                        mpv.pause().unwrap();
                    }
                }
                Event::KeyDown { keycode: Some(Keycode::Right), repeat: false, .. } => {
                    mpv.seek_forward(&Duration::from_secs(10)).unwrap();
                }
                _ => { }
            }
        }
    }
}

fn gl_update_callback(events: &AssertUnwindSafe<sdl2::EventSubsystem>) {
    events.push_custom_event(Draw{}).unwrap()
}
<commit_msg>[examples] Remove needless Mutex<commit_after>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use mpv::*;
use sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

use std::env;
use std::panic::AssertUnwindSafe;
use std::rc::Rc;
use std::time::Duration;

struct Draw {}

pub fn exec() {
    let path = env::args().nth(1).expect("Expected path to media as argument, found nil.");

    // Check for driver availability
    let driver_index = if let Some(i) = sdl2::render::drivers().position(|e| e.name == "opengl") {
        i
    } else {
        panic!("OpenGl driver not found!")
    };

    // Create SDL state
    let sdl = sdl2::init().unwrap();
    let video_subsystem = Rc::new(sdl.video().unwrap());
    let vs = video_subsystem.clone();
    let window = vs.window("mpv-rs sdl2 example", 1280, 720)
        .resizable()
        .position_centered()
        .opengl()
        .build()
        .unwrap();
    let renderer = window.renderer()
        .index(driver_index as _)
        .build()
        .expect("Failed to create renderer with given parameters");
    let wref = renderer.window().unwrap();
    let mut event_pump = sdl.event_pump().unwrap();
    let events = sdl.event().unwrap();
    events.register_custom_event::<Draw>().unwrap();

    // Create mpv state
    let mpv = Parent::with_options(false,
                                   &[("vo", "opengl-cb".into()),
                                     ("cache-initial", 1.into()),
                                     ("volume", 30.into()),
                                     ("ytdl", true.into())])
            .unwrap();
    let vs = video_subsystem.clone();
    let mut mpv_ogl = mpv.create_opengl_context(move |name| vs.gl_get_proc_address(name)).unwrap();
    unsafe { mpv_ogl.set_update_callback(AssertUnwindSafe(events), gl_update_callback) };

    // Load specified file
    mpv.playlist_load_files(&[(&path, FileState::AppendPlay, None)]).unwrap();

    // Setup event handling
    'main: loop {
        for event in event_pump.wait_iter() {
            if event.is_user_event() {
                // The only user event is `Draw`, we don't have to check.
                let (width, height) = wref.size();
                unsafe {
                    mpv_ogl.draw(0, width as _, -(height as isize)).unwrap();
                }
                wref.gl_swap_window();
                continue;
            }

            match event {
                Event::Quit { .. } |
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
                Event::KeyDown { keycode: Some(Keycode::Q), .. } => {
                    break 'main;
                }
                Event::KeyDown { keycode: Some(Keycode::Space), repeat: false, .. } => {
                    if let Data::Flag(true) = mpv.get_property("pause", Format::Flag).unwrap() {
                        mpv.unpause().unwrap();
                    } else {
                        mpv.pause().unwrap();
                    }
                }
                Event::KeyDown { keycode: Some(Keycode::Right), repeat: false, .. } => {
                    mpv.seek_forward(&Duration::from_secs(10)).unwrap();
                }
                _ => {}
            }
        }
    }
}

fn gl_update_callback(events: &AssertUnwindSafe<sdl2::EventSubsystem>) {
    events.push_custom_event(Draw {}).unwrap()
}
<|endoftext|>


<commit_before>use bit_vector::BitVector;

pub fn maximum_set_packing(subsets: &Vec<Vec<u8>>) -> Vec<usize> {
    let bit_vectors = subsets.iter().map(BitVector::from_vec).collect::<Vec<_>>();

    let mut packing = vec![];
    let mut available_subsets_indexes = (0..subsets.len()).collect::<Vec<_>>();

    loop {
        // To find a minimum set packing, simply replace `min_by_key` with `max_by_key`.
        match available_subsets_indexes.iter().min_by_key(|i| subsets[**i].len()) {
            None => {
                return packing;
            }

            Some(&smallest_available_subset_index) => {
                packing.push(smallest_available_subset_index);

                let bit_vector = &bit_vectors[smallest_available_subset_index];
                available_subsets_indexes.retain(|i| !bit_vector.intersects(&bit_vectors[*i]));
            }
        }
    }
}
<commit_msg>[set_packing/rust] Add comments<commit_after>use bit_vector::BitVector;

pub fn maximum_set_packing(subsets: &Vec<Vec<u8>>) -> Vec<usize> {
    let bit_vectors = subsets.iter().map(BitVector::from_vec).collect::<Vec<_>>();

    let mut packing = vec![];
    let mut available_subsets_indexes = (0..subsets.len()).collect::<Vec<_>>();

    loop {
        // Select the smallest subset that hasn't been used yet.
        // To find a minimum set packing, simply replace `min_by_key` with `max_by_key`.
        match available_subsets_indexes.iter().min_by_key(|i| subsets[**i].len()) {
            None => {
                return packing;
            }

            Some(&smallest_available_subset_index) => {
                packing.push(smallest_available_subset_index);

                // Mark all intersected subsets as unavailable.
                let bit_vector = &bit_vectors[smallest_available_subset_index];
                available_subsets_indexes.retain(|i| !bit_vector.intersects(&bit_vectors[*i]));
            }
        }
    }
}
<|endoftext|>


<commit_before>use iron::prelude::*;
use super::*;
use iron::modifiers::*;
use iron::status;

fn default_param() -> BaseDataMap {
    btreemap! {
        "module".to_string() => "pages".to_json(),
    }
}

pub fn get_main(_: &mut Request) -> RenderResult {
    Render::new("admin/pages/index", default_param())
}

pub fn get_create(_: &mut Request) -> RenderResult {
    Render::new("admin/pages/create", default_param())
}

pub fn get_show(req: &mut Request) -> RenderResult {
    let conn = req.db_conn();
    models::pages::list(&conn);
    Render::new("admin/pages/create", default_param())
}

pub fn post_create(req: &mut Request) -> RenderResult {
    use params::{Params};

    let conn = req.db_conn();
    let values = itry!(req.get::<Params>());
    let validate = models::pages::validate(&values);
    if let Some(err) = validate.get_errors() {
        println!("Validation Errors: {:?}\n\n {:?}", err, validate.to_json());
    } else {
        itry!(models::pages::create(&conn, validate.get_values()));
        return Ok(Response::with((status::Found, Redirect(url_for!(req, "admin_pages_main")))))
    }

    Render::new("admin/pages/create", default_param())
}<commit_msg>Validations results to Json - as array<commit_after>use iron::prelude::*;
use super::*;
use iron::modifiers::*;
use iron::status;

fn default_param() -> BaseDataMap {
    btreemap! {
        "module".to_string() => "pages".to_json(),
    }
}

pub fn get_main(_: &mut Request) -> RenderResult {
    Render::new("admin/pages/index", default_param())
}

pub fn get_create(_: &mut Request) -> RenderResult {
    Render::new("admin/pages/create", default_param())
}

pub fn get_show(req: &mut Request) -> RenderResult {
    let conn = req.db_conn();
    models::pages::list(&conn);
    Render::new("admin/pages/create", default_param())
}

pub fn post_create(req: &mut Request) -> RenderResult {
    use params::{Params};

    let conn = req.db_conn();
    let values = itry!(req.get::<Params>());
    let validate = models::pages::validate(&values);
    if let Some(err) = validate.get_errors() {
        println!("Validation Errors: {:?}\n\n {:?}", err, validate.to_json());
        return Render::new("admin/pages/create", default_param());
    } else {
        itry!(models::pages::create(&conn, validate.get_values()));
        return Ok(Response::with((status::Found, Redirect(url_for!(req, "admin_pages_main")))))
    }

    Render::new("admin/pages/create", default_param())
}<|endoftext|>


<commit_before>//! Compares the decoding results with reference renderings.

extern crate crc32fast;
extern crate glob;
extern crate image;

use std::fs;
use std::io;
use std::path::PathBuf;
use std::u32;

use crc32fast::Hasher as Crc32;

const BASE_PATH: [&str; 2] = [".", "tests"];
const IMAGE_DIR: &str = "images";
const OUTPUT_DIR: &str = "output";
const REFERENCE_DIR: &str = "reference";

fn process_images<F>(dir: &str, input_decoder: Option<&str>, func: F)
where
    F: Fn(&PathBuf, PathBuf, &str),
{
    let base: PathBuf = BASE_PATH.iter().collect();
    let decoders = &["tga", "tiff", "png", "gif", "bmp", "ico", "jpg", "hdr", "pbm", "webp"];
    for decoder in decoders {
        let mut path = base.clone();
        path.push(dir);
        path.push(decoder);
        path.push("**");
        path.push(
            "*.".to_string() + match input_decoder {
                Some(val) => val,
                None => decoder,
            },
        );
        let pattern = &*format!("{}", path.display());
        for path in glob::glob(pattern).unwrap().filter_map(Result::ok) {
            func(&base, path, decoder)
        }
    }
}

#[cfg(feature = "png")]
#[test]
fn render_images() {
    process_images(IMAGE_DIR, None, |base, path, decoder| {
        println!("render_images {}", path.display());
        let img = match image::open(&path) {
            Ok(img) => img.to_rgba(),
            // Do not fail on unsupported error
            // This might happen because the testsuite contains unsupported images
            // or because a specific decoder included via a feature.
            Err(image::ImageError::Unsupported(e)) => {
                println!("UNSUPPORTED {}: {}", path.display(), e);
                return;
            }
            Err(err) => panic!(format!("decoding of {:?} failed with: {}", path, err)),
        };
        let mut crc = Crc32::new();
        crc.update(&*img);

        let (filename, testsuite) = {
            let mut path: Vec<_> = path.components().collect();
            (path.pop().unwrap(), path.pop().unwrap())
        };
        let mut out_path = base.clone();

        out_path.push(OUTPUT_DIR);
        out_path.push(decoder);
        out_path.push(testsuite.as_os_str());
        fs::create_dir_all(&out_path).unwrap();
        out_path.push(format!(
            "{}.{}.{}",
            filename.as_os_str().to_str().unwrap(),
            format!("{:x}", crc.finalize()),
            "png"
        ));
        img.save(out_path).unwrap();
    })
}

/// Describes a single test case of `check_references`.
struct ReferenceTestCase {
    orig_filename: String,
    crc: u32,
    kind: ReferenceTestKind,
}

enum ReferenceTestKind {
    /// The test image is loaded using `image::open`, and the result is compared
    /// against the reference image.
    SingleImage,

    /// From the test image file, a single frame is extracted using a fitting animation decoder and
    /// the result is compared against the reference image.
    AnimatedFrame {
        /// A zero-based frame number.
        frame: usize,
    },
}

impl std::str::FromStr for ReferenceTestCase {
    type Err = &'static str;

    /// Construct `ReferenceTestCase` from the file name of a reference
    /// image.
    fn from_str(filename: &str) -> Result<Self, Self::Err> {
        let mut filename_parts = filename.rsplitn(3, '.');

        // Ignore the file extension
        filename_parts.next().unwrap();

        // The penultimate part of `filename_parts` represents the metadata,
        // describing the test type and other details.
        let meta_str = filename_parts.next().ok_or("missing metadata part")?;
        let meta = meta_str.split('_').collect::<Vec<_>>();
        let (crc, kind);

        if meta.len() == 1 {
            // `CRC`
            crc = parse_crc(&meta[0]).ok_or("malformed CRC")?;
            kind = ReferenceTestKind::SingleImage;
        } else if meta.len() == 3 && meta[0] == "anim" {
            // `anim_FRAME_CRC`
            crc = parse_crc(&meta[2]).ok_or("malformed CRC")?;
            let frame: usize = meta[1].parse().map_err(|_| "malformed frame number")?;
            kind = ReferenceTestKind::AnimatedFrame {
                frame: frame.checked_sub(1).ok_or("frame number must be 1-based")?,
            };
        } else {
            return Err("unrecognized reference image metadata format");
        }

        // The remaining part represents the original file name
        let orig_filename = filename_parts
            .next()
            .ok_or("missing original file name")?
            .to_owned();

        Ok(Self {
            orig_filename,
            crc,
            kind,
        })
    }
}

/// Parse the given string as a hexadecimal CRC hash, used by `check_references`.
fn parse_crc(src: &str) -> Option<u32> {
    u32::from_str_radix(src, 16).ok()
}

#[test]
fn check_references() {
    process_images(REFERENCE_DIR, Some("png"), |base, path, decoder| {
        println!("check_references {}", path.display());

        let ref_img = match image::open(&path) {
            Ok(img) => img.to_rgba(),
            // Do not fail on unsupported error
            // This might happen because the testsuite contains unsupported images
            // or because a specific decoder included via a feature.
            Err(image::ImageError::Unsupported(_)) => return,
            Err(err) => panic!(format!("{}", err)),
        };

        let (filename, testsuite) = {
            let mut path: Vec<_> = path.components().collect();
            (path.pop().unwrap(), path.pop().unwrap())
        };

        // Parse the file name to obtain the test case information
        let filename_str = filename.as_os_str().to_str().unwrap();
        let case: ReferenceTestCase = filename_str.parse().unwrap();

        let mut img_path = base.clone();
        img_path.push(IMAGE_DIR);
        img_path.push(decoder);
        img_path.push(testsuite.as_os_str());
        img_path.push(case.orig_filename);

        // Load the test image
        let mut test_img = None;

        match case.kind {
            ReferenceTestKind::AnimatedFrame { frame: frame_num } => {
                let format = image::io::Reader::open(&img_path)
                        .unwrap()
                        .with_guessed_format()
                        .unwrap()
                        .format();

                #[cfg(feature = "gif")]
                if format == Some(image::ImageFormat::Gif) {
                    // Interpret the input file as an animation file
                    use image::AnimationDecoder;
                    let stream = io::BufReader::new(fs::File::open(&img_path).unwrap());
                    let decoder = match image::gif::GifDecoder::new(stream) {
                        Ok(decoder) => decoder,
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => {
                            panic!(format!("decoding of {:?} failed with: {}", img_path, err))
                        }
                    };

                    let mut frames = match decoder.into_frames().collect_frames() {
                        Ok(frames) => frames,
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => panic!(format!(
                            "collecting frames of {:?} failed with: {}",
                            img_path, err
                        )),
                    };

                    // Select a single frame
                    let frame = frames.drain(frame_num..).nth(0).unwrap();

                    // Convert the frame to a`RgbaImage`
                    test_img = Some(frame.into_buffer());
                }

                #[cfg(feature = "png")]
                if format == Some(image::ImageFormat::Png) {
                    // Interpret the input file as an animation file
                    use image::AnimationDecoder;
                    let stream = io::BufReader::new(fs::File::open(&img_path).unwrap());
                    let decoder = match image::png::PngDecoder::new(stream) {
                        Ok(decoder) => decoder.apng(),
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => {
                            panic!(format!("decoding of {:?} failed with: {}", img_path, err))
                        }
                    };

                    let mut frames = match decoder.into_frames().collect_frames() {
                        Ok(frames) => frames,
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => panic!(format!(
                            "collecting frames of {:?} failed with: {}",
                            img_path, err
                        )),
                    };

                    // Select a single frame
                    let frame = frames.drain(frame_num..).nth(0).unwrap();

                    // Convert the frame to a`RgbaImage`
                    test_img = Some(frame.into_buffer());
                }

                if test_img.is_none() {
                    println!("Skipping - GIF codec is not enabled");
                    return;
                }
            }

            ReferenceTestKind::SingleImage => {
                // Read the input file as a single image
                match image::open(&img_path) {
                    Ok(img) => test_img = Some(img.to_rgba()),
                    // Do not fail on unsupported error
                    // This might happen because the testsuite contains unsupported images
                    // or because a specific decoder included via a feature.
                    Err(image::ImageError::Unsupported(_)) => return,
                    Err(err) => panic!(format!("decoding of {:?} failed with: {}", img_path, err)),
                };
            }
        }

        let test_img = match test_img.as_ref() {
            Some(img) => img,
            None => return,
        };

        let test_crc_actual = {
            let mut hasher = Crc32::new();
            hasher.update(&*test_img);
            hasher.finalize()
        };

        if test_crc_actual != case.crc {
            panic!(
                "The decoded image's hash does not match (expected = {:08x}, actual = {:08x}).",
                case.crc, test_crc_actual
            );
        }

        if *ref_img != **test_img {
            panic!("Reference rendering does not match.");
        }
    })
}

#[cfg(feature = "hdr")]
#[test]
fn check_hdr_references() {
    let mut ref_path: PathBuf = BASE_PATH.iter().collect();
    ref_path.push(REFERENCE_DIR);
    ref_path.push("hdr");
    let mut path: PathBuf = BASE_PATH.iter().collect();
    path.push(IMAGE_DIR);
    path.push("hdr");
    path.push("*");
    path.push("*.hdr");
    let pattern = &*format!("{}", path.display());
    for path in glob::glob(pattern).unwrap().filter_map(Result::ok) {
        use std::path::Component::Normal;
        let mut ref_path = ref_path.clone();
        // append 2 last components of image path to reference path
        for c in path.components()
            .rev()
            .take(2)
            .collect::<Vec<_>>()
            .iter()
            .rev()
        {
            match *c {
                Normal(name) => ref_path.push(name),
                _ => panic!(),
            }
        }
        ref_path.set_extension("raw");
        println!("{}", ref_path.display());
        println!("{}", path.display());
        let decoder = image::hdr::HdrDecoder::new(io::BufReader::new(
            fs::File::open(&path).unwrap(),
        )).unwrap();
        let decoded = decoder.read_image_hdr().unwrap();
        let reference = image::hdr::read_raw_file(&ref_path).unwrap();
        assert_eq!(decoded, reference);
    }
}

/// Check that BMP files with large values could cause OOM issues are rejected.
///
/// The images are postfixed with `bad_bmp` to not be loaded by the other test.
#[test]
fn bad_bmps() {
    let path: PathBuf = BASE_PATH
        .iter()
        .collect::<PathBuf>()
        .join(IMAGE_DIR)
        .join("bmp/images")
        .join("*.bad_bmp");

    let pattern = &*format!("{}", path.display());
    for path in glob::glob(pattern).unwrap().filter_map(Result::ok) {
        let im = image::open(path);
        assert!(im.is_err());
    }
}
<commit_msg>Fix deprecated warnings in reference_images test<commit_after>//! Compares the decoding results with reference renderings.

extern crate crc32fast;
extern crate glob;
extern crate image;

use std::fs;
use std::io;
use std::path::PathBuf;
use std::u32;

use crc32fast::Hasher as Crc32;

const BASE_PATH: [&str; 2] = [".", "tests"];
const IMAGE_DIR: &str = "images";
const OUTPUT_DIR: &str = "output";
const REFERENCE_DIR: &str = "reference";

fn process_images<F>(dir: &str, input_decoder: Option<&str>, func: F)
where
    F: Fn(&PathBuf, PathBuf, &str),
{
    let base: PathBuf = BASE_PATH.iter().collect();
    let decoders = &["tga", "tiff", "png", "gif", "bmp", "ico", "jpg", "hdr", "pbm", "webp"];
    for decoder in decoders {
        let mut path = base.clone();
        path.push(dir);
        path.push(decoder);
        path.push("**");
        path.push(
            "*.".to_string() + match input_decoder {
                Some(val) => val,
                None => decoder,
            },
        );
        let pattern = &*format!("{}", path.display());
        for path in glob::glob(pattern).unwrap().filter_map(Result::ok) {
            func(&base, path, decoder)
        }
    }
}

#[cfg(feature = "png")]
#[test]
fn render_images() {
    process_images(IMAGE_DIR, None, |base, path, decoder| {
        println!("render_images {}", path.display());
        let img = match image::open(&path) {
            Ok(img) => img.to_rgba8(),
            // Do not fail on unsupported error
            // This might happen because the testsuite contains unsupported images
            // or because a specific decoder included via a feature.
            Err(image::ImageError::Unsupported(e)) => {
                println!("UNSUPPORTED {}: {}", path.display(), e);
                return;
            }
            Err(err) => panic!(format!("decoding of {:?} failed with: {}", path, err)),
        };
        let mut crc = Crc32::new();
        crc.update(&*img);

        let (filename, testsuite) = {
            let mut path: Vec<_> = path.components().collect();
            (path.pop().unwrap(), path.pop().unwrap())
        };
        let mut out_path = base.clone();

        out_path.push(OUTPUT_DIR);
        out_path.push(decoder);
        out_path.push(testsuite.as_os_str());
        fs::create_dir_all(&out_path).unwrap();
        out_path.push(format!(
            "{}.{}.{}",
            filename.as_os_str().to_str().unwrap(),
            format!("{:x}", crc.finalize()),
            "png"
        ));
        img.save(out_path).unwrap();
    })
}

/// Describes a single test case of `check_references`.
struct ReferenceTestCase {
    orig_filename: String,
    crc: u32,
    kind: ReferenceTestKind,
}

enum ReferenceTestKind {
    /// The test image is loaded using `image::open`, and the result is compared
    /// against the reference image.
    SingleImage,

    /// From the test image file, a single frame is extracted using a fitting animation decoder and
    /// the result is compared against the reference image.
    AnimatedFrame {
        /// A zero-based frame number.
        frame: usize,
    },
}

impl std::str::FromStr for ReferenceTestCase {
    type Err = &'static str;

    /// Construct `ReferenceTestCase` from the file name of a reference
    /// image.
    fn from_str(filename: &str) -> Result<Self, Self::Err> {
        let mut filename_parts = filename.rsplitn(3, '.');

        // Ignore the file extension
        filename_parts.next().unwrap();

        // The penultimate part of `filename_parts` represents the metadata,
        // describing the test type and other details.
        let meta_str = filename_parts.next().ok_or("missing metadata part")?;
        let meta = meta_str.split('_').collect::<Vec<_>>();
        let (crc, kind);

        if meta.len() == 1 {
            // `CRC`
            crc = parse_crc(&meta[0]).ok_or("malformed CRC")?;
            kind = ReferenceTestKind::SingleImage;
        } else if meta.len() == 3 && meta[0] == "anim" {
            // `anim_FRAME_CRC`
            crc = parse_crc(&meta[2]).ok_or("malformed CRC")?;
            let frame: usize = meta[1].parse().map_err(|_| "malformed frame number")?;
            kind = ReferenceTestKind::AnimatedFrame {
                frame: frame.checked_sub(1).ok_or("frame number must be 1-based")?,
            };
        } else {
            return Err("unrecognized reference image metadata format");
        }

        // The remaining part represents the original file name
        let orig_filename = filename_parts
            .next()
            .ok_or("missing original file name")?
            .to_owned();

        Ok(Self {
            orig_filename,
            crc,
            kind,
        })
    }
}

/// Parse the given string as a hexadecimal CRC hash, used by `check_references`.
fn parse_crc(src: &str) -> Option<u32> {
    u32::from_str_radix(src, 16).ok()
}

#[test]
fn check_references() {
    process_images(REFERENCE_DIR, Some("png"), |base, path, decoder| {
        println!("check_references {}", path.display());

        let ref_img = match image::open(&path) {
            Ok(img) => img.to_rgba8(),
            // Do not fail on unsupported error
            // This might happen because the testsuite contains unsupported images
            // or because a specific decoder included via a feature.
            Err(image::ImageError::Unsupported(_)) => return,
            Err(err) => panic!(format!("{}", err)),
        };

        let (filename, testsuite) = {
            let mut path: Vec<_> = path.components().collect();
            (path.pop().unwrap(), path.pop().unwrap())
        };

        // Parse the file name to obtain the test case information
        let filename_str = filename.as_os_str().to_str().unwrap();
        let case: ReferenceTestCase = filename_str.parse().unwrap();

        let mut img_path = base.clone();
        img_path.push(IMAGE_DIR);
        img_path.push(decoder);
        img_path.push(testsuite.as_os_str());
        img_path.push(case.orig_filename);

        // Load the test image
        let mut test_img = None;

        match case.kind {
            ReferenceTestKind::AnimatedFrame { frame: frame_num } => {
                let format = image::io::Reader::open(&img_path)
                        .unwrap()
                        .with_guessed_format()
                        .unwrap()
                        .format();

                #[cfg(feature = "gif")]
                if format == Some(image::ImageFormat::Gif) {
                    // Interpret the input file as an animation file
                    use image::AnimationDecoder;
                    let stream = io::BufReader::new(fs::File::open(&img_path).unwrap());
                    let decoder = match image::gif::GifDecoder::new(stream) {
                        Ok(decoder) => decoder,
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => {
                            panic!(format!("decoding of {:?} failed with: {}", img_path, err))
                        }
                    };

                    let mut frames = match decoder.into_frames().collect_frames() {
                        Ok(frames) => frames,
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => panic!(format!(
                            "collecting frames of {:?} failed with: {}",
                            img_path, err
                        )),
                    };

                    // Select a single frame
                    let frame = frames.drain(frame_num..).nth(0).unwrap();

                    // Convert the frame to a`RgbaImage`
                    test_img = Some(frame.into_buffer());
                }

                #[cfg(feature = "png")]
                if format == Some(image::ImageFormat::Png) {
                    // Interpret the input file as an animation file
                    use image::AnimationDecoder;
                    let stream = io::BufReader::new(fs::File::open(&img_path).unwrap());
                    let decoder = match image::png::PngDecoder::new(stream) {
                        Ok(decoder) => decoder.apng(),
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => {
                            panic!(format!("decoding of {:?} failed with: {}", img_path, err))
                        }
                    };

                    let mut frames = match decoder.into_frames().collect_frames() {
                        Ok(frames) => frames,
                        Err(image::ImageError::Unsupported(_)) => return,
                        Err(err) => panic!(format!(
                            "collecting frames of {:?} failed with: {}",
                            img_path, err
                        )),
                    };

                    // Select a single frame
                    let frame = frames.drain(frame_num..).nth(0).unwrap();

                    // Convert the frame to a`RgbaImage`
                    test_img = Some(frame.into_buffer());
                }

                if test_img.is_none() {
                    println!("Skipping - GIF codec is not enabled");
                    return;
                }
            }

            ReferenceTestKind::SingleImage => {
                // Read the input file as a single image
                match image::open(&img_path) {
                    Ok(img) => test_img = Some(img.to_rgba8()),
                    // Do not fail on unsupported error
                    // This might happen because the testsuite contains unsupported images
                    // or because a specific decoder included via a feature.
                    Err(image::ImageError::Unsupported(_)) => return,
                    Err(err) => panic!(format!("decoding of {:?} failed with: {}", img_path, err)),
                };
            }
        }

        let test_img = match test_img.as_ref() {
            Some(img) => img,
            None => return,
        };

        let test_crc_actual = {
            let mut hasher = Crc32::new();
            hasher.update(&*test_img);
            hasher.finalize()
        };

        if test_crc_actual != case.crc {
            panic!(
                "The decoded image's hash does not match (expected = {:08x}, actual = {:08x}).",
                case.crc, test_crc_actual
            );
        }

        if *ref_img != **test_img {
            panic!("Reference rendering does not match.");
        }
    })
}

#[cfg(feature = "hdr")]
#[test]
fn check_hdr_references() {
    let mut ref_path: PathBuf = BASE_PATH.iter().collect();
    ref_path.push(REFERENCE_DIR);
    ref_path.push("hdr");
    let mut path: PathBuf = BASE_PATH.iter().collect();
    path.push(IMAGE_DIR);
    path.push("hdr");
    path.push("*");
    path.push("*.hdr");
    let pattern = &*format!("{}", path.display());
    for path in glob::glob(pattern).unwrap().filter_map(Result::ok) {
        use std::path::Component::Normal;
        let mut ref_path = ref_path.clone();
        // append 2 last components of image path to reference path
        for c in path.components()
            .rev()
            .take(2)
            .collect::<Vec<_>>()
            .iter()
            .rev()
        {
            match *c {
                Normal(name) => ref_path.push(name),
                _ => panic!(),
            }
        }
        ref_path.set_extension("raw");
        println!("{}", ref_path.display());
        println!("{}", path.display());
        let decoder = image::hdr::HdrDecoder::new(io::BufReader::new(
            fs::File::open(&path).unwrap(),
        )).unwrap();
        let decoded = decoder.read_image_hdr().unwrap();
        let reference = image::hdr::read_raw_file(&ref_path).unwrap();
        assert_eq!(decoded, reference);
    }
}

/// Check that BMP files with large values could cause OOM issues are rejected.
///
/// The images are postfixed with `bad_bmp` to not be loaded by the other test.
#[test]
fn bad_bmps() {
    let path: PathBuf = BASE_PATH
        .iter()
        .collect::<PathBuf>()
        .join(IMAGE_DIR)
        .join("bmp/images")
        .join("*.bad_bmp");

    let pattern = &*format!("{}", path.display());
    for path in glob::glob(pattern).unwrap().filter_map(Result::ok) {
        let im = image::open(path);
        assert!(im.is_err());
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate neon;
extern crate ratel;

use neon::vm::{Call, JsResult};
use neon::js::{JsString, Variant};
use ratel::{parser, transformer, codegen};

fn transform(call: Call) -> JsResult<JsString> {
  let scope = call.scope;

  let source = match call.arguments.get(scope, 0).unwrap().variant() {
      Variant::String(handle) => handle.value() + "\n",
      _                       => panic!("First argument must be a string"),
  };

  let minify = match call.arguments.get(scope, 1).unwrap().variant() {
      Variant::Boolean(handle) => handle.value(),
      _                        => false,
  };

  let mut ast = parser::parse(source);
  transformer::transform(&mut ast, transformer::Settings::target_es5());
  let out = codegen::generate_code(ast, minify);
  Ok(JsString::new(scope, &out).unwrap())
}

fn parse(call: Call) -> JsResult<JsString> {
  let scope = call.scope;
  let source = match call.arguments.get(scope, 0).unwrap().variant() {
      Variant::String(handle) => handle.value(),
      _                       => panic!("First argument must be a string"),
  };

  let ast = parser::parse(source);
  let out = format!("{:#?}", ast.body);
  Ok(JsString::new(scope, &out).unwrap())
}

register_module!(m, {
  try!(m.export("transform", transform));
  try!(m.export("parse", parse));
  Ok(())
});
<commit_msg>Fixed error handling.<commit_after>#[macro_use]
extern crate neon;
extern crate ratel;

use neon::vm::{Call, JsResult};
use neon::js::{JsString, Variant};
use ratel::{parser, transformer, codegen};

fn transform(call: Call) -> JsResult<JsString> {
    let scope = call.scope;

    let source = match call.arguments.get(scope, 0).unwrap().variant() {
        Variant::String(handle) => handle.value() + "\n",
        _                       => panic!("First argument must be a string"),
    };

    let minify = match call.arguments.get(scope, 1).unwrap().variant() {
        Variant::Boolean(handle) => handle.value(),
        _                        => false,
    };

    let mut ast = match parser::parse(source) {
        Err(error) => {
            println!("{}", error);

            // TODO: return Ok(JsNull) or some such
            ::std::process::exit(1);
        },
        Ok(ast) => ast,
    };

    transformer::transform(&mut ast, transformer::Settings::target_es5());
    let out = codegen::generate_code(ast, minify);
    Ok(JsString::new(scope, &out).unwrap())
}

fn parse(call: Call) -> JsResult<JsString> {
    let scope = call.scope;
    let source = match call.arguments.get(scope, 0).unwrap().variant() {
        Variant::String(handle) => handle.value(),
        _                       => panic!("First argument must be a string"),
    };

    let ast = match parser::parse(source) {
        Err(error) => {
            println!("{}", error);

            // TODO: return Ok(JsNull) or some such
            ::std::process::exit(1);
        },
        Ok(ast) => ast,
    };

    let out = format!("{:#?}", ast.body);

    Ok(JsString::new(scope, &out).unwrap())
}

register_module!(m, {
    try!(m.export("transform", transform));
    try!(m.export("parse", parse));
    Ok(())
});
<|endoftext|>


<commit_before>use std::path::Path;

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::Rect;
use sdl2::render::{BlendMode, Renderer, Texture, TextureQuery};
use sdl2::surface::Surface;
use sdl2::ttf::{Sdl2TtfContext, STYLE_BOLD};

use position::Position;
use text::Text;

const FONT_FILE: &'static str = "../assets/FantasqueSansMono-Bold.ttf";
const FONT_COLOR: Color = Color::RGBA(45, 200, 45, 255);

pub struct Console<'a> {
    pub visible: bool,

    leader: Text,
    input_buffer: String,
    cursor_position: usize,
    buffer: Vec<String>,
    texture: Texture,
    backbuffer_texture: Texture,
    ttf_context: &'a Sdl2TtfContext,
}

impl<'a> Console<'a> {
    /// Creates a new empty Console
    pub fn new(ttf_context: &'a Sdl2TtfContext, mut renderer: &mut Renderer) -> Console<'a> {
        let mut texture = renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, 640, 720)
            .unwrap();
        texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..720 {
                    for x in 0..640 {
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        let mut backbuffer_texture =
            renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, 640, 720)
                .unwrap();
        backbuffer_texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..720 {
                    for x in 0..640 {
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        Console {
            visible: false,
            leader: Text::new(&ttf_context,
                              &mut renderer,
                              "hakka>",
                              Position::XY(0, 720 - 18),
                              18,
                              FONT_COLOR,
                              FONT_FILE),
            input_buffer: "".into(),
            cursor_position: 0,
            buffer: Vec::new(),
            texture: texture,
            backbuffer_texture: backbuffer_texture,
            ttf_context: ttf_context,
        }
    }

    pub fn process(&mut self, event: &Event) {
        match event {
            &Event::TextInput { ref text, .. } => {
                if self.visible {
                    if text == "`" {
                        return;
                    }
                    self.add_text(text);
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Backquote), .. } => {
                self.toggle();
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Left), .. } => {
                if self.visible {
                    self.cursor_left();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Right), .. } => {
                if self.visible {
                    self.cursor_right();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Return), .. } => {
                if self.visible {
                    self.commit();
                }
            }
            &Event::KeyDown { keycode: Option::Some(Keycode::Backspace), .. } => {
                if self.visible {
                    self.backspace();
                }
            }
            _ => (),
        }
    }

    /// Toggles the visibility of the Console
    pub fn toggle(&mut self) {
        self.visible = !self.visible;
    }

    pub fn add_text(&mut self, input: &str) {
        self.input_buffer.insert(self.cursor_position, input.chars().next().unwrap());
        self.cursor_position += 1;
    }

    pub fn commit(&mut self) {
        self.buffer.push(format!("hakka> {}", self.input_buffer.clone()));
        self.input_buffer.clear();
        self.cursor_position = 0;
    }

    pub fn cursor_left(&mut self) {
        if self.cursor_position > 0 {
            self.cursor_position -= 1;
        }
    }

    pub fn cursor_right(&mut self) {
        if self.cursor_position < self.input_buffer.len() {
            self.cursor_position += 1;
        }
    }

    pub fn backspace(&mut self) {
        if self.visible {
            if self.cursor_position > 0 {
                self.input_buffer.remove(self.cursor_position - 1);
                self.cursor_position -= 1;
            }
        }
    }

    /// Renders the Console
    pub fn render(&mut self, mut renderer: &mut Renderer) {
        if self.visible {

            renderer.set_blend_mode(BlendMode::Blend);
            self.texture.set_blend_mode(BlendMode::Blend);
            renderer.copy(&self.texture, None, Some(Rect::new(0, 0, 640, 720))).unwrap();
            self.render_leader(&mut renderer);
            self.generate_backbuffer_texture(&mut renderer);
            // self.render_buffer(&mut renderer);

            // Insert the cursor in its proper position
            let mut output_text = self.input_buffer.clone();
            if self.cursor_position < output_text.len() {
                output_text.insert(self.cursor_position, '|');
            } else {
                output_text.push_str("|");
            }

            // If no input.. only draw the cursor
            if self.input_buffer.len() == 0 {
                output_text = "|".into();
            }

            let text = Text::new(&self.ttf_context,
                                 &mut renderer,
                                 &output_text[..],
                                 Position::XY(60, 720 - 18),
                                 18,
                                 FONT_COLOR,
                                 FONT_FILE);
            text.render(&mut renderer);
        }
    }

    fn render_leader(&self, mut renderer: &mut Renderer) {
        self.leader.render(&mut renderer);
    }

    fn generate_backbuffer_texture(&mut self, mut renderer: &mut Renderer) {
        let mut font = self.ttf_context.load_font(Path::new(FONT_FILE), 18).unwrap();
        font.set_style(STYLE_BOLD);
        let mut main_surface = Surface::new(640, 702, PixelFormatEnum::RGBA8888).unwrap();
        let mut counter = 2;
        for line in self.buffer.iter().rev() {
            let surface = font.render(&line)
                .blended(FONT_COLOR)
                .unwrap();
            surface.blit(None,
                      &mut main_surface,
                      Some(Rect::new(0, 720 - (18 * counter), 720, 18)))
                .unwrap();
            counter += 1;
        }
        let texture = renderer.create_texture_from_surface(&main_surface)
            .unwrap();

        let TextureQuery { width, height, .. } = texture.query();

        renderer.copy(&texture, None, Some(Rect::new(0, 0, width, height)));
    }
}<commit_msg>Add some font constants<commit_after>use std::path::Path;

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::Rect;
use sdl2::render::{BlendMode, Renderer, Texture, TextureQuery};
use sdl2::surface::Surface;
use sdl2::ttf::{Sdl2TtfContext, STYLE_BOLD};

use position::Position;
use text::Text;

const FONT_FILE: &'static str = "../assets/FantasqueSansMono-Bold.ttf";
const FONT_COLOR: Color = Color::RGBA(45, 200, 45, 255);
const FONT_SIZE: u16 = 18;

pub struct Console<'a> {
    pub visible: bool,

    leader: Text,
    input_buffer: String,
    cursor_position: usize,
    buffer: Vec<String>,
    texture: Texture,
    backbuffer_texture: Texture,
    ttf_context: &'a Sdl2TtfContext,
}

impl<'a> Console<'a> {
    /// Creates a new empty Console
    pub fn new(ttf_context: &'a Sdl2TtfContext, mut renderer: &mut Renderer) -> Console<'a> {
        let mut texture = renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, 640, 720)
            .unwrap();
        texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..720 {
                    for x in 0..640 {
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        let mut backbuffer_texture =
            renderer.create_texture_streaming(PixelFormatEnum::RGBA8888, 640, 720)
                .unwrap();
        backbuffer_texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
                for y in 0..720 {
                    for x in 0..640 {
                        let offset = y * pitch + x * 4;
                        buffer[offset + 0] = 182;
                        buffer[offset + 1] = 0;
                        buffer[offset + 2] = 0;
                        buffer[offset + 3] = 0;
                    }
                }
            })
            .unwrap();

        Console {
            visible: false,
            leader: Text::new(&ttf_context,
                              &mut renderer,
                              "hakka>",
                              Position::XY(0, 720 - FONT_SIZE as i32),
                              FONT_SIZE,
                              FONT_COLOR,
                              FONT_FILE),
            input_buffer: "".into(),
            cursor_position: 0,
            buffer: Vec::new(),
            texture: texture,
            backbuffer_texture: backbuffer_texture,
            ttf_context: ttf_context,
        }
    }

    pub fn process(&mut self, event: &Event) {
        match event {
            &Event::TextInput { ref text, .. } => {
                if self.visible {
                    if text == "`" {
                        return;
                    }
                    self.add_text(text);
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Backquote), .. } => {
                self.toggle();
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Left), .. } => {
                if self.visible {
                    self.cursor_left();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Right), .. } => {
                if self.visible {
                    self.cursor_right();
                }
            }
            &Event::KeyUp { keycode: Option::Some(Keycode::Return), .. } => {
                if self.visible {
                    self.commit();
                }
            }
            &Event::KeyDown { keycode: Option::Some(Keycode::Backspace), .. } => {
                if self.visible {
                    self.backspace();
                }
            }
            _ => (),
        }
    }

    /// Toggles the visibility of the Console
    pub fn toggle(&mut self) {
        self.visible = !self.visible;
    }

    pub fn add_text(&mut self, input: &str) {
        self.input_buffer.insert(self.cursor_position, input.chars().next().unwrap());
        self.cursor_position += 1;
    }

    pub fn commit(&mut self) {
        self.buffer.push(format!("hakka> {}", self.input_buffer.clone()));
        self.input_buffer.clear();
        self.cursor_position = 0;
    }

    pub fn cursor_left(&mut self) {
        if self.cursor_position > 0 {
            self.cursor_position -= 1;
        }
    }

    pub fn cursor_right(&mut self) {
        if self.cursor_position < self.input_buffer.len() {
            self.cursor_position += 1;
        }
    }

    pub fn backspace(&mut self) {
        if self.visible {
            if self.cursor_position > 0 {
                self.input_buffer.remove(self.cursor_position - 1);
                self.cursor_position -= 1;
            }
        }
    }

    /// Renders the Console
    pub fn render(&mut self, mut renderer: &mut Renderer) {
        if self.visible {

            renderer.set_blend_mode(BlendMode::Blend);
            self.texture.set_blend_mode(BlendMode::Blend);
            renderer.copy(&self.texture, None, Some(Rect::new(0, 0, 640, 720))).unwrap();
            self.render_leader(&mut renderer);
            self.generate_backbuffer_texture(&mut renderer);
            // self.render_buffer(&mut renderer);

            // Insert the cursor in its proper position
            let mut output_text = self.input_buffer.clone();
            if self.cursor_position < output_text.len() {
                output_text.insert(self.cursor_position, '|');
            } else {
                output_text.push_str("|");
            }

            // If no input.. only draw the cursor
            if self.input_buffer.len() == 0 {
                output_text = "|".into();
            }

            let text = Text::new(&self.ttf_context,
                                 &mut renderer,
                                 &output_text[..],
                                 Position::XY(60, 720 - FONT_SIZE as i32),
                                 FONT_SIZE,
                                 FONT_COLOR,
                                 FONT_FILE);
            text.render(&mut renderer);
        }
    }

    fn render_leader(&self, mut renderer: &mut Renderer) {
        self.leader.render(&mut renderer);
    }

    fn generate_backbuffer_texture(&mut self, mut renderer: &mut Renderer) {
        let mut font = self.ttf_context.load_font(Path::new(FONT_FILE), FONT_SIZE).unwrap();
        font.set_style(STYLE_BOLD);
        let mut main_surface = Surface::new(640, 702, PixelFormatEnum::RGBA8888).unwrap();
        let mut counter = 2;
        for line in self.buffer.iter().rev() {
            let surface = font.render(&line)
                .blended(FONT_COLOR)
                .unwrap();
            surface.blit(None,
                      &mut main_surface,
                      Some(Rect::new(0,
                                     720 - (FONT_SIZE as i32 * counter),
                                     720,
                                     FONT_SIZE as u32)))
                .unwrap();
            counter += 1;
        }
        let texture = renderer.create_texture_from_surface(&main_surface)
            .unwrap();

        let TextureQuery { width, height, .. } = texture.query();

        renderer.copy(&texture, None, Some(Rect::new(0, 0, width, height)));
    }
}<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate regex;

use regex::Regex;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;

fn main() {
    let root_path = Path::new("../../../");
    let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs");
    let glue_file = root_path.join("ports/geckolib/glue.rs");

    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed={}", glue_file.display());
    println!("cargo:rerun-if-changed={}", bindings_file.display());

    let env_out_dir = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&env_out_dir);

    {
        let output = out_dir.join("check_bindings.rs");
        let r = BufReader::new(File::open(bindings_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"fn assert_types() {\n").unwrap();

        let matcher = Regex::new(r"fn\s*Servo_([a-zA-Z0-9_]+)\s*\(").unwrap();

        for line in r.lines() {
            let s = line.unwrap();
            for cap in matcher.captures_iter(&s) {
                // GetStyleVariables is a Servo_* function, but temporarily defined
                // on the Gecko side.
                if &cap[1] != "GetStyleVariables" {
                    w.write_all(format!("    [ Servo_{0}, bindings::Servo_{0} ];\n", &cap[1]).as_bytes()).unwrap();
                }
            }
        }

        w.write_all(b"}\n").unwrap();
    }

    {
        let output = out_dir.join("glue.rs");
        let r = BufReader::new(File::open(glue_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"pub use style::gecko::arc_types::*;\n").unwrap();

        for line in r.lines() {
            let s = line.unwrap().replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn");
            w.write_all(s.as_bytes()).unwrap();
            w.write_all(b"\n").unwrap();
        }
    }

    // https://github.com/rust-lang/cargo/issues/3544
    let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \
                                     TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap();
    File::create(out_dir.join("bindings.rs"))
        .unwrap()
        .write_all(format!("include!(concat!({:?}, \"/gecko/structs.rs\"));",
                           style_out_dir).as_bytes())
        .unwrap();
}
<commit_msg>Auto merge of #18873 - heycam:rm-gsv-check, r=emilio<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate regex;

use regex::Regex;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;

fn main() {
    let root_path = Path::new("../../../");
    let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs");
    let glue_file = root_path.join("ports/geckolib/glue.rs");

    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed={}", glue_file.display());
    println!("cargo:rerun-if-changed={}", bindings_file.display());

    let env_out_dir = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&env_out_dir);

    {
        let output = out_dir.join("check_bindings.rs");
        let r = BufReader::new(File::open(bindings_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"fn assert_types() {\n").unwrap();

        let matcher = Regex::new(r"fn\s*Servo_([a-zA-Z0-9_]+)\s*\(").unwrap();

        for line in r.lines() {
            let s = line.unwrap();
            for cap in matcher.captures_iter(&s) {
                w.write_all(format!("    [ Servo_{0}, bindings::Servo_{0} ];\n", &cap[1]).as_bytes()).unwrap();
            }
        }

        w.write_all(b"}\n").unwrap();
    }

    {
        let output = out_dir.join("glue.rs");
        let r = BufReader::new(File::open(glue_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"pub use style::gecko::arc_types::*;\n").unwrap();

        for line in r.lines() {
            let s = line.unwrap().replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn");
            w.write_all(s.as_bytes()).unwrap();
            w.write_all(b"\n").unwrap();
        }
    }

    // https://github.com/rust-lang/cargo/issues/3544
    let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \
                                     TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap();
    File::create(out_dir.join("bindings.rs"))
        .unwrap()
        .write_all(format!("include!(concat!({:?}, \"/gecko/structs.rs\"));",
                           style_out_dir).as_bytes())
        .unwrap();
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! bits {
    ($val:expr, $low:expr => $hi:expr) => {{
        let max_bit = ::std::mem::size_of_val(&$val) * 8 - 1;
        $val << (max_bit - $hi) >> (max_bit - $hi + $low)
    }};
}

#[cfg(feature="use_std")]
use std::ops::{BitOrAssign, BitXorAssign, Shl, Shr};
#[cfg(feature="use_std")]
use std::marker::PhantomData;

#[cfg(not(feature="use_std"))]
use core::ops::{BitOrAssign, BitXorAssign, Shl, Shr};
#[cfg(not(feature="use_std"))]
use core::marker::PhantomData;

#[allow(dead_code)]
pub struct BfPos<T>
    where T: Copy + BitOrAssign + BitXorAssign
                  + Shl<usize, Output=T> + Shr<usize, Output=T> {
    pos: (usize, usize),
    marker: PhantomData<T>
}
impl<T> BfPos<T>
    where T: Copy + BitOrAssign + BitXorAssign
                  + Shl<usize, Output=T> + Shr<usize, Output=T> {
    #[inline(always)]
    #[allow(dead_code)]
    pub fn new(pos: (usize, usize)) -> BfPos<T> {
        BfPos::<T> {
            pos: pos,
            marker: PhantomData
        }
    }

    #[inline(always)]
    #[allow(dead_code)]
    pub fn extract(&self, val: T) -> T {
        let pos = self.pos;
        bits!(val, pos.0 => pos.1)
    }

    #[inline(always)]
    #[allow(dead_code)]
    pub fn place(&self, mut val: T, new_val: T) -> T {
        let pos = self.pos;
        val ^= bits!(val, pos.0 => pos.1) << pos.0;
        val |= bits!(new_val, 0 => pos.1 - pos.0) << pos.0;
        val
    }
}

#[macro_export]
macro_rules! bfdesc {
    ($name:ident: $ty:ty, { $($var_name:ident: $var_low:expr => $var_hi:expr),* }) => {
        #[allow(non_snake_case)]
        pub mod $name {
            $(
                #[inline(always)]
                pub fn $var_name() -> $crate::bfdesc::BfPos<$ty> {
                    $crate::bfdesc::BfPos::<$ty>::new(($var_low, $var_hi))
                }
            )*
        }
    };
}

#[macro_export]
macro_rules! bf {
    {$var:tt.$item:ident} => ($var.get($var.$item()));
    {$var:tt.$item:ident = $val:expr} => ({
        let pos = $var.$item();
        $var.set(pos, $val)
    });
    {$var:tt @ $item:path} => (
        $item().extract($var)
    );
    {$var:tt @ $item:path = $val:expr} => (
        $var = $item().place($var, $val)
    );
    {$var:tt @ $item:path as $val:expr} => (
        $item().place($var, $val)
    );
}

#[cfg(test)]
mod test {
    const MAGIC: u8 = 0b10101010;

    mod m {
        bfdesc!(TestDesc: u8, {
            bottom: 0 => 5
        });
    }

    #[test]
    pub fn bfdesc_extract() {
        assert_eq!(bf!(MAGIC @ m::TestDesc::bottom), 0b101010);
    }

    #[test]
    pub fn bfdesc_place() {
        let mut magic = MAGIC;
        bf!(magic @ m::TestDesc::bottom = 0b110111);
        assert_eq!(magic, 0b10110111);
    }

    #[test]
    pub fn bfdesc_as() {
        assert_eq!(bf!(MAGIC @ m::TestDesc::bottom as 0b110111), 0b10110111);
    }
}<commit_msg>Get rid of redundant bits! macro in bfdesc.rs<commit_after>#[cfg(feature="use_std")]
use std::ops::{BitOrAssign, BitXorAssign, Shl, Shr};
#[cfg(feature="use_std")]
use std::marker::PhantomData;

#[cfg(not(feature="use_std"))]
use core::ops::{BitOrAssign, BitXorAssign, Shl, Shr};
#[cfg(not(feature="use_std"))]
use core::marker::PhantomData;

#[allow(dead_code)]
pub struct BfPos<T>
    where T: Copy + BitOrAssign + BitXorAssign
                  + Shl<usize, Output=T> + Shr<usize, Output=T> {
    pos: (usize, usize),
    marker: PhantomData<T>
}
impl<T> BfPos<T>
    where T: Copy + BitOrAssign + BitXorAssign
                  + Shl<usize, Output=T> + Shr<usize, Output=T> {
    #[inline(always)]
    #[allow(dead_code)]
    pub fn new(pos: (usize, usize)) -> BfPos<T> {
        BfPos::<T> {
            pos: pos,
            marker: PhantomData
        }
    }

    #[inline(always)]
    #[allow(dead_code)]
    pub fn extract(&self, val: T) -> T {
        let pos = self.pos;
        bits!(val, pos.0 => pos.1)
    }

    #[inline(always)]
    #[allow(dead_code)]
    pub fn place(&self, mut val: T, new_val: T) -> T {
        let pos = self.pos;
        val ^= bits!(val, pos.0 => pos.1) << pos.0;
        val |= bits!(new_val, 0 => pos.1 - pos.0) << pos.0;
        val
    }
}

#[macro_export]
macro_rules! bfdesc {
    ($name:ident: $ty:ty, { $($var_name:ident: $var_low:expr => $var_hi:expr),* }) => {
        #[allow(non_snake_case)]
        pub mod $name {
            $(
                #[inline(always)]
                pub fn $var_name() -> $crate::bfdesc::BfPos<$ty> {
                    $crate::bfdesc::BfPos::<$ty>::new(($var_low, $var_hi))
                }
            )*
        }
    };
}

#[macro_export]
macro_rules! bf {
    {$var:tt.$item:ident} => ($var.get($var.$item()));
    {$var:tt.$item:ident = $val:expr} => ({
        let pos = $var.$item();
        $var.set(pos, $val)
    });
    {$var:tt @ $item:path} => (
        $item().extract($var)
    );
    {$var:tt @ $item:path = $val:expr} => (
        $var = $item().place($var, $val)
    );
    {$var:tt @ $item:path as $val:expr} => (
        $item().place($var, $val)
    );
}

#[cfg(test)]
mod test {
    const MAGIC: u8 = 0b10101010;

    mod m {
        bfdesc!(TestDesc: u8, {
            bottom: 0 => 5
        });
    }

    #[test]
    pub fn bfdesc_extract() {
        assert_eq!(bf!(MAGIC @ m::TestDesc::bottom), 0b101010);
    }

    #[test]
    pub fn bfdesc_place() {
        let mut magic = MAGIC;
        bf!(magic @ m::TestDesc::bottom = 0b110111);
        assert_eq!(magic, 0b10110111);
    }

    #[test]
    pub fn bfdesc_as() {
        assert_eq!(bf!(MAGIC @ m::TestDesc::bottom as 0b110111), 0b10110111);
    }
}
<|endoftext|>


<commit_before>use tokio::reactor::Handle;
use {RamStore, sexp_proto, TailService, ServerService};
use service::{Service, NewService, simple_service};
use tokio::io::FramedIo;
use futures::{self, Poll, Async, Future, stream, BoxFuture};
use proto::pipeline::{self, Frame};
use proto::{self, Message};

use std::net::SocketAddr;
use std::io;
use std::sync::{Mutex, Arc};

use std::collections::{BTreeMap, VecDeque};
use void::Void;
use take::Take;
use std::marker::PhantomData;

use hosting::{HostConfig, Host, CoreService};

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BovineAddr(pub usize);

pub struct InnerBovine<S: Service> {
    new_service: Box<NewService<Request = S::Request,
                                Response = S::Response,
                                Item = S,
                                Error = S::Error> + Send>,
    connections: BTreeMap<usize, ()>,
}

pub struct SphericalBovine<S: Service> {
    inner: Arc<Mutex<InnerBovine<S>>>,
}

pub struct BovinePort<S, R>(Arc<Mutex<VecDeque<S>>>, Arc<Mutex<VecDeque<R>>>);

impl<S: Service> SphericalBovine<S>
    where S::Request: Send + 'static,
          S::Response: Send + 'static,
          S::Future: Send + 'static,
          S: Send + Sync + 'static,
          S::Error: From<proto::Error<S::Error>> + Send + 'static
{
    pub fn new<N>(service: N) -> Self
        where N: NewService<Request = S::Request,
                            Response = S::Response,
                            Item = S,
                            Error = S::Error> + Send + 'static
    {
        let inner = InnerBovine {
            new_service: Box::new(service),
            connections: BTreeMap::new(),
        };
        SphericalBovine { inner: Arc::new(Mutex::new(inner)) }
    }

    fn connect_transport(&self,
                         handle: &Handle)
                         -> Result<BovinePort<Frame<Message<S::Request,
                                                            stream::Empty<Void, Void>>,
                                                    Void,
                                                    S::Error>,
                                              Frame<Message<S::Response,
                                                            stream::Empty<Void, Void>>,
                                                    Void,
                                                    S::Error>>,
                                   io::Error> {
        let cloned_ref = self.inner.clone();
        let mut inner = self.inner.lock().expect("lock");

        let n = inner.connections.keys().rev().next().map(|n| n + 1).unwrap_or(0);
        assert!(inner.connections.get(&n).is_none());

        let cts = Arc::new(Mutex::new(VecDeque::new()));
        let stc = Arc::new(Mutex::new(VecDeque::new()));

        let service_transport = BovinePort(stc.clone(), cts.clone());
        let client_transport = BovinePort(cts.clone(), stc.clone());

        let service = try!(inner.new_service.new_service());
        let service = simple_service(move |req: Message<S::Request, _>| -> BoxFuture<Message<S::Response,
                                                                stream::Empty<Void, S::Error>>,
                                                        S::Error> {
            service.call(req.into_inner()).map(Message::WithoutBody).boxed()
        });

        let _: &pipeline::Transport<In = S::Response, /* Message<S::Response, stream::Empty<Void, Void>>, */
                                    Out = Message<S::Request, stream::Empty<Void, Void>>,
                                    BodyIn = Void,
                                    BodyOut = Void,
                                    Error = S::Error> = &service_transport;

        let task_f = try!(pipeline::Server::new(service, service_transport));
        let () = handle.spawn(task_f.map_err(|e| panic!("transport error? {:?}", e)));

        inner.connections.insert(n, ());
        // Ok(client_transport)
        unimplemented!()
    }
}

impl<S: Service> Host for SphericalBovine<S> {
    type Addr = BovineAddr;

    fn build_server(&mut self,
                    _service: CoreService,
                    _handle: &Handle,
                    head_addr: Self::Addr,
                    tail_addr: Self::Addr)
                    -> Result<HostConfig<Self::Addr>, io::Error> {
        // let CoreService { head, tail } = service;
        let _head_host = unimplemented!();
        let _tail_host = unimplemented!();

        Ok(HostConfig {
            head: head_addr,
            tail: tail_addr,
        })
    }
}

impl<S, R> FramedIo for BovinePort<S, R> {
    type In = S;
    type Out = R;

    fn poll_read(&mut self) -> Async<()> {
        let &mut BovinePort(ref inner, ref id) = self;
        unimplemented!()
    }
    fn read(&mut self) -> Poll<Self::Out, io::Error> {
        let &mut BovinePort(ref inner, ref id) = self;
        // unimplemented!()
        Ok(Async::NotReady)
    }
    fn poll_write(&mut self) -> Async<()> {
        let &mut BovinePort(ref inner, ref id) = self;
        let inner = inner.lock().expect("lock");
        // let ref service = inner.connections[id];
        // service.poll_ready()
        unimplemented!()
    }
    fn write(&mut self, _msg: Self::In) -> Poll<(), io::Error> {
        let &mut BovinePort(ref inner, ref id) = self;
        let inner = inner.lock().expect("lock");
        // Not quite right, should be a pipeline/ FramedIo thingy.
        // let ref blah: S = inner.connections[id];
        unimplemented!();
        Ok(Async::Ready(()))
    }
    fn flush(&mut self) -> Poll<(), io::Error> {
        let &mut BovinePort(ref inner, ref id) = self;
        Ok(Async::Ready(()))
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use tokio::reactor::{Core, Handle};
    use proto::{self, pipeline, Message};
    use service::{simple_service, Service};
    use void::Void;
    use take::Take;
    use futures;
    use std::io;

    #[cfg(never)]
    #[test]
    fn should_go_moo() {
        let mut core = Core::new().expect("Core::new");
        let service = simple_service(|n: usize| -> Result<usize, ()> { Ok(n + 1) });

        let net = SphericalBovine::new(service);

        let handle = core.handle();
        let client_transport = net.connect_transport(&handle).expect("connect_transport");
        let new_transport = Take::new(move || Ok(client_transport));
        let _: &pipeline::NewTransport<In = Message<usize, _>,
                                       Out = usize,
                                       BodyIn = Void,
                                       BodyOut = Void,
                                       Error = io::Error,
                                       Item = BovinePort<_, _>,
                                       Future = futures::Done<_, _>> = &new_transport;
        let client: proto::Client<_, _, futures::stream::Empty<Void, io::Error>, io::Error> =
            pipeline::connect(new_transport, handle);

        // let client : proto::Client<usize, usize, futures::stream::Empty<Void, io::Error>, io::Error> = pipeline::connect(|| , &core.handle());

        let f = client.call(Message::WithoutBody(Message::WithoutBody(42)));

        let ret = core.run(f).expect("run");
        assert_eq!(ret, 42);
    }
}
<commit_msg>Something that seems to approximate workingness.<commit_after>use tokio::reactor::Handle;
use {RamStore, sexp_proto, TailService, ServerService};
use service::{Service, NewService, simple_service};
use tokio::io::FramedIo;
use futures::{self, Poll, Async, Future, stream, BoxFuture};
use proto;

use std::net::SocketAddr;
use std::io;
use std::sync::{Mutex, Arc};

use std::collections::{BTreeMap, VecDeque};
use void::Void;
use take::Take;
use std::marker::PhantomData;
use std::fmt;

use hosting::{HostConfig, Host, CoreService};

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BovineAddr(pub usize);

pub struct InnerBovine<S: Service> {
    new_service: Box<NewService<Request = S::Request,
                                Response = S::Response,
                                Item = S,
                                Error = S::Error> + Send>,
    connections: BTreeMap<usize, BoxFuture<(), io::Error>>,
}

pub struct SphericalBovine<S: Service> {
    inner: Arc<Mutex<InnerBovine<S>>>,
}

pub struct BovinePort<S, R>(Arc<Mutex<VecDeque<S>>>, Arc<Mutex<VecDeque<R>>>);

pub struct BovineHostTask<S: Service, T> {
    service: S,
    transport: T,
    pending: Option<S::Future>,
}

impl<S: Service, T> BovineHostTask<S, T> {
    fn new(service: S, transport: T) -> Self {
        BovineHostTask {
            service: service,
            transport: transport,
            pending: None,
        }
    }
}

pub struct BovineHostClient<T: FramedIo> {
    transport: Arc<Mutex<T>>,
    queue: Arc<Mutex<VecDeque<futures::Complete<T::Out>>>>,
}

impl<T: FramedIo> BovineHostClient<T> {
    fn new(transport: T) -> Self {
        BovineHostClient {
            transport: Arc::new(Mutex::new(transport)),
            queue: Arc::new(Mutex::new(VecDeque::new())),
        }
    }
}

impl<S: Service, T: FramedIo<Out=S::Request, In=Result<S::Response, S::Error>>> Future for BovineHostTask<S, T> {
    type Item = ();
    type Error = io::Error;
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        trace!("BovineHostTask#poll");
        loop {
            if self.transport.poll_write().is_ready() {
                if let Some(mut f) = self.pending.take() {
                    trace!("has pending");
                    match f.poll() {
                        Ok(Async::Ready(resp)) => {
                            trace!("-> done");
                            self.transport.write(Ok(resp)).expect("write resp");
                        }
                        Err(e) => {
                            trace!("-> error");
                            self.transport.write(Err(e)).expect("write resp");
                        }
                        Ok(Async::NotReady) => {
                            self.pending = Some(f);
                        }
                    }
                }
            }
            assert!(self.pending.is_none());
            let req = try_ready!(self.transport.read());
            trace!("-> new req");
            let resp_f = self.service.call(req);
            self.pending = Some(resp_f);
        }
    }
}

pub struct BovineClientFut<T: FramedIo> {
    inner: futures::Oneshot<T::Out>,
    transport: Arc<Mutex<T>>,
    queue: Arc<Mutex<VecDeque<futures::Complete<T::Out>>>>,
}

impl<T: FramedIo> Service for BovineHostClient<T> {
    type Request = T::In;
    type Response = T::Out;
    type Error = futures::Canceled;
    type Future = BovineClientFut<T>;

    fn poll_ready(&self) -> Async<()> {
        trace!("BovineHostClient#poll_ready");
        self.transport.lock().expect("lock").poll_write()
    }

    fn call(&self, _req: Self::Request) -> Self::Future {
        trace!("BovineHostClient#call");
        let (c, p) = futures::oneshot();
        {
            let mut q = self.queue.lock().expect("lock");
            self.transport.lock().expect("lock").write(_req).expect("write");
            q.push_back(c);
        }
        BovineClientFut {
            inner: p,
            transport: self.transport.clone(),
            queue: self.queue.clone(),
        }
    }
}

impl<T: FramedIo> Future for BovineClientFut<T> {
    type Item = T::Out;
    type Error = futures::Canceled;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let &mut BovineClientFut { ref mut inner, ref mut transport, ref mut queue } = self;
        {
            let mut q = queue.lock().expect("lock queue");
            let mut t = transport.lock().expect("lock transport");
            if let Some(c) = q.pop_front() {
                match t.read() {
                    Ok(Async::Ready(val)) => c.complete(val),
                    Ok(Async::NotReady) => q.push_front(c),
                    Err(e) => panic!("Unexpected error on read: {:?}", e),
                }
            }
        }
        inner.poll()
    }
}

impl<S: Service> SphericalBovine<S>
    where S::Request: Send + 'static,
          S::Response: Send + 'static,
          S::Future: Send + 'static,
          S: Send + Sync + 'static,
          S::Error: From<proto::Error<S::Error>> + Send + 'static
{
    pub fn new<N>(service: N) -> Self
        where N: NewService<Request = S::Request,
                            Response = S::Response,
                            Item = S,
                            Error = S::Error> + Send + 'static
    {
        let inner = InnerBovine {
            new_service: Box::new(service),
            connections: BTreeMap::new(),
        };
        SphericalBovine { inner: Arc::new(Mutex::new(inner)) }
    }

    fn connect(&self)
               -> Result<BovineHostClient<BovinePort<S::Request, Result<S::Response, S::Error>>>, io::Error> {
        let cloned_ref = self.inner.clone();
        let mut inner = self.inner.lock().expect("lock");

        let n = inner.connections.keys().rev().next().map(|n| n + 1).unwrap_or(0);
        assert!(inner.connections.get(&n).is_none());

        let cts = Arc::new(Mutex::new(VecDeque::new()));
        let stc = Arc::new(Mutex::new(VecDeque::new()));

        let service_transport = BovinePort(stc.clone(), cts.clone());
        let client_transport = BovinePort(cts.clone(), stc.clone());

        let service = try!(inner.new_service.new_service());

        let t = BovineHostTask::new(service, service_transport);

        inner.connections.insert(n, t.boxed());

        let c = BovineHostClient::new(client_transport);
        Ok(c)
    }
}
impl<S: Service> Future for SphericalBovine<S> {
    type Item = ();
    type Error = ();
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        trace!("SphericalBovine#poll");
        let mut inner = self.inner.lock().expect("lock");
        for (addr, serv) in inner.connections.iter_mut() {
            trace!("-> SphericalBovine@{:?}#poll", addr);
            match serv.poll() {
                Ok(Async::Ready(())) => unimplemented!(),
                Ok(Async::NotReady) => (),
                Err(e) => panic!("service {:?} failed with {:?}", addr, e),
            };
            trace!("<- SphericalBovine@{:?}#poll", addr);
        }
        Ok(Async::NotReady)
    }
}

impl<S: Service> Host for SphericalBovine<S> {
    type Addr = BovineAddr;

    fn build_server(&mut self,
                    _service: CoreService,
                    _handle: &Handle,
                    head_addr: Self::Addr,
                    tail_addr: Self::Addr)
                    -> Result<HostConfig<Self::Addr>, io::Error> {
        // let CoreService { head, tail } = service;
        let _head_host = unimplemented!();
        let _tail_host = unimplemented!();

        Ok(HostConfig {
            head: head_addr,
            tail: tail_addr,
        })
    }
}

impl<S, R> FramedIo for BovinePort<S, R> {
    type In = S;
    type Out = R;

    fn poll_read(&mut self) -> Async<()> {
        trace!("BovinePort#poll_read");
        // let &mut BovinePort(ref inner, ref id) = self;
        unimplemented!()
    }
    fn read(&mut self) -> Poll<Self::Out, io::Error> {
        trace!("BovinePort#read");
        let &mut BovinePort(_, ref recv) = self;
        let mut recv = recv.lock().expect("lock");
        trace!("recv queue pre: {:?}", recv.len());
        if let Some(res) = recv.pop_front() {
            debug!("-> value");
            Ok(Async::Ready(res))
        } else {
            Ok(Async::NotReady)
        }
    }
    fn poll_write(&mut self) -> Async<()> {
        trace!("BovinePort#poll_write");
        Async::Ready(())
    }
    fn write(&mut self, msg: Self::In) -> Poll<(), io::Error> {
        trace!("BovinePort#write");
        let &mut BovinePort(ref send, _) = self;
        let mut send = send.lock().expect("lock");
        send.push_back(msg);
        trace!("send queue post: {:?}", send.len());
        Ok(Async::Ready(()))
    }
    fn flush(&mut self) -> Poll<(), io::Error> {
        // let &mut BovinePort(ref inner, ref id) = self;
        Ok(Async::Ready(()))
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use tokio::reactor::Core;
    use service::{simple_service, Service};
    use std::io;
    use env_logger;
    use futures::{Async, Future};
    use futures::task::{self, Unpark};
    use std::sync::Arc;

    struct Unparker;

    impl Unpark for Unparker {
        fn unpark(&self) {
            debug!("Unpark!");
        }
    }

    #[test]
    fn should_go_moo() {
        env_logger::init().unwrap_or(());
        let mut core = Core::new().expect("Core::new");
        let service = simple_service(|n: usize| -> Result<usize, io::Error> {
            debug!("Adding: {:?}", n);
            Ok(n + 1)
        });

        let net = SphericalBovine::new(service);

        let handle = core.handle();
        let client = net.connect().expect("connect");

        let mut f = task::spawn(client.call(42));
        let mut net = task::spawn(net);
        loop {
            match net.poll_future(Arc::new(Unparker)) {
                Ok(Async::NotReady) => (),
                Ok(Async::Ready(())) => panic!("Network terminated"),
                Err(e) => panic!("Network failed: {:?}", e),
            };
            match f.poll_future(Arc::new(Unparker)) {
                Ok(Async::NotReady) => (),
                Ok(Async::Ready(val)) => {
                    assert_eq!(val.expect("result"), 43);
                    break;
                }
                Err(e) => panic!("Addition failed: {:?}", e),
            }
        }
    }
}
<|endoftext|>