<commit_before>use std::{process::Command, sync::atomic::Ordering};

use crate::AnvilState;

#[cfg(feature = "udev")]
use smithay::backend::session::Session;
use smithay::{
    backend::input::{
        self, Event, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent,
        PointerButtonEvent, PointerMotionAbsoluteEvent, PointerMotionEvent,
    },
    reexports::wayland_server::protocol::wl_pointer,
    wayland::{
        seat::{keysyms as xkb, AxisFrame, Keysym, ModifiersState},
        SERIAL_COUNTER as SCOUNTER,
    },
};

impl AnvilState {
    pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
        match event {
            InputEvent::Keyboard { event, .. } => self.on_keyboard_key::<B>(event),
            InputEvent::PointerMotion { event, .. } => self.on_pointer_move::<B>(event),
            InputEvent::PointerMotionAbsolute { event, .. } => self.on_pointer_move_absolute::<B>(event),
            InputEvent::PointerButton { event, .. } => self.on_pointer_button::<B>(event),
            InputEvent::PointerAxis { event, .. } => self.on_pointer_axis::<B>(event),
            _ => {
                // other events are not handled in anvil (yet)
            }
        }
    }

    fn on_keyboard_key<B: InputBackend>(&mut self, evt: B::KeyboardKeyEvent) {
        let keycode = evt.key_code();
        let state = evt.state();
        debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
        let serial = SCOUNTER.next_serial();
        let log = &self.log;
        let time = Event::time(&evt);
        let mut action = KeyAction::None;
        self.keyboard
            .input(keycode, state, serial, time, |modifiers, keysym| {
                debug!(log, "keysym";
                    "state" => format!("{:?}", state),
                    "mods" => format!("{:?}", modifiers),
                    "keysym" => ::xkbcommon::xkb::keysym_get_name(keysym)
                );
                action = process_keyboard_shortcut(*modifiers, keysym);
                // forward to client only if action == KeyAction::Forward
                // both for pressed and released, to avoid inconsistencies
                if let KeyAction::Forward = action {
                    true
                } else {
                    false
                }
            });
        if let KeyState::Released = state {
            // only process special actions on key press, not release
            return;
        }
        match action {
            KeyAction::Quit => {
                info!(self.log, "Quitting.");
                self.running.store(false, Ordering::SeqCst);
            }
            #[cfg(feature = "udev")]
            KeyAction::VtSwitch(vt) => {
                if let Some(ref mut session) = self.session {
                    info!(log, "Trying to switch to vt {}", vt);
                    if let Err(err) = session.change_vt(vt) {
                        error!(log, "Error switching to vt {}: {}", vt, err);
                    }
                }
            }
            KeyAction::Run(cmd) => {
                info!(self.log, "Starting program"; "cmd" => cmd.clone());
                if let Err(e) = Command::new(&cmd).spawn() {
                    error!(log,
                        "Failed to start program";
                        "cmd" => cmd,
                        "err" => format!("{:?}", e)
                    );
                }
            }
            _ => (),
        }
    }

    fn on_pointer_move<B: InputBackend>(&mut self, evt: B::PointerMotionEvent) {
        let (x, y) = (evt.delta_x(), evt.delta_y());
        let serial = SCOUNTER.next_serial();
        let mut location = self.pointer_location.borrow_mut();
        location.0 += x as f64;
        location.1 += y as f64;

        #[cfg(feature = "udev")]
        {
            // clamp to screen limits
            // this event is never generated by winit
            *location = self.clamp_coords(*location);
        }

        let under = self
            .window_map
            .borrow()
            .get_surface_under((location.0, location.1));
        self.pointer.motion(*location, under, serial, evt.time());
    }

    fn on_pointer_move_absolute<B: InputBackend>(&mut self, evt: B::PointerMotionAbsoluteEvent) {
        // different cases depending on the context:
        let (x, y) = {
            #[cfg(feature = "udev")]
            {
                if self.session.is_some() {
                    // we are started on a tty
                    let x = self.pointer_location.borrow().0;
                    let screen_size = self.current_output_size(x);
                    // monitor coordinates
                    let (ux, uy) = evt.position_transformed(screen_size);
                    ((ux + self.current_output_offset(x)) as f64, uy as f64)
                } else {
                    // we are started in winit
                    evt.position()
                }
            }
            #[cfg(not(feature = "udev"))]
            {
                evt.position()
            }
        };
        *self.pointer_location.borrow_mut() = (x, y);
        let serial = SCOUNTER.next_serial();
        let under = self.window_map.borrow().get_surface_under((x as f64, y as f64));
        self.pointer.motion((x, y), under, serial, evt.time());
    }

    #[cfg(feature = "udev")]
    fn clamp_coords(&self, pos: (f64, f64)) -> (f64, f64) {
        let output_map = self.output_map
            .as_ref().unwrap();
        let outputs = output_map.borrow();

        if outputs.len() == 0 {
            return pos;
        }

        let (mut x, mut y) = pos;
        // max_x is the sum of the width of all outputs
        let max_x = outputs
            .iter()
            .fold(0u32, |acc, output| acc + output.size.0);
        x = x.max(0.0).min(max_x as f64);

        // max y depends on the current output
        let max_y = self.current_output_size(x).1;
        y = y.max(0.0).min(max_y as f64);

        (x, y)
    }

    #[cfg(feature = "udev")]
    fn current_output_idx(&self, x: f64) -> usize {
        let output_map = self.output_map.as_ref().unwrap();
        let outputs = output_map.borrow();

        outputs
            .iter()
            // map each output to their x position
            .scan(0u32, |acc, output| {
                let curr_x = *acc;
                *acc += output.size.0;
                Some(curr_x)
            })
            // get an index
            .enumerate()
            // find the first one with a greater x
            .find(|(_idx, x_pos)| *x_pos as f64 > x)
            // the previous output is the one we are on
            .map(|(idx, _)| idx - 1)
            .unwrap_or(outputs.len() - 1)
    }
    #[cfg(feature = "udev")]
    fn current_output_size(&self, x: f64) -> (u32, u32) {
        let output_map = self.output_map.as_ref().unwrap();
        let outputs = output_map.borrow();
        outputs[self.current_output_idx(x)].size
    }
    #[cfg(feature = "udev")]
    fn current_output_offset(&self, x: f64) -> u32 {
        let output_map = self.output_map.as_ref().unwrap();
        let outputs = output_map.borrow();
        outputs
            .iter()
            .take(self.current_output_idx(x))
            .fold(0u32, |acc, output| acc + output.size.0)
    }

    fn on_pointer_button<B: InputBackend>(&mut self, evt: B::PointerButtonEvent) {
        let serial = SCOUNTER.next_serial();
        let button = match evt.button() {
            input::MouseButton::Left => 0x110,
            input::MouseButton::Right => 0x111,
            input::MouseButton::Middle => 0x112,
            input::MouseButton::Other(b) => b as u32,
        };
        let state = match evt.state() {
            input::MouseButtonState::Pressed => {
                // change the keyboard focus unless the pointer is grabbed
                if !self.pointer.is_grabbed() {
                    let under = self
                        .window_map
                        .borrow_mut()
                        .get_surface_and_bring_to_top(*self.pointer_location.borrow());
                    self.keyboard
                        .set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
                }
                wl_pointer::ButtonState::Pressed
            }
            input::MouseButtonState::Released => wl_pointer::ButtonState::Released,
        };
        self.pointer.button(button, state, serial, evt.time());
    }

    fn on_pointer_axis<B: InputBackend>(&mut self, evt: B::PointerAxisEvent) {
        let source = match evt.source() {
            input::AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
            input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
            input::AxisSource::Wheel | input::AxisSource::WheelTilt => wl_pointer::AxisSource::Wheel,
        };
        let horizontal_amount = evt
            .amount(input::Axis::Horizontal)
            .unwrap_or_else(|| evt.amount_discrete(input::Axis::Horizontal).unwrap() * 3.0);
        let vertical_amount = evt
            .amount(input::Axis::Vertical)
            .unwrap_or_else(|| evt.amount_discrete(input::Axis::Vertical).unwrap() * 3.0);
        let horizontal_amount_discrete = evt.amount_discrete(input::Axis::Horizontal);
        let vertical_amount_discrete = evt.amount_discrete(input::Axis::Vertical);

        {
            let mut frame = AxisFrame::new(evt.time()).source(source);
            if horizontal_amount != 0.0 {
                frame = frame.value(wl_pointer::Axis::HorizontalScroll, horizontal_amount);
                if let Some(discrete) = horizontal_amount_discrete {
                    frame = frame.discrete(wl_pointer::Axis::HorizontalScroll, discrete as i32);
                }
            } else if source == wl_pointer::AxisSource::Finger {
                frame = frame.stop(wl_pointer::Axis::HorizontalScroll);
            }
            if vertical_amount != 0.0 {
                frame = frame.value(wl_pointer::Axis::VerticalScroll, vertical_amount);
                if let Some(discrete) = vertical_amount_discrete {
                    frame = frame.discrete(wl_pointer::Axis::VerticalScroll, discrete as i32);
                }
            } else if source == wl_pointer::AxisSource::Finger {
                frame = frame.stop(wl_pointer::Axis::VerticalScroll);
            }
            self.pointer.axis(frame);
        }
    }
}

/// Possible results of a keyboard action
enum KeyAction {
    /// Quit the compositor
    Quit,
    /// Trigger a vt-switch
    VtSwitch(i32),
    /// run a command
    Run(String),
    /// Forward the key to the client
    Forward,
    /// Do nothing more
    None,
}

fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> KeyAction {
    if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace
        || modifiers.logo && keysym == xkb::KEY_q
    {
        // ctrl+alt+backspace = quit
        // logo + q = quit
        KeyAction::Quit
    } else if keysym >= xkb::KEY_XF86Switch_VT_1 && keysym <= xkb::KEY_XF86Switch_VT_12 {
        // VTSwicth
        KeyAction::VtSwitch((keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32)
    } else if modifiers.logo && keysym == xkb::KEY_Return {
        // run terminal
        KeyAction::Run("weston-terminal".into())
    } else {
        KeyAction::Forward
    }
}
<commit_msg>anvil: allow swapping monitors via shortcut<commit_after>use std::{process::Command, sync::atomic::Ordering};

use crate::AnvilState;

#[cfg(feature = "udev")]
use smithay::backend::session::Session;
use smithay::{
    backend::input::{
        self, Event, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent,
        PointerButtonEvent, PointerMotionAbsoluteEvent, PointerMotionEvent,
    },
    reexports::wayland_server::protocol::wl_pointer,
    wayland::{
        seat::{keysyms as xkb, AxisFrame, Keysym, ModifiersState},
        SERIAL_COUNTER as SCOUNTER,
    },
};

impl AnvilState {
    pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
        match event {
            InputEvent::Keyboard { event, .. } => self.on_keyboard_key::<B>(event),
            InputEvent::PointerMotion { event, .. } => self.on_pointer_move::<B>(event),
            InputEvent::PointerMotionAbsolute { event, .. } => self.on_pointer_move_absolute::<B>(event),
            InputEvent::PointerButton { event, .. } => self.on_pointer_button::<B>(event),
            InputEvent::PointerAxis { event, .. } => self.on_pointer_axis::<B>(event),
            _ => {
                // other events are not handled in anvil (yet)
            }
        }
    }

    fn on_keyboard_key<B: InputBackend>(&mut self, evt: B::KeyboardKeyEvent) {
        let keycode = evt.key_code();
        let state = evt.state();
        debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
        let serial = SCOUNTER.next_serial();
        let log = &self.log;
        let time = Event::time(&evt);
        let mut action = KeyAction::None;
        self.keyboard
            .input(keycode, state, serial, time, |modifiers, keysym| {
                debug!(log, "keysym";
                    "state" => format!("{:?}", state),
                    "mods" => format!("{:?}", modifiers),
                    "keysym" => ::xkbcommon::xkb::keysym_get_name(keysym)
                );
                action = process_keyboard_shortcut(*modifiers, keysym);
                // forward to client only if action == KeyAction::Forward
                // both for pressed and released, to avoid inconsistencies
                if let KeyAction::Forward = action {
                    true
                } else {
                    false
                }
            });
        if let KeyState::Released = state {
            // only process special actions on key press, not release
            return;
        }
        match action {
            KeyAction::Quit => {
                info!(self.log, "Quitting.");
                self.running.store(false, Ordering::SeqCst);
            }
            #[cfg(feature = "udev")]
            KeyAction::VtSwitch(vt) => {
                if let Some(ref mut session) = self.session {
                    info!(log, "Trying to switch to vt {}", vt);
                    if let Err(err) = session.change_vt(vt) {
                        error!(log, "Error switching to vt {}: {}", vt, err);
                    }
                }
            }
            KeyAction::Run(cmd) => {
                info!(self.log, "Starting program"; "cmd" => cmd.clone());
                if let Err(e) = Command::new(&cmd).spawn() {
                    error!(log,
                        "Failed to start program";
                        "cmd" => cmd,
                        "err" => format!("{:?}", e)
                    );
                }
            },
            KeyAction::Screen(num) => {
                let output_map = self.output_map
                    .as_ref().unwrap();
                let outputs = output_map.borrow();
                if let Some(output) = outputs.get(num) {
                    let x = outputs.iter().take(num).fold(0, |acc, output| acc + output.size.0) as f64 + (output.size.0 as f64 / 2.0);
                    let y = output.size.1 as f64 / 2.0;
                    *self.pointer_location.borrow_mut() = (x as f64, y as f64)
                }

            }
            _ => (),
        }
    }

    fn on_pointer_move<B: InputBackend>(&mut self, evt: B::PointerMotionEvent) {
        let (x, y) = (evt.delta_x(), evt.delta_y());
        let serial = SCOUNTER.next_serial();
        let mut location = self.pointer_location.borrow_mut();
        location.0 += x as f64;
        location.1 += y as f64;

        #[cfg(feature = "udev")]
        {
            // clamp to screen limits
            // this event is never generated by winit
            *location = self.clamp_coords(*location);
        }

        let under = self
            .window_map
            .borrow()
            .get_surface_under((location.0, location.1));
        self.pointer.motion(*location, under, serial, evt.time());
    }

    fn on_pointer_move_absolute<B: InputBackend>(&mut self, evt: B::PointerMotionAbsoluteEvent) {
        // different cases depending on the context:
        let (x, y) = {
            #[cfg(feature = "udev")]
            {
                if self.session.is_some() {
                    // we are started on a tty
                    let x = self.pointer_location.borrow().0;
                    let screen_size = self.current_output_size(x);
                    // monitor coordinates
                    let (ux, uy) = evt.position_transformed(screen_size);
                    ((ux + self.current_output_offset(x)) as f64, uy as f64)
                } else {
                    // we are started in winit
                    evt.position()
                }
            }
            #[cfg(not(feature = "udev"))]
            {
                evt.position()
            }
        };
        *self.pointer_location.borrow_mut() = (x, y);
        let serial = SCOUNTER.next_serial();
        let under = self.window_map.borrow().get_surface_under((x as f64, y as f64));
        self.pointer.motion((x, y), under, serial, evt.time());
    }

    #[cfg(feature = "udev")]
    fn clamp_coords(&self, pos: (f64, f64)) -> (f64, f64) {
        let output_map = self.output_map
            .as_ref().unwrap();
        let outputs = output_map.borrow();

        if outputs.len() == 0 {
            return pos;
        }

        let (mut x, mut y) = pos;
        // max_x is the sum of the width of all outputs
        let max_x = outputs
            .iter()
            .fold(0u32, |acc, output| acc + output.size.0);
        x = x.max(0.0).min(max_x as f64);

        // max y depends on the current output
        let max_y = self.current_output_size(x).1;
        y = y.max(0.0).min(max_y as f64);

        (x, y)
    }

    #[cfg(feature = "udev")]
    fn current_output_idx(&self, x: f64) -> usize {
        let output_map = self.output_map.as_ref().unwrap();
        let outputs = output_map.borrow();

        outputs
            .iter()
            // map each output to their x position
            .scan(0u32, |acc, output| {
                let curr_x = *acc;
                *acc += output.size.0;
                Some(curr_x)
            })
            // get an index
            .enumerate()
            // find the first one with a greater x
            .find(|(_idx, x_pos)| *x_pos as f64 > x)
            // the previous output is the one we are on
            .map(|(idx, _)| idx - 1)
            .unwrap_or(outputs.len() - 1)
    }
    #[cfg(feature = "udev")]
    fn current_output_size(&self, x: f64) -> (u32, u32) {
        let output_map = self.output_map.as_ref().unwrap();
        let outputs = output_map.borrow();
        outputs[self.current_output_idx(x)].size
    }
    #[cfg(feature = "udev")]
    fn current_output_offset(&self, x: f64) -> u32 {
        let output_map = self.output_map.as_ref().unwrap();
        let outputs = output_map.borrow();
        outputs
            .iter()
            .take(self.current_output_idx(x))
            .fold(0u32, |acc, output| acc + output.size.0)
    }

    fn on_pointer_button<B: InputBackend>(&mut self, evt: B::PointerButtonEvent) {
        let serial = SCOUNTER.next_serial();
        let button = match evt.button() {
            input::MouseButton::Left => 0x110,
            input::MouseButton::Right => 0x111,
            input::MouseButton::Middle => 0x112,
            input::MouseButton::Other(b) => b as u32,
        };
        let state = match evt.state() {
            input::MouseButtonState::Pressed => {
                // change the keyboard focus unless the pointer is grabbed
                if !self.pointer.is_grabbed() {
                    let under = self
                        .window_map
                        .borrow_mut()
                        .get_surface_and_bring_to_top(*self.pointer_location.borrow());
                    self.keyboard
                        .set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
                }
                wl_pointer::ButtonState::Pressed
            }
            input::MouseButtonState::Released => wl_pointer::ButtonState::Released,
        };
        self.pointer.button(button, state, serial, evt.time());
    }

    fn on_pointer_axis<B: InputBackend>(&mut self, evt: B::PointerAxisEvent) {
        let source = match evt.source() {
            input::AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
            input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
            input::AxisSource::Wheel | input::AxisSource::WheelTilt => wl_pointer::AxisSource::Wheel,
        };
        let horizontal_amount = evt
            .amount(input::Axis::Horizontal)
            .unwrap_or_else(|| evt.amount_discrete(input::Axis::Horizontal).unwrap() * 3.0);
        let vertical_amount = evt
            .amount(input::Axis::Vertical)
            .unwrap_or_else(|| evt.amount_discrete(input::Axis::Vertical).unwrap() * 3.0);
        let horizontal_amount_discrete = evt.amount_discrete(input::Axis::Horizontal);
        let vertical_amount_discrete = evt.amount_discrete(input::Axis::Vertical);

        {
            let mut frame = AxisFrame::new(evt.time()).source(source);
            if horizontal_amount != 0.0 {
                frame = frame.value(wl_pointer::Axis::HorizontalScroll, horizontal_amount);
                if let Some(discrete) = horizontal_amount_discrete {
                    frame = frame.discrete(wl_pointer::Axis::HorizontalScroll, discrete as i32);
                }
            } else if source == wl_pointer::AxisSource::Finger {
                frame = frame.stop(wl_pointer::Axis::HorizontalScroll);
            }
            if vertical_amount != 0.0 {
                frame = frame.value(wl_pointer::Axis::VerticalScroll, vertical_amount);
                if let Some(discrete) = vertical_amount_discrete {
                    frame = frame.discrete(wl_pointer::Axis::VerticalScroll, discrete as i32);
                }
            } else if source == wl_pointer::AxisSource::Finger {
                frame = frame.stop(wl_pointer::Axis::VerticalScroll);
            }
            self.pointer.axis(frame);
        }
    }
}

/// Possible results of a keyboard action
enum KeyAction {
    /// Quit the compositor
    Quit,
    /// Trigger a vt-switch
    VtSwitch(i32),
    /// run a command
    Run(String),
    /// Switch the current screen
    Screen(usize),
    /// Forward the key to the client
    Forward,
    /// Do nothing more
    None,
}

fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> KeyAction {
    if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace
        || modifiers.logo && keysym == xkb::KEY_q
    {
        // ctrl+alt+backspace = quit
        // logo + q = quit
        KeyAction::Quit
    } else if keysym >= xkb::KEY_XF86Switch_VT_1 && keysym <= xkb::KEY_XF86Switch_VT_12 {
        // VTSwicth
        KeyAction::VtSwitch((keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32)
    } else if modifiers.logo && keysym == xkb::KEY_Return {
        // run terminal
        KeyAction::Run("weston-terminal".into())
    } else if modifiers.logo && keysym >= xkb::KEY_1 && keysym <= xkb::KEY_9 {
        KeyAction::Screen((keysym - xkb::KEY_1) as usize)
    } else {
        KeyAction::Forward
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2019 Fabian Schuiki

use crate::{crate_prelude::*, hir::HirNode, ty::Type};

pub(crate) fn type_of<'gcx>(cx: &impl Context<'gcx>, node_id: NodeId) -> Result<Type<'gcx>> {
    let hir = cx.hir_of(node_id)?;

    #[allow(unreachable_patterns)]
    match hir {
        HirNode::Port(p) => cx.type_of(p.ty),
        HirNode::Type(hir) => match hir.kind {
            hir::TypeKind::Builtin(hir::BuiltinType::Void) => Ok(cx.mkty_void()),
            hir::TypeKind::Builtin(hir::BuiltinType::Bit) => Ok(cx.mkty_bit()),
            hir::TypeKind::Named(name) => {
                trace!("resolve type name {}", name);
                cx.unimp_msg("name resolution of", hir)
            }
            _ => cx.unimp_msg("type analysis of", hir),
        },
        _ => cx.unimp_msg("type analysis of", &hir),
    }
}
<commit_msg>vlog: resolve named types<commit_after>// Copyright (c) 2016-2019 Fabian Schuiki

use crate::{crate_prelude::*, hir::HirNode, ty::Type};

pub(crate) fn type_of<'gcx>(cx: &impl Context<'gcx>, node_id: NodeId) -> Result<Type<'gcx>> {
    let hir = cx.hir_of(node_id)?;

    #[allow(unreachable_patterns)]
    match hir {
        HirNode::Port(p) => cx.type_of(p.ty),
        HirNode::Type(hir) => match hir.kind {
            hir::TypeKind::Builtin(hir::BuiltinType::Void) => Ok(cx.mkty_void()),
            hir::TypeKind::Builtin(hir::BuiltinType::Bit) => Ok(cx.mkty_bit()),
            hir::TypeKind::Named(name) => {
                let binding =
                    cx.resolve_upwards_or_error(name, cx.parent_node_id(node_id).unwrap())?;
                Ok(cx.mkty_named(name, binding))
            }
            _ => cx.unimp_msg("type analysis of", hir),
        },
        _ => cx.unimp_msg("type analysis of", &hir),
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(clippy::redundant_static_lifetimes)]
#![allow(clippy::unreadable_literal)]
#![allow(clippy::missing_safety_doc)]
// This allow should be removed once bindgen finds a way to
// generate struct alignment tests without triggering errors
// in the compiler. See https://github.com/rust-lang/rust-bindgen/issues/1651.
#![allow(deref_nullptr)]

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
<commit_msg>Allow lint in order to cover our lowest supported toolchain<commit_after>#![allow(dead_code)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(clippy::redundant_static_lifetimes)]
#![allow(clippy::unreadable_literal)]
#![allow(clippy::missing_safety_doc)]
// This allow should be removed once bindgen finds a way to
// generate struct alignment tests without triggering errors
// in the compiler. See https://github.com/rust-lang/rust-bindgen/issues/1651.
#![allow(unknown_lints)]
#![allow(deref_nullptr)]

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
<|endoftext|>


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

/*!

Utilities for program-wide and customizable logging

## Example

```
#![feature(phase)]
#[phase(syntax, link)] extern crate log;

fn main() {
    debug!("this is a debug {}", "message");
    error!("this is printed by default");

    if log_enabled!(log::INFO) {
        let x = 3 * 4; // expensive computation
        info!("the answer was: {}", x);
    }
}
```

## Logging Macros

There are five macros that the logging subsystem uses:

* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
                       related `format!` arguments
* `debug!(...)` - a macro hard-wired to the log level of `DEBUG`
* `info!(...)` - a macro hard-wired to the log level of `INFO`
* `warn!(...)` - a macro hard-wired to the log level of `WARN`
* `error!(...)` - a macro hard-wired to the log level of `ERROR`

All of these macros use std::the same style of syntax as the `format!` syntax
extension. Details about the syntax can be found in the documentation of
`std::fmt` along with the Rust tutorial/manual.

If you want to check at runtime if a given logging level is enabled (e.g. if the
information you would want to log is expensive to produce), you can use std::the
following macro:

* `log_enabled!(level)` - returns true if logging of the given level is enabled

## Enabling logging

Log levels are controlled on a per-module basis, and by default all logging is
disabled except for `error!` (a log level of 1). Logging is controlled via the
`RUST_LOG` environment variable. The value of this environment variable is a
comma-separated list of logging directives. A logging directive is of the form:

```notrust
path::to::module=log_level
```

The path to the module is rooted in the name of the crate it was compiled for,
so if your program is contained in a file `hello.rs`, for example, to turn on
logging for this file you would use std::a value of `RUST_LOG=hello`.
Furthermore, this path is a prefix-search, so all modules nested in the
specified module will also have logging enabled.

The actual `log_level` is optional to specify. If omitted, all logging will be
enabled. If specified, the it must be either a numeric in the range of 1-255, or
it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
is specified, then all logging less than or equal to that numeral is enabled.
For example, if logging level 3 is active, error, warn, and info logs will be
printed, but debug will be omitted.

As the log level for a module is optional, the module to enable logging for is
also optional. If only a `log_level` is provided, then the global log level for
all modules is set to this value.

Some examples of valid values of `RUST_LOG` are:

```notrust
hello                // turns on all logging for the 'hello' module
info                 // turns on all info logging
hello=debug          // turns on debug logging for 'hello'
hello=3              // turns on info logging for 'hello'
hello,std::option    // turns on hello, and std's option logging
error,hello=warn     // turn on global error logging and also warn for hello
```

## Performance and Side Effects

Each of these macros will expand to code similar to:

```rust,ignore
if log_level <= my_module_log_level() {
    ::log::log(log_level, format!(...));
}
```

What this means is that each of these macros are very cheap at runtime if
they're turned off (just a load and an integer comparison). This also means that
if logging is disabled, none of the components of the log will be executed.

*/

#![crate_id = "log#0.11-pre"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]

#![feature(macro_rules)]
#![deny(missing_doc, deprecated_owned_vector)]

extern crate sync;

use std::cast;
use std::fmt;
use std::io::LineBufferedWriter;
use std::io;
use std::local_data;
use std::os;
use std::rt;
use std::slice;

use sync::one::{Once, ONCE_INIT};

pub mod macros;
mod directive;

/// Maximum logging level of a module that can be specified. Common logging
/// levels are found in the DEBUG/INFO/WARN/ERROR constants.
pub static MAX_LOG_LEVEL: u32 = 255;

/// The default logging level of a crate if no other is specified.
static DEFAULT_LOG_LEVEL: u32 = 1;

/// An unsafe constant that is the maximum logging level of any module
/// specified. This is the first line of defense to determining whether a
/// logging statement should be run.
static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;

static mut DIRECTIVES: *Vec<directive::LogDirective> =
    0 as *Vec<directive::LogDirective>;

/// Debug log level
pub static DEBUG: u32 = 4;
/// Info log level
pub static INFO: u32 = 3;
/// Warn log level
pub static WARN: u32 = 2;
/// Error log level
pub static ERROR: u32 = 1;

local_data_key!(local_logger: ~Logger:Send)

/// A trait used to represent an interface to a task-local logger. Each task
/// can have its own custom logger which can respond to logging messages
/// however it likes.
pub trait Logger {
    /// Logs a single message described by the `args` structure. The level is
    /// provided in case you want to do things like color the message, etc.
    fn log(&mut self, level: u32, args: &fmt::Arguments);
}

struct DefaultLogger {
    handle: LineBufferedWriter<io::stdio::StdWriter>,
}

impl Logger for DefaultLogger {
    // by default, just ignore the level
    fn log(&mut self, _level: u32, args: &fmt::Arguments) {
        match fmt::writeln(&mut self.handle, args) {
            Err(e) => fail!("failed to log: {}", e),
            Ok(()) => {}
        }
    }
}

impl Drop for DefaultLogger {
    fn drop(&mut self) {
        // FIXME(#12628): is failure the right thing to do?
        match self.handle.flush() {
            Err(e) => fail!("failed to flush a logger: {}", e),
            Ok(()) => {}
        }
    }
}

/// This function is called directly by the compiler when using the logging
/// macros. This function does not take into account whether the log level
/// specified is active or not, it will always log something if this method is
/// called.
///
/// It is not recommended to call this function directly, rather it should be
/// invoked through the logging family of macros.
pub fn log(level: u32, args: &fmt::Arguments) {
    // Completely remove the local logger from TLS in case anyone attempts to
    // frob the slot while we're doing the logging. This will destroy any logger
    // set during logging.
    let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
        ~DefaultLogger { handle: io::stderr() } as ~Logger:Send
    });
    logger.log(level, args);
    local_data::set(local_logger, logger);
}

/// Getter for the global log level. This is a function so that it can be called
/// safely
#[doc(hidden)]
#[inline(always)]
pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }

/// Replaces the task-local logger with the specified logger, returning the old
/// logger.
pub fn set_logger(logger: ~Logger:Send) -> Option<~Logger:Send> {
    let prev = local_data::pop(local_logger);
    local_data::set(local_logger, logger);
    return prev;
}

/// Tests whether a given module's name is enabled for a particular level of
/// logging. This is the second layer of defense about determining whether a
/// module's log statement should be emitted or not.
#[doc(hidden)]
pub fn mod_enabled(level: u32, module: &str) -> bool {
    static mut INIT: Once = ONCE_INIT;
    unsafe { INIT.doit(init); }

    // It's possible for many threads are in this function, only one of them
    // will peform the global initialization, but all of them will need to check
    // again to whether they should really be here or not. Hence, despite this
    // check being expanded manually in the logging macro, this function checks
    // the log level again.
    if level > unsafe { LOG_LEVEL } { return false }

    // This assertion should never get tripped unless we're in an at_exit
    // handler after logging has been torn down and a logging attempt was made.
    assert!(unsafe { !DIRECTIVES.is_null() });

    enabled(level, module, unsafe { (*DIRECTIVES).iter() })
}

fn enabled(level: u32, module: &str,
           iter: slice::Items<directive::LogDirective>) -> bool {
    // Search for the longest match, the vector is assumed to be pre-sorted.
    for directive in iter.rev() {
        match directive.name {
            Some(ref name) if !module.starts_with(*name) => {},
            Some(..) | None => {
                return level <= directive.level
            }
        }
    }
    level <= DEFAULT_LOG_LEVEL
}

/// Initialize logging for the current process.
///
/// This is not threadsafe at all, so initialization os performed through a
/// `Once` primitive (and this function is called from that primitive).
fn init() {
    let mut directives = match os::getenv("RUST_LOG") {
        Some(spec) => directive::parse_logging_spec(spec),
        None => Vec::new(),
    };

    // Sort the provided directives by length of their name, this allows a
    // little more efficient lookup at runtime.
    directives.sort_by(|a, b| {
        let alen = a.name.as_ref().map(|a| a.len()).unwrap_or(0);
        let blen = b.name.as_ref().map(|b| b.len()).unwrap_or(0);
        alen.cmp(&blen)
    });

    let max_level = {
        let max = directives.iter().max_by(|d| d.level);
        max.map(|d| d.level).unwrap_or(DEFAULT_LOG_LEVEL)
    };

    unsafe {
        LOG_LEVEL = max_level;

        assert!(DIRECTIVES.is_null());
        DIRECTIVES = cast::transmute(~directives);

        // Schedule the cleanup for this global for when the runtime exits.
        rt::at_exit(proc() {
            assert!(!DIRECTIVES.is_null());
            let _directives: ~Vec<directive::LogDirective> =
                cast::transmute(DIRECTIVES);
            DIRECTIVES = 0 as *Vec<directive::LogDirective>;
        });
    }
}

#[cfg(test)]
mod tests {
    use super::enabled;
    use directive::LogDirective;

    #[test]
    fn match_full_path() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(2, "crate1::mod1", dirs.iter()));
        assert!(!enabled(3, "crate1::mod1", dirs.iter()));
        assert!(enabled(3, "crate2", dirs.iter()));
        assert!(!enabled(4, "crate2", dirs.iter()));
    }

    #[test]
    fn no_match() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(!enabled(2, "crate3", dirs.iter()));
    }

    #[test]
    fn match_beginning() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(3, "crate2::mod1", dirs.iter()));
    }

    #[test]
    fn match_beginning_longest_match() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate2::mod"), level: 4 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(4, "crate2::mod1", dirs.iter()));
        assert!(!enabled(4, "crate2", dirs.iter()));
    }

    #[test]
    fn match_default() {
        let dirs = [LogDirective { name: None, level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(2, "crate1::mod1", dirs.iter()));
        assert!(enabled(3, "crate2::mod2", dirs.iter()));
    }

    #[test]
    fn zero_level() {
        let dirs = [LogDirective { name: None, level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 0 }];
        assert!(!enabled(1, "crate1::mod1", dirs.iter()));
        assert!(enabled(3, "crate2::mod2", dirs.iter()));
    }
}
<commit_msg>auto merge of #13460 : SimonSapin/rust/patch-9, r=alexcrichton<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Utilities for program-wide and customizable logging

## Example

```
#![feature(phase)]
#[phase(syntax, link)] extern crate log;

fn main() {
    debug!("this is a debug {}", "message");
    error!("this is printed by default");

    if log_enabled!(log::INFO) {
        let x = 3 * 4; // expensive computation
        info!("the answer was: {}", x);
    }
}
```

## Logging Macros

There are five macros that the logging subsystem uses:

* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
                       related `format!` arguments
* `debug!(...)` - a macro hard-wired to the log level of `DEBUG`
* `info!(...)` - a macro hard-wired to the log level of `INFO`
* `warn!(...)` - a macro hard-wired to the log level of `WARN`
* `error!(...)` - a macro hard-wired to the log level of `ERROR`

All of these macros use the same style of syntax as the `format!` syntax
extension. Details about the syntax can be found in the documentation of
`std::fmt` along with the Rust tutorial/manual.

If you want to check at runtime if a given logging level is enabled (e.g. if the
information you would want to log is expensive to produce), you can use the
following macro:

* `log_enabled!(level)` - returns true if logging of the given level is enabled

## Enabling logging

Log levels are controlled on a per-module basis, and by default all logging is
disabled except for `error!` (a log level of 1). Logging is controlled via the
`RUST_LOG` environment variable. The value of this environment variable is a
comma-separated list of logging directives. A logging directive is of the form:

```notrust
path::to::module=log_level
```

The path to the module is rooted in the name of the crate it was compiled for,
so if your program is contained in a file `hello.rs`, for example, to turn on
logging for this file you would use a value of `RUST_LOG=hello`.
Furthermore, this path is a prefix-search, so all modules nested in the
specified module will also have logging enabled.

The actual `log_level` is optional to specify. If omitted, all logging will be
enabled. If specified, the it must be either a numeric in the range of 1-255, or
it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
is specified, then all logging less than or equal to that numeral is enabled.
For example, if logging level 3 is active, error, warn, and info logs will be
printed, but debug will be omitted.

As the log level for a module is optional, the module to enable logging for is
also optional. If only a `log_level` is provided, then the global log level for
all modules is set to this value.

Some examples of valid values of `RUST_LOG` are:

```notrust
hello                // turns on all logging for the 'hello' module
info                 // turns on all info logging
hello=debug          // turns on debug logging for 'hello'
hello=3              // turns on info logging for 'hello'
hello,std::option    // turns on hello, and std's option logging
error,hello=warn     // turn on global error logging and also warn for hello
```

## Performance and Side Effects

Each of these macros will expand to code similar to:

```rust,ignore
if log_level <= my_module_log_level() {
    ::log::log(log_level, format!(...));
}
```

What this means is that each of these macros are very cheap at runtime if
they're turned off (just a load and an integer comparison). This also means that
if logging is disabled, none of the components of the log will be executed.

*/

#![crate_id = "log#0.11-pre"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]

#![feature(macro_rules)]
#![deny(missing_doc, deprecated_owned_vector)]

extern crate sync;

use std::cast;
use std::fmt;
use std::io::LineBufferedWriter;
use std::io;
use std::local_data;
use std::os;
use std::rt;
use std::slice;

use sync::one::{Once, ONCE_INIT};

pub mod macros;
mod directive;

/// Maximum logging level of a module that can be specified. Common logging
/// levels are found in the DEBUG/INFO/WARN/ERROR constants.
pub static MAX_LOG_LEVEL: u32 = 255;

/// The default logging level of a crate if no other is specified.
static DEFAULT_LOG_LEVEL: u32 = 1;

/// An unsafe constant that is the maximum logging level of any module
/// specified. This is the first line of defense to determining whether a
/// logging statement should be run.
static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;

static mut DIRECTIVES: *Vec<directive::LogDirective> =
    0 as *Vec<directive::LogDirective>;

/// Debug log level
pub static DEBUG: u32 = 4;
/// Info log level
pub static INFO: u32 = 3;
/// Warn log level
pub static WARN: u32 = 2;
/// Error log level
pub static ERROR: u32 = 1;

local_data_key!(local_logger: ~Logger:Send)

/// A trait used to represent an interface to a task-local logger. Each task
/// can have its own custom logger which can respond to logging messages
/// however it likes.
pub trait Logger {
    /// Logs a single message described by the `args` structure. The level is
    /// provided in case you want to do things like color the message, etc.
    fn log(&mut self, level: u32, args: &fmt::Arguments);
}

struct DefaultLogger {
    handle: LineBufferedWriter<io::stdio::StdWriter>,
}

impl Logger for DefaultLogger {
    // by default, just ignore the level
    fn log(&mut self, _level: u32, args: &fmt::Arguments) {
        match fmt::writeln(&mut self.handle, args) {
            Err(e) => fail!("failed to log: {}", e),
            Ok(()) => {}
        }
    }
}

impl Drop for DefaultLogger {
    fn drop(&mut self) {
        // FIXME(#12628): is failure the right thing to do?
        match self.handle.flush() {
            Err(e) => fail!("failed to flush a logger: {}", e),
            Ok(()) => {}
        }
    }
}

/// This function is called directly by the compiler when using the logging
/// macros. This function does not take into account whether the log level
/// specified is active or not, it will always log something if this method is
/// called.
///
/// It is not recommended to call this function directly, rather it should be
/// invoked through the logging family of macros.
pub fn log(level: u32, args: &fmt::Arguments) {
    // Completely remove the local logger from TLS in case anyone attempts to
    // frob the slot while we're doing the logging. This will destroy any logger
    // set during logging.
    let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
        ~DefaultLogger { handle: io::stderr() } as ~Logger:Send
    });
    logger.log(level, args);
    local_data::set(local_logger, logger);
}

/// Getter for the global log level. This is a function so that it can be called
/// safely
#[doc(hidden)]
#[inline(always)]
pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }

/// Replaces the task-local logger with the specified logger, returning the old
/// logger.
pub fn set_logger(logger: ~Logger:Send) -> Option<~Logger:Send> {
    let prev = local_data::pop(local_logger);
    local_data::set(local_logger, logger);
    return prev;
}

/// Tests whether a given module's name is enabled for a particular level of
/// logging. This is the second layer of defense about determining whether a
/// module's log statement should be emitted or not.
#[doc(hidden)]
pub fn mod_enabled(level: u32, module: &str) -> bool {
    static mut INIT: Once = ONCE_INIT;
    unsafe { INIT.doit(init); }

    // It's possible for many threads are in this function, only one of them
    // will peform the global initialization, but all of them will need to check
    // again to whether they should really be here or not. Hence, despite this
    // check being expanded manually in the logging macro, this function checks
    // the log level again.
    if level > unsafe { LOG_LEVEL } { return false }

    // This assertion should never get tripped unless we're in an at_exit
    // handler after logging has been torn down and a logging attempt was made.
    assert!(unsafe { !DIRECTIVES.is_null() });

    enabled(level, module, unsafe { (*DIRECTIVES).iter() })
}

fn enabled(level: u32, module: &str,
           iter: slice::Items<directive::LogDirective>) -> bool {
    // Search for the longest match, the vector is assumed to be pre-sorted.
    for directive in iter.rev() {
        match directive.name {
            Some(ref name) if !module.starts_with(*name) => {},
            Some(..) | None => {
                return level <= directive.level
            }
        }
    }
    level <= DEFAULT_LOG_LEVEL
}

/// Initialize logging for the current process.
///
/// This is not threadsafe at all, so initialization os performed through a
/// `Once` primitive (and this function is called from that primitive).
fn init() {
    let mut directives = match os::getenv("RUST_LOG") {
        Some(spec) => directive::parse_logging_spec(spec),
        None => Vec::new(),
    };

    // Sort the provided directives by length of their name, this allows a
    // little more efficient lookup at runtime.
    directives.sort_by(|a, b| {
        let alen = a.name.as_ref().map(|a| a.len()).unwrap_or(0);
        let blen = b.name.as_ref().map(|b| b.len()).unwrap_or(0);
        alen.cmp(&blen)
    });

    let max_level = {
        let max = directives.iter().max_by(|d| d.level);
        max.map(|d| d.level).unwrap_or(DEFAULT_LOG_LEVEL)
    };

    unsafe {
        LOG_LEVEL = max_level;

        assert!(DIRECTIVES.is_null());
        DIRECTIVES = cast::transmute(~directives);

        // Schedule the cleanup for this global for when the runtime exits.
        rt::at_exit(proc() {
            assert!(!DIRECTIVES.is_null());
            let _directives: ~Vec<directive::LogDirective> =
                cast::transmute(DIRECTIVES);
            DIRECTIVES = 0 as *Vec<directive::LogDirective>;
        });
    }
}

#[cfg(test)]
mod tests {
    use super::enabled;
    use directive::LogDirective;

    #[test]
    fn match_full_path() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(2, "crate1::mod1", dirs.iter()));
        assert!(!enabled(3, "crate1::mod1", dirs.iter()));
        assert!(enabled(3, "crate2", dirs.iter()));
        assert!(!enabled(4, "crate2", dirs.iter()));
    }

    #[test]
    fn no_match() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(!enabled(2, "crate3", dirs.iter()));
    }

    #[test]
    fn match_beginning() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(3, "crate2::mod1", dirs.iter()));
    }

    #[test]
    fn match_beginning_longest_match() {
        let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
                    LogDirective { name: Some(~"crate2::mod"), level: 4 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(4, "crate2::mod1", dirs.iter()));
        assert!(!enabled(4, "crate2", dirs.iter()));
    }

    #[test]
    fn match_default() {
        let dirs = [LogDirective { name: None, level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
        assert!(enabled(2, "crate1::mod1", dirs.iter()));
        assert!(enabled(3, "crate2::mod2", dirs.iter()));
    }

    #[test]
    fn zero_level() {
        let dirs = [LogDirective { name: None, level: 3 },
                    LogDirective { name: Some(~"crate1::mod1"), level: 0 }];
        assert!(!enabled(1, "crate1::mod1", dirs.iter()));
        assert!(enabled(3, "crate2::mod2", dirs.iter()));
    }
}
<|endoftext|>


<commit_before>use crate::utils::deserialize::deserialize_opt_duration;
use cosmogony::ZoneType;
use geojson::{GeoJson, Geometry};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::time::Duration;

use crate::adapters::primary::common::coord::Coord;
use crate::adapters::primary::common::filters::Filters;
use common::document::ContainerDocument;
use places::{addr::Addr, admin::Admin, poi::Poi, stop::Stop, street::Street};

pub const DEFAULT_LIMIT_RESULT_ES: i64 = 10;

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ForwardGeocoderExplainQuery {
    pub doc_id: String,
    pub doc_type: String,

    #[serde(flatten)]
    pub query: ForwardGeocoderQuery,
}

/// This structure contains all the query parameters that
/// can be submitted for the autocomplete endpoint.
///
/// Only the `q` parameter is mandatory.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ForwardGeocoderQuery {
    pub q: String,
    pub lat: Option<f32>,
    pub lon: Option<f32>,
    pub shape_scope: Option<Vec<Type>>,
    pub datasets: Option<Vec<String>>,
    #[serde(default, rename = "type")]
    pub types: Option<Vec<Type>>,
    #[serde(default, rename = "zone_type")]
    pub zone_types: Option<Vec<ZoneType>>,
    pub poi_types: Option<Vec<String>>,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration", default)]
    pub timeout: Option<Duration>,
}

fn default_result_limit() -> i64 {
    DEFAULT_LIMIT_RESULT_ES
}

impl From<(ForwardGeocoderQuery, Option<Geometry>)> for Filters {
    fn from(source: (ForwardGeocoderQuery, Option<Geometry>)) -> Self {
        let (
            ForwardGeocoderQuery {
                q: _,
                lat,
                lon,
                shape_scope,
                datasets,
                types: _,
                zone_types,
                poi_types,
                limit,
                timeout,
            },
            geometry,
        ) = source;
        let zone_types = zone_types.map(|zts| {
            zts.iter()
                .map(|t| t.as_str().to_string())
                .collect()
        });
        Filters {
            // When option_zip_option becomes available: coord: input.lat.zip_with(input.lon, Coord::new),
            coord: match (lat, lon) {
                (Some(lat), Some(lon)) => Some(Coord::new(lat, lon)),
                _ => None,
            },
            shape: geometry.map(|geometry| {
                (
                    geometry,
                    shape_scope
                        .map(|shape_scope| {
                            shape_scope.iter().map(|t| t.as_str().to_string()).collect()
                        })
                        .unwrap_or_else(|| {
                            vec![
                                Type::House,
                                Type::Poi,
                                Type::StopArea,
                                Type::Street,
                                Type::Zone,
                            ]
                            .iter()
                            .map(|t| t.as_str().to_string())
                            .collect()
                        }),
                )
            }),
            datasets,
            zone_types,
            poi_types,
            limit,
            timeout,
        }
    }
}

/// This structure contains all the query parameters that
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ReverseGeocoderQuery {
    pub lat: f64,
    pub lon: f64,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration")]
    pub timeout: Option<Duration>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JsonParam {
    pub shape: GeoJson,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExplainResponseBody {
    pub explanation: JsonValue,
}

impl From<JsonValue> for ExplainResponseBody {
    fn from(explanation: JsonValue) -> Self {
        ExplainResponseBody { explanation }
    }
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BragiStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MimirStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ElasticsearchStatus {
    pub version: String,
    pub health: String,
    pub url: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct StatusResponseBody {
    pub bragi: BragiStatus,
    pub mimir: MimirStatus,
    pub elasticsearch: ElasticsearchStatus,
}

/// This macro is used to define the forward_geocoder route.
/// It takes a client (ElasticsearchStorage) and query settings
/// It can be either a GET request, with query parameters,
/// or a POST request, with both query parameters and a GeoJson shape
/// in the body.
#[macro_export]
macro_rules! forward_geocoder {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_get()
            .or(routes::forward_geocoder_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder)
    };
}

pub use forward_geocoder;

#[macro_export]
macro_rules! forward_geocoder_explain {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_explain_get()
            .or(routes::forward_geocoder_explain_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder_explain)
    };
}
pub use forward_geocoder_explain;

#[macro_export]
macro_rules! reverse_geocoder {
    ($cl:expr, $st:expr) => {
        routes::reverse_geocoder()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::reverse_geocoder)
    };
}
pub use reverse_geocoder;

#[macro_export]
macro_rules! status {
    ($cl:expr, $es:expr) => {
        routes::status()
            .and(routes::with_client($cl))
            .and(routes::with_elasticsearch($es))
            .and_then(handlers::status)
    };
}
pub use status;

#[derive(PartialEq, Copy, Clone, Debug, Deserialize, Serialize)]
pub enum Type {
    #[serde(rename = "house")]
    House,
    #[serde(rename = "poi")]
    Poi,
    #[serde(rename = "public_transport:stop_area")]
    StopArea,
    #[serde(rename = "street")]
    Street,
    #[serde(rename = "zone")]
    Zone,
}

impl Type {
    pub fn as_str(&self) -> &'static str {
        match self {
            Type::House => "house",
            Type::Poi => "poi",
            Type::StopArea => "public_transport:stop_area",
            Type::Street => "street",
            Type::Zone => "zone",
        }
    }

    pub fn as_index_type(&self) -> &'static str {
        match self {
            Type::House => Addr::static_doc_type(),
            Type::Poi => Poi::static_doc_type(),
            Type::StopArea => Stop::static_doc_type(),
            Type::Street => Street::static_doc_type(),
            Type::Zone => Admin::static_doc_type(),
        }
    }
}
<commit_msg>fmt passed<commit_after>use crate::utils::deserialize::deserialize_opt_duration;
use cosmogony::ZoneType;
use geojson::{GeoJson, Geometry};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::time::Duration;

use crate::adapters::primary::common::coord::Coord;
use crate::adapters::primary::common::filters::Filters;
use common::document::ContainerDocument;
use places::{addr::Addr, admin::Admin, poi::Poi, stop::Stop, street::Street};

pub const DEFAULT_LIMIT_RESULT_ES: i64 = 10;

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ForwardGeocoderExplainQuery {
    pub doc_id: String,
    pub doc_type: String,

    #[serde(flatten)]
    pub query: ForwardGeocoderQuery,
}

/// This structure contains all the query parameters that
/// can be submitted for the autocomplete endpoint.
///
/// Only the `q` parameter is mandatory.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ForwardGeocoderQuery {
    pub q: String,
    pub lat: Option<f32>,
    pub lon: Option<f32>,
    pub shape_scope: Option<Vec<Type>>,
    pub datasets: Option<Vec<String>>,
    #[serde(default, rename = "type")]
    pub types: Option<Vec<Type>>,
    #[serde(default, rename = "zone_type")]
    pub zone_types: Option<Vec<ZoneType>>,
    pub poi_types: Option<Vec<String>>,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration", default)]
    pub timeout: Option<Duration>,
}

fn default_result_limit() -> i64 {
    DEFAULT_LIMIT_RESULT_ES
}

impl From<(ForwardGeocoderQuery, Option<Geometry>)> for Filters {
    fn from(source: (ForwardGeocoderQuery, Option<Geometry>)) -> Self {
        let (
            ForwardGeocoderQuery {
                q: _,
                lat,
                lon,
                shape_scope,
                datasets,
                types: _,
                zone_types,
                poi_types,
                limit,
                timeout,
            },
            geometry,
        ) = source;
        let zone_types = zone_types.map(|zts| zts.iter().map(|t| t.as_str().to_string()).collect());
        Filters {
            // When option_zip_option becomes available: coord: input.lat.zip_with(input.lon, Coord::new),
            coord: match (lat, lon) {
                (Some(lat), Some(lon)) => Some(Coord::new(lat, lon)),
                _ => None,
            },
            shape: geometry.map(|geometry| {
                (
                    geometry,
                    shape_scope
                        .map(|shape_scope| {
                            shape_scope.iter().map(|t| t.as_str().to_string()).collect()
                        })
                        .unwrap_or_else(|| {
                            vec![
                                Type::House,
                                Type::Poi,
                                Type::StopArea,
                                Type::Street,
                                Type::Zone,
                            ]
                            .iter()
                            .map(|t| t.as_str().to_string())
                            .collect()
                        }),
                )
            }),
            datasets,
            zone_types,
            poi_types,
            limit,
            timeout,
        }
    }
}

/// This structure contains all the query parameters that
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ReverseGeocoderQuery {
    pub lat: f64,
    pub lon: f64,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration")]
    pub timeout: Option<Duration>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JsonParam {
    pub shape: GeoJson,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExplainResponseBody {
    pub explanation: JsonValue,
}

impl From<JsonValue> for ExplainResponseBody {
    fn from(explanation: JsonValue) -> Self {
        ExplainResponseBody { explanation }
    }
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BragiStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MimirStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ElasticsearchStatus {
    pub version: String,
    pub health: String,
    pub url: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct StatusResponseBody {
    pub bragi: BragiStatus,
    pub mimir: MimirStatus,
    pub elasticsearch: ElasticsearchStatus,
}

/// This macro is used to define the forward_geocoder route.
/// It takes a client (ElasticsearchStorage) and query settings
/// It can be either a GET request, with query parameters,
/// or a POST request, with both query parameters and a GeoJson shape
/// in the body.
#[macro_export]
macro_rules! forward_geocoder {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_get()
            .or(routes::forward_geocoder_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder)
    };
}

pub use forward_geocoder;

#[macro_export]
macro_rules! forward_geocoder_explain {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_explain_get()
            .or(routes::forward_geocoder_explain_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder_explain)
    };
}
pub use forward_geocoder_explain;

#[macro_export]
macro_rules! reverse_geocoder {
    ($cl:expr, $st:expr) => {
        routes::reverse_geocoder()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::reverse_geocoder)
    };
}
pub use reverse_geocoder;

#[macro_export]
macro_rules! status {
    ($cl:expr, $es:expr) => {
        routes::status()
            .and(routes::with_client($cl))
            .and(routes::with_elasticsearch($es))
            .and_then(handlers::status)
    };
}
pub use status;

#[derive(PartialEq, Copy, Clone, Debug, Deserialize, Serialize)]
pub enum Type {
    #[serde(rename = "house")]
    House,
    #[serde(rename = "poi")]
    Poi,
    #[serde(rename = "public_transport:stop_area")]
    StopArea,
    #[serde(rename = "street")]
    Street,
    #[serde(rename = "zone")]
    Zone,
}

impl Type {
    pub fn as_str(&self) -> &'static str {
        match self {
            Type::House => "house",
            Type::Poi => "poi",
            Type::StopArea => "public_transport:stop_area",
            Type::Street => "street",
            Type::Zone => "zone",
        }
    }

    pub fn as_index_type(&self) -> &'static str {
        match self {
            Type::House => Addr::static_doc_type(),
            Type::Poi => Poi::static_doc_type(),
            Type::StopArea => Stop::static_doc_type(),
            Type::Street => Street::static_doc_type(),
            Type::Zone => Admin::static_doc_type(),
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use iron::prelude::*;
use iron::headers::ContentType;
use rustc_serialize::json::Json;
use super::page::Page;
use super::pool::Pool;
use time;
use db::connect_db;

pub fn sitemap_handler(req: &mut Request) -> IronResult<Response> {
    let conn = extension!(req, Pool);
    let mut releases: Vec<(String, String)> = Vec::new();
    for row in &conn.query("SELECT DISTINCT ON (crates.name)
                                   crates.name,
                                   releases.release_time
                            FROM crates
                            INNER JOIN releases ON releases.crate_id = crates.id
                            WHERE rustdoc_status = true",
               &[])
        .unwrap() {
        releases.push((row.get(0), format!("{}", time::at(row.get(1)).rfc3339())));
    }
    let mut resp = ctry!(Page::new(releases).to_resp("sitemap"));
    resp.headers.set(ContentType("application/xml".parse().unwrap()));
    Ok(resp)
}

pub fn robots_txt_handler(_: &mut Request) -> IronResult<Response> {
    let mut resp = Response::with("Sitemap: https://docs.rs/sitemap.xml");
    resp.headers.set(ContentType("text/plain".parse().unwrap()));
    Ok(resp)
}

pub fn about_handler(req: &mut Request) -> IronResult<Response> {
    let mut content = BTreeMap::new();

    let conn = extension!(req, Pool);
    let res = ctry!(conn.query("SELECT value FROM config WHERE name = 'rustc_version'", &[]));

    if let Some(row) = res.iter().next() {
        if let Some(Ok::<Json, _>(res)) = row.get_opt(0) {
            if let Some(vers) = res.as_string() {
                content.insert("rustc_version".to_string(), vers.to_string());
            }
        }
    }

    Page::new(content).title("About Docs.rs").to_resp("about")
}
<commit_msg>Remove unused import<commit_after>use std::collections::BTreeMap;
use iron::prelude::*;
use iron::headers::ContentType;
use rustc_serialize::json::Json;
use super::page::Page;
use super::pool::Pool;
use time;

pub fn sitemap_handler(req: &mut Request) -> IronResult<Response> {
    let conn = extension!(req, Pool);
    let mut releases: Vec<(String, String)> = Vec::new();
    for row in &conn.query("SELECT DISTINCT ON (crates.name)
                                   crates.name,
                                   releases.release_time
                            FROM crates
                            INNER JOIN releases ON releases.crate_id = crates.id
                            WHERE rustdoc_status = true",
               &[])
        .unwrap() {
        releases.push((row.get(0), format!("{}", time::at(row.get(1)).rfc3339())));
    }
    let mut resp = ctry!(Page::new(releases).to_resp("sitemap"));
    resp.headers.set(ContentType("application/xml".parse().unwrap()));
    Ok(resp)
}

pub fn robots_txt_handler(_: &mut Request) -> IronResult<Response> {
    let mut resp = Response::with("Sitemap: https://docs.rs/sitemap.xml");
    resp.headers.set(ContentType("text/plain".parse().unwrap()));
    Ok(resp)
}

pub fn about_handler(req: &mut Request) -> IronResult<Response> {
    let mut content = BTreeMap::new();

    let conn = extension!(req, Pool);
    let res = ctry!(conn.query("SELECT value FROM config WHERE name = 'rustc_version'", &[]));

    if let Some(row) = res.iter().next() {
        if let Some(Ok::<Json, _>(res)) = row.get_opt(0) {
            if let Some(vers) = res.as_string() {
                content.insert("rustc_version".to_string(), vers.to_string());
            }
        }
    }

    Page::new(content).title("About Docs.rs").to_resp("about")
}
<|endoftext|>


<commit_before>extern crate pihex;
use pihex::*;

#[test]
fn pihex_test() {
    assert_eq!(pihex(0), "243f");
    assert_eq!(pihex(1), "43f6");
    assert_eq!(pihex(2), "3f6a");
    assert_eq!(pihex(3), "f6a8");
    assert_eq!(pihex(4), "6a88");
    assert_eq!(pihex(8), "85a3");
    assert_eq!(pihex(12), "08d3");
    assert_eq!(pihex(96), "c0ac");
    assert_eq!(pihex(128), "9216");
    assert_eq!(pihex(1024), "25d4");
    assert_eq!(pihex(4096), "5a04");
    assert_eq!(pihex(8192), "77af");
}
<commit_msg>add more test cases (especially test not to make error due to precision bugs)<commit_after>extern crate pihex;
use pihex::*;

const TEST_CASES: &[(u32, &str)] = &[(0, "243f"),
                                     (1, "43f6"),
                                     (2, "3f6a"),
                                     (3, "f6a8"),
                                     (4, "6a88"),
                                     (8, "85a3"),
                                     (12, "08d3"),
                                     (96, "c0ac"),
                                     (128, "9216"),
                                     (1024, "25d4"),
                                     (3704, "34c6"),
                                     (4096, "5a04"),
                                     (4527, "e4f3"),
                                     (8192, "77af"),
                                     (2090, "e674"),
                                     (2944, "5094"),
                                     (11027, "e70f"),
                                     (11742, "41fb"),
                                     (15367, "0c67")];

#[test]
fn pihex_test() {
    for &(d, hex) in TEST_CASES {
        assert_eq!(pihex(d), hex);
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code, unused_variables)]

extern crate rebind;
extern crate input;

use rebind::{Action, Builder, ButtonTuple, InputRebind, InputTranslator, Translated};
use input::Input;
use input::Button::Keyboard;
use input::keyboard::Key;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
enum TestAction {
    Action1,
    Action2,
    Action3,
    Action4,
    Action5,
    Action6,
    Action7,
    Action8,
    Action9,
    Action10,
}

impl Action for TestAction { }

type TestBuilder = Builder<TestAction>;
type TestTranslator = InputTranslator<TestAction>;
type TestRebind = InputRebind<TestAction>;

fn create_prepopulated_builder() -> TestBuilder {
    Builder::default()
        .with_mapping(TestAction::Action1, Keyboard(Key::Up))
        .with_mapping(TestAction::Action1, Keyboard(Key::W))
        .with_mapping(TestAction::Action2, Keyboard(Key::Down))
        .with_mapping(TestAction::Action2, Keyboard(Key::S))
        .with_mapping(TestAction::Action3, Keyboard(Key::Left))
        .with_mapping(TestAction::Action3, Keyboard(Key::A))
        .with_mapping(TestAction::Action4, Keyboard(Key::Right))
        .with_mapping(TestAction::Action4, Keyboard(Key::D))
}

#[test]
fn test_translator_get_action_from_buttonpress() {
    let translator = create_prepopulated_builder().build_translator();

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Down))).unwrap(),
               Translated::Press(TestAction::Action2));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::D))).unwrap(),
               Translated::Press(TestAction::Action4));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Left))).unwrap(),
               Translated::Press(TestAction::Action3));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::W))).unwrap(),
               Translated::Press(TestAction::Action1));
}

#[test]
fn test_conversion_from_rebind_to_translator() {
    let translator = create_prepopulated_builder().build_translator();

    let translator_clone = translator.clone();
    let converted_translator = Into::<TestTranslator>::into(Into::<TestRebind>::into(translator));

    assert_eq!(translator_clone, converted_translator);
}

#[test]
fn test_add_button_to_translator_using_rebind() {
    use input::Button;
    const Q_KEY: Button = Keyboard(Key::Q);
    const E_KEY: Button = Keyboard(Key::E);

    let translator = create_prepopulated_builder().build_translator();
    let mut rebind = translator.into_rebind();
    rebind.insert_action_with_buttons(TestAction::Action5,
                                      ButtonTuple(Some(Q_KEY), Some(E_KEY), None));

    let translator = rebind.into_translator();

    assert_eq!(translator.translate(&Input::Press(Q_KEY)),
               Some(Translated::Press(TestAction::Action5)));
    assert_eq!(translator.translate(&Input::Press(E_KEY)),
               Some(Translated::Press(TestAction::Action5)));
}

#[test]
fn test_get_num_buttons_set() {
    let mut bt = ButtonTuple::new();
    assert_eq!(bt.num_buttons_set(), 0);

    bt.0 = Some(Keyboard(Key::Z));
    assert_eq!(bt.num_buttons_set(), 1);

    bt.1 = Some(Keyboard(Key::Q));
    assert_eq!(bt.num_buttons_set(), 2);

    bt.2 = Some(Keyboard(Key::D0));
    assert_eq!(bt.num_buttons_set(), 3);
}

#[test]
fn test_get_button_iter_len() {
    let bt = ButtonTuple(Some(Keyboard(Key::B)), None, None);
    let mut bti = bt.iter();
    assert_eq!(bti.len(), 3);
    let _ = bti.next();
    assert_eq!(bti.len(), 2);
    let _ = bti.next();
    assert_eq!(bti.len(), 1);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
}
<commit_msg>Add some initial mouse tests (failing atm), some refactoring<commit_after>#![allow(dead_code)]

extern crate rebind;
extern crate input;
extern crate window;

use input::Input;
use input::Button::Keyboard;
use input::keyboard::Key;
use rebind::{Action, Builder, ButtonTuple, InputRebind, InputTranslator, Translated};
use window::Size;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
enum TestAction {
    Action1,
    Action2,
    Action3,
    Action4,
    Action5,
    Action6,
    Action7,
    Action8,
    Action9,
    Action10,
}

impl Action for TestAction { }

type TestBuilder = Builder<TestAction>;
type TestTranslator = InputTranslator<TestAction>;
type TestRebind = InputRebind<TestAction>;

fn create_prepopulated_builder_with_size(s: Size) -> TestBuilder {
    populate_builder(Builder::new(s))
}

fn create_prepopulated_builder() -> TestBuilder {
    populate_builder(Builder::default())
}

fn populate_builder(builder: TestBuilder) -> TestBuilder {
    builder.with_mapping(TestAction::Action1, Keyboard(Key::Up))
           .with_mapping(TestAction::Action1, Keyboard(Key::W))
           .with_mapping(TestAction::Action2, Keyboard(Key::Down))
           .with_mapping(TestAction::Action2, Keyboard(Key::S))
           .with_mapping(TestAction::Action3, Keyboard(Key::Left))
           .with_mapping(TestAction::Action3, Keyboard(Key::A))
           .with_mapping(TestAction::Action4, Keyboard(Key::Right))
           .with_mapping(TestAction::Action4, Keyboard(Key::D))
}

#[test]
fn test_translator_get_action_from_buttonpress() {
    let translator = create_prepopulated_builder().build_translator();

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Down))).unwrap(),
               Translated::Press(TestAction::Action2));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::D))).unwrap(),
               Translated::Press(TestAction::Action4));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Left))).unwrap(),
               Translated::Press(TestAction::Action3));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::W))).unwrap(),
               Translated::Press(TestAction::Action1));
}

#[test]
fn test_conversion_from_rebind_to_translator() {
    let translator = create_prepopulated_builder().build_translator();

    let translator_clone = translator.clone();
    let converted_translator = Into::<TestTranslator>::into(Into::<TestRebind>::into(translator));

    assert_eq!(translator_clone, converted_translator);
}

#[test]
fn test_add_button_to_translator_using_rebind() {
    use input::Button;
    const Q_KEY: Button = Keyboard(Key::Q);
    const E_KEY: Button = Keyboard(Key::E);

    let translator = create_prepopulated_builder().build_translator();
    let mut rebind = translator.into_rebind();
    rebind.insert_action_with_buttons(TestAction::Action5,
                                      ButtonTuple(Some(Q_KEY), Some(E_KEY), None));

    let translator = rebind.into_translator();

    assert_eq!(translator.translate(&Input::Press(Q_KEY)),
               Some(Translated::Press(TestAction::Action5)));
    assert_eq!(translator.translate(&Input::Press(E_KEY)),
               Some(Translated::Press(TestAction::Action5)));
}

#[test]
fn test_unmodified_mouse_input_works() {
    const TEST_SIZE: Size = Size { width: 800, height: 600 };

    let translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_mirror_mouse_input_along_x_axis() {
    const TEST_SIZE: Size = Size { width: 800, height: 600 };

    let translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_mirror_mouse_input_along_y_axis() {
    const TEST_SIZE: Size = Size { width: 800, height: 600 };

    let translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_get_num_buttons_set() {
    let mut bt = ButtonTuple::new();
    assert_eq!(bt.num_buttons_set(), 0);

    bt.0 = Some(Keyboard(Key::Z));
    assert_eq!(bt.num_buttons_set(), 1);

    bt.1 = Some(Keyboard(Key::Q));
    assert_eq!(bt.num_buttons_set(), 2);

    bt.2 = Some(Keyboard(Key::D0));
    assert_eq!(bt.num_buttons_set(), 3);
}

#[test]
fn test_get_button_iter_len() {
    let bt = ButtonTuple(Some(Keyboard(Key::B)), None, None);
    let mut bti = bt.iter();
    assert_eq!(bti.len(), 3);
    let _ = bti.next();
    assert_eq!(bti.len(), 2);
    let _ = bti.next();
    assert_eq!(bti.len(), 1);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
}
<|endoftext|>


<commit_before>extern crate presort;

use presort::PermutedVec;
use std::rc::Rc;
use std::cell::RefCell;

struct TreeNode<T> {
    //whether this node's data has changed
    dirty_val: bool,
    //whether some descendant is dirty
    dirty_descendant: bool,
    //the old size of the tree
    old_size: usize,
    //parent and index in parent's child vec
    parent: Option<(Tree<T>, usize)>,
    //this node's data
    data: T,
    children: Vec<Tree<T>>,
}

type Tree<T> = Rc<RefCell<TreeNode<T>>>;

trait IncTree<T: PartialEq + Clone> {
    fn new_node(data: T) -> Tree<T>;
    fn dirty_decendents(&self);
    fn dirty_ancestors(&self);
    fn get_data(&self) -> T;
    fn set_data(&self, data: T);
    fn get_child(&self, child_num: usize) -> Tree<T>;
    fn set_child(&self, child_num: usize, child: Tree<T>);
    fn push_child(&self, child: Tree<T>);
    fn pop_child(&self) -> Option<Tree<T>>;
}

impl<T: PartialEq + Clone> IncTree<T> for Tree<T> {
    fn new_node(data: T) -> Tree<T>{
        Rc::new(RefCell::new(TreeNode {
            dirty_val: true,
            dirty_descendant: true,
            old_size: 0,
            parent: None,
            data: data,
            children: vec![]
        }))
    }

    //sets dirty flags, but leaves counts
    fn dirty_decendents(&self) {
        let mut tree = self.borrow_mut();
        tree.dirty_val = true;
        tree.dirty_descendant = true;
        for kid in &tree.children {
            kid.dirty_decendents();
        }
    }

        fn dirty_ancestors(&self){
                let mut node = self.borrow_mut();
                node.dirty_descendant = true;
                if let Some((ref parent, _)) = node.parent {
                    parent.dirty_ancestors();
                }
    }

    fn get_data(&self) -> T {
        self.borrow().data.clone()
    }

    fn set_data(&self, data: T) {
        {
            let mut tree = self.borrow_mut();
            if tree.data == data {return}
            tree.data = data;
            tree.dirty_val = true;
        }
        self.dirty_ancestors();
    }

    fn get_child(&self, child_num: usize) -> Tree<T> {
        self.borrow().children[child_num].clone() //Rc clone
    }

    fn set_child(&self, child_num: usize, child: Tree<T>) {
        //assume all new values are dirty
        child.dirty_decendents();
        child.borrow_mut().parent = Some((self.clone(), child_num)); //Rc clone
        child.dirty_ancestors();
        self.borrow_mut().children[child_num] = child;
    }

    fn push_child(&self, child: Tree<T>) {
        //assume all new values are dirty
        child.dirty_decendents();
        child.borrow_mut().parent = Some((self.clone(), self.borrow().children.len())); //Rc clone
        child.dirty_ancestors();
        self.borrow_mut().children.push(child);
    }

    fn pop_child(&self) -> Option<Tree<T>> {
        let child = self.borrow_mut().children.pop();
        if let Some(ref child) = child {
            self.borrow_mut().dirty_val = true;
            self.dirty_ancestors();
            child.borrow_mut().parent = None;
        }
        child
    }
}

fn dump<T: Clone>(tree: &Tree<T>, vec: &mut PermutedVec<T>) -> usize {
    let mut tree = tree.borrow_mut();
    let mut size = 1;
    vec.push(tree.data.clone());
    tree.dirty_val = false;
    for kid in &tree.children { size += dump(&kid, vec); }
    tree.dirty_descendant = false;
    tree.old_size = size;
    size
}

fn update<T: Clone>(tree: &Tree<T>, start_index: usize, vec: &mut PermutedVec<T>) -> usize {
    let mut tree = tree.borrow_mut();
    let mut size = tree.old_size;
    if tree.dirty_descendant || vec.len() < start_index + size {
        if vec.len() <= start_index {
            vec.push(tree.data.clone());
        } else if tree.dirty_val {
            vec.set(start_index, tree.data.clone());
        }
        tree.dirty_val = false;
        size = 1;
        for kid in &tree.children { size += update(&kid, start_index + size, vec); }
        tree.dirty_descendant = false;
        if tree.old_size != size {
            vec.truncate(start_index + size);
            tree.old_size = size;
        }
    }
    size
}

#[test]
fn test_tree() {
    let main_tree = Tree::new_node(37);
    let mut vec = PermutedVec::new();
    dump(&main_tree, &mut vec);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&37]);
}

#[test]
fn test_update() {
    println!("start first dump");
    let main_tree = Tree::new_node(37);
    main_tree.push_child(Tree::new_node(42));
    main_tree.push_child(Tree::new_node(20));
    main_tree.push_child(Tree::new_node(63));
    let mut vec = PermutedVec::new();
    dump(&main_tree, &mut vec);
    println!("finished first dump");
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&20,&37,&42,&63]);

    println!("start first update");
    main_tree.get_child(1).set_data(25);
    update(&main_tree, 0, &mut vec);
    println!("finished first update");
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&25,&37,&42,&63]);

    println!("start add branch");
    let branch = main_tree.get_child(2);
    branch.push_child(Tree::new_node(47));
    branch.push_child(Tree::new_node(53));
    branch.push_child(Tree::new_node(61));
    branch.push_child(Tree::new_node(57));
    update(&main_tree, 0, &mut vec);
    println!("finished add branch");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&25,&37,&42,&47,&53,&57,&61,&63]
    );

    println!("start update branch");
    branch.get_child(2).set_data(77);
    update(&main_tree, 0, &mut vec);
    println!("finished update branch");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&25,&37,&42,&47,&53,&57,&63,&77]
    );

    println!("start early insertion");
    let branch = main_tree.get_child(1);
    branch.push_child(Tree::new_node(1));
    update(&main_tree, 0, &mut vec);
    println!("finished early insertion");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77]
    );

    println!("start deep add");
    let branch = main_tree.get_child(2).get_child(2);
    let new_branch = Tree::new_node(100);
    new_branch.push_child(Tree::new_node(101));
    branch.push_child(new_branch);
    update(&main_tree, 0, &mut vec);
    println!("finished deep add");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77,&100,&101]
    );

    println!("start deep edit");
    let branch = branch.get_child(0).get_child(0);
    branch.set_data(105);
    update(&main_tree, 0, &mut vec);
    println!("finished deep edit");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77,&100,&105]
    );

    println!("start pop branch");
    let branch = main_tree.get_child(2).get_child(2);
    branch.pop_child();
    update(&main_tree, 0, &mut vec);
    println!("finished pop branch");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77]
    );

}
<commit_msg>rename for clarification<commit_after>extern crate presort;

use presort::PermutedVec;
use std::rc::Rc;
use std::cell::RefCell;

struct TreeNode<T> {
    //whether this node's data has changed
    dirty_val: bool,
    //whether some this or decendents have changed
    needs_update: bool,
    //the old size of the tree
    old_size: usize,
    //parent and index in parent's child vec
    parent: Option<(Tree<T>, usize)>,
    //this node's data
    data: T,
    children: Vec<Tree<T>>,
}

type Tree<T> = Rc<RefCell<TreeNode<T>>>;

trait IncTree<T: PartialEq + Clone> {
    fn new_node(data: T) -> Tree<T>;
    fn flag_as_new(&self);
    fn flag_as_updated(&self);
    fn get_data(&self) -> T;
    fn set_data(&self, data: T);
    fn get_child(&self, child_num: usize) -> Tree<T>;
    fn set_child(&self, child_num: usize, child: Tree<T>);
    fn push_child(&self, child: Tree<T>);
    fn pop_child(&self) -> Option<Tree<T>>;
}

impl<T: PartialEq + Clone> IncTree<T> for Tree<T> {
    fn new_node(data: T) -> Tree<T>{
        Rc::new(RefCell::new(TreeNode {
            dirty_val: true,
            needs_update: true,
            old_size: 0,
            parent: None,
            data: data,
            children: vec![]
        }))
    }

    //sets dirty flags on all children and parents
    //set the new parent first for proper effect
    fn flag_as_new(&self) {
        let mut tree = self.borrow_mut();
        tree.dirty_val = true;
        tree.needs_update = true;
        for kid in &tree.children {
            kid.flag_as_new();
        }
        tree.flag_as_updated();
    }

    //sets dirty flags on self and parents
    fn flag_as_updated(&self){
            let mut node = self.borrow_mut();
            node.needs_update = true;
            if let Some((ref parent, _)) = node.parent {
                parent.flag_as_updated();
            }
    }

    fn get_data(&self) -> T {
        self.borrow().data.clone()
    }

    fn set_data(&self, data: T) {
        {
            let mut tree = self.borrow_mut();
            if tree.data == data {return}
            tree.data = data;
            tree.dirty_val = true;
        }
        self.flag_as_updated();
    }

    fn get_child(&self, child_num: usize) -> Tree<T> {
        self.borrow().children[child_num].clone() //Rc clone
    }

    fn set_child(&self, child_num: usize, child: Tree<T>) {
        child.borrow_mut().parent = Some((self.clone(), child_num)); //Rc clone
        child.flag_as_new();
        self.borrow_mut().children[child_num] = child;
    }

    fn push_child(&self, child: Tree<T>) {
        child.borrow_mut().parent = Some((self.clone(), self.borrow().children.len())); //Rc clone
        child.flag_as_new();
        self.borrow_mut().children.push(child);
    }

    fn pop_child(&self) -> Option<Tree<T>> {
        let child = self.borrow_mut().children.pop();
        if let Some(ref child) = child {
            self.borrow_mut().dirty_val = true;
            self.flag_as_updated();
            child.borrow_mut().parent = None;
        }
        child
    }
}

fn dump<T: Clone>(tree: &Tree<T>, vec: &mut PermutedVec<T>) -> usize {
    let mut tree = tree.borrow_mut();
    let mut size = 1;
    vec.push(tree.data.clone());
    tree.dirty_val = false;
    for kid in &tree.children { size += dump(&kid, vec); }
    tree.needs_update = false;
    tree.old_size = size;
    size
}

fn update<T: Clone>(tree: &Tree<T>, start_index: usize, vec: &mut PermutedVec<T>) -> usize {
    let mut tree = tree.borrow_mut();
    let mut size = tree.old_size;
    if tree.needs_update || vec.len() < start_index + size {
        if vec.len() <= start_index {
            vec.push(tree.data.clone());
        } else if tree.dirty_val {
            vec.set(start_index, tree.data.clone());
        }
        tree.dirty_val = false;
        size = 1;
        for kid in &tree.children { size += update(&kid, start_index + size, vec); }
        tree.needs_update = false;
        if tree.old_size != size {
            vec.truncate(start_index + size);
            tree.old_size = size;
        }
    }
    size
}

#[test]
fn test_tree() {
    let main_tree = Tree::new_node(37);
    let mut vec = PermutedVec::new();
    dump(&main_tree, &mut vec);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&37]);
}

#[test]
fn test_update() {
    println!("start first dump");
    let main_tree = Tree::new_node(37);
    main_tree.push_child(Tree::new_node(42));
    main_tree.push_child(Tree::new_node(20));
    main_tree.push_child(Tree::new_node(63));
    let mut vec = PermutedVec::new();
    dump(&main_tree, &mut vec);
    println!("finished first dump");
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&20,&37,&42,&63]);

    println!("start first update");
    main_tree.get_child(1).set_data(25);
    update(&main_tree, 0, &mut vec);
    println!("finished first update");
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&25,&37,&42,&63]);

    println!("start add branch");
    let branch = main_tree.get_child(2);
    branch.push_child(Tree::new_node(47));
    branch.push_child(Tree::new_node(53));
    branch.push_child(Tree::new_node(61));
    branch.push_child(Tree::new_node(57));
    update(&main_tree, 0, &mut vec);
    println!("finished add branch");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&25,&37,&42,&47,&53,&57,&61,&63]
    );

    println!("start update branch");
    branch.get_child(2).set_data(77);
    update(&main_tree, 0, &mut vec);
    println!("finished update branch");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&25,&37,&42,&47,&53,&57,&63,&77]
    );

    println!("start early insertion");
    let branch = main_tree.get_child(1);
    branch.push_child(Tree::new_node(1));
    update(&main_tree, 0, &mut vec);
    println!("finished early insertion");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77]
    );

    println!("start deep add");
    let branch = main_tree.get_child(2).get_child(2);
    let new_branch = Tree::new_node(100);
    new_branch.push_child(Tree::new_node(101));
    branch.push_child(new_branch);
    update(&main_tree, 0, &mut vec);
    println!("finished deep add");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77,&100,&101]
    );

    println!("start deep edit");
    let branch = branch.get_child(0).get_child(0);
    branch.set_data(105);
    update(&main_tree, 0, &mut vec);
    println!("finished deep edit");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77,&100,&105]
    );

    println!("start pop branch");
    let branch = main_tree.get_child(2).get_child(2);
    branch.pop_child();
    update(&main_tree, 0, &mut vec);
    println!("finished pop branch");
    assert_eq!(
        vec.sorted_iter().collect::<Vec<&usize>>(),
        vec![&1,&25,&37,&42,&47,&53,&57,&63,&77]
    );

}
<|endoftext|>