<commit_before>pub mod dummy;
pub mod full;
pub mod stack_trace;

use super::{heap::Pointer, ChannelId, FiberId, Heap};
use crate::{compiler::hir::Id, module::Module};

/// An event that happened inside a VM.
#[derive(Clone)]
pub enum VmEvent<'event> {
    FiberCreated {
        fiber: FiberId,
    },
    FiberDone {
        fiber: FiberId,
    },
    FiberPanicked {
        fiber: FiberId,
        panicked_child: Option<FiberId>,
    },
    FiberCanceled {
        fiber: FiberId,
    },
    FiberExecutionStarted {
        fiber: FiberId,
    },
    FiberExecutionEnded {
        fiber: FiberId,
    },
    ChannelCreated {
        channel: ChannelId,
    },
    InFiber {
        fiber: FiberId,
        event: FiberEvent<'event>,
    },
}

/// An event that happened inside a fiber.
#[derive(Clone)]
pub enum FiberEvent<'event> {
    ModuleStarted {
        module: Module,
    },
    ModuleEnded {
        export_map: Pointer,
        heap: &'event Heap,
    },
    ValueEvaluated {
        id: Id,
        value: Pointer,
        heap: &'event Heap,
    },
    FoundFuzzableClosure {
        id: Id,
        closure: Pointer,
        heap: &'event Heap,
    },
    CallStarted {
        id: Id,
        closure: Pointer,
        args: Vec<Pointer>,
        heap: &'event Heap,
    },
    CallEnded {
        return_value: Pointer,
        heap: &'event Heap,
    },
    NeedsStarted {
        id: Id,
        condition: Pointer,
        reason: Pointer,
        heap: &'event Heap,
    },
    NeedsEnded,
}

pub trait Tracer {
    fn add(&mut self, event: VmEvent);

    fn for_vm<'a, 'vm>(&'a mut self) -> VmTracer<'vm>
    where
        Self: Sized,
        'a: 'vm,
    {
        VmTracer::<'vm> { tracer: self }
    }
}
pub struct VmTracer<'vm> {
    tracer: &'vm mut dyn Tracer,
}
pub struct FiberTracer<'vm, 'fiber> {
    vm_tracer: &'fiber mut VmTracer<'vm>,
    fiber: FiberId,
}

impl<'vm> VmTracer<'vm> {
    pub fn for_fiber<'fiber>(&'fiber mut self, fiber: FiberId) -> FiberTracer<'vm, 'fiber>
    where
        Self: 'fiber,
    {
        FiberTracer {
            vm_tracer: self,
            fiber,
        }
    }
}

impl<'vm> Tracer for VmTracer<'vm> {
    fn add(&mut self, event: VmEvent) {
        self.tracer.add(event);
    }
}
impl<'vm, 'fiber> FiberTracer<'vm, 'fiber> {
    fn add(&mut self, event: FiberEvent) {
        self.vm_tracer.add(VmEvent::InFiber {
            fiber: self.fiber,
            event,
        });
    }
}

impl Tracer {
    pub fn fiber_created(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberCreated { fiber });
    }
    pub fn fiber_done(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberDone { fiber });
    }
    pub fn fiber_panicked(&mut self, fiber: FiberId, panicked_child: Option<FiberId>) {
        self.add(VmEvent::FiberPanicked {
            fiber,
            panicked_child,
        });
    }
    pub fn fiber_canceled(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberCanceled { fiber });
    }
    pub fn fiber_execution_started(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberExecutionStarted { fiber });
    }
    pub fn fiber_execution_ended(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberExecutionEnded { fiber });
    }
    pub fn channel_created(&mut self, channel: ChannelId) {
        self.add(VmEvent::ChannelCreated { channel });
    }
}
impl<'vm, 'fiber> FiberTracer<'vm, 'fiber> {
    pub fn module_started(&mut self, module: Module) {
        self.add(FiberEvent::ModuleStarted { module });
    }
    pub fn module_ended(&mut self, export_map: Pointer, heap: &Heap) {
        self.add(FiberEvent::ModuleEnded { export_map, heap });
    }
    pub fn value_evaluated(&mut self, id: Id, value: Pointer, heap: &Heap) {
        self.add(FiberEvent::ValueEvaluated { id, value, heap });
    }
    pub fn found_fuzzable_closure(&mut self, id: Id, closure: Pointer, heap: &Heap) {
        self.add(FiberEvent::FoundFuzzableClosure { id, closure, heap });
    }
    pub fn call_started(&mut self, id: Id, closure: Pointer, args: Vec<Pointer>, heap: &Heap) {
        self.add(FiberEvent::CallStarted {
            id,
            closure,
            args,
            heap,
        });
    }
    pub fn call_ended(&mut self, return_value: Pointer, heap: &Heap) {
        self.add(FiberEvent::CallEnded { return_value, heap });
    }
    pub fn needs_started(&mut self, id: Id, condition: Pointer, reason: Pointer, heap: &Heap) {
        self.add(FiberEvent::NeedsStarted {
            id,
            condition,
            reason,
            heap,
        });
    }
    pub fn needs_ended(&mut self) {
        self.add(FiberEvent::NeedsEnded);
    }
}
<commit_msg>Move tracer methods<commit_after>pub mod dummy;
pub mod full;
pub mod stack_trace;

use super::{heap::Pointer, ChannelId, FiberId, Heap};
use crate::{compiler::hir::Id, module::Module};

/// An event that happened inside a VM.
#[derive(Clone)]
pub enum VmEvent<'event> {
    FiberCreated {
        fiber: FiberId,
    },
    FiberDone {
        fiber: FiberId,
    },
    FiberPanicked {
        fiber: FiberId,
        panicked_child: Option<FiberId>,
    },
    FiberCanceled {
        fiber: FiberId,
    },
    FiberExecutionStarted {
        fiber: FiberId,
    },
    FiberExecutionEnded {
        fiber: FiberId,
    },
    ChannelCreated {
        channel: ChannelId,
    },
    InFiber {
        fiber: FiberId,
        event: FiberEvent<'event>,
    },
}

/// An event that happened inside a fiber.
#[derive(Clone)]
pub enum FiberEvent<'event> {
    ModuleStarted {
        module: Module,
    },
    ModuleEnded {
        export_map: Pointer,
        heap: &'event Heap,
    },
    ValueEvaluated {
        id: Id,
        value: Pointer,
        heap: &'event Heap,
    },
    FoundFuzzableClosure {
        id: Id,
        closure: Pointer,
        heap: &'event Heap,
    },
    CallStarted {
        id: Id,
        closure: Pointer,
        args: Vec<Pointer>,
        heap: &'event Heap,
    },
    CallEnded {
        return_value: Pointer,
        heap: &'event Heap,
    },
    NeedsStarted {
        id: Id,
        condition: Pointer,
        reason: Pointer,
        heap: &'event Heap,
    },
    NeedsEnded,
}

pub trait Tracer {
    fn add(&mut self, event: VmEvent);

    fn fiber_created(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberCreated { fiber });
    }
    fn fiber_done(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberDone { fiber });
    }
    fn fiber_panicked(&mut self, fiber: FiberId, panicked_child: Option<FiberId>) {
        self.add(VmEvent::FiberPanicked {
            fiber,
            panicked_child,
        });
    }
    fn fiber_canceled(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberCanceled { fiber });
    }
    fn fiber_execution_started(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberExecutionStarted { fiber });
    }
    fn fiber_execution_ended(&mut self, fiber: FiberId) {
        self.add(VmEvent::FiberExecutionEnded { fiber });
    }
    fn channel_created(&mut self, channel: ChannelId) {
        self.add(VmEvent::ChannelCreated { channel });
    }

    fn for_vm<'a, 'vm>(&'a mut self) -> VmTracer<'vm>
    where
        Self: Sized,
        'a: 'vm,
    {
        VmTracer::<'vm> { tracer: self }
    }
}
pub struct VmTracer<'vm> {
    tracer: &'vm mut dyn Tracer,
}
pub struct FiberTracer<'vm, 'fiber> {
    vm_tracer: &'fiber mut VmTracer<'vm>,
    fiber: FiberId,
}

impl<'vm> VmTracer<'vm> {
    pub fn for_fiber<'fiber>(&'fiber mut self, fiber: FiberId) -> FiberTracer<'vm, 'fiber>
    where
        Self: 'fiber,
    {
        FiberTracer {
            vm_tracer: self,
            fiber,
        }
    }
}

impl<'vm> Tracer for VmTracer<'vm> {
    fn add(&mut self, event: VmEvent) {
        self.tracer.add(event);
    }
}
impl<'vm, 'fiber> FiberTracer<'vm, 'fiber> {
    fn add(&mut self, event: FiberEvent) {
        self.vm_tracer.add(VmEvent::InFiber {
            fiber: self.fiber,
            event,
        });
    }
}

impl<'vm, 'fiber> FiberTracer<'vm, 'fiber> {
    pub fn module_started(&mut self, module: Module) {
        self.add(FiberEvent::ModuleStarted { module });
    }
    pub fn module_ended(&mut self, export_map: Pointer, heap: &Heap) {
        self.add(FiberEvent::ModuleEnded { export_map, heap });
    }
    pub fn value_evaluated(&mut self, id: Id, value: Pointer, heap: &Heap) {
        self.add(FiberEvent::ValueEvaluated { id, value, heap });
    }
    pub fn found_fuzzable_closure(&mut self, id: Id, closure: Pointer, heap: &Heap) {
        self.add(FiberEvent::FoundFuzzableClosure { id, closure, heap });
    }
    pub fn call_started(&mut self, id: Id, closure: Pointer, args: Vec<Pointer>, heap: &Heap) {
        self.add(FiberEvent::CallStarted {
            id,
            closure,
            args,
            heap,
        });
    }
    pub fn call_ended(&mut self, return_value: Pointer, heap: &Heap) {
        self.add(FiberEvent::CallEnded { return_value, heap });
    }
    pub fn needs_started(&mut self, id: Id, condition: Pointer, reason: Pointer, heap: &Heap) {
        self.add(FiberEvent::NeedsStarted {
            id,
            condition,
            reason,
            heap,
        });
    }
    pub fn needs_ended(&mut self) {
        self.add(FiberEvent::NeedsEnded);
    }
}
<|endoftext|>


<commit_before>use winapi::*;
use user32::{CreateWindowExW, RegisterClassExW, GetClassInfoExW, DefWindowProcW, PostQuitMessage,
             LoadCursorW, GetClientRect};
use kernel32::GetModuleHandleW;
use std::ptr;
use libc;

use utils::*;
use std::mem;
use std::cell::RefCell;

use user32::{TranslateMessage, DispatchMessageW, PeekMessageW};
// use kernel32::{Sleep};

pub struct Window {
    hwnd: HWND,
}

pub struct PollEventIterator<'a> {
    wnd: &'a Window,
}

impl<'a> Iterator for PollEventIterator<'a> {
    type Item = Option<MSG>;

    fn next(&mut self) -> Option<Self::Item> {
        let mut maybe_injected_msg = None;
        // Extract WM_SIZE message from thread-local data associated with this window
        WINDOW.with(|rc| {
            if let Some(ThreadLocalData {inject_msg: ref mut imsg, ..}) = *rc.borrow_mut() {
                maybe_injected_msg = imsg.take();
            }
        });
        if let Some(imsg) = maybe_injected_msg {
            return Some(Some(imsg));
        }
        let mut msg = unsafe { mem::uninitialized::<MSG>() };
        let ret = unsafe { PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, PM_REMOVE) };
        if ret == 0 {
            Some(None)
        } else {
            // debug!("Windows message:{}", msg.message);
            if msg.message == WM_QUIT {
                None
            } else if msg.hwnd == self.wnd.hwnd {
                unsafe { TranslateMessage(&mut msg) };
                unsafe { DispatchMessageW(&mut msg) };
                Some(Some(msg))
            } else {
                Some(None)
            }
        }
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

impl Window {
    pub fn get_hwnd(&self) -> HWND {
        self.hwnd
    }
    pub fn poll_events<'a>(&'a self) -> PollEventIterator<'a> {
        PollEventIterator { wnd: &self }
    }
    pub fn size(&self) -> (u32, u32) {
        let mut rect = RECT {
            left: 0,
            top: 0,
            right: 0,
            bottom: 0,
        };
        if unsafe { GetClientRect(self.hwnd, &mut rect) } == 0 {
            (0, 0)
        } else {
            (rect.right as u32, rect.bottom as u32)
        }
    }
}

impl Clone for Window {
    fn clone(&self) -> Self {
        Window { hwnd: self.hwnd }
    }
}
impl Copy for Window {}
impl !Send for Window {}
impl !Sync for Window {}

type ResizeFn = Box<FnMut(u32, u32, u32) -> ()>;

struct ThreadLocalData {
    hwnd: HWND,
    inject_msg: Option<MSG>, // MSG for injection into message queue
}

thread_local!(static WINDOW: RefCell<Option<ThreadLocalData>> = RefCell::new(None) );

unsafe extern "system" fn wnd_callback(hwnd: HWND,
                                       msg: UINT,
                                       wparam: WPARAM,
                                       lparam: LPARAM)
                                       -> LRESULT {
    match msg {
        WM_DESTROY => {
            PostQuitMessage(0);
            return 0;
        }
        WM_SIZE => {
            // WM_SIZE can be received while calling DXGISwapChain::present
            // so, it's better to postpone processing
            trace!("WM_SIZE wndproc");
            WINDOW.with(|rc| {
                if let Some(ThreadLocalData {inject_msg: ref mut imsg, ..}) = *rc.borrow_mut() {
                    *imsg = Some(MSG {
                        hwnd: hwnd,
                        message: msg,
                        wParam: wparam,
                        lParam: lparam,
                        time: 0,
                        pt: POINT { x: 0, y: 0 },
                    });
                }
            });
            return 0;
        }
        _ => (),
    }
    DefWindowProcW(hwnd, msg, wparam, lparam)
}

// No more than 1 (one) window for now
pub fn create_window(title: &str, width: i32, height: i32) -> Window {
    if let Some(wnd) = WINDOW.with(|rc| {
        match *rc.borrow() {
            Some(ref td) => Some(Window { hwnd: td.hwnd }),
            _ => None,
        }
    }) {
        return wnd;
    };
    let class_name = str_to_vec_u16("RustMainWndClass_14f22");
    let h_module = unsafe { GetModuleHandleW(ptr::null_mut()) };
    let mut class = WNDCLASSEXW {
        cbSize: mem::size_of::<WNDCLASSEXW>() as UINT,
        style: CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
        lpfnWndProc: Some(wnd_callback),
        cbClsExtra: 0,
        cbWndExtra: 0,
        hInstance: h_module,
        hIcon: ptr::null_mut(),
        hCursor: unsafe { LoadCursorW(ptr::null_mut(), IDC_ARROW) },
        hbrBackground: ptr::null_mut(),
        lpszMenuName: ptr::null_mut(),
        lpszClassName: class_name.as_ptr(),
        hIconSm: ptr::null_mut(),
    };
    if unsafe { GetClassInfoExW(h_module, class_name.as_ptr(), &mut class as *mut _) } == 0 {
        unsafe { RegisterClassExW(&mut class as *mut _) };
    }

    let w_title = str_to_vec_u16(title);
    let hwnd = unsafe {
        CreateWindowExW(0,
                        class_name.as_ptr(),
                        w_title.as_ptr(),
                        WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        width as libc::c_int,
                        height as libc::c_int,
                        ptr::null_mut(),
                        ptr::null_mut(),
                        h_module,
                        ptr::null_mut())
    };
    if hwnd == ptr::null_mut() {
        panic!("CreateWindowExW failed.");
    }
    WINDOW.with(|rc| {
        let td = &mut *rc.borrow_mut();
        *td = Some(ThreadLocalData {
            hwnd: hwnd,
            inject_msg: None,
        });
    });
    Window { hwnd: hwnd }
}
<commit_msg>Comment fix<commit_after>use winapi::*;
use user32::{CreateWindowExW, RegisterClassExW, GetClassInfoExW, DefWindowProcW, PostQuitMessage,
             LoadCursorW, GetClientRect};
use kernel32::GetModuleHandleW;
use std::ptr;
use libc;

use utils::*;
use std::mem;
use std::cell::RefCell;

use user32::{TranslateMessage, DispatchMessageW, PeekMessageW};
// use kernel32::{Sleep};

pub struct Window {
    hwnd: HWND,
}

pub struct PollEventIterator<'a> {
    wnd: &'a Window,
}

impl<'a> Iterator for PollEventIterator<'a> {
    type Item = Option<MSG>;

    fn next(&mut self) -> Option<Self::Item> {
        let mut maybe_injected_msg = None;
        // Extract WM_SIZE message from thread-local data associated with this window
        WINDOW.with(|rc| {
            if let Some(ThreadLocalData {inject_msg: ref mut imsg, ..}) = *rc.borrow_mut() {
                maybe_injected_msg = imsg.take();
            }
        });
        if let Some(imsg) = maybe_injected_msg {
            return Some(Some(imsg));
        }
        let mut msg = unsafe { mem::uninitialized::<MSG>() };
        let ret = unsafe { PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, PM_REMOVE) };
        if ret == 0 {
            Some(None)
        } else {
            // debug!("Windows message:{}", msg.message);
            if msg.message == WM_QUIT {
                None
            } else if msg.hwnd == self.wnd.hwnd {
                unsafe { TranslateMessage(&mut msg) };
                unsafe { DispatchMessageW(&mut msg) };
                Some(Some(msg))
            } else {
                Some(None)
            }
        }
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

impl Window {
    pub fn get_hwnd(&self) -> HWND {
        self.hwnd
    }
    pub fn poll_events<'a>(&'a self) -> PollEventIterator<'a> {
        PollEventIterator { wnd: &self }
    }
    pub fn size(&self) -> (u32, u32) {
        let mut rect = RECT {
            left: 0,
            top: 0,
            right: 0,
            bottom: 0,
        };
        if unsafe { GetClientRect(self.hwnd, &mut rect) } == 0 {
            (0, 0)
        } else {
            (rect.right as u32, rect.bottom as u32)
        }
    }
}

impl Clone for Window {
    fn clone(&self) -> Self {
        Window { hwnd: self.hwnd }
    }
}
impl Copy for Window {}
impl !Send for Window {}
impl !Sync for Window {}

type ResizeFn = Box<FnMut(u32, u32, u32) -> ()>;

struct ThreadLocalData {
    hwnd: HWND,
    inject_msg: Option<MSG>, // MSG for injection into message queue
}

thread_local!(static WINDOW: RefCell<Option<ThreadLocalData>> = RefCell::new(None) );

unsafe extern "system" fn wnd_callback(hwnd: HWND,
                                       msg: UINT,
                                       wparam: WPARAM,
                                       lparam: LPARAM)
                                       -> LRESULT {
    match msg {
        WM_DESTROY => {
            PostQuitMessage(0);
            return 0;
        }
        WM_SIZE => {
            // WM_SIZE can be received while calling DXGISwapChain::present
            // so, it's better to postpone processing
            trace!("WM_SIZE wndproc");
            WINDOW.with(|rc| {
                if let Some(ThreadLocalData {inject_msg: ref mut imsg, ..}) = *rc.borrow_mut() {
                    *imsg = Some(MSG {
                        hwnd: hwnd,
                        message: msg,
                        wParam: wparam,
                        lParam: lparam,
                        time: 0,
                        pt: POINT { x: 0, y: 0 },
                    });
                }
            });
            return 0;
        }
        _ => (),
    }
    DefWindowProcW(hwnd, msg, wparam, lparam)
}

// No more than 1 (one) window per thread for now
pub fn create_window(title: &str, width: i32, height: i32) -> Window {
    if let Some(wnd) = WINDOW.with(|rc| {
        match *rc.borrow() {
            Some(ref td) => Some(Window { hwnd: td.hwnd }),
            _ => None,
        }
    }) {
        return wnd;
    };
    let class_name = str_to_vec_u16("RustMainWndClass_14f22");
    let h_module = unsafe { GetModuleHandleW(ptr::null_mut()) };
    let mut class = WNDCLASSEXW {
        cbSize: mem::size_of::<WNDCLASSEXW>() as UINT,
        style: CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
        lpfnWndProc: Some(wnd_callback),
        cbClsExtra: 0,
        cbWndExtra: 0,
        hInstance: h_module,
        hIcon: ptr::null_mut(),
        hCursor: unsafe { LoadCursorW(ptr::null_mut(), IDC_ARROW) },
        hbrBackground: ptr::null_mut(),
        lpszMenuName: ptr::null_mut(),
        lpszClassName: class_name.as_ptr(),
        hIconSm: ptr::null_mut(),
    };
    if unsafe { GetClassInfoExW(h_module, class_name.as_ptr(), &mut class as *mut _) } == 0 {
        unsafe { RegisterClassExW(&mut class as *mut _) };
    }

    let w_title = str_to_vec_u16(title);
    let hwnd = unsafe {
        CreateWindowExW(0,
                        class_name.as_ptr(),
                        w_title.as_ptr(),
                        WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        width as libc::c_int,
                        height as libc::c_int,
                        ptr::null_mut(),
                        ptr::null_mut(),
                        h_module,
                        ptr::null_mut())
    };
    if hwnd == ptr::null_mut() {
        panic!("CreateWindowExW failed.");
    }
    WINDOW.with(|rc| {
        let td = &mut *rc.borrow_mut();
        *td = Some(ThreadLocalData {
            hwnd: hwnd,
            inject_msg: None,
        });
    });
    Window { hwnd: hwnd }
}
<|endoftext|>


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

#![feature(box_syntax)]
#![feature(iter_cmp)]
#![feature(slice_bytes)]
#![feature(vec_push_all)]

#[macro_use]
extern crate log;

extern crate azure;
extern crate canvas;
extern crate canvas_traits;
extern crate devtools_traits;
extern crate euclid;
extern crate gfx;
extern crate ipc_channel;
extern crate layers;
extern crate layout_traits;
extern crate offscreen_gl_context;
extern crate png;
extern crate script_traits;
extern crate msg;
extern crate num;
#[macro_use]
extern crate profile_traits;
extern crate net_traits;
extern crate gfx_traits;
extern crate style;
#[macro_use]
extern crate util;
extern crate gleam;
extern crate clipboard;

extern crate time;
extern crate url;

#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;

pub use compositor_task::{CompositorEventListener, CompositorProxy, CompositorTask};
pub use constellation::Constellation;

pub mod compositor_task;

mod surface_map;
mod compositor_layer;
mod compositor;
mod headless;
mod scrolling;

pub mod pipeline;
pub mod constellation;
pub mod windowing;

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

#![feature(box_syntax)]
#![feature(iter_cmp)]
#![feature(slice_bytes)]
#![feature(vec_push_all)]

#![deny(unsafe_code)]

#[macro_use]
extern crate log;

extern crate azure;
extern crate canvas;
extern crate canvas_traits;
extern crate devtools_traits;
extern crate euclid;
extern crate gfx;
extern crate ipc_channel;
extern crate layers;
extern crate layout_traits;
extern crate offscreen_gl_context;
extern crate png;
extern crate script_traits;
extern crate msg;
extern crate num;
#[macro_use]
extern crate profile_traits;
extern crate net_traits;
extern crate gfx_traits;
extern crate style;
#[macro_use]
extern crate util;
extern crate gleam;
extern crate clipboard;

extern crate time;
extern crate url;

#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;

pub use compositor_task::{CompositorEventListener, CompositorProxy, CompositorTask};
pub use constellation::Constellation;

pub mod compositor_task;

mod surface_map;
mod compositor_layer;
mod compositor;
mod headless;
mod scrolling;

pub mod pipeline;
pub mod constellation;
pub mod windowing;

<|endoftext|>


<commit_before>use core;

use cortex_m;
use stm32f0x2::{USART1 as UART1, GPIOA, NVIC, RCC};
use stm32f0x2::interrupt::*;

const FREQUENCY: u32 = 48000000;

static mut DATA_UART1: u16 = 0;

pub enum NBits {
    _8bits,
    _9bits,
}

pub enum StopBits {
    _0b5,
    _1b,
    _1b5,
    _2b,
}

pub enum Parity {
    /// No Parity
    None,
    /// Even Parity
    Even,
    /// Odd Parity
    Odd,
}

interrupt!(USART1, receive);

pub fn setup<F>(baudrate: u32, nbits: NBits, nbstopbits: StopBits, parity: Parity, mut f: F)
where F: FnMut(u8)
 {
    cortex_m::interrupt::free(|cs| {
        let rcc = RCC.borrow(cs);
        let gpioa = GPIOA.borrow(cs);
        let uart1 = UART1.borrow(cs);
        let nvic = NVIC.borrow(cs);

        // Enable GPIOA Clock
        rcc.ahbenr.write(|w| w.iopaen().enabled());
        // Enable USART1 Clock
        rcc.apb2enr.write(|w| w.usart1en().enabled());

        // Configure PA9/PA10 Alternate Function 1 -> USART1
        gpioa.ospeedr.write(|w| {
            w.ospeedr9().high_speed().ospeedr10().high_speed()
        });
        gpioa.pupdr.write(
            |w| w.pupdr9().pull_up().pupdr10().pull_up(),
        );
        gpioa.afrh.write(|w| w.afrh9().af1().afrh10().af1());
        gpioa.moder.write(
            |w| w.moder9().alternate().moder10().alternate(),
        );
        gpioa.otyper.write(
            |w| w.ot9().push_pull().ot10().push_pull(),
        );

        // Configure UART : Word length
        match nbits {
            NBits::_8bits => {
                uart1.cr1.modify(|_, w| w.m()._8bits());
            }
            NBits::_9bits => {
                uart1.cr1.modify(|_, w| w.m()._9bits());
            }
        }
        // Configure UART : Parity
        match parity {
            Parity::None => {
                uart1.cr1.modify(|_, w| w.pce().disabled());
            }
            Parity::Even => {
                uart1.cr1.modify(|_, w| w.pce().enabled());
                uart1.cr1.modify(|_, w| w.ps().even());
            }
            Parity::Odd => {
                uart1.cr1.modify(|_, w| w.pce().enabled());
                uart1.cr1.modify(|_, w| w.ps().odd());
            }
        }
        // Configure UART : Transfert Direction - Oversampling - RX Interrupt
        uart1.cr1.modify(|_, w| {
            w.te()
                .enabled()
                .re()
                .enabled()
                .over8()
                .over8()
                .rxneie()
                .enabled()
        });
        // Configure UART : 1 stop bit
        match nbstopbits {
            StopBits::_0b5 => {
                uart1.cr2.modify(|_, w| w.stop().half_stop());
            }
            StopBits::_1b => {
                uart1.cr2.modify(|_, w| w.stop()._1stop());
            }
            StopBits::_1b5 => {
                uart1.cr2.modify(|_, w| w.stop()._1half_stop());
            }
            StopBits::_2b => {
                uart1.cr2.modify(|_, w| w.stop()._2stop());
            }
        }

        // Configure UART : disable hardware flow control - Overrun interrupt
        uart1.cr3.write(|w| {
            w.rtse()
                .disabled()
                .ctse()
                .disabled()
                .ctsie()
                .disabled()
                .ovrdis()
                .disabled()
        });
        // Configure UART : baudrate
        uart1.brr.write(|w| {
            w.div_fraction().bits(
                (FREQUENCY / (baudrate / 2)) as u8 & 0x0F,
            )
        });
        uart1.brr.write(|w| {
            w.div_mantissa().bits(
                ((FREQUENCY / (baudrate / 2)) >> 4) as u16,
            )
        });
        // Configure UART : Asynchronous mode
        uart1.cr2.modify(
            |_, w| w.linen().disabled().clken().disabled(),
        );
        // UART1 enabled
        uart1.cr1.modify(|_, w| w.ue().enabled());
        nvic.enable(Interrupt::USART1);
        nvic.clear_pending(Interrupt::USART1);
    });
    unsafe {
        RECV_CB = Some(extend_lifetime(&mut f));
    }
}

pub fn send(byte: u8) {
    cortex_m::interrupt::free(|cs| {
        let uart1 = UART1.borrow(cs);
        uart1.tdr.write(|w| w.tdr().bits(byte as u16));
    })
}

pub fn transmit_complete() -> bool {
    cortex_m::interrupt::free(|cs| {
        let uart1 = UART1.borrow(cs);
        if uart1.isr.read().tc().bit_is_set() {
            uart1.icr.write(|w| w.tccf().clear_bit());
            true
        } else {
            false
        }
    })
}

static mut RECV_CB: Option<&'static mut FnMut(u8)> = None;

fn receive_callback() {
    cortex_m::interrupt::free(|cs| {
        let uart = UART1.borrow(cs);
        unsafe {
            DATA_UART1 = uart.rdr.read().rdr().bits();
        }
    });
    unsafe {
        if let Some(ref mut cb) = RECV_CB {
            cb(DATA_UART1 as u8);
        }
    }
}

pub fn receive() {
    cortex_m::interrupt::free(|cs| {
        let uart = UART1.borrow(cs);
        if uart.isr.read().rxne().bit_is_set() {
            receive_callback();
        }
    })
}

unsafe fn extend_lifetime<'a>(f: &'a mut FnMut(u8)) -> &'static mut FnMut(u8) {
    core::mem::transmute::<&'a mut FnMut(u8), &'static mut FnMut(u8)>(f)
}
<commit_msg>Rustfmt.<commit_after>use core;

use cortex_m;
use stm32f0x2::{USART1 as UART1, GPIOA, NVIC, RCC};
use stm32f0x2::interrupt::*;

const FREQUENCY: u32 = 48000000;

static mut DATA_UART1: u16 = 0;

pub enum NBits {
    _8bits,
    _9bits,
}

pub enum StopBits {
    _0b5,
    _1b,
    _1b5,
    _2b,
}

pub enum Parity {
    /// No Parity
    None,
    /// Even Parity
    Even,
    /// Odd Parity
    Odd,
}

interrupt!(USART1, receive);

pub fn setup<F>(baudrate: u32, nbits: NBits, nbstopbits: StopBits, parity: Parity, mut f: F)
where
    F: FnMut(u8),
{
    cortex_m::interrupt::free(|cs| {
        let rcc = RCC.borrow(cs);
        let gpioa = GPIOA.borrow(cs);
        let uart1 = UART1.borrow(cs);
        let nvic = NVIC.borrow(cs);

        // Enable GPIOA Clock
        rcc.ahbenr.write(|w| w.iopaen().enabled());
        // Enable USART1 Clock
        rcc.apb2enr.write(|w| w.usart1en().enabled());

        // Configure PA9/PA10 Alternate Function 1 -> USART1
        gpioa.ospeedr.write(|w| {
            w.ospeedr9().high_speed().ospeedr10().high_speed()
        });
        gpioa.pupdr.write(
            |w| w.pupdr9().pull_up().pupdr10().pull_up(),
        );
        gpioa.afrh.write(|w| w.afrh9().af1().afrh10().af1());
        gpioa.moder.write(
            |w| w.moder9().alternate().moder10().alternate(),
        );
        gpioa.otyper.write(
            |w| w.ot9().push_pull().ot10().push_pull(),
        );

        // Configure UART : Word length
        match nbits {
            NBits::_8bits => {
                uart1.cr1.modify(|_, w| w.m()._8bits());
            }
            NBits::_9bits => {
                uart1.cr1.modify(|_, w| w.m()._9bits());
            }
        }
        // Configure UART : Parity
        match parity {
            Parity::None => {
                uart1.cr1.modify(|_, w| w.pce().disabled());
            }
            Parity::Even => {
                uart1.cr1.modify(|_, w| w.pce().enabled());
                uart1.cr1.modify(|_, w| w.ps().even());
            }
            Parity::Odd => {
                uart1.cr1.modify(|_, w| w.pce().enabled());
                uart1.cr1.modify(|_, w| w.ps().odd());
            }
        }
        // Configure UART : Transfert Direction - Oversampling - RX Interrupt
        uart1.cr1.modify(|_, w| {
            w.te()
                .enabled()
                .re()
                .enabled()
                .over8()
                .over8()
                .rxneie()
                .enabled()
        });
        // Configure UART : 1 stop bit
        match nbstopbits {
            StopBits::_0b5 => {
                uart1.cr2.modify(|_, w| w.stop().half_stop());
            }
            StopBits::_1b => {
                uart1.cr2.modify(|_, w| w.stop()._1stop());
            }
            StopBits::_1b5 => {
                uart1.cr2.modify(|_, w| w.stop()._1half_stop());
            }
            StopBits::_2b => {
                uart1.cr2.modify(|_, w| w.stop()._2stop());
            }
        }

        // Configure UART : disable hardware flow control - Overrun interrupt
        uart1.cr3.write(|w| {
            w.rtse()
                .disabled()
                .ctse()
                .disabled()
                .ctsie()
                .disabled()
                .ovrdis()
                .disabled()
        });
        // Configure UART : baudrate
        uart1.brr.write(|w| {
            w.div_fraction().bits(
                (FREQUENCY / (baudrate / 2)) as u8 & 0x0F,
            )
        });
        uart1.brr.write(|w| {
            w.div_mantissa().bits(
                ((FREQUENCY / (baudrate / 2)) >> 4) as u16,
            )
        });
        // Configure UART : Asynchronous mode
        uart1.cr2.modify(
            |_, w| w.linen().disabled().clken().disabled(),
        );
        // UART1 enabled
        uart1.cr1.modify(|_, w| w.ue().enabled());
        nvic.enable(Interrupt::USART1);
        nvic.clear_pending(Interrupt::USART1);
    });
    unsafe {
        RECV_CB = Some(extend_lifetime(&mut f));
    }
}

pub fn send(byte: u8) {
    cortex_m::interrupt::free(|cs| {
        let uart1 = UART1.borrow(cs);
        uart1.tdr.write(|w| w.tdr().bits(byte as u16));
    })
}

pub fn transmit_complete() -> bool {
    cortex_m::interrupt::free(|cs| {
        let uart1 = UART1.borrow(cs);
        if uart1.isr.read().tc().bit_is_set() {
            uart1.icr.write(|w| w.tccf().clear_bit());
            true
        } else {
            false
        }
    })
}

static mut RECV_CB: Option<&'static mut FnMut(u8)> = None;

fn receive_callback() {
    cortex_m::interrupt::free(|cs| {
        let uart = UART1.borrow(cs);
        unsafe {
            DATA_UART1 = uart.rdr.read().rdr().bits();
        }
    });
    unsafe {
        if let Some(ref mut cb) = RECV_CB {
            cb(DATA_UART1 as u8);
        }
    }
}

pub fn receive() {
    cortex_m::interrupt::free(|cs| {
        let uart = UART1.borrow(cs);
        if uart.isr.read().rxne().bit_is_set() {
            receive_callback();
        }
    })
}

unsafe fn extend_lifetime<'a>(f: &'a mut FnMut(u8)) -> &'static mut FnMut(u8) {
    core::mem::transmute::<&'a mut FnMut(u8), &'static mut FnMut(u8)>(f)
}
<|endoftext|>


<commit_before><commit_msg>done, I really need find something to write<commit_after>fn remove_element<T>(a: Vec<T>, k: T) -> Vec<T>
where
    T: PartialEq + Clone,
{
    let mut result = vec![];
    for i in a {
        if i != k {
            result.push(i);
        }
    }
    result
}

fn main() {
    let test_case = vec![1, 2, 3, 4, 5, 6, 7];
    println!("{:?}", remove_element(test_case, 4));
}
<|endoftext|>


<commit_before><commit_msg>x86_64: remove acpi=noirq kernel option<commit_after><|endoftext|>


<commit_before>#![allow(non_snake_case, non_upper_case_globals)]
extern crate time;
use time::precise_time_s;

///////////////////////////////////////////////////////////////////////////////
// 1. Calibration
///////////////////////////////////////////////////////////////////////////////
const aalpha:f64 = 0.33333333333;  // Elasticity of output w.r.t. capital
const bbeta:f64 = 0.95;           // Discount factor

// Productivity values
const vProductivity:[f64; 5] = [0.9792, 0.9896, 1.0000, 1.0106, 1.0212];

// Transition matrix
const mTransition:[[f64; 5]; 5] = [[0.9727, 0.0273, 0.0000, 0.0000, 0.0000],
                                   [0.0041, 0.9806, 0.0153, 0.0000, 0.0000],
                                   [0.0000, 0.0082, 0.9837, 0.0082, 0.0000],
                                   [0.0000, 0.0000, 0.0153, 0.9806, 0.0041],
                                   [0.0000, 0.0000, 0.0000, 0.0273, 0.9727]];

// Dimensions to generate the grid of capital
const nGridCapital: usize = 17820;
const nGridProductivity: usize = 5;

fn main() {

    let cpu0 = precise_time_s();

  /////////////////////////////////////////////////////////////////////////////
  // 2. Steady State
  /////////////////////////////////////////////////////////////////////////////

    let capitalSteadyState: f64 = (aalpha * bbeta).powf(1_f64 / (1_f64 - aalpha));
    let outputSteadyState: f64 = capitalSteadyState.powf(aalpha);
    let consumptionSteadyState: f64 = outputSteadyState - capitalSteadyState;

    println!("\
    Output = {}, Capital = {}, Consumption = {}",
    outputSteadyState, capitalSteadyState, consumptionSteadyState);

    let vGridCapital = (0..nGridCapital)
                           .map(|nCapital| 0.5 * capitalSteadyState + 0.00001 * (nCapital as f64))
                           .collect::<Vec<f64>>();

  // 3. Required matrices and vectors
  // One could use: vec![vec![0_f64; nGridProductivity]; nGridCapital];
  // but for some reasons this is faster.

    #[inline]
    fn row() -> Vec<f64> {
        (0..nGridProductivity).map(|_| 0_f64).collect::<Vec<f64>>()
    }

    let mut mValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut mValueFunctionNew = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut mPolicyFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut expectedValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();

  // 4. We pre-build output for each point in the grid
    let mOutput = (0..nGridCapital)
                      .map(|nCapital| {
                          (0..nGridProductivity).map(|nProductivity|
        vProductivity[nProductivity]*vGridCapital[nCapital].powf(aalpha)
      ).collect::<Vec<f64>>()
                      })
                      .collect::<Vec<Vec<f64>>>();

  // 5. Main iteration
  // TODO: one could implement a macro for the multiple declarations
    let mut maxDifference = 10_f64;
    let mut diff: f64;
    let mut diffHighSoFar: f64;
    let tolerance = 0.0000001_f64; // compiler warn: variable does not need to be mutable
    let mut valueHighSoFar: f64;
    let mut valueProvisional: f64;
    let mut consumption: f64;
    let mut capitalChoice: f64;

    let mut iteration = 0;

    while maxDifference > tolerance {

        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                expectedValueFunction[nCapital][nProductivity] = 0.0;
                for nProductivityNextPeriod in 0..nGridProductivity {
                    expectedValueFunction[nCapital][nProductivity] +=
                        mTransition[nProductivity][nProductivityNextPeriod] *
                        mValueFunction[nCapital][nProductivityNextPeriod];
                }
            }
        }

        for nProductivity in 0..nGridProductivity {

        // We start from previous choice (monotonicity of policy function)
            let mut gridCapitalNextPeriod = 0;

            for nCapital in 0..nGridCapital {

                valueHighSoFar = -100000.0;
            //capitalChoice  = vGridCapital[0]; // compiler warn: is never read

                for nCapitalNextPeriod in gridCapitalNextPeriod..nGridCapital {

                    consumption = mOutput[nCapital][nProductivity] -
                                  vGridCapital[nCapitalNextPeriod];
                    valueProvisional = (1_f64 - bbeta) * (consumption.ln()) +
                                       bbeta *
                                       expectedValueFunction[nCapitalNextPeriod][nProductivity];

                    if valueProvisional > valueHighSoFar {
                        valueHighSoFar = valueProvisional;
                        capitalChoice = vGridCapital[nCapitalNextPeriod];
                        gridCapitalNextPeriod = nCapitalNextPeriod;
                    } else {
                        break; // We break when we have achieved the max
                    }

                    mValueFunctionNew[nCapital][nProductivity] = valueHighSoFar;
                    mPolicyFunction[nCapital][nProductivity] = capitalChoice;
                }

            }

        }

        diffHighSoFar = -100000.0;
        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                diff = (mValueFunction[nCapital][nProductivity] -
                        mValueFunctionNew[nCapital][nProductivity])
                           .abs();
                if diff > diffHighSoFar {
                    diffHighSoFar = diff;
                }
                mValueFunction[nCapital][nProductivity] =
                    mValueFunctionNew[nCapital][nProductivity];
            }
        }
        maxDifference = diffHighSoFar;

        iteration += 1;
        if iteration % 10 == 0 || iteration == 1 {
            println!("Iteration = {}, Sup Diff = {}", iteration, maxDifference);
        }
    }

    println!("Iteration = {}, Sup Diff = {}\n", iteration, maxDifference);
    println!("My check = {}\n", mPolicyFunction[999][2]);

    let cpu1 = precise_time_s();

    println!("Elapsed time is   = {}", cpu1  - cpu0);
}
<commit_msg>Swap mValueFunction and mValueFunctionNew only at the end, rather than per element<commit_after>#![allow(non_snake_case, non_upper_case_globals)]
extern crate time;

use time::precise_time_s;
use std::mem;

///////////////////////////////////////////////////////////////////////////////
// 1. Calibration
///////////////////////////////////////////////////////////////////////////////
const aalpha:f64 = 0.33333333333;  // Elasticity of output w.r.t. capital
const bbeta:f64 = 0.95;           // Discount factor

// Productivity values
const vProductivity:[f64; 5] = [0.9792, 0.9896, 1.0000, 1.0106, 1.0212];

// Transition matrix
const mTransition:[[f64; 5]; 5] = [[0.9727, 0.0273, 0.0000, 0.0000, 0.0000],
                                   [0.0041, 0.9806, 0.0153, 0.0000, 0.0000],
                                   [0.0000, 0.0082, 0.9837, 0.0082, 0.0000],
                                   [0.0000, 0.0000, 0.0153, 0.9806, 0.0041],
                                   [0.0000, 0.0000, 0.0000, 0.0273, 0.9727]];

// Dimensions to generate the grid of capital
const nGridCapital: usize = 17820;
const nGridProductivity: usize = 5;

fn main() {

    let cpu0 = precise_time_s();

  /////////////////////////////////////////////////////////////////////////////
  // 2. Steady State
  /////////////////////////////////////////////////////////////////////////////

    let capitalSteadyState: f64 = (aalpha * bbeta).powf(1_f64 / (1_f64 - aalpha));
    let outputSteadyState: f64 = capitalSteadyState.powf(aalpha);
    let consumptionSteadyState: f64 = outputSteadyState - capitalSteadyState;

    println!("\
    Output = {}, Capital = {}, Consumption = {}",
    outputSteadyState, capitalSteadyState, consumptionSteadyState);

    let vGridCapital = (0..nGridCapital)
                           .map(|nCapital| 0.5 * capitalSteadyState + 0.00001 * (nCapital as f64))
                           .collect::<Vec<f64>>();

  // 3. Required matrices and vectors
  // One could use: vec![vec![0_f64; nGridProductivity]; nGridCapital];
  // but for some reasons this is faster.

    #[inline]
    fn row() -> Vec<f64> {
        (0..nGridProductivity).map(|_| 0_f64).collect::<Vec<f64>>()
    }

    let mut mValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut mValueFunctionNew = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut mPolicyFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut expectedValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();

  // 4. We pre-build output for each point in the grid
    let mOutput = (0..nGridCapital)
                      .map(|nCapital| {
                          (0..nGridProductivity).map(|nProductivity|
        vProductivity[nProductivity]*vGridCapital[nCapital].powf(aalpha)
      ).collect::<Vec<f64>>()
                      })
                      .collect::<Vec<Vec<f64>>>();

  // 5. Main iteration
  // TODO: one could implement a macro for the multiple declarations
    let mut maxDifference = 10_f64;
    let mut diff: f64;
    let tolerance = 0.0000001_f64; // compiler warn: variable does not need to be mutable
    let mut valueHighSoFar: f64;
    let mut valueProvisional: f64;
    let mut consumption: f64;
    let mut capitalChoice: f64;

    let mut iteration = 0;

    while maxDifference > tolerance {

        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                expectedValueFunction[nCapital][nProductivity] = 0.0;
                for nProductivityNextPeriod in 0..nGridProductivity {
                    expectedValueFunction[nCapital][nProductivity] +=
                        mTransition[nProductivity][nProductivityNextPeriod] *
                        mValueFunction[nCapital][nProductivityNextPeriod];
                }
            }
        }

        for nProductivity in 0..nGridProductivity {

        // We start from previous choice (monotonicity of policy function)
            let mut gridCapitalNextPeriod = 0;

            for nCapital in 0..nGridCapital {

                valueHighSoFar = -100000.0;
            //capitalChoice  = vGridCapital[0]; // compiler warn: is never read

                for nCapitalNextPeriod in gridCapitalNextPeriod..nGridCapital {

                    consumption = mOutput[nCapital][nProductivity] -
                                  vGridCapital[nCapitalNextPeriod];
                    valueProvisional = (1_f64 - bbeta) * (consumption.ln()) +
                                       bbeta *
                                       expectedValueFunction[nCapitalNextPeriod][nProductivity];

                    if valueProvisional > valueHighSoFar {
                        valueHighSoFar = valueProvisional;
                        capitalChoice = vGridCapital[nCapitalNextPeriod];
                        gridCapitalNextPeriod = nCapitalNextPeriod;
                    } else {
                        break; // We break when we have achieved the max
                    }

                    mValueFunctionNew[nCapital][nProductivity] = valueHighSoFar;
                    mPolicyFunction[nCapital][nProductivity] = capitalChoice;
                }

            }

        }

        let mut diffHighSoFar = -100000.0;
        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                diff = (mValueFunction[nCapital][nProductivity] -
                        mValueFunctionNew[nCapital][nProductivity])
                           .abs();
                if diff > diffHighSoFar {
                    diffHighSoFar = diff;
                }
            }
        }

        // swap buffers after the loop
        mem::swap(&mut mValueFunction, &mut mValueFunctionNew);

        maxDifference = diffHighSoFar;

        iteration += 1;
        if iteration % 10 == 0 || iteration == 1 {
            println!("Iteration = {}, Sup Diff = {}", iteration, maxDifference);
        }
    }

    println!("Iteration = {}, Sup Diff = {}\n", iteration, maxDifference);
    println!("My check = {}\n", mPolicyFunction[999][2]);

    let cpu1 = precise_time_s();

    println!("Elapsed time is   = {}", cpu1  - cpu0);
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#[macro_use]
extern crate pest;

use pest::{Error, Parser, ParseResult, ParserState, state};
use pest::iterators::{Pair, Pairs};
use pest::Span;
use std::collections::HashMap;

#[allow(dead_code, non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    json,
    object,
    pair,
    array,
    value,
    string,
    escape,
    unicode,
    hex,
    number,
    int,
    exp,
    bool,
    null,
}

struct JsonParser;

impl Parser<Rule> for JsonParser {
    fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
        fn json(state: ParserState<Rule>) -> ParseResult<Rule> {
            value(state)
        }

        fn object(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::object, |s| {
                s.sequence(move |s| {
                    s.match_string("{")
                        .and_then(|s| skip(s))
                        .and_then(|s| pair(s))
                        .and_then(|s| skip(s))
                        .and_then(|s| {
                            s.repeat(|s| {
                                s.sequence(|s| {
                                    s.match_string(",")
                                        .and_then(|s| skip(s))
                                        .and_then(|s| pair(s))
                                        .and_then(|s| skip(s))
                                })
                            })
                        })
                        .and_then(|s| s.match_string("}"))
                })
                    .or_else(|s| {
                        s.sequence(|s| {
                            s.match_string("{")
                                .and_then(|s| skip(s))
                                .and_then(|s| s.match_string("}"))
                        })
                    })
            })
        }

        fn pair(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::pair, |s| {
                s.sequence(|s| {
                    string(s)
                        .and_then(|s| skip(s))
                        .and_then(|s| s.match_string(":"))
                        .and_then(|s| skip(s))
                        .and_then(|s| value(s))
                })
            })
        }

        fn array(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::array, |s| {
                s.sequence(|s| {
                    s.match_string("[")
                        .and_then(|s| skip(s))
                        .and_then(|s| value(s))
                        .and_then(|s| skip(s))
                        .and_then(|s| {
                            s.repeat(|s| {
                                s.sequence(|s| {
                                    s.match_string(",")
                                        .and_then(|s| skip(s))
                                        .and_then(|s| value(s))
                                        .and_then(|s| skip(s))
                                })
                            })
                        })
                        .and_then(|s| s.match_string("]"))
                })
                    .or_else(|s| {
                        s.sequence(|s| {
                            s.match_string("[")
                                .and_then(|s| skip(s))
                                .and_then(|s| s.match_string("]"))
                        })
                    })
            })
        }

        fn value(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::value, |s| {
                string(s)
                    .or_else(|s| number(s))
                    .or_else(|s| object(s))
                    .or_else(|s| array(s))
                    .or_else(|s| bool(s))
                    .or_else(|s| null(s))
            })
        }

        fn string(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::string, |s| {
                s.match_string("\"")
                    .and_then(|s| {
                        s.repeat(|s| {
                            escape(s).or_else(|s| {
                                s.sequence(|s| {
                                    s
                                        .lookahead(false, |s| {
                                            s.match_string("\"")
                                                .or_else(|s| s.match_string("\\"))
                                        })
                                        .and_then(|s| s.skip(1))
                                })
                            })
                        })
                    })
                    .and_then(|pos| pos.match_string("\""))
            })
        }

        fn escape(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.sequence(|s| {
                s.match_string("\\").and_then(|s| {
                    s.match_string("\"")
                        .or_else(|s| s.match_string("\\"))
                        .or_else(|s| s.match_string("/"))
                        .or_else(|s| s.match_string("b"))
                        .or_else(|s| s.match_string("f"))
                        .or_else(|s| s.match_string("n"))
                        .or_else(|s| s.match_string("r"))
                        .or_else(|s| s.match_string("t"))
                        .or_else(|s| unicode(s))
                })
            })
        }

        fn unicode(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.sequence(|s| {
                s.match_string("u")
                    .and_then(|s| hex(s))
                    .and_then(|s| hex(s))
                    .and_then(|s| hex(s))
            })
        }

        fn hex(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.match_range('0'..'9')
                .or_else(|s| s.match_range('a'..'f'))
                .or_else(|s| s.match_range('A'..'F'))
        }

        fn number(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::number, |s| {
                s.sequence(|s| {
                    s.optional(|s| s.match_string("-"))
                        .and_then(|s| int(s))
                        .and_then(|s| {
                            s.optional(|s| {
                                s.sequence(|s| {
                                    s.match_string(".")
                                        .and_then(|s| s.match_range('0'..'9'))
                                        .and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
                                        .and_then(|s| s.optional(|s| exp(s)))
                                        .or_else(|s| exp(s))
                                })
                            })
                        })
                })
            })
        }

        fn int(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.match_string("0").or_else(|s| {
                s.sequence(|s| {
                    s.match_range('1'..'9')
                        .and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
                })
            })
        }

        fn exp(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.sequence(|s| {
                s.match_string("E")
                    .or_else(|s| s.match_string("e"))
                    .and_then(|s| {
                        s.optional(|s| {
                            s.match_string("+").or_else(|s| s.match_string("-"))
                        })
                    })
                    .and_then(|s| int(s))
            })
        }

        fn bool(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::bool, |s| {
                s.match_string("true")
                    .or_else(|s| s.match_string("false"))
            })
        }

        fn null(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::null, |s| s.match_string("null"))
        }

        fn skip(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.repeat(|s| {
                s.match_string(" ")
                    .or_else(|s| s.match_string("\t"))
                    .or_else(|s| s.match_string("\r"))
                    .or_else(|s| s.match_string("\n"))
            })
        }

        state(input, |state| match rule {
            Rule::json => json(state),
            Rule::object => object(state),
            Rule::pair => pair(state),
            Rule::array => array(state),
            Rule::value => value(state),
            Rule::string => string(state),
            Rule::escape => escape(state),
            Rule::unicode => unicode(state),
            Rule::hex => hex(state),
            Rule::number => number(state),
            Rule::int => int(state),
            Rule::exp => exp(state),
            Rule::bool => bool(state),
            Rule::null => null(state)
        })
    }
}

#[derive(Debug, PartialEq)]
enum Json<'i> {
    Null,
    Bool(bool),
    Number(f64),
    String(Span<'i>),
    Array(Vec<Json<'i>>),
    Object(HashMap<Span<'i>, Json<'i>>),
}

fn consume(pair: Pair<Rule>) -> Json {
    fn value(pair: Pair<Rule>) -> Json {
        let pair = pair.into_inner().next().unwrap();

        match pair.as_rule() {
            Rule::null => Json::Null,
            Rule::bool => match pair.as_str() {
                "false" => Json::Bool(false),
                "true" => Json::Bool(true),
                _ => unreachable!()
            },
            Rule::number => Json::Number(pair.as_str().parse().unwrap()),
            Rule::string => Json::String(pair.into_span()),
            Rule::array => Json::Array(pair.into_inner().map(value).collect()),
            Rule::object => {
                let pairs = pair.into_inner().map(|pos| {
                    let mut pair = pos.into_inner();

                    let key = pair.next().unwrap().into_span();
                    let value = value(pair.next().unwrap());

                    (key, value)
                });

                Json::Object(pairs.collect())
            }
            _ => unreachable!()
        }
    }

    value(pair)
}

#[test]
fn null() {
    parses_to! {
        parser: JsonParser,
        input: "null",
        rule: Rule::null,
        tokens: [
            null(0, 4)
        ]
    };
}

#[test]
fn bool() {
    parses_to! {
        parser: JsonParser,
        input: "false",
        rule: Rule::bool,
        tokens: [
            bool(0, 5)
        ]
    };
}

#[test]
fn number_zero() {
    parses_to! {
        parser: JsonParser,
        input: "0",
        rule: Rule::number,
        tokens: [
            number(0, 1)
        ]
    };
}

#[test]
fn float() {
    parses_to! {
        parser: JsonParser,
        input: "100.001",
        rule: Rule::number,
        tokens: [
            number(0, 7)
        ]
    };
}

#[test]
fn float_with_exp() {
    parses_to! {
        parser: JsonParser,
        input: "100.001E+100",
        rule: Rule::number,
        tokens: [
            number(0, 12)
        ]
    };
}

#[test]
fn number_minus_zero() {
    parses_to! {
        parser: JsonParser,
        input: "-0",
        rule: Rule::number,
        tokens: [
            number(0, 2)
        ]
    };
}

#[test]
fn string_with_escapes() {
    parses_to! {
        parser: JsonParser,
        input: "\"asd\\u0000\\\"\"",
        rule: Rule::string,
        tokens: [
            string(0, 13)
        ]
    };
}

#[test]
fn array_empty() {
    parses_to! {
        parser: JsonParser,
        input: "[ ]",
        rule: Rule::array,
        tokens: [
            array(0, 3)
        ]
    };
}

#[test]
fn array() {
    parses_to! {
        parser: JsonParser,
        input: "[0.0e1, false, null, \"a\", [0]]",
        rule: Rule::array,
        tokens: [
            array(0, 30, [
                value(1,  6, [number(1, 6)]),
                value(8, 13, [bool(8, 13)]),
                value(15, 19, [null(15, 19)]),
                value(21, 24, [string(21, 24)]),
                value(26, 29, [
                    array(26, 29, [
                        value(27, 28, [number(27, 28)])
                    ])
                ])
            ])
        ]
    };
}

#[test]
fn object() {
    parses_to! {
        parser: JsonParser,
        input: "{\"a\" : 3, \"b\" : [{}, 3]}",
        rule: Rule::object,
        tokens: [
            object(0, 24, [
                pair(1, 8, [
                    string(1, 4),
                    value(7, 8, [number(7, 8)])
                ]),
                pair(10, 23, [
                    string(10, 13),
                    value(16, 23, [
                        array(16, 23, [
                            value(17, 19, [object(17, 19)]),
                            value(21, 22, [number(21, 22)])
                        ])
                    ])
                ])
            ])
        ]
    };
}

//#[test]
//fn ast() {
//    let input = "{\"a\": [null, true, 3.4]}";
//    let start = Position::from_start(input).skip(1).unwrap();
//    let end = start.clone().skip(3).unwrap();
//    let span = start.span(&end);
//
//    let mut pairs = HashMap::new();
//    pairs.insert(
//        span,
//        Json::Array(vec![Json::Null, Json::Bool(true), Json::Number(3.4)])
//    );
//
//    let ast = consume(
//        JsonParser::parse(Rule::json, input)
//            .unwrap()
//            .next()
//            .unwrap()
//    );
//
//    assert_eq!(ast, Json::Object(pairs));
//}
<commit_msg>bring back the ast test<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#[macro_use]
extern crate pest;

use pest::{Error, Parser, ParseResult, ParserState, state};
use pest::iterators::{Pair, Pairs};
use pest::{Position, Span};
use std::collections::HashMap;

#[allow(dead_code, non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    json,
    object,
    pair,
    array,
    value,
    string,
    escape,
    unicode,
    hex,
    number,
    int,
    exp,
    bool,
    null,
}

struct JsonParser;

impl Parser<Rule> for JsonParser {
    fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
        fn json(state: ParserState<Rule>) -> ParseResult<Rule> {
            value(state)
        }

        fn object(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::object, |s| {
                s.sequence(|s| {
                    s.match_string("{")
                        .and_then(|s| skip(s))
                        .and_then(|s| pair(s))
                        .and_then(|s| skip(s))
                        .and_then(|s| {
                            s.repeat(|s| {
                                s.sequence(|s| {
                                    s.match_string(",")
                                        .and_then(|s| skip(s))
                                        .and_then(|s| pair(s))
                                        .and_then(|s| skip(s))
                                })
                            })
                        })
                        .and_then(|s| s.match_string("}"))
                })
                    .or_else(|s| {
                        s.sequence(|s| {
                            s.match_string("{")
                                .and_then(|s| skip(s))
                                .and_then(|s| s.match_string("}"))
                        })
                    })
            })
        }

        fn pair(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::pair, |s| {
                s.sequence(|s| {
                    string(s)
                        .and_then(|s| skip(s))
                        .and_then(|s| s.match_string(":"))
                        .and_then(|s| skip(s))
                        .and_then(|s| value(s))
                })
            })
        }

        fn array(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::array, |s| {
                s.sequence(|s| {
                    s.match_string("[")
                        .and_then(|s| skip(s))
                        .and_then(|s| value(s))
                        .and_then(|s| skip(s))
                        .and_then(|s| {
                            s.repeat(|s| {
                                s.sequence(|s| {
                                    s.match_string(",")
                                        .and_then(|s| skip(s))
                                        .and_then(|s| value(s))
                                        .and_then(|s| skip(s))
                                })
                            })
                        })
                        .and_then(|s| s.match_string("]"))
                })
                    .or_else(|s| {
                        s.sequence(|s| {
                            s.match_string("[")
                                .and_then(|s| skip(s))
                                .and_then(|s| s.match_string("]"))
                        })
                    })
            })
        }

        fn value(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::value, |s| {
                string(s)
                    .or_else(|s| number(s))
                    .or_else(|s| object(s))
                    .or_else(|s| array(s))
                    .or_else(|s| bool(s))
                    .or_else(|s| null(s))
            })
        }

        fn string(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::string, |s| {
                s.match_string("\"")
                    .and_then(|s| {
                        s.repeat(|s| {
                            escape(s).or_else(|s| {
                                s.sequence(|s| {
                                    s
                                        .lookahead(false, |s| {
                                            s.match_string("\"")
                                                .or_else(|s| s.match_string("\\"))
                                        })
                                        .and_then(|s| s.skip(1))
                                })
                            })
                        })
                    })
                    .and_then(|pos| pos.match_string("\""))
            })
        }

        fn escape(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.sequence(|s| {
                s.match_string("\\").and_then(|s| {
                    s.match_string("\"")
                        .or_else(|s| s.match_string("\\"))
                        .or_else(|s| s.match_string("/"))
                        .or_else(|s| s.match_string("b"))
                        .or_else(|s| s.match_string("f"))
                        .or_else(|s| s.match_string("n"))
                        .or_else(|s| s.match_string("r"))
                        .or_else(|s| s.match_string("t"))
                        .or_else(|s| unicode(s))
                })
            })
        }

        fn unicode(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.sequence(|s| {
                s.match_string("u")
                    .and_then(|s| hex(s))
                    .and_then(|s| hex(s))
                    .and_then(|s| hex(s))
            })
        }

        fn hex(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.match_range('0'..'9')
                .or_else(|s| s.match_range('a'..'f'))
                .or_else(|s| s.match_range('A'..'F'))
        }

        fn number(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::number, |s| {
                s.sequence(|s| {
                    s.optional(|s| s.match_string("-"))
                        .and_then(|s| int(s))
                        .and_then(|s| {
                            s.optional(|s| {
                                s.sequence(|s| {
                                    s.match_string(".")
                                        .and_then(|s| s.match_range('0'..'9'))
                                        .and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
                                        .and_then(|s| s.optional(|s| exp(s)))
                                        .or_else(|s| exp(s))
                                })
                            })
                        })
                })
            })
        }

        fn int(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.match_string("0").or_else(|s| {
                s.sequence(|s| {
                    s.match_range('1'..'9')
                        .and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
                })
            })
        }

        fn exp(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.sequence(|s| {
                s.match_string("E")
                    .or_else(|s| s.match_string("e"))
                    .and_then(|s| {
                        s.optional(|s| {
                            s.match_string("+").or_else(|s| s.match_string("-"))
                        })
                    })
                    .and_then(|s| int(s))
            })
        }

        fn bool(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::bool, |s| {
                s.match_string("true")
                    .or_else(|s| s.match_string("false"))
            })
        }

        fn null(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.rule(Rule::null, |s| s.match_string("null"))
        }

        fn skip(state: ParserState<Rule>) -> ParseResult<Rule> {
            state.repeat(|s| {
                s.match_string(" ")
                    .or_else(|s| s.match_string("\t"))
                    .or_else(|s| s.match_string("\r"))
                    .or_else(|s| s.match_string("\n"))
            })
        }

        state(input, |state| match rule {
            Rule::json => json(state),
            Rule::object => object(state),
            Rule::pair => pair(state),
            Rule::array => array(state),
            Rule::value => value(state),
            Rule::string => string(state),
            Rule::escape => escape(state),
            Rule::unicode => unicode(state),
            Rule::hex => hex(state),
            Rule::number => number(state),
            Rule::int => int(state),
            Rule::exp => exp(state),
            Rule::bool => bool(state),
            Rule::null => null(state)
        })
    }
}

#[derive(Debug, PartialEq)]
enum Json<'i> {
    Null,
    Bool(bool),
    Number(f64),
    String(Span<'i>),
    Array(Vec<Json<'i>>),
    Object(HashMap<Span<'i>, Json<'i>>),
}

fn consume(pair: Pair<Rule>) -> Json {
    fn value(pair: Pair<Rule>) -> Json {
        let pair = pair.into_inner().next().unwrap();

        match pair.as_rule() {
            Rule::null => Json::Null,
            Rule::bool => match pair.as_str() {
                "false" => Json::Bool(false),
                "true" => Json::Bool(true),
                _ => unreachable!()
            },
            Rule::number => Json::Number(pair.as_str().parse().unwrap()),
            Rule::string => Json::String(pair.into_span()),
            Rule::array => Json::Array(pair.into_inner().map(value).collect()),
            Rule::object => {
                let pairs = pair.into_inner().map(|pos| {
                    let mut pair = pos.into_inner();

                    let key = pair.next().unwrap().into_span();
                    let value = value(pair.next().unwrap());

                    (key, value)
                });

                Json::Object(pairs.collect())
            }
            _ => unreachable!()
        }
    }

    value(pair)
}

#[test]
fn null() {
    parses_to! {
        parser: JsonParser,
        input: "null",
        rule: Rule::null,
        tokens: [
            null(0, 4)
        ]
    };
}

#[test]
fn bool() {
    parses_to! {
        parser: JsonParser,
        input: "false",
        rule: Rule::bool,
        tokens: [
            bool(0, 5)
        ]
    };
}

#[test]
fn number_zero() {
    parses_to! {
        parser: JsonParser,
        input: "0",
        rule: Rule::number,
        tokens: [
            number(0, 1)
        ]
    };
}

#[test]
fn float() {
    parses_to! {
        parser: JsonParser,
        input: "100.001",
        rule: Rule::number,
        tokens: [
            number(0, 7)
        ]
    };
}

#[test]
fn float_with_exp() {
    parses_to! {
        parser: JsonParser,
        input: "100.001E+100",
        rule: Rule::number,
        tokens: [
            number(0, 12)
        ]
    };
}

#[test]
fn number_minus_zero() {
    parses_to! {
        parser: JsonParser,
        input: "-0",
        rule: Rule::number,
        tokens: [
            number(0, 2)
        ]
    };
}

#[test]
fn string_with_escapes() {
    parses_to! {
        parser: JsonParser,
        input: "\"asd\\u0000\\\"\"",
        rule: Rule::string,
        tokens: [
            string(0, 13)
        ]
    };
}

#[test]
fn array_empty() {
    parses_to! {
        parser: JsonParser,
        input: "[ ]",
        rule: Rule::array,
        tokens: [
            array(0, 3)
        ]
    };
}

#[test]
fn array() {
    parses_to! {
        parser: JsonParser,
        input: "[0.0e1, false, null, \"a\", [0]]",
        rule: Rule::array,
        tokens: [
            array(0, 30, [
                value(1,  6, [number(1, 6)]),
                value(8, 13, [bool(8, 13)]),
                value(15, 19, [null(15, 19)]),
                value(21, 24, [string(21, 24)]),
                value(26, 29, [
                    array(26, 29, [
                        value(27, 28, [number(27, 28)])
                    ])
                ])
            ])
        ]
    };
}

#[test]
fn object() {
    parses_to! {
        parser: JsonParser,
        input: "{\"a\" : 3, \"b\" : [{}, 3]}",
        rule: Rule::object,
        tokens: [
            object(0, 24, [
                pair(1, 8, [
                    string(1, 4),
                    value(7, 8, [number(7, 8)])
                ]),
                pair(10, 23, [
                    string(10, 13),
                    value(16, 23, [
                        array(16, 23, [
                            value(17, 19, [object(17, 19)]),
                            value(21, 22, [number(21, 22)])
                        ])
                    ])
                ])
            ])
        ]
    };
}

#[test]
fn ast() {
    let input = "{\"a\": [null, true, 3.4]}";
    let start = Position::from_start(input).skip(1).unwrap();
    let end = start.clone().skip(3).unwrap();
    let span = start.span(&end);

    let mut pairs = HashMap::new();
    pairs.insert(
        span,
        Json::Array(vec![Json::Null, Json::Bool(true), Json::Number(3.4)])
    );

    let ast = consume(
        JsonParser::parse(Rule::json, input)
            .unwrap()
            .next()
            .unwrap()
    );

    assert_eq!(ast, Json::Object(pairs));
}
<|endoftext|>


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

// Functions for dealing with device mapper devices.

use std::fmt;
use std::fmt::Display;

use devicemapper::{DmNameBuf, ThinDevId};

use super::super::errors::EngineResult;

use super::super::super::engine::{FilesystemUuid, PoolUuid};

const FORMAT_VERSION: u16 = 1;

pub enum FlexRole {
    MetadataVolume,
    ThinData,
    ThinMeta,
    ThinMetaSpare,
}

impl Display for FlexRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FlexRole::MetadataVolume => write!(f, "mdv"),
            FlexRole::ThinData => write!(f, "thindata"),
            FlexRole::ThinMeta => write!(f, "thinmeta"),
            FlexRole::ThinMetaSpare => write!(f, "thinmetaspare"),
        }
    }
}

pub enum ThinRole {
    Filesystem(FilesystemUuid),
}

impl Display for ThinRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinRole::Filesystem(uuid) => write!(f, "fs-{}", uuid.simple().to_string()),
        }
    }
}

pub enum ThinPoolRole {
    Pool,
}

impl Display for ThinPoolRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinPoolRole::Pool => write!(f, "pool"),
        }
    }
}

/// Format a name for the flex layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 72
pub fn format_flex_name(pool_uuid: &PoolUuid, role: FlexRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-flex-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 72")

}

/// Format a name for the thin layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 50
pub fn format_thin_name(pool_uuid: &PoolUuid, role: ThinRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thin-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 50")
}

/// Format a name for the thin pool layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 81
pub fn format_thinpool_name(pool_uuid: &PoolUuid, role: ThinPoolRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thinpool-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display_length < 81")
}

#[derive(Debug)]
/// A pool of thindev ids, all unique.
pub struct ThinDevIdPool {
    next_id: u32,
}

impl ThinDevIdPool {
    /// Make a new pool from a possibly empty Vec of ids.
    /// Does not verify the absence of duplicate ids.
    pub fn new_from_ids(ids: &[ThinDevId]) -> ThinDevIdPool {
        let max_id: Option<u32> = ids.into_iter().map(|x| (*x).into()).max();
        ThinDevIdPool { next_id: max_id.map(|x| x + 1).unwrap_or(0) }
    }

    /// Get a new id for a thindev.
    /// Returns an error if no thindev id can be constructed.
    // TODO: Improve this so that it is guaranteed only to fail if every 24 bit
    // number has been used.
    pub fn new_id(&mut self) -> EngineResult<ThinDevId> {
        let next_id = ThinDevId::new_u64(u64::from(self.next_id))?;
        self.next_id += 1;
        Ok(next_id)
    }
}
<commit_msg>Implement Copy for all Role enums<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Functions for dealing with device mapper devices.

use std::fmt;
use std::fmt::Display;

use devicemapper::{DmNameBuf, ThinDevId};

use super::super::errors::EngineResult;

use super::super::super::engine::{FilesystemUuid, PoolUuid};

const FORMAT_VERSION: u16 = 1;

#[derive(Clone, Copy)]
pub enum FlexRole {
    MetadataVolume,
    ThinData,
    ThinMeta,
    ThinMetaSpare,
}

impl Display for FlexRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FlexRole::MetadataVolume => write!(f, "mdv"),
            FlexRole::ThinData => write!(f, "thindata"),
            FlexRole::ThinMeta => write!(f, "thinmeta"),
            FlexRole::ThinMetaSpare => write!(f, "thinmetaspare"),
        }
    }
}

#[derive(Clone, Copy)]
pub enum ThinRole {
    Filesystem(FilesystemUuid),
}

impl Display for ThinRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinRole::Filesystem(uuid) => write!(f, "fs-{}", uuid.simple().to_string()),
        }
    }
}

#[derive(Clone, Copy)]
pub enum ThinPoolRole {
    Pool,
}

impl Display for ThinPoolRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinPoolRole::Pool => write!(f, "pool"),
        }
    }
}

/// Format a name for the flex layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 72
pub fn format_flex_name(pool_uuid: &PoolUuid, role: FlexRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-flex-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 72")

}

/// Format a name for the thin layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 50
pub fn format_thin_name(pool_uuid: &PoolUuid, role: ThinRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thin-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 50")
}

/// Format a name for the thin pool layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 81
pub fn format_thinpool_name(pool_uuid: &PoolUuid, role: ThinPoolRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thinpool-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display_length < 81")
}

#[derive(Debug)]
/// A pool of thindev ids, all unique.
pub struct ThinDevIdPool {
    next_id: u32,
}

impl ThinDevIdPool {
    /// Make a new pool from a possibly empty Vec of ids.
    /// Does not verify the absence of duplicate ids.
    pub fn new_from_ids(ids: &[ThinDevId]) -> ThinDevIdPool {
        let max_id: Option<u32> = ids.into_iter().map(|x| (*x).into()).max();
        ThinDevIdPool { next_id: max_id.map(|x| x + 1).unwrap_or(0) }
    }

    /// Get a new id for a thindev.
    /// Returns an error if no thindev id can be constructed.
    // TODO: Improve this so that it is guaranteed only to fail if every 24 bit
    // number has been used.
    pub fn new_id(&mut self) -> EngineResult<ThinDevId> {
        let next_id = ThinDevId::new_u64(u64::from(self.next_id))?;
        self.next_id += 1;
        Ok(next_id)
    }
}
<|endoftext|>