<commit_before>#![feature(asm)]
#![feature(box_syntax)]
#![feature(core)]
#![feature(lang_items)]
#![feature(no_std)]
#![no_std]

extern crate core;

use core::mem::size_of;
use core::result::Result;

use common::debug::*;
use common::elf::*;
use common::pio::*;
use common::memory::*;
use common::vector::*;

use drivers::disk::*;
use drivers::keyboard::*;
use drivers::mouse::*;

use filesystems::unfs::*;

use graphics::color::*;
use graphics::display::*;
use graphics::point::*;
use graphics::size::*;

use programs::program::*;
use programs::editor::*;
use programs::viewer::*;

mod common {
    pub mod debug;
    pub mod elf;
    pub mod memory;
	pub mod pio;
	pub mod string;
	pub mod vector;
}

mod drivers {
    pub mod disk;
    pub mod keyboard;
    pub mod mouse;
}

mod filesystems {
    pub mod unfs;
}

mod graphics {
    pub mod bmp;
	pub mod color;
	pub mod display;
	pub mod point;
	pub mod size;
	pub mod window;
}

mod programs {
    pub mod program;
    pub mod editor;
    pub mod viewer;
}

#[lang = "owned_box"]
pub struct Box<T>(*mut T);

#[lang="exchange_malloc"]
pub fn exchange_malloc(size: usize, align: usize) -> *mut u8{
    alloc(size) as *mut u8
}

#[lang="exchange_free"]
pub fn exchange_free(ptr: *mut u8, size: usize, align: usize){
    unalloc(ptr as usize);
}

unsafe fn initialize(){
    dd(size_of::<usize>() * 8);
    d(" bits");
    dl();

    d("Paging\n");
    page_init();

    d("Clusters\n");
    cluster_init();

    d("Mouse\n");
    mouse_init();

    d("Keyboard Status\n");
    keyboard_init();

    d("Fonts\n");
    let unfs = UnFS::new(Disk::new());
    FONT_LOCATION = unfs.load("unifont.font");

    if FONT_LOCATION > 0 {
        d("Read font file\n");
    }else{
        d("Did not find font file\n");
    }

    d("ELF\n");
    let elf = ELF::new(unfs.load("test.bin"));
    elf.run();
}

pub unsafe fn timestamp() -> u64 {
    let low: u32;
    let high: u32;
    asm!("rdtsc"
        : "={eax}"(low), "={edx}"(high) : : "intel");

    return low as u64;
}

const INTERRUPT: *mut u8 = 0x200000 as *mut u8;

#[no_mangle]
pub unsafe fn kernel() {
    if *INTERRUPT == 255 {
        initialize();

        let display = Display::new();

        let mut mouse_point: Point = Point {
            x: 0,
            y: 0
        };

        let programs =
            Vector::<Box<Program>>::from_value(box Viewer::new()) +
            Vector::<Box<Program>>::from_value(box Editor::new());

        loop{
            asm!("cli");
            let interrupt = *INTERRUPT;
            *INTERRUPT = 255;

            let mut draw = false;
            match interrupt {
                32 => {
                },
                33 => {
                    let key_event = keyboard_interrupt();

                    d("KEY ");
                    dc(key_event.character);
                    dl();

                    for program in programs.as_slice() {
                        (*program).on_key(key_event);
                    }

                    draw = true;
                },
                44 => {
                    let mouse_event = mouse_interrupt();

                    if mouse_event.valid {
                        mouse_point.x += mouse_event.x;
                        if mouse_point.x < 0 {
                            mouse_point.x = 0;
                        }
                        if mouse_point.x >= display.size.width as i32 {
                            mouse_point.x = display.size.width as i32 - 1;
                        }

                        mouse_point.y += mouse_event.y;
                        if mouse_point.y < 0 {
                            mouse_point.y = 0;
                        }
                        if mouse_point.y >= display.size.height as i32 {
                            mouse_point.y = display.size.height as i32 - 1;
                        }

                        d("MOUSE ");
                        dd(mouse_point.x as usize);
                        d(", ");
                        dd(mouse_point.y as usize);
                        dl();

                        for program in programs.as_slice() {
                            if (*program).on_mouse(mouse_point, mouse_event) {
                                break;
                            }
                        }

                        draw = true;
                    }
                },
                255 => {
                    draw = true;
                },
                _ => {
                    d("I: ");
                    dd(interrupt as usize);
                    dl();
                }
            }

            if draw {
                let t_clear = timestamp();
                display.clear(Color::new(64, 64, 64));

                let t_rect = timestamp();
                display.rect(Point::new(0, 0), Size::new(display.size.width, 18), Color::new(0, 0, 0));

                let t_text = timestamp();
                display.text(Point::new(display.size.width as i32/ 2 - 3*8, 1), "UberOS", Color::new(255, 255, 255));

                let t_prog = timestamp();
                for program in programs.as_slice() {
                    (*program).draw(&display);
                }

                let t_mouse = timestamp();
                display.char_bitmap(mouse_point, &MOUSE_CURSOR as *const u8, Color::new(255, 255, 255));

                let t_copy = timestamp();
                display.copy();

                let t_finish = timestamp();

                /*
                d("Clear: ");
                dd((t_rect - t_clear) as usize);
                dl();

                d("Rect: ");
                dd((t_text - t_rect) as usize);
                dl();

                d("Text: ");
                dd((t_prog - t_text) as usize);
                dl();

                d("Prog: ");
                dd((t_mouse - t_prog) as usize);
                dl();

                d("Mouse: ");
                dd((t_copy - t_mouse) as usize);
                dl();

                d("Copy: ");
                dd((t_finish - t_copy) as usize);
                dl();
                */
            }

            if interrupt >= 0x20 && interrupt < 0x30 {
                if interrupt >= 0x28 {
                    outb(0xA0, 0x20);
                }

                outb(0x20, 0x20);
            }

            asm!("sti\nhlt");
        }
	}
}<commit_msg>Hide timing information<commit_after>#![feature(asm)]
#![feature(box_syntax)]
#![feature(core)]
#![feature(lang_items)]
#![feature(no_std)]
#![no_std]

extern crate core;

use core::mem::size_of;
use core::result::Result;

use common::debug::*;
use common::elf::*;
use common::pio::*;
use common::memory::*;
use common::vector::*;

use drivers::disk::*;
use drivers::keyboard::*;
use drivers::mouse::*;

use filesystems::unfs::*;

use graphics::color::*;
use graphics::display::*;
use graphics::point::*;
use graphics::size::*;

use programs::program::*;
use programs::editor::*;
use programs::viewer::*;

mod common {
    pub mod debug;
    pub mod elf;
    pub mod memory;
	pub mod pio;
	pub mod string;
	pub mod vector;
}

mod drivers {
    pub mod disk;
    pub mod keyboard;
    pub mod mouse;
}

mod filesystems {
    pub mod unfs;
}

mod graphics {
    pub mod bmp;
	pub mod color;
	pub mod display;
	pub mod point;
	pub mod size;
	pub mod window;
}

mod programs {
    pub mod program;
    pub mod editor;
    pub mod viewer;
}

#[lang = "owned_box"]
pub struct Box<T>(*mut T);

#[lang="exchange_malloc"]
pub fn exchange_malloc(size: usize, align: usize) -> *mut u8{
    alloc(size) as *mut u8
}

#[lang="exchange_free"]
pub fn exchange_free(ptr: *mut u8, size: usize, align: usize){
    unalloc(ptr as usize);
}

unsafe fn initialize(){
    dd(size_of::<usize>() * 8);
    d(" bits");
    dl();

    d("Paging\n");
    page_init();

    d("Clusters\n");
    cluster_init();

    d("Mouse\n");
    mouse_init();

    d("Keyboard Status\n");
    keyboard_init();

    d("Fonts\n");
    let unfs = UnFS::new(Disk::new());
    FONT_LOCATION = unfs.load("unifont.font");

    if FONT_LOCATION > 0 {
        d("Read font file\n");
    }else{
        d("Did not find font file\n");
    }

    d("ELF\n");
    let elf = ELF::new(unfs.load("test.bin"));
    elf.run();
}

pub unsafe fn timestamp() -> u64 {
    let low: u32;
    let high: u32;
    asm!("rdtsc"
        : "={eax}"(low), "={edx}"(high) : : "intel");

    return low as u64;
}

const INTERRUPT: *mut u8 = 0x200000 as *mut u8;

#[no_mangle]
pub unsafe fn kernel() {
    if *INTERRUPT == 255 {
        initialize();

        let display = Display::new();

        let mut mouse_point: Point = Point {
            x: 0,
            y: 0
        };

        let programs =
            Vector::<Box<Program>>::from_value(box Viewer::new()) +
            Vector::<Box<Program>>::from_value(box Editor::new());

        loop{
            asm!("cli");
            let interrupt = *INTERRUPT;
            *INTERRUPT = 255;

            let mut draw = false;
            match interrupt {
                32 => {
                },
                33 => {
                    let key_event = keyboard_interrupt();

                    d("KEY ");
                    dc(key_event.character);
                    dl();

                    for program in programs.as_slice() {
                        (*program).on_key(key_event);
                    }

                    draw = true;
                },
                44 => {
                    let mouse_event = mouse_interrupt();

                    if mouse_event.valid {
                        mouse_point.x += mouse_event.x;
                        if mouse_point.x < 0 {
                            mouse_point.x = 0;
                        }
                        if mouse_point.x >= display.size.width as i32 {
                            mouse_point.x = display.size.width as i32 - 1;
                        }

                        mouse_point.y += mouse_event.y;
                        if mouse_point.y < 0 {
                            mouse_point.y = 0;
                        }
                        if mouse_point.y >= display.size.height as i32 {
                            mouse_point.y = display.size.height as i32 - 1;
                        }

                        d("MOUSE ");
                        dd(mouse_point.x as usize);
                        d(", ");
                        dd(mouse_point.y as usize);
                        dl();

                        for program in programs.as_slice() {
                            if (*program).on_mouse(mouse_point, mouse_event) {
                                break;
                            }
                        }

                        draw = true;
                    }
                },
                255 => {
                    draw = true;
                },
                _ => {
                    d("I: ");
                    dd(interrupt as usize);
                    dl();
                }
            }

            if draw {
                //let t_clear = timestamp();
                display.clear(Color::new(64, 64, 64));

                //let t_rect = timestamp();
                display.rect(Point::new(0, 0), Size::new(display.size.width, 18), Color::new(0, 0, 0));

                //let t_text = timestamp();
                display.text(Point::new(display.size.width as i32/ 2 - 3*8, 1), "UberOS", Color::new(255, 255, 255));

                //let t_prog = timestamp();
                for program in programs.as_slice() {
                    (*program).draw(&display);
                }

                //let t_mouse = timestamp();
                display.char_bitmap(mouse_point, &MOUSE_CURSOR as *const u8, Color::new(255, 255, 255));

                //let t_copy = timestamp();
                display.copy();

                //let t_finish = timestamp();

                /*
                d("Clear: ");
                dd((t_rect - t_clear) as usize);
                dl();

                d("Rect: ");
                dd((t_text - t_rect) as usize);
                dl();

                d("Text: ");
                dd((t_prog - t_text) as usize);
                dl();

                d("Prog: ");
                dd((t_mouse - t_prog) as usize);
                dl();

                d("Mouse: ");
                dd((t_copy - t_mouse) as usize);
                dl();

                d("Copy: ");
                dd((t_finish - t_copy) as usize);
                dl();
                */
            }

            if interrupt >= 0x20 && interrupt < 0x30 {
                if interrupt >= 0x28 {
                    outb(0xA0, 0x20);
                }

                outb(0x20, 0x20);
            }

            asm!("sti\nhlt");
        }
	}
}<|endoftext|>


<commit_before><commit_msg>Adjust to ImageSurface::get_data change<commit_after><|endoftext|>


<commit_before>use std;

use galois::{Polynomial, PolynomialCoefs, P25Codeword, P25Field, GaloisField};

/// Implements the iterative part of the Berlekamp-Massey algorithm.
pub struct BerlMasseyDecoder<P: PolynomialCoefs> {
    /// Saved p polynomial: p_{z_i-1}.
    p_saved: Polynomial<P>,
    /// Previous iteration's p polynomial: p_{i-1}.
    p_cur: Polynomial<P>,
    /// Saved q polynomial: q_{z_i-1}.
    q_saved: Polynomial<P>,
    /// Previous iteration's q polynomial: q_{i-1}.
    q_cur: Polynomial<P>,
    /// Degree-related term of saved p polynomial: D_{z_i-1}.
    deg_saved: usize,
    /// Degree-related term of previous p polynomial: D_{i-1}.
    deg_cur: usize,
}

impl<P: PolynomialCoefs> BerlMasseyDecoder<P> {
    /// Construct a new `BerlMasseyDecoder` from the given syndrome polynomial.
    pub fn new(syn: Polynomial<P>) -> BerlMasseyDecoder<P> {
        // 2t zeroes followed by a one.
        let p = Polynomial::new((0..P::syndromes()+1).map(|_| P25Codeword::default())
                                    .chain(std::iter::once(P25Codeword::for_power(0))));

        BerlMasseyDecoder {
            q_saved: syn,
            q_cur: syn.shift(),
            p_saved: p,
            p_cur: p.shift(),
            deg_saved: 0,
            deg_cur: 1,
        }
    }

    /// Perform the iterative steps to get the error-location polynomial Λ(x) wih deg(Λ)
    /// <= t.
    pub fn decode(mut self) -> Polynomial<P> {
        for _ in 0..P::syndromes() {
            self.step();
        }

        self.p_cur
    }

    /// Perform one iterative step of the algorithm, updating the state polynomials and
    /// degrees.
    fn step(&mut self) {
        let (save, q, p, d) = if self.q_cur.constant().zero() {
            self.reduce()
        } else {
            self.transform()
        };

        if save {
            self.q_saved = self.q_cur;
            self.p_saved = self.p_cur;
            self.deg_saved = self.deg_cur;
        }

        self.q_cur = q;
        self.p_cur = p;
        self.deg_cur = d;
    }

    /// Simply shift the polynomials since they have no degree-0 term.
    fn reduce(&mut self) -> (bool, Polynomial<P>, Polynomial<P>, usize) {
        (
            false,
            self.q_cur.shift(),
            self.p_cur.shift(),
            2 + self.deg_cur,
        )
    }

    /// Remove the degree-0 terms and shift the polynomials.
    fn transform(&mut self) -> (bool, Polynomial<P>, Polynomial<P>, usize) {
        let mult = self.q_cur.constant() / self.q_saved.constant();

        (
            self.deg_cur >= self.deg_saved,
            (self.q_cur + self.q_saved * mult).shift(),
            (self.p_cur + self.p_saved * mult).shift(),
            2 + std::cmp::min(self.deg_cur, self.deg_saved),
        )
   }
}

/// Uses Chien search to find the roots in GF(2^6) of an error-locator polynomial and
/// produce an iterator of error bit positions. The Forney algorithm is used to find the
/// associated error values.
pub struct Errors<P: PolynomialCoefs> {
    /// Error location polynomial.
    epoly: Polynomial<P>,
    /// Derivative of above.
    deriv: Polynomial<P>,
    /// Error value polynomial.
    vpoly: Polynomial<P>,
    /// Current exponent power of the iteration.
    pow: std::ops::Range<usize>,
}

impl<P: PolynomialCoefs> Errors<P> {
    /// Construct a new `Errors` from the given error and syndrome polynomials.
    pub fn new(mut epoly: Polynomial<P>, syn: Polynomial<P>) -> Errors<P> {
        let deriv = epoly.deriv();
        let vpoly = (epoly * syn).truncate(P::syndromes());

        for (pow, cur) in epoly.iter_mut().enumerate() {
            // Since the first call to `update_terms()` multiplies by `pow` and the
            // coefficients should equal themselves on the first iteration, divide by
            // `pow` here.
            *cur = *cur / P25Codeword::for_power(pow)
        }

        Errors {
            epoly: epoly,
            deriv: deriv,
            vpoly: vpoly,
            pow: 0..P25Field::size(),
        }
    }

    /// Perform the term-updating step of the algorithm: x_{j,i} = x_{j,i-1} * α^j.
    fn update_terms(&mut self) {
        for (pow, term) in self.epoly.iter_mut().enumerate() {
            *term = *term * P25Codeword::for_power(pow);
        }
    }

    /// Calculate the sum of the terms: x_{0,i} + x_{1,i} + ... + x_{t,i} -- evaluate the
    /// error-locator polynomial at Λ(α^i).
    fn sum_terms(&self) -> P25Codeword {
        self.epoly.iter().fold(P25Codeword::default(), |s, &x| s + x)
    }

    /// Determine the error value for the given error location/root.
    fn value(&self, loc: P25Codeword, root: P25Codeword) -> P25Codeword {
        self.vpoly.eval(root) / self.deriv.eval(root) * loc
    }
}

impl<P: PolynomialCoefs> Iterator for Errors<P> {
    type Item = (usize, P25Codeword);

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            let pow = match self.pow.next() {
                Some(pow) => pow,
                None => return None,
            };

            self.update_terms();

            if self.sum_terms().zero() {
                let root = P25Codeword::for_power(pow);
                let loc = root.invert();

                return Some((loc.power().unwrap(), self.value(loc, root)));
            }
        }
    }
}
<commit_msg>s/epoly/err/ and s/vpoly/vals/<commit_after>use std;

use galois::{Polynomial, PolynomialCoefs, P25Codeword, P25Field, GaloisField};

/// Implements the iterative part of the Berlekamp-Massey algorithm.
pub struct BerlMasseyDecoder<P: PolynomialCoefs> {
    /// Saved p polynomial: p_{z_i-1}.
    p_saved: Polynomial<P>,
    /// Previous iteration's p polynomial: p_{i-1}.
    p_cur: Polynomial<P>,
    /// Saved q polynomial: q_{z_i-1}.
    q_saved: Polynomial<P>,
    /// Previous iteration's q polynomial: q_{i-1}.
    q_cur: Polynomial<P>,
    /// Degree-related term of saved p polynomial: D_{z_i-1}.
    deg_saved: usize,
    /// Degree-related term of previous p polynomial: D_{i-1}.
    deg_cur: usize,
}

impl<P: PolynomialCoefs> BerlMasseyDecoder<P> {
    /// Construct a new `BerlMasseyDecoder` from the given syndrome polynomial.
    pub fn new(syn: Polynomial<P>) -> BerlMasseyDecoder<P> {
        // 2t zeroes followed by a one.
        let p = Polynomial::new((0..P::syndromes()+1).map(|_| P25Codeword::default())
                                    .chain(std::iter::once(P25Codeword::for_power(0))));

        BerlMasseyDecoder {
            q_saved: syn,
            q_cur: syn.shift(),
            p_saved: p,
            p_cur: p.shift(),
            deg_saved: 0,
            deg_cur: 1,
        }
    }

    /// Perform the iterative steps to get the error-location polynomial Λ(x) wih deg(Λ)
    /// <= t.
    pub fn decode(mut self) -> Polynomial<P> {
        for _ in 0..P::syndromes() {
            self.step();
        }

        self.p_cur
    }

    /// Perform one iterative step of the algorithm, updating the state polynomials and
    /// degrees.
    fn step(&mut self) {
        let (save, q, p, d) = if self.q_cur.constant().zero() {
            self.reduce()
        } else {
            self.transform()
        };

        if save {
            self.q_saved = self.q_cur;
            self.p_saved = self.p_cur;
            self.deg_saved = self.deg_cur;
        }

        self.q_cur = q;
        self.p_cur = p;
        self.deg_cur = d;
    }

    /// Simply shift the polynomials since they have no degree-0 term.
    fn reduce(&mut self) -> (bool, Polynomial<P>, Polynomial<P>, usize) {
        (
            false,
            self.q_cur.shift(),
            self.p_cur.shift(),
            2 + self.deg_cur,
        )
    }

    /// Remove the degree-0 terms and shift the polynomials.
    fn transform(&mut self) -> (bool, Polynomial<P>, Polynomial<P>, usize) {
        let mult = self.q_cur.constant() / self.q_saved.constant();

        (
            self.deg_cur >= self.deg_saved,
            (self.q_cur + self.q_saved * mult).shift(),
            (self.p_cur + self.p_saved * mult).shift(),
            2 + std::cmp::min(self.deg_cur, self.deg_saved),
        )
   }
}

/// Uses Chien search to find the roots in GF(2^6) of an error-locator polynomial and
/// produce an iterator of error bit positions. The Forney algorithm is used to find the
/// associated error values.
pub struct Errors<P: PolynomialCoefs> {
    /// Error location polynomial.
    errs: Polynomial<P>,
    /// Derivative of above.
    deriv: Polynomial<P>,
    /// Error value polynomial.
    vals: Polynomial<P>,
    /// Current exponent power of the iteration.
    pow: std::ops::Range<usize>,
}

impl<P: PolynomialCoefs> Errors<P> {
    /// Construct a new `Errors` from the given error and syndrome polynomials.
    pub fn new(mut errs: Polynomial<P>, syn: Polynomial<P>) -> Errors<P> {
        let deriv = errs.deriv();
        let vals = (errs * syn).truncate(P::syndromes());

        for (pow, cur) in errs.iter_mut().enumerate() {
            // Since the first call to `update_terms()` multiplies by `pow` and the
            // coefficients should equal themselves on the first iteration, divide by
            // `pow` here.
            *cur = *cur / P25Codeword::for_power(pow)
        }

        Errors {
            errs: errs,
            deriv: deriv,
            vals: vals,
            pow: 0..P25Field::size(),
        }
    }

    /// Perform the term-updating step of the algorithm: x_{j,i} = x_{j,i-1} * α^j.
    fn update_terms(&mut self) {
        for (pow, term) in self.errs.iter_mut().enumerate() {
            *term = *term * P25Codeword::for_power(pow);
        }
    }

    /// Calculate the sum of the terms: x_{0,i} + x_{1,i} + ... + x_{t,i} -- evaluate the
    /// error-locator polynomial at Λ(α^i).
    fn sum_terms(&self) -> P25Codeword {
        self.errs.iter().fold(P25Codeword::default(), |s, &x| s + x)
    }

    /// Determine the error value for the given error location/root.
    fn value(&self, loc: P25Codeword, root: P25Codeword) -> P25Codeword {
        self.vals.eval(root) / self.deriv.eval(root) * loc
    }
}

impl<P: PolynomialCoefs> Iterator for Errors<P> {
    type Item = (usize, P25Codeword);

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            let pow = match self.pow.next() {
                Some(pow) => pow,
                None => return None,
            };

            self.update_terms();

            if self.sum_terms().zero() {
                let root = P25Codeword::for_power(pow);
                let loc = root.invert();

                return Some((loc.power().unwrap(), self.value(loc, root)));
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 Jeffery Olson
//
// Licensed under the 3-Clause BSD License, see LICENSE.txt
// at the top-level of this repository.
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::vec_ng::Vec;

use sdl2::{rect, pixels};

use p2d::sprite::SpriteTile;
use gfx::GameDisplay;

pub trait SpriteFontSheet {
    fn get_sheet(&self) -> ~str;
    fn sprite_for<'a>(&'a self, c: &char) -> Option<&'a SpriteTile>;

    fn draw_line(&self, display: &GameDisplay, coords: (int, int), text: ~str) {
        let (mut cx, cy) = coords;
        let sheet = display.sheets.get(&self.get_sheet());
        let text_slice = text.slice_from(0);
        for c in text_slice.chars() {
            let font_sprite = self.sprite_for(&c).expect(
                format!("Sprite not found for {:?}! Shouldn't happen...", c));
            let (fsx, _) = font_sprite.size;
            sheet.draw_tile(display.renderer, font_sprite, (cx, cy), font_sprite.size);
            cx += (fsx+2) as int;
        }
    }
}

pub trait SpriteUxBox {
    fn unit_size(&self) -> uint;
    fn get_sheet(&self) -> ~str;
    fn get_ul_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_ur_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_ll_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_lr_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_top<'a>(&'a self) -> &'a SpriteTile;
    fn get_bottom<'a>(&'a self) -> &'a SpriteTile;
    fn get_left<'a>(&'a self) -> &'a SpriteTile;
    fn get_right<'a>(&'a self) -> &'a SpriteTile;
    fn draw_box(&self, display: &GameDisplay, coords: (int, int),
                size_in_units: (uint, uint), bg_color: (u8, u8, u8)) {
        let (start_x, start_y) = coords;
        let unit_size = self.unit_size() as int;
        let (w, h) = size_in_units;
        let (w, h) = (w as int, h as int);
        let sheet = display.sheets.get(&self.get_sheet());
        let tile_size = (unit_size as uint, unit_size as uint);
        // draw background
        let (r, g, b) = bg_color;
        let bgc = pixels::RGB(r, g, b);
        display.set_draw_sdl2_color(bgc);
        let (rect_w, rect_h) = (w*unit_size, h*unit_size);
        let bg_rect = rect::Rect::new(
            start_x as i32, start_y as i32, rect_w as i32, rect_h as i32);
        display.renderer.fill_rect(&bg_rect);
        // draw corners
        let (ul_x, ul_y) = coords;
        sheet.draw_tile(display.renderer, self.get_ul_corner(),
                        (ul_x, ul_y), tile_size);
        let (ur_x, ur_y) = (start_x + (unit_size * (w-1)) as int,
                        start_y);
        sheet.draw_tile(display.renderer, self.get_ur_corner(),
                        (ur_x, ur_y), tile_size);
        let (ll_x, ll_y) = (start_x,
                        start_y + (unit_size * (h-1)) as int);
        sheet.draw_tile(display.renderer, self.get_ll_corner(),
                        (ll_x, ll_y), tile_size);
        let (lr_x, lr_y) = (start_x + (unit_size * (w-1) as int),
                        start_y + (unit_size * (h-1)) as int);
        sheet.draw_tile(display.renderer, self.get_lr_corner(),
                        (lr_x, lr_y), tile_size);
        //top/bottom
        let (top_y, bottom_y) = (ul_y, ll_y);
        let mut tb_x = ul_x + unit_size;
        while tb_x < ur_x {
            let top_coords = (tb_x, top_y);
            let bottom_coords = (tb_x, bottom_y);
            sheet.draw_tile(display.renderer, self.get_top(),
                            top_coords, tile_size);
            sheet.draw_tile(display.renderer, self.get_bottom(),
                            bottom_coords, tile_size);
            tb_x += unit_size;
        }
        // left/right
        let (left_x, right_x) = (ul_x, ur_x);
        let mut left_right_y = ul_y + unit_size;
        while left_right_y < ll_y {
            let left_coords = (left_x, left_right_y);
            let right_coords = (right_x, left_right_y);
            sheet.draw_tile(display.renderer, self.get_left(),
                            left_coords, tile_size);
            sheet.draw_tile(display.renderer, self.get_right(),
                            right_coords, tile_size);
            left_right_y += unit_size;
        }
    }
}

pub trait SpriteUxTextBox: SpriteFontSheet + SpriteUxBox {
    /*
    fn draw_dialog_box<TFont: SpriteFontSheet, TBox: SpriteUxBox>(&self,
            display: &GameDisplay, coords: (int, int), lines: &[~str],
            bg_color: (u8, u8, u8)) {
        self.draw_line(display, coords, ~"sdfsdfsdfsdf");
    }
    */
}

pub struct SpriteUxDialog {
    title: ~str,
    lines: Vec<~str>,
    selected_idx: uint,
    box_size: (uint, uint)
}

impl SpriteUxDialog {
    pub fn new(title: ~str) -> SpriteUxDialog {
        SpriteUxDialog {
            title: title,
            lines: Vec::new(),
            selected_idx: 0,
            box_size: (0, 0)
        }
    }
    pub fn recompute(&mut self) {
    }
}
<commit_msg>fine tuning in ux api primitives + rough cut of draw_text_box()<commit_after>// Copyright 2013-2014 Jeffery Olson
//
// Licensed under the 3-Clause BSD License, see LICENSE.txt
// at the top-level of this repository.
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::vec_ng::Vec;

use sdl2::{rect, pixels};

use p2d::sprite::SpriteTile;
use gfx::GameDisplay;

pub trait SpriteUxFont {
    fn get_sheet(&self) -> ~str;
    fn sprite_for<'a>(&'a self, c: &char) -> Option<&'a SpriteTile>;

    fn draw_line(&self, display: &GameDisplay, coords: (int, int), text: &str, gap: uint) {
        let (mut cx, cy) = coords;
        let sheet = display.sheets.get(&self.get_sheet());
        let text_slice = text.slice_from(0);
        for c in text_slice.chars() {
            let font_sprite = self.sprite_for(&c).expect(
                format!("Sprite not found for {:?}! Shouldn't happen...", c));
            let (fsx, _) = font_sprite.size;
            sheet.draw_tile(display.renderer, font_sprite, (cx, cy), font_sprite.size);
            cx += (fsx+gap) as int;
        }
    }
}

pub trait SpriteUxBox {
    fn unit_size(&self) -> uint;
    fn get_sheet(&self) -> ~str;
    fn get_ul_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_ur_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_ll_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_lr_corner<'a>(&'a self) -> &'a SpriteTile;
    fn get_top<'a>(&'a self) -> &'a SpriteTile;
    fn get_bottom<'a>(&'a self) -> &'a SpriteTile;
    fn get_left<'a>(&'a self) -> &'a SpriteTile;
    fn get_right<'a>(&'a self) -> &'a SpriteTile;
    fn draw_box(&self, display: &GameDisplay, coords: (int, int),
                size_in_units: (uint, uint), bg_color: (u8, u8, u8)) {
        let (start_x, start_y) = coords;
        let unit_size = self.unit_size() as int;
        let (w, h) = size_in_units;
        let (w, h) = (w as int, h as int);
        let sheet = display.sheets.get(&self.get_sheet());
        let tile_size = (unit_size as uint, unit_size as uint);
        // draw background
        let (r, g, b) = bg_color;
        let bgc = pixels::RGB(r, g, b);
        display.set_draw_sdl2_color(bgc);
        let (rect_w, rect_h) = (w*unit_size, h*unit_size);
        let bg_rect = rect::Rect::new(
            start_x as i32, start_y as i32, rect_w as i32, rect_h as i32);
        display.renderer.fill_rect(&bg_rect);
        // draw corners
        let (ul_x, ul_y) = coords;
        sheet.draw_tile(display.renderer, self.get_ul_corner(),
                        (ul_x, ul_y), tile_size);
        let (ur_x, ur_y) = (start_x + (unit_size * (w-1)) as int,
                        start_y);
        sheet.draw_tile(display.renderer, self.get_ur_corner(),
                        (ur_x, ur_y), tile_size);
        let (ll_x, ll_y) = (start_x,
                        start_y + (unit_size * (h-1)) as int);
        sheet.draw_tile(display.renderer, self.get_ll_corner(),
                        (ll_x, ll_y), tile_size);
        let (lr_x, lr_y) = (start_x + (unit_size * (w-1) as int),
                        start_y + (unit_size * (h-1)) as int);
        sheet.draw_tile(display.renderer, self.get_lr_corner(),
                        (lr_x, lr_y), tile_size);
        //top/bottom
        let (top_y, bottom_y) = (ul_y, ll_y);
        let mut tb_x = ul_x + unit_size;
        while tb_x < ur_x {
            let top_coords = (tb_x, top_y);
            let bottom_coords = (tb_x, bottom_y);
            sheet.draw_tile(display.renderer, self.get_top(),
                            top_coords, tile_size);
            sheet.draw_tile(display.renderer, self.get_bottom(),
                            bottom_coords, tile_size);
            tb_x += unit_size;
        }
        // left/right
        let (left_x, right_x) = (ul_x, ur_x);
        let mut left_right_y = ul_y + unit_size;
        while left_right_y < ll_y {
            let left_coords = (left_x, left_right_y);
            let right_coords = (right_x, left_right_y);
            sheet.draw_tile(display.renderer, self.get_left(),
                            left_coords, tile_size);
            sheet.draw_tile(display.renderer, self.get_right(),
                            right_coords, tile_size);
            left_right_y += unit_size;
        }
    }
}

pub struct SpriteUxTextBox<'a, TFont, TBox> {
    ux_font: &'a TFont,
    ux_box: &'a TBox
}

pub fn draw_text_box<TFont: SpriteUxFont, TBox: SpriteUxBox>(
        display: &GameDisplay, coords: (int, int), size_in_units: (uint, uint),
        bg_color: (u8, u8, u8), lines: &[~str], ux_font: &TFont, ux_box: &TBox,
        gap: uint) {
    // draw backing box
    ux_box.draw_box(display, coords, size_in_units, bg_color);
    // info to draw boxed text (note we aren't doing any bounds checking..)
    let box_unit_size = ux_box.unit_size();
    let (start_x, start_y) = coords;
    let start_x = start_x + box_unit_size as int;
    let mut curr_y = start_y + box_unit_size as int;
    for curr_line in lines.iter() {
        let l_coords = (start_x as int, curr_y as int);
        ux_font.draw_line(display, l_coords, *curr_line, gap);
        curr_y += box_unit_size as int + (box_unit_size >> 2) as int;
    }
}

pub struct SpriteUxMenuBox<'a, TFont, TBox> {
    ux_tb: &'a SpriteUxTextBox<'a, TFont, TBox>,
    title: Option<~str>,
    lines: Vec<~str>,
    bounds: (int, int, uint, uint),
    bg_color: (u8, u8, u8)
}

impl<'a, TFont: SpriteUxFont, TBox: SpriteUxBox> SpriteUxMenuBox<'a, TFont, TBox> {
    pub fn new(tb: &'a SpriteUxTextBox<'a, TFont, TBox>) -> SpriteUxMenuBox<'a, TFont, TBox> {
        SpriteUxMenuBox {
            ux_tb: tb,
            title: None,
            lines: Vec::new(),
            bounds: (0,0,0,0),
            bg_color: (0,0,0)
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>[storescu] safeguard max pdu length check<commit_after><|endoftext|>


<commit_before>#![feature(globs)]
#![crate_type = "bin"]
extern crate rust_js;
extern crate test;
extern crate collections;
use rust_js::lexer::Lexer;
use rust_js::parser::{Parser, VerboseResult};
use rust_js::exec::{Executor, Interpreter};
use rust_js::js::value::{Value, ValueData, VNull, VNumber, VString, VBoolean, from_value};

fn run(script:&str) -> Value {
	let mut lexer = Lexer::new();
	lexer.lex_str(script.to_owned()).v_unwrap();
	let mut parser = Parser::new(lexer.tokens);
	let result = parser.parse_all().v_unwrap();
	let mut engine : ~Interpreter = Executor::new();
	let result : Result<Value, Value> = engine.run(result);
	return result.unwrap();
}
fn assert_eq(a:ValueData, b:Value) -> () {
	if a != *b.borrow() {
		fail!("Expected {}, got {}", a, b.borrow());
	}
}
#[test]
fn test_value_conversion() {
	let val:Vec<i32> = from_value(run("[0, 2, 34, 12]")).unwrap();
	if *val.get(0) != 0 || *val.get(1) != 2 || *val.get(2) != 34 || *val.get(3) != 12 {
		fail!("Bad value {}", val);
	}
}
#[test]
fn test_array_comma() {
	assert_eq(VNull, run("[ , 'home', , 'school'][0]"));
}
#[test]
fn test_escape() {
	assert_eq(VString(~"Newline:'"), run("'Newline:\\\''"));
}
#[test]
fn test_to_string() {
	assert_eq(VString(~"117"), run("117+''"));
	assert_eq(VString(~"0.12"), run("0.12+''"));
	assert_eq(VString(~"null"), run("null+''"));
	assert_eq(VString(~"undefined"), run("unexisty+''"));
}
#[test]
fn test_num_op() {
	assert_eq(VNumber(10.0), run("((4 + 2) / 3) * 5"));
}
#[test]
fn test_hello_world() {
	assert_eq(VString(~"Hello, world!"), run("'Hello, world!'"));
}
#[test]
fn test_function() {
	assert_eq(VString(~"Function!"), run("(function(a){return a + '!'})('Function')"))
}
#[test]
fn test_constructor() {
	assert_eq(VString(~"Hello"), run("function Text(phrase) { this.phrase = phrase; }; text = new Text('Hello'); text.phrase"));
}
#[test]
fn test_json() {
	assert_eq(VNumber(42.0), run("JSON.parse(JSON.stringify({num: 42})).num"))
}
#[test]
fn test_typeof() {
	assert_eq(VString(~"number"), run("typeof Math.PI"));
	assert_eq(VString(~"boolean"), run("typeof true"));
	assert_eq(VString(~"undefined"), run("typeof undefined"));
	assert_eq(VString(~"string"), run("typeof ''"));
	assert_eq(VString(~"function"), run("typeof Object.prototype.hasOwnProperty"));
}
#[test]
fn test_define_prop() {
	assert_eq(VBoolean(true), run("{
		var obj = {};
		Object.defineProperty(obj, \"some_bool\", {
			value: true
		});
		obj.some_bool
	}"));
}<commit_msg>Add benchmarking code<commit_after>#![feature(globs)]
#![crate_type = "bin"]
extern crate rust_js;
extern crate test;
extern crate collections;
use test::Bencher;
use rust_js::lexer::Lexer;
use rust_js::parser::{Parser, VerboseResult};
use rust_js::exec::{Executor, Interpreter};
use rust_js::js::value::{Value, ValueData, VNull, VNumber, VString, VBoolean, VFunction, VUndefined, from_value, to_value};
use std::gc::Gc;
fn run(script:&str) -> Value {
	let mut lexer = Lexer::new();
	lexer.lex_str(script.to_owned()).v_unwrap();
	let mut parser = Parser::new(lexer.tokens);
	let result = parser.parse_all().v_unwrap();
	let mut engine : ~Interpreter = Executor::new();
	let result : Result<Value, Value> = engine.run(result);
	return result.unwrap();
}
fn assert_eq(a:ValueData, b:Value) -> () {
	if a != *b.borrow() {
		fail!("Expected {}, got {}", a, b.borrow());
	}
}
#[test]
fn test_value_conversion() {
	let val:Vec<i32> = from_value(run("[0, 2, 34, 12]")).unwrap();
	if *val.get(0) != 0 || *val.get(1) != 2 || *val.get(2) != 34 || *val.get(3) != 12 {
		fail!("Bad value {}", val);
	}
}
#[test]
fn test_array_comma() {
	assert_eq(VNull, run("[ , 'home', , 'school'][0]"));
}
#[test]
fn test_escape() {
	assert_eq(VString(~"Newline:'"), run("'Newline:\\\''"));
}
#[test]
fn test_to_string() {
	assert_eq(VString(~"117"), run("117+''"));
	assert_eq(VString(~"0.12"), run("0.12+''"));
	assert_eq(VString(~"null"), run("null+''"));
	assert_eq(VString(~"undefined"), run("unexisty+''"));
}
#[test]
fn test_num_op() {
	assert_eq(VNumber(10.0), run("((4 + 2) / 3) * 5"));
}
#[test]
fn test_hello_world() {
	assert_eq(VString(~"Hello, world!"), run("'Hello, world!'"));
}
#[test]
fn test_function() {
	assert_eq(VString(~"Function!"), run("(function(a){return a + '!'})('Function')"))
}
#[test]
fn test_constructor() {
	assert_eq(VString(~"Hello"), run("function Text(phrase) { this.phrase = phrase; }; text = new Text('Hello'); text.phrase"));
}
#[test]
fn test_json() {
	assert_eq(VNumber(42.0), run("JSON.parse(JSON.stringify({num: 42})).num"))
}
#[test]
fn test_typeof() {
	assert_eq(VString(~"number"), run("typeof Math.PI"));
	assert_eq(VString(~"boolean"), run("typeof true"));
	assert_eq(VString(~"undefined"), run("typeof undefined"));
	assert_eq(VString(~"string"), run("typeof ''"));
	assert_eq(VString(~"function"), run("typeof Object.prototype.hasOwnProperty"));
}
#[test]
fn test_define_prop() {
	assert_eq(VBoolean(true), run("{
		var obj = {};
		Object.defineProperty(obj, \"some_bool\", {
			value: true
		});
		obj.some_bool
	}"));
}
#[bench]
fn bench_fib(b: &mut Bencher) {
	let code = "function fib(n) {
		return n <= 1 ? 1 : fib(n - 2) + fib(n - 1);
	}";
	let mut lexer = Lexer::new();
	lexer.lex_str(code.to_owned()).v_unwrap();
	let mut parser = Parser::new(lexer.tokens);
	let result = parser.parse_all().v_unwrap();
	let engine : &mut Interpreter = Executor::new();
	let result : Result<Value, Value> = engine.run(result);
	let fib = result.unwrap();
	b.iter(|| {
		match *fib.borrow() {
			VFunction(ref func) => {
				func.borrow().call(&mut engine.clone(), ValueData::new_obj(None), Gc::new(VUndefined), vec!(to_value(40i32)));
			},
			_ => ()
		}
	});
}<|endoftext|>


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

macro_rules! define_matrix {
    (
        $(#[$attr:meta])*
        pub struct $name:ident<T, $($phantom:ident),+> {
            $(pub $field:ident: T,)+
        }
    ) => (
        #[repr(C)]
        $(#[$attr])*
        pub struct $name<T, $($phantom),+> {
            $(pub $field: T,)+
            _unit: PhantomData<($($phantom),+)>
        }

        impl<T: Clone, $($phantom),+> Clone for $name<T, $($phantom),+> {
            fn clone(&self) -> Self {
                $name {
                    $($field: self.$field.clone(),)+
                    _unit: PhantomData,
                }
            }
        }

        impl<T: Copy, $($phantom),+> Copy for $name<T, $($phantom),+> {}

        #[cfg(feature = "serde")]
        impl<'de, T, $($phantom),+> ::serde::Deserialize<'de> for $name<T, $($phantom),+>
            where T: ::serde::Deserialize<'de>
        {
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where D: ::serde::Deserializer<'de>
            {
                let ($($field,)+) =
                    try!(::serde::Deserialize::deserialize(deserializer));
                Ok($name {
                    $($field: $field,)+
                    _unit: PhantomData,
                })
            }
        }

        #[cfg(feature = "serde")]
        impl<T, $($phantom),+> ::serde::Serialize for $name<T, $($phantom),+>
            where T: ::serde::Serialize
        {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
                where S: ::serde::Serializer
            {
                ($(&self.$field,)+).serialize(serializer)
            }
        }

        impl<T, $($phantom),+> ::core::cmp::Eq for $name<T, $($phantom),+>
            where T: ::core::cmp::Eq {}

        impl<T, $($phantom),+> ::core::cmp::PartialEq for $name<T, $($phantom),+>
            where T: ::core::cmp::PartialEq
        {
            fn eq(&self, other: &Self) -> bool {
                true $(&& self.$field == other.$field)+
            }
        }

        impl<T, $($phantom),+> ::core::hash::Hash for $name<T, $($phantom),+>
            where T: ::core::hash::Hash
        {
            fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
                $(self.$field.hash(h);)+
            }
        }
    )
}
<commit_msg>Make the unit a hidden public member instead of private.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

macro_rules! define_matrix {
    (
        $(#[$attr:meta])*
        pub struct $name:ident<T, $($phantom:ident),+> {
            $(pub $field:ident: T,)+
        }
    ) => (
        #[repr(C)]
        $(#[$attr])*
        pub struct $name<T, $($phantom),+> {
            $(pub $field: T,)+

            // Keep this (secretly) public for the few cases where we would like to
            // create static constants which currently can't be initialized with a
            // function.
            #[doc(hidden)]
            pub _unit: PhantomData<($($phantom),+)>
        }

        impl<T: Clone, $($phantom),+> Clone for $name<T, $($phantom),+> {
            fn clone(&self) -> Self {
                $name {
                    $($field: self.$field.clone(),)+
                    _unit: PhantomData,
                }
            }
        }

        impl<T: Copy, $($phantom),+> Copy for $name<T, $($phantom),+> {}

        #[cfg(feature = "serde")]
        impl<'de, T, $($phantom),+> ::serde::Deserialize<'de> for $name<T, $($phantom),+>
            where T: ::serde::Deserialize<'de>
        {
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where D: ::serde::Deserializer<'de>
            {
                let ($($field,)+) =
                    try!(::serde::Deserialize::deserialize(deserializer));
                Ok($name {
                    $($field: $field,)+
                    _unit: PhantomData,
                })
            }
        }

        #[cfg(feature = "serde")]
        impl<T, $($phantom),+> ::serde::Serialize for $name<T, $($phantom),+>
            where T: ::serde::Serialize
        {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
                where S: ::serde::Serializer
            {
                ($(&self.$field,)+).serialize(serializer)
            }
        }

        impl<T, $($phantom),+> ::core::cmp::Eq for $name<T, $($phantom),+>
            where T: ::core::cmp::Eq {}

        impl<T, $($phantom),+> ::core::cmp::PartialEq for $name<T, $($phantom),+>
            where T: ::core::cmp::PartialEq
        {
            fn eq(&self, other: &Self) -> bool {
                true $(&& self.$field == other.$field)+
            }
        }

        impl<T, $($phantom),+> ::core::hash::Hash for $name<T, $($phantom),+>
            where T: ::core::hash::Hash
        {
            fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
                $(self.$field.hash(h);)+
            }
        }
    )
}
<|endoftext|>


<commit_before>use request::ToParams;

#[derive(Debug)]
pub struct Usage {
    metrics: Vec<(String, String)>,
    usage_params: Vec<(String, String)>,
}

impl Usage {
    /// Creates a `Usage`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::usage::*;
    ///
    /// let mut metrics = Vec::new();
    /// metrics.push(("metric1", 10));
    /// metrics.push(("metric2", 20));
    /// let usage = Usage::new(&metrics);
    /// ```
    pub fn new<T1: ToString, T2: ToString>(metrics: &Vec<(T1, T2)>) -> Self {
        let string_metrics = metrics
            .iter()
            .map(|&(ref metric, ref value)| (metric.to_string(), value.to_string()))
            .collect();

        Self {
            metrics: string_metrics,
            usage_params: Usage::usage_params_from(metrics),
        }
    }

    fn usage_params_from<T1: ToString, T2: ToString>(metrics: &Vec<(T1, T2)>)
                                                     -> Vec<(String, String)> {
        metrics
            .iter()
            .map(|&(ref metric, ref value)| {
                     (Usage::param_name(&metric.to_string()), value.to_string())
                 })
            .collect()
    }

    fn param_name(param: &str) -> String {
        "usage[".to_owned() + param + "]"
    }
}

impl ToParams for Usage {
    fn to_params(&self) -> Vec<(&str, &str)> {
        self.usage_params
            .iter()
            .map(|&(ref metric, ref value)| (metric.as_str(), value.as_str()))
            .collect()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn can_be_transformed_into_params() {
        let metric1_name = "metric1";
        let metric1_val = "10";
        let metric2_name = "metric2";
        let metric2_val = "20";
        let mut metrics = Vec::new();
        metrics.push((metric1_name, metric1_val));
        metrics.push((metric2_name, metric2_val));
        let usage = Usage::new(&metrics);

        let result = usage.to_params();

        let expected = vec![("usage[metric1]", metric1_val),
                            ("usage[metric2]", metric2_val)];
        assert_eq!(expected, result);
    }
}
<commit_msg>usage: fix ToParams import<commit_after>use crate::request::ToParams;

#[derive(Debug)]
pub struct Usage {
    metrics: Vec<(String, String)>,
    usage_params: Vec<(String, String)>,
}

impl Usage {
    /// Creates a `Usage`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::usage::*;
    ///
    /// let mut metrics = Vec::new();
    /// metrics.push(("metric1", 10));
    /// metrics.push(("metric2", 20));
    /// let usage = Usage::new(&metrics);
    /// ```
    pub fn new<T1: ToString, T2: ToString>(metrics: &Vec<(T1, T2)>) -> Self {
        let string_metrics = metrics
            .iter()
            .map(|&(ref metric, ref value)| (metric.to_string(), value.to_string()))
            .collect();

        Self {
            metrics: string_metrics,
            usage_params: Usage::usage_params_from(metrics),
        }
    }

    fn usage_params_from<T1: ToString, T2: ToString>(metrics: &Vec<(T1, T2)>)
                                                     -> Vec<(String, String)> {
        metrics
            .iter()
            .map(|&(ref metric, ref value)| {
                     (Usage::param_name(&metric.to_string()), value.to_string())
                 })
            .collect()
    }

    fn param_name(param: &str) -> String {
        "usage[".to_owned() + param + "]"
    }
}

impl ToParams for Usage {
    fn to_params(&self) -> Vec<(&str, &str)> {
        self.usage_params
            .iter()
            .map(|&(ref metric, ref value)| (metric.as_str(), value.as_str()))
            .collect()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn can_be_transformed_into_params() {
        let metric1_name = "metric1";
        let metric1_val = "10";
        let metric2_name = "metric2";
        let metric2_val = "20";
        let mut metrics = Vec::new();
        metrics.push((metric1_name, metric1_val));
        metrics.push((metric2_name, metric2_val));
        let usage = Usage::new(&metrics);

        let result = usage.to_params();

        let expected = vec![("usage[metric1]", metric1_val),
                            ("usage[metric2]", metric2_val)];
        assert_eq!(expected, result);
    }
}
<|endoftext|>


<commit_before>use libc;
use std::ffi::CStr;
use std::sync::atomic::{AtomicPtr, Ordering};

use utils::*;
use types::*;
use qobject::*;

extern "C" {
    fn dos_qvariant_create() -> DosQVariant;
    fn dos_qvariant_create_int(value: i32) -> DosQVariant;
    fn dos_qvariant_create_bool(value: bool) -> DosQVariant;
    fn dos_qvariant_create_string(value: DosCStr) -> DosQVariant;
    fn dos_qvariant_create_qobject(value: DosQObject) -> DosQVariant;
    fn dos_qvariant_create_qvariant(value: DosQVariant) -> DosQVariant;
    fn dos_qvariant_create_float(value: f32) -> DosQVariant;
    fn dos_qvariant_create_double(value: f64) -> DosQVariant;
    fn dos_qvariant_create_array(size: i32, array: *const DosQVariant) -> DosQVariant;

    fn dos_qvariant_toInt(val: DosQVariant) -> i32;
    fn dos_qvariant_toBool(val: DosQVariant) -> bool;
    fn dos_qvariant_toString(val: DosQVariant) -> *mut libc::c_char;
    fn dos_qvariant_toFloat(val: DosQVariant) -> f32;
    fn dos_qvariant_toDouble(val: DosQVariant) -> f64;
    // DOS_API DosQObject *DOS_CALL dos_qvariant_toQObject(const DosQVariant *vptr);

    fn dos_qvariant_isnull(val: DosQVariant) -> bool;
    fn dos_qvariant_assign(val: MutDosQVariant, other: DosQVariant);
    fn dos_qvariant_delete(val: DosQVariant);
    fn dos_chararray_delete(ptr: DosCStr);
// DOS_API void   DOS_CALL dos_qvariant_setInt    (DosQVariant *vptr, int value);
// DOS_API void   DOS_CALL dos_qvariant_setBool   (DosQVariant *vptr, bool value);
// DOS_API void   DOS_CALL dos_qvariant_setFloat  (DosQVariant *vptr, float value);
// DOS_API void   DOS_CALL dos_qvariant_setDouble (DosQVariant *vptr, double value);
// DOS_API void   DOS_CALL dos_qvariant_setString (DosQVariant *vptr, const char *value);
// DOS_API void   DOS_CALL dos_qvariant_setQObject(DosQVariant *vptr, DosQObject *value);

}

/// This holds a value to be providen for a QML context.
///
/// A value can be different: int, string, float, double, bool or even a custom object.
#[derive(Debug)]
pub struct QVariant {
    ptr: AtomicPtr<WQVariant>,
    owned: bool,
}

impl PartialEq for QVariant {
    fn eq(&self, other: &QVariant) -> bool {
        self.ptr.load(Ordering::Relaxed) == other.ptr.load(Ordering::Relaxed)
    }
}

impl Clone for QVariant {
    fn clone(&self) -> Self {
        unsafe {
            new_qvar(dos_qvariant_create_qvariant(self.ptr.load(Ordering::Relaxed)),
                     true)
        }
    }
}

impl QVariant {
    pub fn to_int(&self) -> i32 {
        unsafe { dos_qvariant_toInt(self.ptr.load(Ordering::Relaxed)) }
    }

    pub fn into_bool(self) -> bool {
        unsafe { dos_qvariant_toBool(self.ptr.load(Ordering::Relaxed)) }
    }

    pub fn into_float(self) -> f32 {
        unsafe { dos_qvariant_toFloat(self.ptr.load(Ordering::Relaxed)) }
    }

    pub fn into_double(self) -> f64 {
        unsafe { dos_qvariant_toDouble(self.ptr.load(Ordering::Relaxed)) }
    }

    /// Sets the value for this `QVariant`
    pub fn set(&mut self, other: &QVariant) {
        unsafe {
            dos_qvariant_assign(self.ptr.load(Ordering::Relaxed),
                                other.ptr.load(Ordering::Relaxed));
        }
    }
}

pub fn throw(qvar: &mut QVariant, flag: bool) {
    qvar.owned = flag;
}
fn new_qvar(ptr: DosQVariant, owned: bool) -> QVariant {
    QVariant {
        ptr: AtomicPtr::new(ptr as MutDosQVariant),
        owned: owned,
    }
}

pub fn new_qvariant(ptr: DosQVariant) -> QVariant {
    new_qvar(ptr, false)
}

pub fn get_private_variant(from: &QVariant) -> DosQVariant {
    from.ptr.load(Ordering::Relaxed)
}

impl Drop for QVariant {
    fn drop(&mut self) {
        if self.owned {
            unsafe { dos_qvariant_delete(self.ptr.load(Ordering::Relaxed)) }
        }
    }
}

#[doc(hidden)]
impl From<DosQObject> for QVariant {
    fn from(i: DosQObject) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(i), true) }
    }
}

#[doc(hidden)]
impl From<DosQAbstractListModel> for QVariant {
    fn from(i: DosQAbstractListModel) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(i as DosQObject), true) }
    }
}

#[doc(hidden)]
impl From<DosQVariant> for QVariant {
    fn from(vptr: DosQVariant) -> Self {
        new_qvar(vptr, false)
    }
}

#[doc(hidden)]
impl From<MutDosQVariant> for QVariant {
    fn from(vptr: MutDosQVariant) -> Self {
        new_qvar(vptr, false)
    }
}

#[doc(hidden)]
impl From<QObject> for QVariant {
    fn from(i: QObject) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(get_qobj_ptr(&i)), true) }
    }
}

impl<'a> From<&'a [QVariant]> for QVariant {
    fn from(i: &'a [QVariant]) -> Self {
        unsafe {
            let vec = i.iter()
                .map(|qvar| qvar.ptr.load(Ordering::Relaxed) as DosQVariant)
                .collect::<Vec<DosQVariant>>();
            let ptr = vec.as_ptr();
            forget(vec);
            new_qvar(dos_qvariant_create_array(i.len() as i32, ptr), true)
        }
    }
}

use std::mem::forget;

impl From<Vec<QVariant>> for QVariant {
    fn from(i: Vec<QVariant>) -> Self {
        unsafe {
            let len = i.len();
            let vec = i.iter()
                .map(|qvar| qvar.ptr.load(Ordering::Relaxed) as DosQVariant)
                .collect::<Vec<DosQVariant>>();
            let ptr = vec.as_ptr();
            forget(vec);
            new_qvar(dos_qvariant_create_array(len as i32, ptr), true)
        }
    }
}

#[doc(hidden)]
impl<'a> From<&'a QObject> for QVariant {
    fn from(i: &'a QObject) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(get_qobj_ptr(i)), true) }
    }
}

impl From<i32> for QVariant {
    fn from(i: i32) -> Self {
        unsafe { new_qvar(dos_qvariant_create_int(i), true) }
    }
}

impl From<f32> for QVariant {
    fn from(i: f32) -> Self {
        unsafe { new_qvar(dos_qvariant_create_float(i), true) }
    }
}

impl From<f64> for QVariant {
    fn from(i: f64) -> Self {
        unsafe { new_qvar(dos_qvariant_create_double(i), true) }
    }
}

impl From<bool> for QVariant {
    fn from(i: bool) -> Self {
        unsafe { new_qvar(dos_qvariant_create_bool(i), true) }
    }
}

impl<'a> From<&'a str> for QVariant {
    fn from(i: &'a str) -> Self {
        unsafe {
            let ptr = stoptr(i);
            let qvar = new_qvar(dos_qvariant_create_string(ptr), true);
            // Dropping CString
            ptrtos(ptr);
            qvar
        }
    }
}

impl From<String> for QVariant {
    fn from(i: String) -> Self {
        QVariant::from(i.as_str())
    }
}

// reverse Froms
impl From<QVariant> for i32 {
    fn from(i: QVariant) -> Self {
        unsafe { dos_qvariant_toInt(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl From<QVariant> for f32 {
    fn from(i: QVariant) -> Self {
        unsafe { dos_qvariant_toFloat(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl From<QVariant> for f64 {
    fn from(i: QVariant) -> Self {
        unsafe { dos_qvariant_toDouble(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl From<QVariant> for bool {
    fn from(i: QVariant) -> Self {
        i.into_bool()
    }
}

impl<'a> From<&'a QVariant> for i32 {
    fn from(i: &'a QVariant) -> Self {
        i.to_int()
    }
}

impl From<QVariant> for String {
    fn from(i: QVariant) -> Self {
        unsafe {
            let ch_ar = dos_qvariant_toString(load_self(&i));
            let res = CStr::from_ptr(ch_ar)
                .to_string_lossy()
                .into_owned();
            dos_chararray_delete(ch_ar);
            res
        }
    }
}

impl<'a> From<&'a QVariant> for String {
    fn from(i: &'a QVariant) -> Self {
        unsafe {
            let ch_ar = dos_qvariant_toString(load_self(i));
            let res = CStr::from_ptr(ch_ar)
                .to_string_lossy()
                .into_owned();
            dos_chararray_delete(ch_ar);
            res
        }
    }
}

fn load_self(s: &QVariant) -> DosQVariant {
    s.ptr.load(Ordering::Relaxed)
}
<commit_msg>Added couple of froms<commit_after>use libc;
use std::ffi::CStr;
use std::sync::atomic::{AtomicPtr, Ordering};

use utils::*;
use types::*;
use qobject::*;

extern "C" {
    fn dos_qvariant_create() -> DosQVariant;
    fn dos_qvariant_create_int(value: i32) -> DosQVariant;
    fn dos_qvariant_create_bool(value: bool) -> DosQVariant;
    fn dos_qvariant_create_string(value: DosCStr) -> DosQVariant;
    fn dos_qvariant_create_qobject(value: DosQObject) -> DosQVariant;
    fn dos_qvariant_create_qvariant(value: DosQVariant) -> DosQVariant;
    fn dos_qvariant_create_float(value: f32) -> DosQVariant;
    fn dos_qvariant_create_double(value: f64) -> DosQVariant;
    fn dos_qvariant_create_array(size: i32, array: *const DosQVariant) -> DosQVariant;

    fn dos_qvariant_toInt(val: DosQVariant) -> i32;
    fn dos_qvariant_toBool(val: DosQVariant) -> bool;
    fn dos_qvariant_toString(val: DosQVariant) -> *mut libc::c_char;
    fn dos_qvariant_toFloat(val: DosQVariant) -> f32;
    fn dos_qvariant_toDouble(val: DosQVariant) -> f64;
    // DOS_API DosQObject *DOS_CALL dos_qvariant_toQObject(const DosQVariant *vptr);

    fn dos_qvariant_isnull(val: DosQVariant) -> bool;
    fn dos_qvariant_assign(val: MutDosQVariant, other: DosQVariant);
    fn dos_qvariant_delete(val: DosQVariant);
    fn dos_chararray_delete(ptr: DosCStr);
// DOS_API void   DOS_CALL dos_qvariant_setInt    (DosQVariant *vptr, int value);
// DOS_API void   DOS_CALL dos_qvariant_setBool   (DosQVariant *vptr, bool value);
// DOS_API void   DOS_CALL dos_qvariant_setFloat  (DosQVariant *vptr, float value);
// DOS_API void   DOS_CALL dos_qvariant_setDouble (DosQVariant *vptr, double value);
// DOS_API void   DOS_CALL dos_qvariant_setString (DosQVariant *vptr, const char *value);
// DOS_API void   DOS_CALL dos_qvariant_setQObject(DosQVariant *vptr, DosQObject *value);

}

/// This holds a value to be providen for a QML context.
///
/// A value can be different: int, string, float, double, bool or even a custom object.
#[derive(Debug)]
pub struct QVariant {
    ptr: AtomicPtr<WQVariant>,
    owned: bool,
}

impl PartialEq for QVariant {
    fn eq(&self, other: &QVariant) -> bool {
        self.ptr.load(Ordering::Relaxed) == other.ptr.load(Ordering::Relaxed)
    }
}

impl Clone for QVariant {
    fn clone(&self) -> Self {
        unsafe {
            new_qvar(dos_qvariant_create_qvariant(self.ptr.load(Ordering::Relaxed)),
                     true)
        }
    }
}

impl QVariant {
    pub fn to_int(&self) -> i32 {
        unsafe { dos_qvariant_toInt(self.ptr.load(Ordering::Relaxed)) }
    }

    pub fn into_bool(self) -> bool {
        unsafe { dos_qvariant_toBool(self.ptr.load(Ordering::Relaxed)) }
    }

    pub fn into_float(self) -> f32 {
        unsafe { dos_qvariant_toFloat(self.ptr.load(Ordering::Relaxed)) }
    }

    pub fn into_double(self) -> f64 {
        unsafe { dos_qvariant_toDouble(self.ptr.load(Ordering::Relaxed)) }
    }

    /// Sets the value for this `QVariant`
    pub fn set(&mut self, other: &QVariant) {
        unsafe {
            dos_qvariant_assign(self.ptr.load(Ordering::Relaxed),
                                other.ptr.load(Ordering::Relaxed));
        }
    }
}

pub fn throw(qvar: &mut QVariant, flag: bool) {
    qvar.owned = flag;
}
fn new_qvar(ptr: DosQVariant, owned: bool) -> QVariant {
    QVariant {
        ptr: AtomicPtr::new(ptr as MutDosQVariant),
        owned: owned,
    }
}

pub fn new_qvariant(ptr: DosQVariant) -> QVariant {
    new_qvar(ptr, false)
}

pub fn get_private_variant(from: &QVariant) -> DosQVariant {
    from.ptr.load(Ordering::Relaxed)
}

impl Drop for QVariant {
    fn drop(&mut self) {
        if self.owned {
            unsafe { dos_qvariant_delete(self.ptr.load(Ordering::Relaxed)) }
        }
    }
}

#[doc(hidden)]
impl From<DosQObject> for QVariant {
    fn from(i: DosQObject) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(i), true) }
    }
}

#[doc(hidden)]
impl From<DosQAbstractListModel> for QVariant {
    fn from(i: DosQAbstractListModel) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(i as DosQObject), true) }
    }
}

#[doc(hidden)]
impl From<DosQVariant> for QVariant {
    fn from(vptr: DosQVariant) -> Self {
        new_qvar(vptr, false)
    }
}

#[doc(hidden)]
impl From<MutDosQVariant> for QVariant {
    fn from(vptr: MutDosQVariant) -> Self {
        new_qvar(vptr, false)
    }
}

#[doc(hidden)]
impl From<QObject> for QVariant {
    fn from(i: QObject) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(get_qobj_ptr(&i)), true) }
    }
}

impl<'a> From<&'a [QVariant]> for QVariant {
    fn from(i: &'a [QVariant]) -> Self {
        unsafe {
            let vec = i.iter()
                .map(|qvar| qvar.ptr.load(Ordering::Relaxed) as DosQVariant)
                .collect::<Vec<DosQVariant>>();
            let ptr = vec.as_ptr();
            forget(vec);
            new_qvar(dos_qvariant_create_array(i.len() as i32, ptr), true)
        }
    }
}

use std::mem::forget;

impl From<Vec<QVariant>> for QVariant {
    fn from(i: Vec<QVariant>) -> Self {
        unsafe {
            let len = i.len();
            let vec = i.iter()
                .map(|qvar| qvar.ptr.load(Ordering::Relaxed) as DosQVariant)
                .collect::<Vec<DosQVariant>>();
            let ptr = vec.as_ptr();
            forget(vec);
            new_qvar(dos_qvariant_create_array(len as i32, ptr), true)
        }
    }
}

#[doc(hidden)]
impl<'a> From<&'a QObject> for QVariant {
    fn from(i: &'a QObject) -> Self {
        unsafe { new_qvar(dos_qvariant_create_qobject(get_qobj_ptr(i)), true) }
    }
}

impl From<i32> for QVariant {
    fn from(i: i32) -> Self {
        unsafe { new_qvar(dos_qvariant_create_int(i), true) }
    }
}

impl From<f32> for QVariant {
    fn from(i: f32) -> Self {
        unsafe { new_qvar(dos_qvariant_create_float(i), true) }
    }
}

impl From<f64> for QVariant {
    fn from(i: f64) -> Self {
        unsafe { new_qvar(dos_qvariant_create_double(i), true) }
    }
}

impl From<bool> for QVariant {
    fn from(i: bool) -> Self {
        unsafe { new_qvar(dos_qvariant_create_bool(i), true) }
    }
}

impl<'a> From<&'a str> for QVariant {
    fn from(i: &'a str) -> Self {
        unsafe {
            let ptr = stoptr(i);
            let qvar = new_qvar(dos_qvariant_create_string(ptr), true);
            // Dropping CString
            ptrtos(ptr);
            qvar
        }
    }
}

impl From<String> for QVariant {
    fn from(i: String) -> Self {
        QVariant::from(i.as_str())
    }
}

// reverse Froms
impl From<QVariant> for i32 {
    fn from(i: QVariant) -> Self {
        unsafe { dos_qvariant_toInt(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl From<QVariant> for f32 {
    fn from(i: QVariant) -> Self {
        unsafe { dos_qvariant_toFloat(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl From<QVariant> for f64 {
    fn from(i: QVariant) -> Self {
        unsafe { dos_qvariant_toDouble(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl From<QVariant> for bool {
    fn from(i: QVariant) -> Self {
        i.into_bool()
    }
}

impl<'a> From<&'a QVariant> for i32 {
    fn from(i: &'a QVariant) -> Self {
        i.to_int()
    }
}

impl<'a> From<&'a QVariant> for bool {
    fn from(i: &'a QVariant) -> Self {
        unsafe { dos_qvariant_toBool(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl<'a> From<&'a QVariant> for f32 {
    fn from(i: &'a QVariant) -> Self {
        unsafe { dos_qvariant_toFloat(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl<'a> From<&'a QVariant> for f64 {
    fn from(i: &'a QVariant) -> Self {
        unsafe { dos_qvariant_toDouble(i.ptr.load(Ordering::Relaxed)) }
    }
}

impl From<QVariant> for String {
    fn from(i: QVariant) -> Self {
        unsafe {
            let ch_ar = dos_qvariant_toString(load_self(&i));
            let res = CStr::from_ptr(ch_ar)
                .to_string_lossy()
                .into_owned();
            dos_chararray_delete(ch_ar);
            res
        }
    }
}

impl<'a> From<&'a QVariant> for String {
    fn from(i: &'a QVariant) -> Self {
        unsafe {
            let ch_ar = dos_qvariant_toString(load_self(i));
            let res = CStr::from_ptr(ch_ar)
                .to_string_lossy()
                .into_owned();
            dos_chararray_delete(ch_ar);
            res
        }
    }
}

fn load_self(s: &QVariant) -> DosQVariant {
    s.ptr.load(Ordering::Relaxed)
}
<|endoftext|>


<commit_before>use rand;
use rand::Rng;
use rand::distributions::{IndependentSample, Range};
use std::thread;
use std::sync::atomic::{AtomicU64, Ordering};
use time;

trait RaftMsg {
    fn encode(&self) -> (usize, Vec<u8>);
}

trait UserStateMachine {
    fn snapshot(&self) -> Vec<u8>;
    fn id(&self) -> u64;
}

//TODO: Use higher order macro to merge with rpc service! macro when possible to do this in Rust.
//Current major problem is inner repeated macro will be recognized as outer macro which breaks expand

#[macro_export]
macro_rules! state_machine {
    (
        $(
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) $(-> $out:ty)* $(| $error:ty)*;
        )*
    ) => {
        state_machine! {{
            $(
                $(#[$attr])*
                def $smt $fn_name( $( $arg : $in_ ),* ) $(-> $out)* $(| $error)*;
            )*
        }}
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ); // No return, no error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> () | ();
        }
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) -> $out:ty; //return, no error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> $out | ();
        }
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) | $error:ty; //no return, error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> () | $error;
        }
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) -> $out:ty | $error:ty; //return, error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> $out | $error;
        }
    };
    (
        {} // all expanded
        $(
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident ( $( $arg:ident : $in_:ty ),* ) -> $out:ty | $error:ty;
        )*
    ) => {
        use std;
        use byteorder::{ByteOrder, LittleEndian};
        use bincode::{SizeLimit, serde as bincode};

        mod sm_args {
            use super::*;
            $(
                #[derive(Serialize, Deserialize, Debug)]
                pub struct $fn_name {
                    $(pub $arg:$in_),*
                }
                impl $crate::raft::RaftMsg for $fn_name {
                    fn encode(&self) -> (usize, Vec<u8>) {
                        (
                            hash_ident!($fn_name),
                            bincode::serialize(&self, SizeLimit::Infinite).unwrap()
                        )
                    }
                }

            )*
        }
        mod sm_returns {
            $(
                #[derive(Serialize, Deserialize, Debug)]
                pub enum $fn_name {
                    Result($out),
                    Error($error)
                }
            )*
        }
        pub trait StateMachine: $crate::raft::UserStateMachine {
           $(
                $(#[$attr])*
                fn $fn_name(&self, $($arg:$in_),*) -> std::result::Result<$out, $error>;
           )*
           fn dispatch(&self, fn_id: u64, data: &Vec<u8>) -> Option<Vec<u8>> {
                match fn_id as usize {
                    $(hash_ident!($fn_name) => {
                        let decoded: sm_args::$fn_name = bincode::deserialize(data).unwrap();
                        let f_result = self.$fn_name($(decoded.$arg),*);
                        let s_result = match f_result {
                            Ok(v) => sm_returns::$fn_name::Result(v),
                            Err(e) => sm_returns::$fn_name::Error(e)
                        };
                        Some(bincode::serialize(&s_result, SizeLimit::Infinite).unwrap())
                    }),*
                    _ => {
                        println!("Undefined function id: {}", fn_id);
                        None
                    }
                }
           }
        }
    };
}

const ORDERING: Ordering = Ordering::SeqCst;

service! {                                                                                //   sm , fn , data
    rpc AppendEntries(term: u64, leaderId: u64, prev_log_id: u64, prev_log_term: u64, entries: Option<Vec<(u64, u64, Vec<u8>)>>, leader_commit: u64) -> u64; //Err for not success
    rpc RequestVote(term: u64, candidate_id: u64, last_log_id: u64, last_log_term: u64) -> (u64, bool); // term, voteGranted
    rpc InstallSnapshot(term: u64, leader_id: u64, lasr_included_index: u64, last_included_term: u64, data: Vec<u8>, done: bool) -> u64;
}

fn gen_rand(lower: u64, higher: u64) -> u64 {
    let between = Range::new(lower, higher);
    let mut rng = rand::thread_rng();
    between.ind_sample(&mut rng) + 1
}

fn get_time() -> u64 {
    let timespec = time::get_time();
    let mills: f64 = timespec.sec as f64 + (timespec.nsec as f64 / 1000.0 / 1000.0 / 1000.0 );
    mills as u64
}

pub struct RaftServer {
    term: u64,
    log: u64,
    voted: bool,
    timeout: u64,
    last_term: AtomicU64,
}

impl RaftServer {
    pub fn new() -> RaftServer {
        RaftServer {
            term: 0,
            log: 0,
            voted: false,
            timeout: gen_rand(100, 500), // 10~500 ms for timeout
            last_term: AtomicU64::new(get_time()) ,
        }
    }
}

pub fn start_server(server: RaftServer, addr: &String) {
    let server = Arc::new(server);
    let addr = addr.clone();
    let svr_ref = server.clone();
    thread::spawn(move ||{
        listen(svr_ref, &addr);
    });
    let checker_ref = server.clone();
    thread::spawn(move ||{
        let server = checker_ref;
        loop {
            if get_time() > (server.timeout + server.last_term.load(ORDERING)) {

            }
        }
    });
}

impl Server for RaftServer {
    fn AppendEntries(
        &self,
        term: u64, leaderId: u64, prev_log_id: u64,
        prev_log_term: u64, entries: Option<Vec<(u64, u64, Vec<u8>)>>,
        leader_commit: u64
    ) -> Result<u64, ()>  {
        Ok(0)
    }

    fn RequestVote(
        &self,
        term: u64, candidate_id: u64,
        last_log_id: u64, last_log_term: u64
    ) -> Result<(u64, bool), ()> {
        Ok((0, false))
    }

    fn InstallSnapshot(
        &self,
        term: u64, leader_id: u64, lasr_included_index: u64,
        last_included_term: u64, data: Vec<u8>, done: bool
    ) -> Result<u64, ()> {
        Ok(0)
    }
}

#[cfg(test)]
mod syntax_test {
    state_machine! {
        def qry get (key: u64) -> String | ();
        def cmd test(a: u32, b: u32) -> bool;
    }
}

<commit_msg>split meta and rpc<commit_after>use rand;
use rand::Rng;
use rand::distributions::{IndependentSample, Range};
use std::thread;
use std::sync::Mutex;
use time;
use std::time::Duration;

trait RaftMsg {
    fn encode(&self) -> (usize, Vec<u8>);
}

trait UserStateMachine {
    fn snapshot(&self) -> Vec<u8>;
    fn id(&self) -> u64;
}

//TODO: Use higher order macro to merge with rpc service! macro when possible to do this in Rust.
//Current major problem is inner repeated macro will be recognized as outer macro which breaks expand

#[macro_export]
macro_rules! state_machine {
    (
        $(
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) $(-> $out:ty)* $(| $error:ty)*;
        )*
    ) => {
        state_machine! {{
            $(
                $(#[$attr])*
                def $smt $fn_name( $( $arg : $in_ ),* ) $(-> $out)* $(| $error)*;
            )*
        }}
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ); // No return, no error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> () | ();
        }
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) -> $out:ty; //return, no error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> $out | ();
        }
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) | $error:ty; //no return, error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> () | $error;
        }
    };
    (
        {
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident( $( $arg:ident : $in_:ty ),* ) -> $out:ty | $error:ty; //return, error

            $( $unexpanded:tt )*
        }
        $( $expanded:tt )*
    ) => {
        state_machine! {
            { $( $unexpanded )* }

            $( $expanded )*

            $(#[$attr])*
            def $smt $fn_name( $( $arg : $in_ ),* ) -> $out | $error;
        }
    };
    (
        {} // all expanded
        $(
            $(#[$attr:meta])*
            def $smt:ident $fn_name:ident ( $( $arg:ident : $in_:ty ),* ) -> $out:ty | $error:ty;
        )*
    ) => {
        use std;
        use byteorder::{ByteOrder, LittleEndian};
        use bincode::{SizeLimit, serde as bincode};

        mod sm_args {
            use super::*;
            $(
                #[derive(Serialize, Deserialize, Debug)]
                pub struct $fn_name {
                    $(pub $arg:$in_),*
                }
                impl $crate::raft::RaftMsg for $fn_name {
                    fn encode(&self) -> (usize, Vec<u8>) {
                        (
                            hash_ident!($fn_name),
                            bincode::serialize(&self, SizeLimit::Infinite).unwrap()
                        )
                    }
                }

            )*
        }
        mod sm_returns {
            $(
                #[derive(Serialize, Deserialize, Debug)]
                pub enum $fn_name {
                    Result($out),
                    Error($error)
                }
            )*
        }
        pub trait StateMachine: $crate::raft::UserStateMachine {
           $(
                $(#[$attr])*
                fn $fn_name(&self, $($arg:$in_),*) -> std::result::Result<$out, $error>;
           )*
           fn dispatch(&self, fn_id: u64, data: &Vec<u8>) -> Option<Vec<u8>> {
                match fn_id as usize {
                    $(hash_ident!($fn_name) => {
                        let decoded: sm_args::$fn_name = bincode::deserialize(data).unwrap();
                        let f_result = self.$fn_name($(decoded.$arg),*);
                        let s_result = match f_result {
                            Ok(v) => sm_returns::$fn_name::Result(v),
                            Err(e) => sm_returns::$fn_name::Error(e)
                        };
                        Some(bincode::serialize(&s_result, SizeLimit::Infinite).unwrap())
                    }),*
                    _ => {
                        println!("Undefined function id: {}", fn_id);
                        None
                    }
                }
           }
        }
    };
}

const CHECKER_MS: u64 = 10;

service! {                                                                                //   sm , fn , data
    rpc AppendEntries(term: u64, leaderId: u64, prev_log_id: u64, prev_log_term: u64, entries: Option<Vec<(u64, u64, Vec<u8>)>>, leader_commit: u64) -> u64; //Err for not success
    rpc RequestVote(term: u64, candidate_id: u64, last_log_id: u64, last_log_term: u64) -> (u64, bool); // term, voteGranted
    rpc InstallSnapshot(term: u64, leader_id: u64, lasr_included_index: u64, last_included_term: u64, data: Vec<u8>, done: bool) -> u64;
}

fn gen_rand(lower: u64, higher: u64) -> u64 {
    let between = Range::new(lower, higher);
    let mut rng = rand::thread_rng();
    between.ind_sample(&mut rng) + 1
}

fn get_time() -> u64 {
    let timespec = time::get_time();
    let mills: f64 = timespec.sec as f64 + (timespec.nsec as f64 / 1000.0 / 1000.0 / 1000.0 );
    mills as u64
}

pub enum Membership {
    LEADER,
    FOLLOWER,
    CANDIDATE,
}

pub struct RaftMeta {
    term: u64,
    log: u64,
    voted: bool,
    timeout: u64,
    last_checked: u64,
    membership: Membership,
}

pub struct RaftServer {
    meta: Arc<Mutex<RaftMeta>>
}

impl RaftServer {
    pub fn new() -> RaftServer {
        RaftServer {
            meta: Arc::new(Mutex::new(
                RaftMeta {
                    term: 0,
                    log: 0,
                    voted: false,
                    timeout: gen_rand(100, 500), // 10~500 ms for timeout
                    last_checked: get_time(),
                    membership: Membership::FOLLOWER,
                }
            ))
        }
    }
    pub fn become_candidate(&self) {

    }
}

pub fn start_server(addr: &String) -> Arc<RaftServer> {
    let server = Arc::new(RaftServer::new());
    let addr = addr.clone();
    let svr_ref = server.clone();
    thread::spawn(move ||{
        listen(svr_ref, &addr);
    });
    let checker_ref = server.clone();
    thread::spawn(move ||{
        let server = checker_ref;
        loop {
            {
                let mut meta = server.meta.lock().unwrap();
                match meta.membership {
                    Membership::LEADER => {

                    },
                    Membership::FOLLOWER => {
                        if get_time() > (meta.timeout + meta.last_checked) { //Timeout, require election
                            server.become_candidate();
                        }
                    },
                    Membership::CANDIDATE => {

                    }
                }
            }
            thread::sleep(Duration::from_millis(CHECKER_MS));
        }
    });
    server
}

impl Server for RaftServer {
    fn AppendEntries(
        &self,
        term: u64, leaderId: u64, prev_log_id: u64,
        prev_log_term: u64, entries: Option<Vec<(u64, u64, Vec<u8>)>>,
        leader_commit: u64
    ) -> Result<u64, ()>  {
        Ok(0)
    }

    fn RequestVote(
        &self,
        term: u64, candidate_id: u64,
        last_log_id: u64, last_log_term: u64
    ) -> Result<(u64, bool), ()> {
        Ok((0, false))
    }

    fn InstallSnapshot(
        &self,
        term: u64, leader_id: u64, lasr_included_index: u64,
        last_included_term: u64, data: Vec<u8>, done: bool
    ) -> Result<u64, ()> {
        Ok(0)
    }
}

#[cfg(test)]
mod syntax_test {
    state_machine! {
        def qry get (key: u64) -> String | ();
        def cmd test(a: u32, b: u32) -> bool;
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2018 Stefan Lankes, RWTH Aachen University
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pub mod allocator;
pub mod freelist;
mod nodepool;

use alloc::alloc::Layout;
use arch::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags};
use mm::nodepool::NodePool;
use logging::*;
use scheduler::DisabledPreemption;
use arch;

extern "C" {
	static kernel_start: u8;
	static kernel_end: u8;
}

pub static mut POOL: NodePool = NodePool::new();

/// Physical and virtual address of the first 2 MiB page that maps the kernel.
/// Can be easily accessed through kernel_start_address()
static mut KERNEL_START_ADDRESS: usize = 0;

/// Physical and virtual address of the first page after the kernel.
/// Can be easily accessed through kernel_end_address()
static mut KERNEL_END_ADDRESS: usize = 0;

pub fn kernel_start_address() -> usize {
	unsafe { KERNEL_START_ADDRESS }
}

pub fn kernel_end_address() -> usize {
	unsafe { KERNEL_END_ADDRESS }
}

pub fn allocate(size: usize, execute_disable: bool) -> usize {
	let _preemption = DisabledPreemption::new();

	let physical_address = arch::mm::physicalmem::allocate(size);
	let virtual_address = arch::mm::virtualmem::allocate(size);

	let count = size / BasePageSize::SIZE;
	let mut flags = PageTableEntryFlags::empty();
	flags.normal().writable();
	if execute_disable {
		flags.execute_disable();
	}
	arch::mm::paging::map::<BasePageSize>(virtual_address, physical_address, count, flags);

	virtual_address
}

pub fn deallocate(virtual_address: usize, size: usize) {
	let _preemption = DisabledPreemption::new();

	if let Some(entry) = arch::mm::paging::get_page_table_entry::<BasePageSize>(virtual_address) {
		arch::mm::virtualmem::deallocate(virtual_address, size);
		arch::mm::physicalmem::deallocate(entry.address(), size);
	} else {
		panic!("No page table entry for virtual address {:#X}", virtual_address);
	}
}

pub fn init() {
	// Calculate the start and end addresses of the 2 MiB page(s) that map the kernel.
	unsafe {
		KERNEL_START_ADDRESS = align_down!(&kernel_start as *const u8 as usize, arch::mm::paging::LargePageSize::SIZE);
		KERNEL_END_ADDRESS = align_up!(&kernel_end as *const u8 as usize, arch::mm::paging::LargePageSize::SIZE);
	}

	info!("Memory size {} MByte", arch::get_memory_size() >> 20);
	info!("Kernel start address 0x{:x}", kernel_start_address());
	info!("Kernel end address 0x{:x}", kernel_end_address());

	arch::mm::init();
	self::allocator::init();
}

#[cfg(not(test))]
#[lang = "oom"]
#[no_mangle]
pub fn rust_oom(layout: Layout) -> ! {
        println!("[!!!OOM!!!] Memory allocation of {} bytes failed", layout.size());

		loop {}
}
<commit_msg>dump also the kernel image size<commit_after>// Copyright (c) 2018 Stefan Lankes, RWTH Aachen University
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pub mod allocator;
pub mod freelist;
mod nodepool;

use alloc::alloc::Layout;
use arch::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags};
use mm::nodepool::NodePool;
use logging::*;
use scheduler::DisabledPreemption;
use arch;

extern "C" {
	static kernel_start: u8;
	static kernel_end: u8;
}

pub static mut POOL: NodePool = NodePool::new();

/// Physical and virtual address of the first 2 MiB page that maps the kernel.
/// Can be easily accessed through kernel_start_address()
static mut KERNEL_START_ADDRESS: usize = 0;

/// Physical and virtual address of the first page after the kernel.
/// Can be easily accessed through kernel_end_address()
static mut KERNEL_END_ADDRESS: usize = 0;

pub fn kernel_start_address() -> usize {
	unsafe { KERNEL_START_ADDRESS }
}

pub fn kernel_end_address() -> usize {
	unsafe { KERNEL_END_ADDRESS }
}

pub fn allocate(size: usize, execute_disable: bool) -> usize {
	let _preemption = DisabledPreemption::new();

	let physical_address = arch::mm::physicalmem::allocate(size);
	let virtual_address = arch::mm::virtualmem::allocate(size);

	let count = size / BasePageSize::SIZE;
	let mut flags = PageTableEntryFlags::empty();
	flags.normal().writable();
	if execute_disable {
		flags.execute_disable();
	}
	arch::mm::paging::map::<BasePageSize>(virtual_address, physical_address, count, flags);

	virtual_address
}

pub fn deallocate(virtual_address: usize, size: usize) {
	let _preemption = DisabledPreemption::new();

	if let Some(entry) = arch::mm::paging::get_page_table_entry::<BasePageSize>(virtual_address) {
		arch::mm::virtualmem::deallocate(virtual_address, size);
		arch::mm::physicalmem::deallocate(entry.address(), size);
	} else {
		panic!("No page table entry for virtual address {:#X}", virtual_address);
	}
}

pub fn init() {
	let image_size;

	// Calculate the start and end addresses of the 2 MiB page(s) that map the kernel.
	unsafe {
		image_size = &kernel_end as *const u8 as usize - &kernel_start as *const u8 as usize;
		KERNEL_START_ADDRESS = align_down!(&kernel_start as *const u8 as usize, arch::mm::paging::LargePageSize::SIZE);
		KERNEL_END_ADDRESS = align_up!(&kernel_end as *const u8 as usize, arch::mm::paging::LargePageSize::SIZE);
	}

	info!("Memory size {} MByte", arch::get_memory_size() >> 20);
	info!("Kernel start address 0x{:x}", kernel_start_address());
	info!("Kernel end address 0x{:x}", kernel_end_address());
	info!("Kernel image size {} KByte", image_size >> 10);

	arch::mm::init();
	self::allocator::init();
}

#[cfg(not(test))]
#[lang = "oom"]
#[no_mangle]
pub fn rust_oom(layout: Layout) -> ! {
        println!("[!!!OOM!!!] Memory allocation of {} bytes failed", layout.size());

		loop {}
}
<|endoftext|>


<commit_before>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program 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
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

use mimir;
use std::process::exit;
use std::sync::Arc;
use structopt::StructOpt;
use Error;

pub fn format_label(admins: &[Arc<mimir::Admin>], name: &str) -> String {
    match admins.iter().position(|adm| adm.is_city()) {
        Some(idx) => format!("{} ({})", name, admins[idx].name),
        None => name.to_string(),
    }
}

pub fn get_zip_codes_from_admins(admins: &[Arc<mimir::Admin>]) -> Vec<String> {
    let level = admins.iter().fold(0, |level, adm| {
        if adm.level > level && !adm.zip_codes.is_empty() {
            adm.level
        } else {
            level
        }
    });
    if level == 0 {
        return vec![];
    }
    admins
        .into_iter()
        .filter(|adm| adm.level == level)
        .flat_map(|adm| adm.zip_codes.iter().cloned())
        .collect()
}

/// normalize the admin weight for it to be in [0, 1]
pub fn normalize_admin_weight(admins: &mut [mimir::Admin]) {
    let max = admins.iter().fold(1f64, |m, a| f64::max(m, a.weight));
    for ref mut a in admins {
        a.weight = a.weight / max;
    }
}

pub fn launch_run<O, F>(run: F)
where
    F: FnOnce(O) -> Result<(), Error>,
    O: StructOpt,
{
    let _guard = mimir::logger_init();
    if let Err(err) = run(O::from_args()) {
        for cause in err.causes() {
            error!("{}", cause);
        }
        exit(1);
    }
}
<commit_msg>fix logger destruction<commit_after>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program 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
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

use mimir;
use std::process::exit;
use std::sync::Arc;
use structopt::StructOpt;
use Error;

pub fn format_label(admins: &[Arc<mimir::Admin>], name: &str) -> String {
    match admins.iter().position(|adm| adm.is_city()) {
        Some(idx) => format!("{} ({})", name, admins[idx].name),
        None => name.to_string(),
    }
}

pub fn get_zip_codes_from_admins(admins: &[Arc<mimir::Admin>]) -> Vec<String> {
    let level = admins.iter().fold(0, |level, adm| {
        if adm.level > level && !adm.zip_codes.is_empty() {
            adm.level
        } else {
            level
        }
    });
    if level == 0 {
        return vec![];
    }
    admins
        .into_iter()
        .filter(|adm| adm.level == level)
        .flat_map(|adm| adm.zip_codes.iter().cloned())
        .collect()
}

/// normalize the admin weight for it to be in [0, 1]
pub fn normalize_admin_weight(admins: &mut [mimir::Admin]) {
    let max = admins.iter().fold(1f64, |m, a| f64::max(m, a.weight));
    for ref mut a in admins {
        a.weight = a.weight / max;
    }
}

pub fn wrapped_launch_run<O, F>(run: F) -> Result<(), Error>
where
    F: FnOnce(O) -> Result<(), Error>,
    O: StructOpt,
{
    let _guard = mimir::logger_init();
    if let Err(err) = run(O::from_args()) {
        for cause in err.causes() {
            error!("{}", cause);
        }
        Err(err)
    } else {
        Ok(())
    }
}

pub fn launch_run<O, F>(run: F)
where
    F: FnOnce(O) -> Result<(), Error>,
    O: StructOpt,
{
    if wrapped_launch_run(run).is_err() {
        // we wrap the real stuff in another method to std::exit after
        // the destruction of the logger (so we won't loose any messages)
        exit(1);
    }
}
<|endoftext|>


<commit_before>extern crate xcb;
use std;
use xcb::ffi::xproto::xcb_atom_t as xcb_atom_t;
struct Utils;

impl Utils {
  pub fn get_atoms(names: Vec<&str>, atoms: Vec<xcb_atom_t>, c: &xcb::Connection) {
    type AtomicCookie<'a> = xcb::Cookie<'a, xcb::ffi::xproto::xcb_intern_atom_cookie_t>;
    let cookies : std::vec::Vec<AtomicCookie>::new();

    for name in &names {
      cookies.push(xcb::intern_atom(c, false, name));
    }

    for (name, cookie) in names.iter().zip(cookies.iter()) {
      let reply = cookie.get_reply();
      match reply {
        Ok(x) => atoms.push(x.atom()),
        Err(e) => panic!("Error! {:?}", e),
      }
    }
  }
}<commit_msg>works<commit_after>extern crate xcb;
use std;
use xcb::ffi::xproto::xcb_atom_t as xcb_atom_t;
use xcb::ffi::xproto::xcb_intern_atom_cookie_t as xcb_intern_atom_cookie_t;
struct Utils;

impl Utils {
  pub fn get_atoms<'a>(names: Vec<&str>, mut atoms: Vec<xcb_atom_t>, c: &xcb::Connection) {

    // type CookieAtom<'a> = xcb::Cookie<'a, xcb_intern_atom_cookie_t>;
    let mut cookies : Vec<xcb::Cookie<'a, xcb_intern_atom_cookie_t>> = Vec::new();
    // let mut cookies = Vec::<CookieAtom>::new();

    for name in &names {
      cookies.push(xcb::intern_atom(c, false, name));
    }

    for (name, cookie) in names.iter().zip(cookies.iter()) {
      let reply = cookie.get_reply();
      match reply {
        Ok(x) => atoms.push(x.atom()),
        Err(e) => panic!("Error! in get_atoms(), error: {:?}, name: , cookie:", e),
      }
    }
  }
}<|endoftext|>