<commit_before>//! Parser module is responsible for parsing FITS files.

named!(fits<&[u8], ((Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >), Vec<&[u8]>) >,
       pair!(primary_header, many0!( take!(2880) )));

named!(primary_header<&[u8], (Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >)>,
       tuple!(
           count!(a_header, 55),
           end_header,
           count!(blank_header, 16)
       ));

named!(a_header<&[u8], (&[u8], &[u8], &[u8])>,
       tuple!(
           take!(8),
           tag!("="),
           take!(71)
       ));

named!(end_header<&[u8],(&[u8], Vec<&[u8]>)>, pair!(tag!("END"), count!(tag!(" "), 77)));

named!(blank_header<&[u8],Vec<&[u8]> >, count!(tag!(" "), 80));

#[cfg(test)]
mod tests {
    use nom::{IResult};
    use super::{fits, primary_header, end_header, blank_header, a_header};

    #[test]
    fn it_should_parse_a_fits_file(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = fits(data);

        match result {
            IResult::Done(_, (header, blocks)) => {
                assert_eq!(blocks.len(), 3675);
            },
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn primary_header_should_parse_a_primary_header(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = primary_header(&data[0..(2*2880)]);

        match result {
            IResult::Done(_, _) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn a_header_should_parse_a_header(){
        let data = "OBJECT  = 'EPIC 200164267'     / string version of target id                    "
            .as_bytes();

        let result = a_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn end_header_should_parse_an_END_header(){
        let data = "END                                                                             "
            .as_bytes();

        let result = end_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn blank_header_should_parse_a_BLANK_header(){
        let data = "                                                                                "
            .as_bytes();

        let result = blank_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }
}
<commit_msg>Don't rely on actual numbers in primary header parser<commit_after>//! Parser module is responsible for parsing FITS files.

named!(fits<&[u8], ((Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >), Vec<&[u8]>) >,
       pair!(primary_header, many0!( take!(2880) )));

named!(primary_header<&[u8], (Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >)>,
       tuple!(
           many0!(a_header),
           end_header,
           many0!(blank_header)
       ));

named!(a_header<&[u8], (&[u8], &[u8], &[u8])>,
       tuple!(
           take!(8),
           tag!("="),
           take!(71)
       ));

named!(end_header<&[u8],(&[u8], Vec<&[u8]>)>, pair!(tag!("END"), count!(tag!(" "), 77)));

named!(blank_header<&[u8],Vec<&[u8]> >, count!(tag!(" "), 80));

#[cfg(test)]
mod tests {
    use nom::{IResult};
    use super::{fits, primary_header, end_header, blank_header, a_header};

    #[test]
    fn it_should_parse_a_fits_file(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = fits(data);

        match result {
            IResult::Done(_, (header, blocks)) => {
                assert_eq!(blocks.len(), 3675);
            },
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn primary_header_should_parse_a_primary_header(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = primary_header(&data[0..(2*2880)]);

        match result {
            IResult::Done(_, _) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn a_header_should_parse_a_header(){
        let data = "OBJECT  = 'EPIC 200164267'     / string version of target id                    "
            .as_bytes();

        let result = a_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn end_header_should_parse_an_END_header(){
        let data = "END                                                                             "
            .as_bytes();

        let result = end_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn blank_header_should_parse_a_BLANK_header(){
        let data = "                                                                                "
            .as_bytes();

        let result = blank_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use ffi;
use libc::c_void;
use std::mem;

pub use self::event_type::EventType;
pub use self::owner_change::OwnerChange;
pub use self::setting_action::SettingAction;
pub use self::property_state::PropertyState;
pub use self::crossing_mode::CrossingMode;
pub use self::notify_type::NotifyType;
pub use self::scroll_direction::ScrollDirection;
pub use self::visibility_state::VisibilityState;

pub mod event_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum EventType {
        Nothing           = -1,
        Delete            = 0,
        Destroy           = 1,
        Expose            = 2,
        MotionNotify      = 3,
        ButtonPress       = 4,
        DoubleButtonPress = 5,
        TripleButtonPress = 6,
        ButtonRelease     = 7,
        KeyPress          = 8,
        KeyRelease        = 9,
        EnterNotify       = 10,
        LeaveNotify       = 11,
        FocusChange       = 12,
        Configure         = 13,
        Map               = 14,
        Unmap             = 15,
        PropertyNotify    = 16,
        SelectionClear    = 17,
        SelectionRequest  = 18,
        SelectionNotify   = 19,
        ProximityIn       = 20,
        ProximityOut      = 21,
        DragEnter         = 22,
        DragLeave         = 23,
        DragMotion        = 24,
        DragStatus        = 25,
        DropStart         = 26,
        DropFinished      = 27,
        ClientEvent       = 28,
        VisibilityNotify  = 29,
        Scroll            = 31,
        WindowState       = 32,
        Setting           = 33,
        OwnerChange       = 34,
        GrabBroken        = 35,
        Damage            = 36,
        TouchBegin        = 37,
        TouchUpdate       = 38,
        TouchEnd          = 39,
        TouchCancel       = 40
    }
}

pub trait Event: Sized {
    fn get_send_event(&self) -> bool {
        unsafe {
            let event_any : &EventAny = mem::transmute(self);
            event_any.send_event == 0
        }
    }
}

// TODO unfinished, see #25

#[repr(C)]
pub struct EventAny {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,
}

impl Event for EventAny {}

#[allow(dead_code)]
pub struct EventExpose {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub area : ffi::C_GdkRectangle,
    region : *mut c_void, //TODO cairo_region_t
    pub count : i8 /* If non-zero, how many more events follow. */
}

impl Event for EventExpose {}

#[allow(dead_code)]
pub struct EventVisibility{
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub state : ::VisibilityState
}

impl Event for EventVisibility {}

#[allow(dead_code)]
pub struct EventMotion {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub is_hint : i16,
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventMotion {}

#[allow(dead_code)]
pub struct EventButton {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub button : u32,
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventButton {}

#[allow(dead_code)]
pub struct EventTouch {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    sequence : *mut c_void, //::EventSequence
    pub emulating_pointer : i32, // boolean
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventTouch {}

#[allow(dead_code)]
pub struct EventScroll {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub direction : ::ScrollDirection,
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64,
    pub delta_x : f64,
    pub delta_y : f64
}

impl Event for EventScroll {}

#[allow(dead_code)]
pub struct EventKey {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub state : ::enums::modifier_type::ModifierType,
    pub keyval : u32,
    pub length : i32,
    pub string : *mut char,
    pub hardware_keycode : u16,
    pub group : u8,
    pub is_modifier: u32
}

impl Event for EventKey {}

#[allow(dead_code)]
pub struct EventCrossing {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub subwindow : ::Window,
    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub x_root : f64,
    pub y_root : f64,
    pub mode : ::CrossingMode,
    pub detail : ::NotifyType,
    pub focus : i32, // boolean
    pub state : ::enums::modifier_type::ModifierType
}

impl Event for EventCrossing {}

#[allow(dead_code)]
pub struct EventFocus {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub _in : i16
}

impl Event for EventFocus {}

#[allow(dead_code)]
pub struct EventConfigure {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub x : i32,
    pub y : i32,
    pub width : i32,
    pub height : i32
}

impl Event for EventConfigure {}

#[allow(dead_code)]
pub struct EventProperty {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub atom : ::Atom,
    pub time : u32,
    pub state : u32 //FIXME
}

impl Event for EventProperty {}

#[allow(dead_code)]
pub struct EventSelection {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub selection : ::Atom,
    pub target : ::Atom,
    pub property : ::Atom,
    pub time : u32,
    requestor : *mut ::Window
}

impl Event for EventSelection {}

#[allow(dead_code)]
pub struct EventOwnerChange {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    owner : *mut ::Window,
    pub reason : ::OwnerChange,
    pub selection : ::Atom,
    pub time : u32,
    pub selection_time : u32
}

impl Event for EventOwnerChange {}

#[allow(dead_code)]
pub struct EventProximity {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    device : *mut ::Device
}

impl Event for EventProximity {}

#[allow(dead_code)]
pub struct EventSetting {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub action : ::SettingAction,
    pub name : *mut char
}

impl Event for EventSetting {}

#[allow(dead_code)]
pub struct EventWindowState {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub changed_mask : ::WindowState,
    pub new_window_state : ::WindowState
}

impl Event for EventWindowState {}

#[allow(dead_code)]
pub struct EventGrabBroken {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub keyboard : i32, // boolean
    pub implicit : i32, // boolean
    pub grab_window : *mut ::Window
}

impl Event for EventGrabBroken  {}

#[allow(dead_code)]
pub struct EventDND {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    context : *mut c_void, //::DragContext
    pub time : u32,
    pub x_root : i16, //short
    pub y_root : i16  //short
}

impl Event for EventDND  {}

//Supporting types

pub mod visibility_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum VisibilityState{
        VisibilityUnobscured,
        VisibilityPartial,
        VisibilityFullyObscured
    }
}

pub mod scroll_direction {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum ScrollDirection{
        ScrollUp,
        ScrollDown,
        ScrollLeft,
        ScrollRight,
        ScrollSmooth
    }
}

pub mod notify_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum NotifyType{
        NotifyAncestor   = 0,
        NotifyVirtual    = 1,
        NotifyInferior   = 2,
        NotifyNonlinear  = 3,
        NotifyNonlinearVirtual  = 4,
        NotifyUnknown    = 5
    }
}

pub mod crossing_mode {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum CrossingMode{
        CrossingNormal,
        CrossingGrab,
        CrossingUngrab,
        CrossingGtkGrab,
        CrossingGtkUngrab,
        CrossingStateChanged,
        CrossingTouchBegin,
        CrossingTouchEnd,
        CrossingDeviceSwitch
    }
}

pub mod property_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum PropertyState{
        PropertyNewValue,
        PropertyDelete
    }
}

pub mod setting_action {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum SettingAction{
        SettingActionNew,
        SettingActionChanged,
        SettingActionDeleted
    }
}

pub mod owner_change {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum OwnerChange{
        OwnerChangeNewOwner,
        OwnerChangeDestroy,
        OwnerChangeClose
    }
}
<commit_msg>Change #[allow(dead_code)] to #[repr(C)]<commit_after>// Copyright 2013-2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use ffi;
use libc::c_void;
use std::mem;

pub use self::event_type::EventType;
pub use self::owner_change::OwnerChange;
pub use self::setting_action::SettingAction;
pub use self::property_state::PropertyState;
pub use self::crossing_mode::CrossingMode;
pub use self::notify_type::NotifyType;
pub use self::scroll_direction::ScrollDirection;
pub use self::visibility_state::VisibilityState;

pub mod event_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum EventType {
        Nothing           = -1,
        Delete            = 0,
        Destroy           = 1,
        Expose            = 2,
        MotionNotify      = 3,
        ButtonPress       = 4,
        DoubleButtonPress = 5,
        TripleButtonPress = 6,
        ButtonRelease     = 7,
        KeyPress          = 8,
        KeyRelease        = 9,
        EnterNotify       = 10,
        LeaveNotify       = 11,
        FocusChange       = 12,
        Configure         = 13,
        Map               = 14,
        Unmap             = 15,
        PropertyNotify    = 16,
        SelectionClear    = 17,
        SelectionRequest  = 18,
        SelectionNotify   = 19,
        ProximityIn       = 20,
        ProximityOut      = 21,
        DragEnter         = 22,
        DragLeave         = 23,
        DragMotion        = 24,
        DragStatus        = 25,
        DropStart         = 26,
        DropFinished      = 27,
        ClientEvent       = 28,
        VisibilityNotify  = 29,
        Scroll            = 31,
        WindowState       = 32,
        Setting           = 33,
        OwnerChange       = 34,
        GrabBroken        = 35,
        Damage            = 36,
        TouchBegin        = 37,
        TouchUpdate       = 38,
        TouchEnd          = 39,
        TouchCancel       = 40
    }
}

pub trait Event: Sized {
    fn get_send_event(&self) -> bool {
        unsafe {
            let event_any : &EventAny = mem::transmute(self);
            event_any.send_event == 0
        }
    }
}

// TODO unfinished, see #25

#[repr(C)]
pub struct EventAny {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,
}

impl Event for EventAny {}

#[repr(C)]
pub struct EventExpose {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub area : ffi::C_GdkRectangle,
    region : *mut c_void, //TODO cairo_region_t
    pub count : i8 /* If non-zero, how many more events follow. */
}

impl Event for EventExpose {}

#[repr(C)]
pub struct EventVisibility{
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub state : ::VisibilityState
}

impl Event for EventVisibility {}

#[repr(C)]
pub struct EventMotion {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub is_hint : i16,
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventMotion {}

#[repr(C)]
pub struct EventButton {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub button : u32,
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventButton {}

#[repr(C)]
pub struct EventTouch {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    sequence : *mut c_void, //::EventSequence
    pub emulating_pointer : i32, // boolean
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventTouch {}

#[repr(C)]
pub struct EventScroll {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub direction : ::ScrollDirection,
    device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64,
    pub delta_x : f64,
    pub delta_y : f64
}

impl Event for EventScroll {}

#[repr(C)]
pub struct EventKey {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub state : ::enums::modifier_type::ModifierType,
    pub keyval : u32,
    pub length : i32,
    pub string : *mut char,
    pub hardware_keycode : u16,
    pub group : u8,
    pub is_modifier: u32
}

impl Event for EventKey {}

#[repr(C)]
pub struct EventCrossing {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub subwindow : ::Window,
    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub x_root : f64,
    pub y_root : f64,
    pub mode : ::CrossingMode,
    pub detail : ::NotifyType,
    pub focus : i32, // boolean
    pub state : ::enums::modifier_type::ModifierType
}

impl Event for EventCrossing {}

#[repr(C)]
pub struct EventFocus {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub _in : i16
}

impl Event for EventFocus {}

#[repr(C)]
pub struct EventConfigure {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub x : i32,
    pub y : i32,
    pub width : i32,
    pub height : i32
}

impl Event for EventConfigure {}

#[repr(C)]
pub struct EventProperty {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub atom : ::Atom,
    pub time : u32,
    pub state : u32 //FIXME
}

impl Event for EventProperty {}

#[repr(C)]
pub struct EventSelection {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub selection : ::Atom,
    pub target : ::Atom,
    pub property : ::Atom,
    pub time : u32,
    requestor : *mut ::Window
}

impl Event for EventSelection {}

#[repr(C)]
pub struct EventOwnerChange {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    owner : *mut ::Window,
    pub reason : ::OwnerChange,
    pub selection : ::Atom,
    pub time : u32,
    pub selection_time : u32
}

impl Event for EventOwnerChange {}

#[repr(C)]
pub struct EventProximity {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    device : *mut ::Device
}

impl Event for EventProximity {}

#[repr(C)]
pub struct EventSetting {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub action : ::SettingAction,
    pub name : *mut char
}

impl Event for EventSetting {}

#[repr(C)]
pub struct EventWindowState {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub changed_mask : ::WindowState,
    pub new_window_state : ::WindowState
}

impl Event for EventWindowState {}

#[repr(C)]
pub struct EventGrabBroken {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub keyboard : i32, // boolean
    pub implicit : i32, // boolean
    pub grab_window : *mut ::Window
}

impl Event for EventGrabBroken  {}

#[repr(C)]
pub struct EventDND {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    context : *mut c_void, //::DragContext
    pub time : u32,
    pub x_root : i16, //short
    pub y_root : i16  //short
}

impl Event for EventDND  {}

//Supporting types

pub mod visibility_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum VisibilityState{
        VisibilityUnobscured,
        VisibilityPartial,
        VisibilityFullyObscured
    }
}

pub mod scroll_direction {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum ScrollDirection{
        ScrollUp,
        ScrollDown,
        ScrollLeft,
        ScrollRight,
        ScrollSmooth
    }
}

pub mod notify_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum NotifyType{
        NotifyAncestor   = 0,
        NotifyVirtual    = 1,
        NotifyInferior   = 2,
        NotifyNonlinear  = 3,
        NotifyNonlinearVirtual  = 4,
        NotifyUnknown    = 5
    }
}

pub mod crossing_mode {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum CrossingMode{
        CrossingNormal,
        CrossingGrab,
        CrossingUngrab,
        CrossingGtkGrab,
        CrossingGtkUngrab,
        CrossingStateChanged,
        CrossingTouchBegin,
        CrossingTouchEnd,
        CrossingDeviceSwitch
    }
}

pub mod property_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum PropertyState{
        PropertyNewValue,
        PropertyDelete
    }
}

pub mod setting_action {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum SettingAction{
        SettingActionNew,
        SettingActionChanged,
        SettingActionDeleted
    }
}

pub mod owner_change {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum OwnerChange{
        OwnerChangeNewOwner,
        OwnerChangeDestroy,
        OwnerChangeClose
    }
}
<|endoftext|>


<commit_before>#![warn(clippy::all, clippy::pedantic)]

// TOO_MANY_LINES
fn good_lines() {
    /* println!("This is good."); */
    // println!("This is good.");
    /* */ // println!("This is good.");
    /* */ // println!("This is good.");
    /* */ // println!("This is good.");
    /* */ // println!("This is good.");
    /* println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good."); */
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
}

fn bad_lines() {
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
}

fn main() {}
<commit_msg>Updating to just warn for one test.<commit_after>#![warn(clippy::too_many_lines)]

fn good_lines() {
    /* println!("This is good."); */
    // println!("This is good.");
    /* */ // println!("This is good.");
    /* */ // println!("This is good.");
    /* */ // println!("This is good.");
    /* */ // println!("This is good.");
    /* println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good."); */
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
    println!("This is good.");
}

fn bad_lines() {
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
    println!("This is bad.");
}

fn main() {}
<|endoftext|>


<commit_before>use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::error::Error;
use std::io::{self, SeekFrom};
use {GameDataRead, GameDataWrite};

// A couple assumptions are made about the format.
//
// - The root chunk is always a FORM chunk
//
// - One chunk type occurs exactly once.
//
// - Chunk order is important. We write back chunks in the same order we read them.
//
// - Chunks are aligned on even byte offsets. Padding bytes are always zero.

/// A pseudo IFF-like format that Game Maker Studio uses.
///
/// It doesn't actually conform to the IFF spec, so it doesn't make sense
/// to use a generic IFF library.
///
/// Instead, this type deals with the generic IFF-like top-level structure, so
/// we only have to deal with encoding/decoding the chunks we actually care about,
/// and errors in the handling of individual chunks don't break the rest of the chunks.
#[derive(Debug)]
pub struct PseudoIff {
    pub chunks: Vec<Chunk>,
}

#[derive(Debug)]
pub struct Chunk {
    pub type_id: TypeId,
    pub data: Vec<u8>,
}

type TypeId = [u8; 4];

impl PseudoIff {
    pub fn load<R: GameDataRead>(reader: &mut R) -> Result<Self, Box<Error>> {
        Ok(Self { chunks: read_form_chunk(reader)? })
    }
    pub fn save<W: GameDataWrite>(&self, writer: &mut W) -> io::Result<()> {
        writer.write_all(b"FORM")?;
        // Skip writing the FORM length, because we don't know it yet.
        let after_form_len = writer.seek(SeekFrom::Current(4))?;
        for chunk in &self.chunks {
            writer.write_all(&chunk.type_id[..])?;
            writer.write_i32::<LittleEndian>(chunk.data.len() as i32)?;
            writer.write_all(&chunk.data)?;
            // Chunks are aligned on even byte boundaries
            let pos = writer.seek(SeekFrom::Current(0))?;
            if pos % 2 != 0 {
                writer.write_u8(0)?;
            }
        }
        let end = writer.seek(SeekFrom::Current(0))?;
        let form_len = end - after_form_len;
        // Finally write the form length
        writer.seek(SeekFrom::Start(after_form_len - 4))?;
        writer.write_i32::<LittleEndian>(form_len as i32)?;
        Ok(())
    }
}

fn read_form_chunk<R: GameDataRead>(reader: &mut R) -> Result<Vec<Chunk>, Box<Error>> {
    let mut type_id = [0; 4];
    reader.read_exact(&mut type_id)?;
    let _len = reader.read_i32::<LittleEndian>();

    if &type_id[..] != b"FORM" {
        return Err(
            "Invalid data.win file. Must start with a FORM chunk."
                .into(),
        );
    }

    read_chunks(reader)
}

fn read_chunks<R: GameDataRead>(reader: &mut R) -> Result<Vec<Chunk>, Box<Error>> {
    let mut chunks = Vec::new();

    loop {
        match read_chunk(reader) {
            Ok(Some(chunk)) => {
                // Chunks are aligned on even byte boundaries
                let pos = reader.seek(SeekFrom::Current(0))?;
                if pos % 2 != 0 {
                    reader.seek(SeekFrom::Current(1))?;
                }
                chunks.push(chunk)
            }
            Ok(None) => return Ok(chunks),
            Err(e) => return Err(e),
        }
    }
}

fn read_chunk<R: GameDataRead>(reader: &mut R) -> Result<Option<Chunk>, Box<Error>> {
    use std::io::ErrorKind;

    let mut type_id = [0; 4];
    if let Err(e) = reader.read_exact(&mut type_id) {
        match e.kind() {
            ErrorKind::UnexpectedEof => return Ok(None),
            _ => return Err(Box::new(e)),
        }
    }

    let size = reader.read_i32::<LittleEndian>()?;
    let mut data = vec![0; size as usize];
    reader.read_exact(&mut data[..])?;

    Ok(Some(Chunk { type_id, data }))
}
<commit_msg>Yes, that's better rustfmt<commit_after>use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::error::Error;
use std::io::{self, SeekFrom};
use {GameDataRead, GameDataWrite};

// A couple assumptions are made about the format.
//
// - The root chunk is always a FORM chunk
//
// - One chunk type occurs exactly once.
//
// - Chunk order is important. We write back chunks in the same order we read them.
//
// - Chunks are aligned on even byte offsets. Padding bytes are always zero.

/// A pseudo IFF-like format that Game Maker Studio uses.
///
/// It doesn't actually conform to the IFF spec, so it doesn't make sense
/// to use a generic IFF library.
///
/// Instead, this type deals with the generic IFF-like top-level structure, so
/// we only have to deal with encoding/decoding the chunks we actually care about,
/// and errors in the handling of individual chunks don't break the rest of the chunks.
#[derive(Debug)]
pub struct PseudoIff {
    pub chunks: Vec<Chunk>,
}

#[derive(Debug)]
pub struct Chunk {
    pub type_id: TypeId,
    pub data: Vec<u8>,
}

type TypeId = [u8; 4];

impl PseudoIff {
    pub fn load<R: GameDataRead>(reader: &mut R) -> Result<Self, Box<Error>> {
        Ok(Self { chunks: read_form_chunk(reader)? })
    }
    pub fn save<W: GameDataWrite>(&self, writer: &mut W) -> io::Result<()> {
        writer.write_all(b"FORM")?;
        // Skip writing the FORM length, because we don't know it yet.
        let after_form_len = writer.seek(SeekFrom::Current(4))?;
        for chunk in &self.chunks {
            writer.write_all(&chunk.type_id[..])?;
            writer.write_i32::<LittleEndian>(chunk.data.len() as i32)?;
            writer.write_all(&chunk.data)?;
            // Chunks are aligned on even byte boundaries
            let pos = writer.seek(SeekFrom::Current(0))?;
            if pos % 2 != 0 {
                writer.write_u8(0)?;
            }
        }
        let end = writer.seek(SeekFrom::Current(0))?;
        let form_len = end - after_form_len;
        // Finally write the form length
        writer.seek(SeekFrom::Start(after_form_len - 4))?;
        writer.write_i32::<LittleEndian>(form_len as i32)?;
        Ok(())
    }
}

fn read_form_chunk<R: GameDataRead>(reader: &mut R) -> Result<Vec<Chunk>, Box<Error>> {
    let mut type_id = [0; 4];
    reader.read_exact(&mut type_id)?;
    let _len = reader.read_i32::<LittleEndian>();

    if &type_id[..] != b"FORM" {
        return Err(
            "Invalid data.win file. Must start with a FORM chunk.".into(),
        );
    }

    read_chunks(reader)
}

fn read_chunks<R: GameDataRead>(reader: &mut R) -> Result<Vec<Chunk>, Box<Error>> {
    let mut chunks = Vec::new();

    loop {
        match read_chunk(reader) {
            Ok(Some(chunk)) => {
                // Chunks are aligned on even byte boundaries
                let pos = reader.seek(SeekFrom::Current(0))?;
                if pos % 2 != 0 {
                    reader.seek(SeekFrom::Current(1))?;
                }
                chunks.push(chunk)
            }
            Ok(None) => return Ok(chunks),
            Err(e) => return Err(e),
        }
    }
}

fn read_chunk<R: GameDataRead>(reader: &mut R) -> Result<Option<Chunk>, Box<Error>> {
    use std::io::ErrorKind;

    let mut type_id = [0; 4];
    if let Err(e) = reader.read_exact(&mut type_id) {
        match e.kind() {
            ErrorKind::UnexpectedEof => return Ok(None),
            _ => return Err(Box::new(e)),
        }
    }

    let size = reader.read_i32::<LittleEndian>()?;
    let mut data = vec![0; size as usize];
    reader.read_exact(&mut data[..])?;

    Ok(Some(Chunk { type_id, data }))
}
<|endoftext|>


<commit_before>
use Groups;

// https://docs.gitlab.com/ce/api/groups.html
// List groups:                 GET /groups
// List owned groups:           GET /groups/owned
// List a group's projects:     GET /groups/:id/projects
// Details of a group:          GET /groups/:id
// New group:                   POST /groups
// Transfer project to group:   POST  /groups/:id/projects/:project_id
// Update group:                PUT /groups/:id
// Remove group:                DELETE /groups/:id
// Search for group:            GET /groups?search=foobar

pub struct GroupListing {

}

impl GroupListing {
    fn list(&self) -> Groups {
        let groups: Groups = vec![];

        groups
    }
}
<commit_msg>Try to define a `GroupLister` for simple "List groups" action.<commit_after>
use Groups;

// https://docs.gitlab.com/ce/api/groups.html
// List groups:                 GET /groups
// List owned groups:           GET /groups/owned
// List a group's projects:     GET /groups/:id/projects
// Details of a group:          GET /groups/:id
// New group:                   POST /groups
// Transfer project to group:   POST  /groups/:id/projects/:project_id
// Update group:                PUT /groups/:id
// Remove group:                DELETE /groups/:id
// Search for group:            GET /groups?search=foobar

// https://docs.gitlab.com/ce/api/groups.html#list-groups
pub struct GroupLister {
    // pagination: Pagination,

}

enum GroupListerOptionsOrderBy {
    Name,
    Path,
}

impl Default for GroupListerOptionsOrderBy {
    fn default() -> GroupListerOptionsOrderBy { GroupListerOptionsOrderBy::Name }
}

enum GroupListerOptionsSort {
    Asc,
    Desc,
}

impl Default for GroupListerOptionsSort {
    fn default() -> GroupListerOptionsSort { GroupListerOptionsSort::Asc }
}

fn append_group_lister_options_order_by(order_by: GroupListerOptionsOrderBy, s: &mut String) {
    s.push_str(
        match order_by {
            GroupListerOptionsOrderBy::Name => "name",
            GroupListerOptionsOrderBy::Path => "path",
        }
    );
}

fn append_group_lister_options_sort(order_by: GroupListerOptionsSort, s: &mut String) {
    s.push_str(
        match order_by {
            GroupListerOptionsSort::Asc => "asc",
            GroupListerOptionsSort::Desc => "desc",
        }
    );
}

/// https://docs.gitlab.com/ce/api/groups.html#list-groups
#[derive(Default)]
struct GroupListerOptions {
    /// Skip the group IDs passes
    skip_groups: Option<Vec<i64>>,
    /// Show all the groups you have access to
    all_available: Option<bool>,
    /// Return list of authorized groups matching the search criteria
    search: Option<String>,
    /// Order groups by `name` or `path`. Default is `name`
    order_by: GroupListerOptionsOrderBy,
    /// Order groups in `asc` or `desc` order. Default is `asc`
    sort: GroupListerOptionsSort,

}

// #[derive(Default)]
pub struct GroupListing {
    options: GroupListerOptions,
}

impl GroupListing {
    fn list(&self) -> Groups {
        let groups: Groups = vec![];

        groups
    }
}

#[test]
fn test_append_group_lister_options_order_by() {
    let expected_string = "Initialnamepathpathname";

    let mut s = String::from("Initial");

    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Name, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Path, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Path, &mut s);
    append_group_lister_options_order_by(GroupListerOptionsOrderBy::Name, &mut s);

    assert_eq!(s, expected_string);
}

#[test]
fn test_append_group_lister_options_sort() {
    let expected_string = "Initialascdescascdesc";

    let mut s = String::from("Initial");

    append_group_lister_options_sort(GroupListerOptionsSort::Asc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Desc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Asc, &mut s);
    append_group_lister_options_sort(GroupListerOptionsSort::Desc, &mut s);

    assert_eq!(s, expected_string);
}
<|endoftext|>


<commit_before>// Copyright 2013-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.

//! The implementations of `Rand` for the built-in types.

use std::char;
use std::mem;

use {Rand,Rng};

impl Rand for isize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> isize {
        if mem::size_of::<isize>() == 4 {
            rng.gen::<i32>() as isize
        } else {
            rng.gen::<i64>() as isize
        }
    }
}

impl Rand for i8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i8 {
        rng.next_u32() as i8
    }
}

impl Rand for i16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i16 {
        rng.next_u32() as i16
    }
}

impl Rand for i32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i32 {
        rng.next_u32() as i32
    }
}

impl Rand for i64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i64 {
        rng.next_u64() as i64
    }
}

impl Rand for usize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> usize {
        if mem::size_of::<usize>() == 4 {
            rng.gen::<u32>() as usize
        } else {
            rng.gen::<u64>() as usize
        }
    }
}

impl Rand for u8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u8 {
        rng.next_u32() as u8
    }
}

impl Rand for u16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u16 {
        rng.next_u32() as u16
    }
}

impl Rand for u32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u32 {
        rng.next_u32()
    }
}

impl Rand for u64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u64 {
        rng.next_u64()
    }
}

macro_rules! float_impls {
    ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
        mod $mod_name {
            use {Rand, Rng, Open01, Closed01};

            const SCALE: $ty = (1u64 << $mantissa_bits) as $ty;

            impl Rand for $ty {
                /// Generate a floating point number in the half-open
                /// interval `[0,1)`.
                ///
                /// See `Closed01` for the closed interval `[0,1]`,
                /// and `Open01` for the open interval `(0,1)`.
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> $ty {
                    rng.$method_name()
                }
            }
            impl Rand for Open01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
                    // add a small amount (specifically 2 bits below
                    // the precision of f64/f32 at 1.0), so that small
                    // numbers are larger than 0, but large numbers
                    // aren't pushed to/above 1.
                    Open01(rng.$method_name() + 0.25 / SCALE)
                }
            }
            impl Rand for Closed01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
                    // rescale so that 1.0 - epsilon becomes 1.0
                    // precisely.
                    Closed01(rng.$method_name() * SCALE / (SCALE - 1.0))
                }
            }
        }
    }
}
float_impls! { f64_rand_impls, f64, 53, next_f64 }
float_impls! { f32_rand_impls, f32, 24, next_f32 }

impl Rand for char {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> char {
        // a char is 21 bits
        const CHAR_MASK: u32 = 0x001f_ffff;
        loop {
            // Rejection sampling. About 0.2% of numbers with at most
            // 21-bits are invalid codepoints (surrogates), so this
            // will succeed first go almost every time.
            match char::from_u32(rng.next_u32() & CHAR_MASK) {
                Some(c) => return c,
                None => {}
            }
        }
    }
}

impl Rand for bool {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> bool {
        rng.gen::<u8>() & 1 == 1
    }
}

macro_rules! tuple_impl {
    // use variables to indicate the arity of the tuple
    ($($tyvar:ident),* ) => {
        // the trailing commas are for the 1 tuple
        impl<
            $( $tyvar : Rand ),*
            > Rand for ( $( $tyvar ),* , ) {

            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
                (
                    // use the $tyvar's to get the appropriate number of
                    // repeats (they're not actually needed)
                    $(
                        _rng.gen::<$tyvar>()
                    ),*
                    ,
                )
            }
        }
    }
}

impl Rand for () {
    #[inline]
    fn rand<R: Rng>(_: &mut R) -> () { () }
}
tuple_impl!{A}
tuple_impl!{A, B}
tuple_impl!{A, B, C}
tuple_impl!{A, B, C, D}
tuple_impl!{A, B, C, D, E}
tuple_impl!{A, B, C, D, E, F}
tuple_impl!{A, B, C, D, E, F, G}
tuple_impl!{A, B, C, D, E, F, G, H}
tuple_impl!{A, B, C, D, E, F, G, H, I}
tuple_impl!{A, B, C, D, E, F, G, H, I, J}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}

macro_rules! array_impl {
    {$n:expr, $t:ident, $($ts:ident,)*} => {
        array_impl!{($n - 1), $($ts,)*}

        impl<T> Rand for [T; $n] where T: Rand {
            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] {
                [_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*]
            }
        }
    };
    {$n:expr,} => {
        impl<T> Rand for [T; $n] {
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] { [] }
        }
    };
}

array_impl!{32, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,}

impl<T:Rand> Rand for Option<T> {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
        if rng.gen() {
            Some(rng.gen())
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use {Rng, thread_rng, Open01, Closed01};

    struct ConstantRng(u64);
    impl Rng for ConstantRng {
        fn next_u32(&mut self) -> u32 {
            let ConstantRng(v) = *self;
            v as u32
        }
        fn next_u64(&mut self) -> u64 {
            let ConstantRng(v) = *self;
            v
        }
    }

    #[test]
    fn floating_point_edge_cases() {
        // the test for exact equality is correct here.
        assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0);
        assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0);
    }

    #[test]
    fn rand_open() {
        // this is unlikely to catch an incorrect implementation that
        // generates exactly 0 or 1, but it keeps it sane.
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Open01(f) = rng.gen::<Open01<f64>>();
            assert!(0.0 < f && f < 1.0);

            let Open01(f) = rng.gen::<Open01<f32>>();
            assert!(0.0 < f && f < 1.0);
        }
    }

    #[test]
    fn rand_closed() {
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Closed01(f) = rng.gen::<Closed01<f64>>();
            assert!(0.0 <= f && f <= 1.0);

            let Closed01(f) = rng.gen::<Closed01<f32>>();
            assert!(0.0 <= f && f <= 1.0);
        }
    }
}
<commit_msg>Change the Rand trait for bool<commit_after>// Copyright 2013-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.

//! The implementations of `Rand` for the built-in types.

use std::char;
use std::mem;

use {Rand,Rng};

impl Rand for isize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> isize {
        if mem::size_of::<isize>() == 4 {
            rng.gen::<i32>() as isize
        } else {
            rng.gen::<i64>() as isize
        }
    }
}

impl Rand for i8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i8 {
        rng.next_u32() as i8
    }
}

impl Rand for i16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i16 {
        rng.next_u32() as i16
    }
}

impl Rand for i32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i32 {
        rng.next_u32() as i32
    }
}

impl Rand for i64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i64 {
        rng.next_u64() as i64
    }
}

impl Rand for usize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> usize {
        if mem::size_of::<usize>() == 4 {
            rng.gen::<u32>() as usize
        } else {
            rng.gen::<u64>() as usize
        }
    }
}

impl Rand for u8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u8 {
        rng.next_u32() as u8
    }
}

impl Rand for u16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u16 {
        rng.next_u32() as u16
    }
}

impl Rand for u32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u32 {
        rng.next_u32()
    }
}

impl Rand for u64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u64 {
        rng.next_u64()
    }
}

macro_rules! float_impls {
    ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
        mod $mod_name {
            use {Rand, Rng, Open01, Closed01};

            const SCALE: $ty = (1u64 << $mantissa_bits) as $ty;

            impl Rand for $ty {
                /// Generate a floating point number in the half-open
                /// interval `[0,1)`.
                ///
                /// See `Closed01` for the closed interval `[0,1]`,
                /// and `Open01` for the open interval `(0,1)`.
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> $ty {
                    rng.$method_name()
                }
            }
            impl Rand for Open01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
                    // add a small amount (specifically 2 bits below
                    // the precision of f64/f32 at 1.0), so that small
                    // numbers are larger than 0, but large numbers
                    // aren't pushed to/above 1.
                    Open01(rng.$method_name() + 0.25 / SCALE)
                }
            }
            impl Rand for Closed01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
                    // rescale so that 1.0 - epsilon becomes 1.0
                    // precisely.
                    Closed01(rng.$method_name() * SCALE / (SCALE - 1.0))
                }
            }
        }
    }
}
float_impls! { f64_rand_impls, f64, 53, next_f64 }
float_impls! { f32_rand_impls, f32, 24, next_f32 }

impl Rand for char {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> char {
        // a char is 21 bits
        const CHAR_MASK: u32 = 0x001f_ffff;
        loop {
            // Rejection sampling. About 0.2% of numbers with at most
            // 21-bits are invalid codepoints (surrogates), so this
            // will succeed first go almost every time.
            match char::from_u32(rng.next_u32() & CHAR_MASK) {
                Some(c) => return c,
                None => {}
            }
        }
    }
}

impl Rand for bool {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> bool {
        // Generate a 32-bit value and test the sign.
        // Many PRNGs exhibit non-uniform random quality across their bits. The
        // low order bit of LCGs, for example, flips 0/1. Even some high
        // quality PRNGs, like Xoroshiro128+, have strange low order bit
        // behavior. Testing the sign offers protection against these common
        // pathologies.
        rng.gen::<i32>() < 0
    }
}

macro_rules! tuple_impl {
    // use variables to indicate the arity of the tuple
    ($($tyvar:ident),* ) => {
        // the trailing commas are for the 1 tuple
        impl<
            $( $tyvar : Rand ),*
            > Rand for ( $( $tyvar ),* , ) {

            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
                (
                    // use the $tyvar's to get the appropriate number of
                    // repeats (they're not actually needed)
                    $(
                        _rng.gen::<$tyvar>()
                    ),*
                    ,
                )
            }
        }
    }
}

impl Rand for () {
    #[inline]
    fn rand<R: Rng>(_: &mut R) -> () { () }
}
tuple_impl!{A}
tuple_impl!{A, B}
tuple_impl!{A, B, C}
tuple_impl!{A, B, C, D}
tuple_impl!{A, B, C, D, E}
tuple_impl!{A, B, C, D, E, F}
tuple_impl!{A, B, C, D, E, F, G}
tuple_impl!{A, B, C, D, E, F, G, H}
tuple_impl!{A, B, C, D, E, F, G, H, I}
tuple_impl!{A, B, C, D, E, F, G, H, I, J}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}

macro_rules! array_impl {
    {$n:expr, $t:ident, $($ts:ident,)*} => {
        array_impl!{($n - 1), $($ts,)*}

        impl<T> Rand for [T; $n] where T: Rand {
            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] {
                [_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*]
            }
        }
    };
    {$n:expr,} => {
        impl<T> Rand for [T; $n] {
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] { [] }
        }
    };
}

array_impl!{32, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,}

impl<T:Rand> Rand for Option<T> {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
        if rng.gen() {
            Some(rng.gen())
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use {Rng, thread_rng, Open01, Closed01};

    struct ConstantRng(u64);
    impl Rng for ConstantRng {
        fn next_u32(&mut self) -> u32 {
            let ConstantRng(v) = *self;
            v as u32
        }
        fn next_u64(&mut self) -> u64 {
            let ConstantRng(v) = *self;
            v
        }
    }

    #[test]
    fn floating_point_edge_cases() {
        // the test for exact equality is correct here.
        assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0);
        assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0);
    }

    #[test]
    fn rand_open() {
        // this is unlikely to catch an incorrect implementation that
        // generates exactly 0 or 1, but it keeps it sane.
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Open01(f) = rng.gen::<Open01<f64>>();
            assert!(0.0 < f && f < 1.0);

            let Open01(f) = rng.gen::<Open01<f32>>();
            assert!(0.0 < f && f < 1.0);
        }
    }

    #[test]
    fn rand_closed() {
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Closed01(f) = rng.gen::<Closed01<f64>>();
            assert!(0.0 <= f && f <= 1.0);

            let Closed01(f) = rng.gen::<Closed01<f32>>();
            assert!(0.0 <= f && f <= 1.0);
        }
    }
}
<|endoftext|>


<commit_before>use handle::*;

pub struct VertexConnectivity {
    pub halfedge_ : Halfedge,
}

pub struct HalfedgeConnectivity {
    pub face_ : Face,
    pub vertex_ : Vertex,
    pub next_halfedge_ : Halfedge,
    pub prev_halfedge_ : Halfedge,
}

pub struct FaceConnectivity {
    pub halfedge_ : Halfedge,
}
<commit_msg>connectivity : adds construct methods + documentation<commit_after>use handle::*;

/// Store the connectivity of a vertex in a halfedge mesh.
#[derive(Copy, Clone)]
pub struct VertexConnectivity {
    pub halfedge_ : Halfedge,
}

/// Store the connectivity of a halfedge in a halfedge mesh.
#[derive(Copy, Clone)]
pub struct HalfedgeConnectivity {
    pub face_ : Face,
    pub vertex_ : Vertex,
    pub next_halfedge_ : Halfedge,
    pub prev_halfedge_ : Halfedge,
}

/// Store the connectivity of a face in a halfedge mesh.
#[derive(Copy, Clone)]
pub struct FaceConnectivity {
    pub halfedge_ : Halfedge,
}

impl VertexConnectivity {
    /// Constructs an invalid `VertexConnectivity`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::connectivity::VertexConnectivity;
    ///
    /// let vc = VertexConnectivity::invalid();
    /// ```
    pub fn invalid() -> VertexConnectivity {
        VertexConnectivity {
            halfedge_ : Halfedge::invalid(),
        }
    }

    /// Constructs a new `VertexConnectivity`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::connectivity::VertexConnectivity;
    /// use lwmesh::handle::Halfedge;
    ///
    /// let h = Halfedge::new(17);
    /// let vc = VertexConnectivity::new(h);
    /// ```
    pub fn new(h : Halfedge) -> VertexConnectivity {
        VertexConnectivity {
            halfedge_ : h,
        }
    }
}

impl HalfedgeConnectivity {
    /// Constructs an invalid `HalfedgeConnectivity`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::connectivity::HalfedgeConnectivity;
    ///
    /// let hc = HalfedgeConnectivity::invalid();
    /// ```
    pub fn invalid() -> HalfedgeConnectivity {
        HalfedgeConnectivity {
            face_ : Face::invalid(),
            vertex_ : Vertex::invalid(),
            next_halfedge_ : Halfedge::invalid(),
            prev_halfedge_ : Halfedge::invalid(),
        }
    }

    /// Constructs a new `HalfedgeConnectivity`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::connectivity::HalfedgeConnectivity;
    /// use lwmesh::handle::*;
    ///
    /// let f = Face::new(1);
    /// let v = Vertex::new(9);
    /// let nh = Halfedge::new(8);
    /// let ph = Halfedge::new(4);
    /// let hc = HalfedgeConnectivity::new(f,v,nh,ph);
    /// ```
    pub fn new(f : Face, v : Vertex, nh : Halfedge, ph : Halfedge) -> HalfedgeConnectivity {
        HalfedgeConnectivity {
            face_ : f,
            vertex_ : v,
            next_halfedge_ : nh,
            prev_halfedge_ : ph,
        }
    }
}

impl FaceConnectivity {
    /// Constructs an invalid `FaceConnectivity`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::connectivity::FaceConnectivity;
    ///
    /// let fc = FaceConnectivity::invalid();
    /// ```
    pub fn invalid() -> FaceConnectivity {
        FaceConnectivity {
            halfedge_ : Halfedge::invalid(),
        }
    }

    /// Constructs a new `FaceConnectivity`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::connectivity::FaceConnectivity;
    /// use lwmesh::handle::Halfedge;
    ///
    /// let h = Halfedge::new(5);
    /// let fc = FaceConnectivity::new(h);
    /// ```
    pub fn new(h : Halfedge) -> FaceConnectivity {
        FaceConnectivity {
            halfedge_ : h,
        }
    }
}
<|endoftext|>


<commit_before>/// The Toml Insert extensions

use toml::Value;

use tokenizer::Token;
use tokenizer::tokenize_with_seperator;
use error::*;

pub trait TomlValueInsertExt {

    /// Extension function for inserting a value in the current toml::Value document
    /// using a custom seperator.
    ///
    /// For difference to TomlSetExt::set() and friends, read [#semantics].
    ///
    /// # Semantics
    ///
    /// The function automatically creates intermediate data structures based on the query string.
    /// That means, if the query string is `"a.b.c.[0]"`, but only a table `"a"` exists in the
    /// document, the function automatically creates a table `"b"` inside `"a"` and `"c"` inside
    /// `"b"`, and an array in `"c"`. The array index is ignored if the array is created.
    ///
    /// If an Array exists, but the specified index is larger than the last index, the array will
    /// be expanded by one element: If the array has a length of 3, but the query string specifies
    /// that the element should be put at 1000, the function ignores the large index and simply
    /// appends the value to the index.
    ///
    /// If a Value is inserted into an Array, the array indexes are shifted. Semantically this is
    /// the same as doing a `array.insert(4, _)` (see the standard library).
    ///
    /// # Return value
    ///
    /// If the insert operation worked correctly, `Ok(None)` is returned.
    /// If the insert operation replaced an existing value `Ok(Some(old_value))` is returned
    /// On failure, `Err(e)` is returned
    ///
    fn insert_with_seperator(&mut self, query: &str, sep: char, value: Value) -> Result<Option<Value>>;

    /// Extension function for inserting a value from the current toml::Value document
    ///
    /// See documentation of `TomlValueinsertExt::insert_with_seperator`
    fn insert(&mut self, query: &str, value: Value) -> Result<Option<Value>> {
        self.insert_with_seperator(query, '.', value)
    }

}

impl TomlValueInsertExt for Value {

    fn insert_with_seperator(&mut self, query: &str, sep: char, value: Value) -> Result<Option<Value>> {
        use resolver::mut_resolver::resolve;

        let mut tokens = try!(tokenize_with_seperator(query, sep));
        let last       = tokens.pop_last().unwrap();
        let mut val    = try!(resolve(self, &tokens));

        match *last {
            Token::Identifier { ident, .. } => {
                match val {
                    &mut Value::Table(ref mut t) => {
                        Ok(t.insert(ident, value))
                    },
                    _ => Err(Error::from(ErrorKind::NoIdentifierInArray(ident.clone())))
                }
            },

            Token::Index { idx , .. } => {
                match val {
                    &mut Value::Array(ref mut a) => {
                        if a.len() > idx {
                            a.insert(idx, value);
                            Ok(None)
                        } else {
                            a.push(value);
                            Ok(None)
                        }
                    },
                    _ => Err(Error::from(ErrorKind::NoIndexInTable(idx)))
                }
            },
        }
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use toml::Value;
    use toml::from_str as toml_from_str;

    #[test]
    fn test_insert_with_seperator_into_table() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let table = t.get("table");
                assert!(table.is_some());

                let table = table.unwrap();
                assert!(is_match!(table, &Value::Table(_)));
                match table {
                    &Value::Table(ref t) => {
                        assert!(!t.is_empty());

                        let a = t.get("a");
                        assert!(a.is_some());

                        let a = a.unwrap();
                        assert!(is_match!(a, &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_insert_with_seperator_into_array() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = []
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("array.[0]"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let array = t.get("array");
                assert!(array.is_some());

                let array = array.unwrap();
                assert!(is_match!(array, &Value::Array(_)));
                match array {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_insert_with_seperator_into_nested_table() {
        let mut toml : Value = toml_from_str(r#"
        [a.b.c]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("a.b.c.d"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref outer) => {
                assert!(!outer.is_empty());
                let a_tab = outer.get("a");
                assert!(a_tab.is_some());

                let a_tab = a_tab.unwrap();
                assert!(is_match!(a_tab, &Value::Table(_)));
                match a_tab {
                    &Value::Table(ref a) => {
                        assert!(!a.is_empty());

                        let b_tab = a.get("b");
                        assert!(b_tab.is_some());

                        let b_tab = b_tab.unwrap();
                        assert!(is_match!(b_tab, &Value::Table(_)));
                        match b_tab {
                            &Value::Table(ref b) => {
                                assert!(!b.is_empty());

                                let c_tab = b.get("c");
                                assert!(c_tab.is_some());

                                let c_tab = c_tab.unwrap();
                                assert!(is_match!(c_tab, &Value::Table(_)));
                                match c_tab {
                                    &Value::Table(ref c) => {
                                        assert!(!c.is_empty());

                                        let d = c.get("d");
                                        assert!(d.is_some());

                                        let d = d.unwrap();
                                        assert!(is_match!(d, &Value::Integer(1)));
                                    },
                                    _ => panic!("What just happenend?"),
                                }
                            },
                            _ => panic!("What just happenend?"),
                        }
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happened?"),
        }
    }

    #[test]
    fn test_insert_with_seperator_into_table_where_array_is() {
        let mut toml : Value = toml_from_str(r#"
        table = []
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_err());

        let err = res.unwrap_err();
        assert!(is_match!(err.kind(), &ErrorKind::NoIdentifierInArray(_)));
    }

    #[test]
    fn test_insert_with_seperator_into_array_where_table_is() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("table.[0]"), '.', Value::Integer(1));

        assert!(res.is_err());

        let err = res.unwrap_err();
        assert!(is_match!(err.kind(), &ErrorKind::NoIndexInTable(_)));
    }

    #[test]
    fn test_insert_with_seperator_into_array_between_values() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = [1, 2, 3, 4, 5]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("array.[2]"), '.', Value::Integer(6));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let array = t.get("array");
                assert!(array.is_some());

                let array = array.unwrap();
                assert!(is_match!(array, &Value::Array(_)));
                match array {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                        assert!(is_match!(a.index(1), &Value::Integer(2)));
                        assert!(is_match!(a.index(2), &Value::Integer(6)));
                        assert!(is_match!(a.index(3), &Value::Integer(3)));
                        assert!(is_match!(a.index(4), &Value::Integer(4)));
                        assert!(is_match!(a.index(5), &Value::Integer(5)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

}

<commit_msg>Add test: Check whether intermediate structures are created by insert()<commit_after>/// The Toml Insert extensions

use toml::Value;

use tokenizer::Token;
use tokenizer::tokenize_with_seperator;
use error::*;

pub trait TomlValueInsertExt {

    /// Extension function for inserting a value in the current toml::Value document
    /// using a custom seperator.
    ///
    /// For difference to TomlSetExt::set() and friends, read [#semantics].
    ///
    /// # Semantics
    ///
    /// The function automatically creates intermediate data structures based on the query string.
    /// That means, if the query string is `"a.b.c.[0]"`, but only a table `"a"` exists in the
    /// document, the function automatically creates a table `"b"` inside `"a"` and `"c"` inside
    /// `"b"`, and an array in `"c"`. The array index is ignored if the array is created.
    ///
    /// If an Array exists, but the specified index is larger than the last index, the array will
    /// be expanded by one element: If the array has a length of 3, but the query string specifies
    /// that the element should be put at 1000, the function ignores the large index and simply
    /// appends the value to the index.
    ///
    /// If a Value is inserted into an Array, the array indexes are shifted. Semantically this is
    /// the same as doing a `array.insert(4, _)` (see the standard library).
    ///
    /// # Return value
    ///
    /// If the insert operation worked correctly, `Ok(None)` is returned.
    /// If the insert operation replaced an existing value `Ok(Some(old_value))` is returned
    /// On failure, `Err(e)` is returned
    ///
    fn insert_with_seperator(&mut self, query: &str, sep: char, value: Value) -> Result<Option<Value>>;

    /// Extension function for inserting a value from the current toml::Value document
    ///
    /// See documentation of `TomlValueinsertExt::insert_with_seperator`
    fn insert(&mut self, query: &str, value: Value) -> Result<Option<Value>> {
        self.insert_with_seperator(query, '.', value)
    }

}

impl TomlValueInsertExt for Value {

    fn insert_with_seperator(&mut self, query: &str, sep: char, value: Value) -> Result<Option<Value>> {
        use resolver::mut_resolver::resolve;

        let mut tokens = try!(tokenize_with_seperator(query, sep));
        let last       = tokens.pop_last().unwrap();
        let mut val    = try!(resolve(self, &tokens));

        match *last {
            Token::Identifier { ident, .. } => {
                match val {
                    &mut Value::Table(ref mut t) => {
                        Ok(t.insert(ident, value))
                    },
                    _ => Err(Error::from(ErrorKind::NoIdentifierInArray(ident.clone())))
                }
            },

            Token::Index { idx , .. } => {
                match val {
                    &mut Value::Array(ref mut a) => {
                        if a.len() > idx {
                            a.insert(idx, value);
                            Ok(None)
                        } else {
                            a.push(value);
                            Ok(None)
                        }
                    },
                    _ => Err(Error::from(ErrorKind::NoIndexInTable(idx)))
                }
            },
        }
    }

}

#[cfg(test)]
mod test {
    use super::*;
    use toml::Value;
    use toml::from_str as toml_from_str;

    #[test]
    fn test_insert_with_seperator_into_table() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let table = t.get("table");
                assert!(table.is_some());

                let table = table.unwrap();
                assert!(is_match!(table, &Value::Table(_)));
                match table {
                    &Value::Table(ref t) => {
                        assert!(!t.is_empty());

                        let a = t.get("a");
                        assert!(a.is_some());

                        let a = a.unwrap();
                        assert!(is_match!(a, &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_insert_with_seperator_into_array() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = []
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("array.[0]"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let array = t.get("array");
                assert!(array.is_some());

                let array = array.unwrap();
                assert!(is_match!(array, &Value::Array(_)));
                match array {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_insert_with_seperator_into_nested_table() {
        let mut toml : Value = toml_from_str(r#"
        [a.b.c]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("a.b.c.d"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref outer) => {
                assert!(!outer.is_empty());
                let a_tab = outer.get("a");
                assert!(a_tab.is_some());

                let a_tab = a_tab.unwrap();
                assert!(is_match!(a_tab, &Value::Table(_)));
                match a_tab {
                    &Value::Table(ref a) => {
                        assert!(!a.is_empty());

                        let b_tab = a.get("b");
                        assert!(b_tab.is_some());

                        let b_tab = b_tab.unwrap();
                        assert!(is_match!(b_tab, &Value::Table(_)));
                        match b_tab {
                            &Value::Table(ref b) => {
                                assert!(!b.is_empty());

                                let c_tab = b.get("c");
                                assert!(c_tab.is_some());

                                let c_tab = c_tab.unwrap();
                                assert!(is_match!(c_tab, &Value::Table(_)));
                                match c_tab {
                                    &Value::Table(ref c) => {
                                        assert!(!c.is_empty());

                                        let d = c.get("d");
                                        assert!(d.is_some());

                                        let d = d.unwrap();
                                        assert!(is_match!(d, &Value::Integer(1)));
                                    },
                                    _ => panic!("What just happenend?"),
                                }
                            },
                            _ => panic!("What just happenend?"),
                        }
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happened?"),
        }
    }

    #[test]
    fn test_insert_with_seperator_into_table_where_array_is() {
        let mut toml : Value = toml_from_str(r#"
        table = []
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_err());

        let err = res.unwrap_err();
        assert!(is_match!(err.kind(), &ErrorKind::NoIdentifierInArray(_)));
    }

    #[test]
    fn test_insert_with_seperator_into_array_where_table_is() {
        let mut toml : Value = toml_from_str(r#"
        [table]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("table.[0]"), '.', Value::Integer(1));

        assert!(res.is_err());

        let err = res.unwrap_err();
        assert!(is_match!(err.kind(), &ErrorKind::NoIndexInTable(_)));
    }

    #[test]
    fn test_insert_with_seperator_into_array_between_values() {
        use std::ops::Index;

        let mut toml : Value = toml_from_str(r#"
        array = [1, 2, 3, 4, 5]
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("array.[2]"), '.', Value::Integer(6));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let array = t.get("array");
                assert!(array.is_some());

                let array = array.unwrap();
                assert!(is_match!(array, &Value::Array(_)));
                match array {
                    &Value::Array(ref a) => {
                        assert!(!a.is_empty());
                        assert!(is_match!(a.index(0), &Value::Integer(1)));
                        assert!(is_match!(a.index(1), &Value::Integer(2)));
                        assert!(is_match!(a.index(2), &Value::Integer(6)));
                        assert!(is_match!(a.index(3), &Value::Integer(3)));
                        assert!(is_match!(a.index(4), &Value::Integer(4)));
                        assert!(is_match!(a.index(5), &Value::Integer(5)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

    #[test]
    fn test_insert_with_seperator_into_table_with_nonexisting_keys() {
        let mut toml : Value = toml_from_str(r#"
        "#).unwrap();

        let res = toml.insert_with_seperator(&String::from("table.a"), '.', Value::Integer(1));

        assert!(res.is_ok());

        let res = res.unwrap();
        assert!(res.is_none());

        assert!(is_match!(toml, Value::Table(_)));
        match toml {
            Value::Table(ref t) => {
                assert!(!t.is_empty());

                let table = t.get("table");
                assert!(table.is_some());

                let table = table.unwrap();
                assert!(is_match!(table, &Value::Table(_)));
                match table {
                    &Value::Table(ref t) => {
                        assert!(!t.is_empty());

                        let a = t.get("a");
                        assert!(a.is_some());

                        let a = a.unwrap();
                        assert!(is_match!(a, &Value::Integer(1)));
                    },
                    _ => panic!("What just happenend?"),
                }
            },
            _ => panic!("What just happenend?"),
        }
    }

}

<|endoftext|>


<commit_before>extern crate walkdir;

use self::walkdir::{DirEntry, WalkDir, WalkDirIterator};
use std::collections::BTreeSet;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use std::result::Result;

macro_rules! path_buf {
    ($($x: expr),*) => {
        PathBuf::new()
            $(.join($x))*
    };
}

pub fn extract_file_name(full_path: &PathBuf) -> &str {
    match full_path.file_name() {
        Some(option_f) => {
            match option_f.to_str() {
                Some(file_name) => file_name,
                None            => panic!("ERROR: Use UTF-8 characters as file name."),
            }
        },
        None => panic!("ERROR: Invalid path."),
    }
}

fn is_hidden(entry: &DirEntry) -> bool {
    entry
        .file_name()
        .to_str()
        .map_or(false, |s| s.starts_with(".") && s.len() > 1 && s != "..")
}

pub fn walk_dir<P: AsRef<Path>>(root: P) -> BTreeSet<String> {
    let walker = WalkDir::new(root)
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .filter_map(Result::ok)
        .filter(|e| !e.file_type().is_dir())
        .collect::<Vec<DirEntry>>();

    walker
        .iter()
        .map(DirEntry::path)
        .map(Path::as_os_str)
        .map(OsStr::to_os_string)
        .map(OsString::into_string)
        .filter_map(Result::ok)
        .collect::<BTreeSet<String>>()
}
<commit_msg>Minor change<commit_after>extern crate walkdir;

use self::walkdir::{DirEntry, WalkDir, WalkDirIterator};
use std::collections::BTreeSet;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use std::result::Result;

macro_rules! path_buf {
    ($($x: expr),*) => {
        PathBuf::new()
            $(.join($x))*
    };
}

pub fn extract_file_name(full_path: &PathBuf) -> &str {
    match full_path.file_name() {
        Some(osstr) => {
            match osstr.to_str() {
                Some(file_name) => file_name,
                None            => panic!("ERROR: Use UTF-8 characters as file name."),
            }
        },
        None => panic!("ERROR: Invalid path."),
    }
}

fn is_hidden(entry: &DirEntry) -> bool {
    entry
        .file_name()
        .to_str()
        .map_or(false, |s| s.starts_with(".") && s.len() > 1 && s != "..")
}

pub fn walk_dir<P: AsRef<Path>>(root: P) -> BTreeSet<String> {
    let walker = WalkDir::new(root)
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .filter_map(Result::ok)
        .filter(|e| !e.file_type().is_dir())
        .collect::<Vec<DirEntry>>();

    walker
        .iter()
        .map(DirEntry::path)
        .map(Path::as_os_str)
        .map(OsStr::to_os_string)
        .map(OsString::into_string)
        .filter_map(Result::ok)
        .collect::<BTreeSet<String>>()
}
<|endoftext|>