<commit_before>use std::rc::Rc;

use crate::{
    prelude::*,
    proc_macros::{Event, IntoHandler},
    shell::MouseButton,
    utils::*,
};

/// Checks if the given point is inside of a widget.
pub fn check_mouse_condition(mouse_position: Point, widget: &WidgetContainer<'_>) -> bool {
    let enabled = widget.get::<bool>("enabled");

    if !enabled {
        return false;
    }

    let bounds = widget.get::<Rectangle>("bounds");
    let position = widget.get::<Point>("position");

    let mut rect = Rectangle::new(0.0, 0.0, bounds.width(), bounds.height());

    rect.set_x(position.x);
    rect.set_y(position.y);

    rect.contains((mouse_position.x, mouse_position.y))
}

/// `MouseMoveEvent` indicates if the mouse position is changed on the window.
#[derive(Event)]
pub struct MouseMoveEvent {
    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `ScrollEvent` occurs when the mouse wheel is moved.
#[derive(Event)]
pub struct ScrollEvent {
    /// Indicates the scroll offset x and y.
    pub delta: Point,
}

/// Represents the current mouse state of an mouse event.
#[derive(Debug, Copy, Clone)]
pub struct Mouse {
    /// Indicates the mouse button that is connected to the event.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `MouseUpEvent` occurs when a mouse button is released.
#[derive(Event)]
pub struct MouseUpEvent {
    /// Indicates the mouse button that is released.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `ClickEvent` occurs when a user clicked on an element.
#[derive(Event)]
pub struct ClickEvent {
    /// Indicates the x and y position of the click event.
    pub position: Point,
}

/// `MouseDownEvent` occurs when a mouse button is pressed.
#[derive(Event)]
pub struct MouseDownEvent {
    /// Indicates the mouse button that is pressed.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `GlobalMouseUpEvent` occurs when a mouse button is released.
///
/// Global events could not be handled and could be read on each state.
#[derive(Event)]
pub struct GlobalMouseUpEvent {
    /// Indicates the mouse button that is released.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// Defines the mouse handler function.
pub type MouseHandlerFunction = dyn Fn(&mut StatesContext, Mouse) -> bool + 'static;

//// Defines a position based event handler.
pub type PositionHandlerFunction = dyn Fn(&mut StatesContext, Point) -> bool + 'static;

/// Defines the global bouse handler function.
pub type GlobalMouseHandlerFunction = dyn Fn(&mut StatesContext, Mouse) + 'static;

/// Used to handle click events. Could be attached to a widget.
pub struct ClickEventHandler {
    handler: Rc<PositionHandlerFunction>,
}

impl Into<Rc<dyn EventHandler>> for ClickEventHandler {
    fn into(self) -> Rc<dyn EventHandler> {
        Rc::new(self)
    }
}

impl EventHandler for ClickEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<ClickEvent>()
            .ok()
            .map_or(false, |event| (self.handler)(state_context, event.position))
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<ClickEvent>()
    }
}

/// Used to handle mouse down events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct MouseDownEventHandler {
    handler: Rc<MouseHandlerFunction>,
}

impl EventHandler for MouseDownEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<MouseDownEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    Mouse {
                        button: event.button,
                        position: Point::new(event.position.x, event.position.y),
                    },
                )
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<MouseDownEvent>()
    }
}

/// Defines an event handler for a global mouse up event. Global mouse up events could not be handled.
#[derive(IntoHandler)]
pub struct GlobalMouseUpEventHandler {
    handler: Rc<GlobalMouseHandlerFunction>,
}

impl EventHandler for GlobalMouseUpEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<GlobalMouseUpEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    Mouse {
                        button: event.button,
                        position: Point::new(event.position.x, event.position.y),
                    },
                );
                false
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<GlobalMouseUpEvent>()
    }
}

/// Used to handle mouse down events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct MouseUpEventHandler {
    handler: Rc<MouseHandlerFunction>,
}

impl EventHandler for MouseUpEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<MouseUpEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    Mouse {
                        button: event.button,
                        position: Point::new(event.position.x, event.position.y),
                    },
                )
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<MouseUpEvent>()
    }
}

/// Used to handle mouse down events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct MouseMoveEventHandler {
    handler: Rc<PositionHandlerFunction>,
}

impl EventHandler for MouseMoveEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<MouseMoveEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    Point::new(event.position.x, event.position.y),
                )
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<MouseMoveEvent>()
    }
}

/// Used to handle scroll events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct ScrollEventHandler {
    handler: Rc<PositionHandlerFunction>,
}

impl EventHandler for ScrollEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<ScrollEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(state_context, Point::new(event.delta.x, event.delta.y))
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<ScrollEvent>()
    }
}

pub trait MouseHandler: Sized + Widget {
    /// Inserts a click handler.
    fn on_click<H: Fn(&mut StatesContext, Point) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(ClickEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse down handler.
    fn on_mouse_down<H: Fn(&mut StatesContext, Mouse) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(MouseDownEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse up handler.
    fn on_mouse_up<H: Fn(&mut StatesContext, Mouse) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(MouseUpEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse handler for global up event.
    fn on_global_mouse_up<H: Fn(&mut StatesContext, Mouse) + 'static>(self, handler: H) -> Self {
        self.insert_handler(GlobalMouseUpEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse move handler.
    fn on_mouse_move<H: Fn(&mut StatesContext, Point) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(MouseMoveEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse up handler.
    fn on_scroll<H: Fn(&mut StatesContext, Point) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(ScrollEventHandler {
            handler: Rc::new(handler),
        })
    }
}
<commit_msg>Updated usage of `Rectangle` and fixed usage of `Point`<commit_after>use std::rc::Rc;

use crate::{
    prelude::*,
    proc_macros::{Event, IntoHandler},
    shell::MouseButton,
    utils::*,
};

/// Checks if the given point is inside of a widget.
pub fn check_mouse_condition(mouse_position: Point, widget: &WidgetContainer<'_>) -> bool {
    let enabled = widget.get::<bool>("enabled");

    if !enabled {
        return false;
    }

    let bounds = widget.get::<Rectangle>("bounds");
    let position = widget.get::<Point>("position");

    let mut rect = Rectangle::new((0.0, 0.0), bounds.width(), bounds.height());

    rect.set_x(position.x());
    rect.set_y(position.y());

    rect.contains(mouse_position)
}

/// `MouseMoveEvent` indicates if the mouse position is changed on the window.
#[derive(Event)]
pub struct MouseMoveEvent {
    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `ScrollEvent` occurs when the mouse wheel is moved.
#[derive(Event)]
pub struct ScrollEvent {
    /// Indicates the scroll offset x and y.
    pub delta: Point,
}

/// Represents the current mouse state of an mouse event.
#[derive(Debug, Copy, Clone)]
pub struct Mouse {
    /// Indicates the mouse button that is connected to the event.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `MouseUpEvent` occurs when a mouse button is released.
#[derive(Event)]
pub struct MouseUpEvent {
    /// Indicates the mouse button that is released.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `ClickEvent` occurs when a user clicked on an element.
#[derive(Event)]
pub struct ClickEvent {
    /// Indicates the x and y position of the click event.
    pub position: Point,
}

/// `MouseDownEvent` occurs when a mouse button is pressed.
#[derive(Event)]
pub struct MouseDownEvent {
    /// Indicates the mouse button that is pressed.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// `GlobalMouseUpEvent` occurs when a mouse button is released.
///
/// Global events could not be handled and could be read on each state.
#[derive(Event)]
pub struct GlobalMouseUpEvent {
    /// Indicates the mouse button that is released.
    pub button: MouseButton,

    /// Indicates position of the mouse on the window.
    pub position: Point,
}

/// Defines the mouse handler function.
pub type MouseHandlerFunction = dyn Fn(&mut StatesContext, Mouse) -> bool + 'static;

//// Defines a position based event handler.
pub type PositionHandlerFunction = dyn Fn(&mut StatesContext, Point) -> bool + 'static;

/// Defines the global bouse handler function.
pub type GlobalMouseHandlerFunction = dyn Fn(&mut StatesContext, Mouse) + 'static;

/// Used to handle click events. Could be attached to a widget.
pub struct ClickEventHandler {
    handler: Rc<PositionHandlerFunction>,
}

impl Into<Rc<dyn EventHandler>> for ClickEventHandler {
    fn into(self) -> Rc<dyn EventHandler> {
        Rc::new(self)
    }
}

impl EventHandler for ClickEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<ClickEvent>()
            .ok()
            .map_or(false, |event| (self.handler)(state_context, event.position))
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<ClickEvent>()
    }
}

/// Used to handle mouse down events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct MouseDownEventHandler {
    handler: Rc<MouseHandlerFunction>,
}

impl EventHandler for MouseDownEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<MouseDownEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    Mouse {
                        button: event.button,
                        position: event.position,
                    },
                )
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<MouseDownEvent>()
    }
}

/// Defines an event handler for a global mouse up event. Global mouse up events could not be handled.
#[derive(IntoHandler)]
pub struct GlobalMouseUpEventHandler {
    handler: Rc<GlobalMouseHandlerFunction>,
}

impl EventHandler for GlobalMouseUpEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<GlobalMouseUpEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    Mouse {
                        button: event.button,
                        position: event.position,
                    },
                );
                false
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<GlobalMouseUpEvent>()
    }
}

/// Used to handle mouse down events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct MouseUpEventHandler {
    handler: Rc<MouseHandlerFunction>,
}

impl EventHandler for MouseUpEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<MouseUpEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    Mouse {
                        button: event.button,
                        position: event.position,
                    },
                )
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<MouseUpEvent>()
    }
}

/// Used to handle mouse down events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct MouseMoveEventHandler {
    handler: Rc<PositionHandlerFunction>,
}

impl EventHandler for MouseMoveEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<MouseMoveEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(
                    state_context,
                    event.position,
                )
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<MouseMoveEvent>()
    }
}

/// Used to handle scroll events. Could be attached to a widget.
#[derive(IntoHandler)]
pub struct ScrollEventHandler {
    handler: Rc<PositionHandlerFunction>,
}

impl EventHandler for ScrollEventHandler {
    fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
        event
            .downcast_ref::<ScrollEvent>()
            .ok()
            .map_or(false, |event| {
                (self.handler)(state_context, event.delta)
            })
    }

    fn handles_event(&self, event: &EventBox) -> bool {
        event.is_type::<ScrollEvent>()
    }
}

pub trait MouseHandler: Sized + Widget {
    /// Inserts a click handler.
    fn on_click<H: Fn(&mut StatesContext, Point) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(ClickEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse down handler.
    fn on_mouse_down<H: Fn(&mut StatesContext, Mouse) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(MouseDownEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse up handler.
    fn on_mouse_up<H: Fn(&mut StatesContext, Mouse) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(MouseUpEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse handler for global up event.
    fn on_global_mouse_up<H: Fn(&mut StatesContext, Mouse) + 'static>(self, handler: H) -> Self {
        self.insert_handler(GlobalMouseUpEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse move handler.
    fn on_mouse_move<H: Fn(&mut StatesContext, Point) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(MouseMoveEventHandler {
            handler: Rc::new(handler),
        })
    }

    /// Insert a mouse up handler.
    fn on_scroll<H: Fn(&mut StatesContext, Point) -> bool + 'static>(self, handler: H) -> Self {
        self.insert_handler(ScrollEventHandler {
            handler: Rc::new(handler),
        })
    }
}
<|endoftext|>


<commit_before>use crate::Value;

/// Used to describes a thickness e.g a border thickness.
#[derive(Copy, Clone, Default, Debug, PartialEq)]
pub struct Thickness {
    /// Left of thickness.
    pub left: f64,

    /// Top of thickness.
    pub top: f64,

    /// Right of thickness.
    pub right: f64,

    /// Bottom of thickness.
    pub bottom: f64,
}

impl Thickness {
    /// Create a new thickness with the given parameters.
    pub fn new(left: f64, top: f64, right: f64, bottom: f64) -> Self {
        Thickness {
            left,
            top,
            right,
            bottom,
        }
    }

    /// Gets left.
    pub fn left(&self) -> f64 {
        self.left
    }

    /// Sets left.
    pub fn set_left(&mut self, left: f64) {
        self.left = left;
    }

    /// Gets top.
    pub fn top(&self) -> f64 {
        self.top
    }

    /// Sets top.
    pub fn set_top(&mut self, top: f64) {
        self.top = top;
    }

    /// Gets right.
    pub fn right(&self) -> f64 {
        self.right
    }

    /// Sets right.
    pub fn set_right(&mut self, right: f64) {
        self.right = right;
    }

    /// Gets bottom.
    pub fn bottom(&self) -> f64 {
        self.bottom
    }

    /// Sets bottom.
    pub fn set_bottom(&mut self, bottom: f64) {
        self.bottom = bottom;
    }

    /// Gets thickness.
    pub fn thickness(&self) -> Thickness {
        *self
    }

    /// Sets thickness.
    pub fn set_thickness<T: Into<Thickness>>(&mut self, thickness: T) {
        let other = thickness.into();

        self.set_left(other.left());
        self.set_top(other.top());
        self.set_right(other.right());
        self.set_bottom(other.bottom());
    }
}

// --- Trait implementations ---

impl From<(i32, i32, i32, i32)> for Thickness {
    fn from(t: (i32, i32, i32, i32)) -> Self {
        Thickness::new(t.0 as f64, t.1 as f64, t.2 as f64, t.3 as f64)
    }
}

impl From<(i32, i32)> for Thickness {
    fn from(t: (i32, i32)) -> Self {
        Thickness::new(t.0 as f64, t.1 as f64, t.0 as f64, t.1 as f64)
    }
}

impl From<i32> for Thickness {
    fn from(t: i32) -> Self {
        Thickness::new(t as f64, t as f64, t as f64, t as f64)
    }
}

impl From<(f64, f64, f64, f64)> for Thickness {
    fn from(t: (f64, f64, f64, f64)) -> Self {
        Thickness::new(t.0, t.1, t.2, t.3)
    }
}

impl From<(f64, f64)> for Thickness {
    fn from(t: (f64, f64)) -> Self {
        Thickness::new(t.0, t.1, t.0, t.1)
    }
}

impl From<f64> for Thickness {
    fn from(t: f64) -> Self {
        Thickness::new(t, t, t, t)
    }
}

impl From<Value> for Thickness {
    fn from(v: Value) -> Self {
        match v.0 {
            ron::Value::Number(value) => Thickness::from(value.into_f64()),
            ron::Value::Map(map) => {
                let mut left = 0.0;
                let mut top = 0.0;
                let mut right = 0.0;
                let mut bottom = 0.0;

                for (key, value) in map.iter() {
                    if let Ok(key) = key.clone().into_rust::<String>() {
                        let value = if let Ok(value) = value.clone().into_rust::<f64>() {
                            value
                        } else {
                            0.0
                        };

                        if key.as_str().eq("left") {
                            left = value;
                        }

                        if key.as_str().eq("top") {
                            top = value;
                        }

                        if key.as_str().eq("right") {
                            right = value;
                        }

                        if key.as_str().eq("bottom") {
                            bottom = value;
                        }
                    }
                }

                return Thickness::from((left, top, right, bottom));
            }
            _ => Thickness::default(),
        }
    }
}

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

    #[test]
    fn test_new() {
        let rect = Thickness::new(5.0, 10.0, 20.0, 30.0);

        assert_eq!(rect.left, 5.0);
        assert_eq!(rect.top, 10.0);
        assert_eq!(rect.right, 20.0);
        assert_eq!(rect.bottom, 30.0);
    }

    #[test]
    fn test_into() {
        let thickness: Thickness = (10.0, 12.0, 13.0, 14.0).into();

        assert_eq!(thickness.left, 10.0);
        assert_eq!(thickness.top, 12.0);
        assert_eq!(thickness.right, 13.0);
        assert_eq!(thickness.bottom, 14.0);

        let thickness: Thickness = 10.0.into();

        assert_eq!(thickness.left, 10.0);
        assert_eq!(thickness.top, 10.0);
        assert_eq!(thickness.right, 10.0);
        assert_eq!(thickness.bottom, 10.0);
    }
}
<commit_msg>clippy fix<commit_after>use crate::Value;

/// Used to describes a thickness e.g a border thickness.
#[derive(Copy, Clone, Default, Debug, PartialEq)]
pub struct Thickness {
    /// Left of thickness.
    pub left: f64,

    /// Top of thickness.
    pub top: f64,

    /// Right of thickness.
    pub right: f64,

    /// Bottom of thickness.
    pub bottom: f64,
}

impl Thickness {
    /// Create a new thickness with the given parameters.
    pub fn new(left: f64, top: f64, right: f64, bottom: f64) -> Self {
        Thickness {
            left,
            top,
            right,
            bottom,
        }
    }

    /// Gets left.
    pub fn left(&self) -> f64 {
        self.left
    }

    /// Sets left.
    pub fn set_left(&mut self, left: f64) {
        self.left = left;
    }

    /// Gets top.
    pub fn top(&self) -> f64 {
        self.top
    }

    /// Sets top.
    pub fn set_top(&mut self, top: f64) {
        self.top = top;
    }

    /// Gets right.
    pub fn right(&self) -> f64 {
        self.right
    }

    /// Sets right.
    pub fn set_right(&mut self, right: f64) {
        self.right = right;
    }

    /// Gets bottom.
    pub fn bottom(&self) -> f64 {
        self.bottom
    }

    /// Sets bottom.
    pub fn set_bottom(&mut self, bottom: f64) {
        self.bottom = bottom;
    }

    /// Gets thickness.
    pub fn thickness(&self) -> Thickness {
        *self
    }

    /// Sets thickness.
    pub fn set_thickness<T: Into<Thickness>>(&mut self, thickness: T) {
        let other = thickness.into();

        self.set_left(other.left());
        self.set_top(other.top());
        self.set_right(other.right());
        self.set_bottom(other.bottom());
    }
}

// --- Trait implementations ---

impl From<(i32, i32, i32, i32)> for Thickness {
    fn from(t: (i32, i32, i32, i32)) -> Self {
        Thickness::new(t.0 as f64, t.1 as f64, t.2 as f64, t.3 as f64)
    }
}

impl From<(i32, i32)> for Thickness {
    fn from(t: (i32, i32)) -> Self {
        Thickness::new(t.0 as f64, t.1 as f64, t.0 as f64, t.1 as f64)
    }
}

impl From<i32> for Thickness {
    fn from(t: i32) -> Self {
        Thickness::new(t as f64, t as f64, t as f64, t as f64)
    }
}

impl From<(f64, f64, f64, f64)> for Thickness {
    fn from(t: (f64, f64, f64, f64)) -> Self {
        Thickness::new(t.0, t.1, t.2, t.3)
    }
}

impl From<(f64, f64)> for Thickness {
    fn from(t: (f64, f64)) -> Self {
        Thickness::new(t.0, t.1, t.0, t.1)
    }
}

impl From<f64> for Thickness {
    fn from(t: f64) -> Self {
        Thickness::new(t, t, t, t)
    }
}

impl From<Value> for Thickness {
    fn from(v: Value) -> Self {
        match v.0 {
            ron::Value::Number(value) => Thickness::from(value.into_f64()),
            ron::Value::Map(map) => {
                let mut left = 0.0;
                let mut top = 0.0;
                let mut right = 0.0;
                let mut bottom = 0.0;

                for (key, value) in map.iter() {
                    if let Ok(key) = key.clone().into_rust::<String>() {
                        let value = if let Ok(value) = value.clone().into_rust::<f64>() {
                            value
                        } else {
                            0.0
                        };

                        if key.as_str().eq("left") {
                            left = value;
                        }

                        if key.as_str().eq("top") {
                            top = value;
                        }

                        if key.as_str().eq("right") {
                            right = value;
                        }

                        if key.as_str().eq("bottom") {
                            bottom = value;
                        }
                    }
                }

                Thickness::from((left, top, right, bottom))
            }
            _ => Thickness::default(),
        }
    }
}

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

    #[test]
    fn test_new() {
        let rect = Thickness::new(5.0, 10.0, 20.0, 30.0);

        assert_eq!(rect.left, 5.0);
        assert_eq!(rect.top, 10.0);
        assert_eq!(rect.right, 20.0);
        assert_eq!(rect.bottom, 30.0);
    }

    #[test]
    fn test_into() {
        let thickness: Thickness = (10.0, 12.0, 13.0, 14.0).into();

        assert_eq!(thickness.left, 10.0);
        assert_eq!(thickness.top, 12.0);
        assert_eq!(thickness.right, 13.0);
        assert_eq!(thickness.bottom, 14.0);

        let thickness: Thickness = 10.0.into();

        assert_eq!(thickness.left, 10.0);
        assert_eq!(thickness.top, 10.0);
        assert_eq!(thickness.right, 10.0);
        assert_eq!(thickness.bottom, 10.0);
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use protobuf;
use protobuf::compiler_plugin;
use protobuf::descriptor::*;
use protobuf::descriptorx::*;
use protobuf::Message;
use protobuf_codegen::code_writer::CodeWriter;

/// Adjust method name to follow Rust style.
fn snake_name(name: &str) -> String {
    let mut snake_method_name = String::with_capacity(name.len());
    let mut chars = name.chars();
    // initial char can be any char except '_'.
    let mut last_char = '.';
    'outer: while let Some(c) = chars.next() {
        // Please note that '_' is neither uppercase nor lowercase.
        if !c.is_uppercase() {
            last_char = c;
            snake_method_name.push(c);
            continue;
        }
        let mut can_append_underscore = false;
        // check if it's the first char.
        if !snake_method_name.is_empty() && last_char != '_' {
            snake_method_name.push('_');
        }
        last_char = c;
        // find all continous upper case char and append an underscore before
        // last upper case char if neccessary.
        while let Some(c) = chars.next() {
            if !c.is_uppercase() {
                if can_append_underscore && c != '_' {
                    snake_method_name.push('_');
                }
                snake_method_name.extend(last_char.to_lowercase());
                snake_method_name.push(c);
                last_char = c;
                continue 'outer;
            }
            snake_method_name.extend(last_char.to_lowercase());
            last_char = c;
            can_append_underscore = true;
        }
        snake_method_name.extend(last_char.to_lowercase());
    }
    snake_method_name
}

struct MethodGen<'a> {
    proto: &'a MethodDescriptorProto,
    service_path: String,
    root_scope: &'a RootScope<'a>,
}

impl<'a> MethodGen<'a> {
    fn new(
        proto: &'a MethodDescriptorProto,
        service_path: String,
        root_scope: &'a RootScope<'a>,
    ) -> MethodGen<'a> {
        MethodGen {
            proto: proto,
            service_path: service_path,
            root_scope: root_scope,
        }
    }

    fn snake_name(&self) -> String {
        snake_name(self.proto.get_name())
    }

    fn input_empty(&self) -> bool {
        self.root_scope
            .find_message(self.proto.get_input_type())
            .message
            == protobuf::well_known_types::Empty::descriptor_static().get_proto()
    }

    fn output_empty(&self) -> bool {
        self.root_scope
            .find_message(self.proto.get_output_type())
            .message
            == protobuf::well_known_types::Empty::descriptor_static().get_proto()
    }

    fn input_message(&self) -> String {
        let msg = self.root_scope.find_message(self.proto.get_input_type());
        let empty = protobuf::well_known_types::Empty::descriptor_static();
        if msg.message == empty.get_proto() {
            "()".to_string()
        } else {
            format!("super::{}", msg.rust_fq_name())
        }
    }

    fn output_message(&self) -> String {
        let msg = self.root_scope.find_message(self.proto.get_output_type());
        let empty = protobuf::well_known_types::Empty::descriptor_static();
        if msg.message == empty.get_proto() {
            "()".to_string()
        } else {
            format!("super::{}", msg.rust_fq_name())
        }
    }

    fn server_req_type(&self) -> String {
        match self.proto.get_client_streaming() {
            false => format!("{}", self.input_message()),
            // TODO: better streaming
            true => format!("Vec<{}>", self.input_message()),
        }
    }

    fn server_resp_type(&self) -> String {
        match self.proto.get_server_streaming() {
            false => format!("{}", self.output_message()),
            // TODO: better streaming
            true => format!("Vec<{}>", self.output_message()),
        }
    }

    fn server_sig(&self) -> String {
        let arg;
        if self.input_empty() {
            arg = "".to_string();
        } else {
            arg = format!(
                ", {}: {}",
                if self.proto.get_client_streaming() {
                    "reqs"
                } else {
                    "req"
                },
                self.server_req_type(),
            );
        }
        let result;
        if self.output_empty() {
            result = "".to_string();
        } else {
            result = format!(" -> {}", self.server_resp_type());
        }
        format!("{}(&mut self{}){}", self.snake_name(), arg, result)
    }

    fn write_server_intf(&self, w: &mut CodeWriter) {
        w.fn_def(&self.server_sig())
    }

    fn streaming_upper(&self) -> &'static str {
        match (
            self.proto.get_client_streaming(),
            self.proto.get_server_streaming(),
        ) {
            (false, false) => "Unary",
            (false, true) => "ServerStreaming",
            (true, false) => "ClientStreaming",
            (true, true) => "Bidi",
        }
    }

    fn write_dispatch(&self, w: &mut CodeWriter) {
        // TODO: rather than explicitly generating dispatch() boilerplate, instead
        // invoke a generic method that accepts the relevant request/response types.
        let param_in;
        if self.input_empty() {
            param_in = "";
        } else {
            match self.proto.get_client_streaming() {
                false => {
                    param_in = "req";
                    w.write_line("let req = protobuf::parse_from_reader(grpc_channel).unwrap();")
                }
                true => {
                    param_in = "reqs";
                    w.write_line("let mut reqs = vec![];");
                    w.block("loop {", "}", |w| {
                        w.block(
                            "match protobuf::parse_from_reader(grpc_channel) {",
                            "}",
                            |w| {
                                w.write_line("Err(_) => break,");
                                w.write_line("Ok(req) => reqs.push(req),");
                            },
                        );
                    });
                }
            }
        }
        if self.output_empty() {
            w.write_line(&format!("node.{}({});", self.snake_name(), param_in));
        } else {
            match self.proto.get_server_streaming() {
                false => {
                    w.write_line(&format!(
                        "let rsp = node.{}({});",
                        self.snake_name(),
                        param_in
                    ));
                    w.write_line("rsp.write_to_writer(grpc_channel).unwrap();");
                }
                true => {
                    w.write_line(&format!(
                        "let rsps = node.{}({});",
                        self.snake_name(),
                        param_in
                    ));
                    w.block("for rsp in rsps {", "}", |w| {
                        w.write_line("rsp.write_to_writer(grpc_channel).unwrap();");
                    });
                }
            }
        }
    }

    fn write_descriptor(&self, w: &mut CodeWriter, before: &str, after: &str) {
        w.block(
            &format!("{}{}", before, "::grpc::rt::MethodDescriptor {"),
            &format!("{}{}", "}", after),
            |w| {
                w.field_entry(
                    "name",
                    &format!(
                        "::grpc::rt::StringOrStatic::Static(\"{}/{}\")",
                        self.service_path,
                        self.proto.get_name()
                    ),
                );
                w.field_entry(
                    "streaming",
                    &format!("::grpc::rt::GrpcStreaming::{}", self.streaming_upper()),
                );
                w.field_entry(
                    "req_marshaller",
                    "::grpc::rt::ArcOrStatic::Static(&::grpc_protobuf::MarshallerProtobuf)",
                );
                w.field_entry(
                    "resp_marshaller",
                    "::grpc::rt::ArcOrStatic::Static(&::grpc_protobuf::MarshallerProtobuf)",
                );
            },
        );
    }
}

struct ServiceGen<'a> {
    proto: &'a ServiceDescriptorProto,
    _root_scope: &'a RootScope<'a>,
    methods: Vec<MethodGen<'a>>,
    service_path: String,
    _package: String,
}

impl<'a> ServiceGen<'a> {
    fn new(
        proto: &'a ServiceDescriptorProto,
        file: &FileDescriptorProto,
        root_scope: &'a RootScope,
    ) -> ServiceGen<'a> {
        let service_path = if file.get_package().is_empty() {
            format!("/{}", proto.get_name())
        } else {
            format!("/{}.{}", file.get_package(), proto.get_name())
        };
        let methods = proto
            .get_method()
            .into_iter()
            .map(|m| MethodGen::new(m, service_path.clone(), root_scope))
            .collect();

        ServiceGen {
            proto,
            _root_scope: root_scope,
            methods,
            service_path,
            _package: file.get_package().to_string(),
        }
    }

    // server struct name
    fn server_name(&self) -> String {
        format!("{}Server", self.proto.get_name())
    }

    // trait name
    fn server_intf_name(&self) -> String {
        format!("{}Node", self.proto.get_name())
    }

    fn write_server_intf(&self, w: &mut CodeWriter) {
        w.pub_trait(&self.server_intf_name(), |w| {
            for (i, method) in self.methods.iter().enumerate() {
                if i != 0 {
                    w.write_line("");
                }

                method.write_server_intf(w);
            }
        });
    }

    fn write_service_definition(
        &self,
        before: &str,
        after: &str,
        handler: &str,
        w: &mut CodeWriter,
    ) {
        w.block(
            &format!("{}::grpc::rt::ServerServiceDefinition::new(\"{}\",",
                before, self.service_path),
            &format!("){}", after),
            |w| {
                w.block("vec![", "],", |w| {
                    for method in &self.methods {
                        w.block("::grpc::rt::ServerMethod::new(", "),", |w| {
                            method.write_descriptor(w, "::grpc::rt::ArcOrStatic::Static(&", "),");
                            w.block("{", "},", |w| {
                                w.write_line(&format!("let handler_copy = {}.clone();", handler));
                                w.write_line(&format!("::grpc::rt::MethodHandler{}::new(move |ctx, req, resp| (*handler_copy).{}(ctx, req, resp))",
                                    method.streaming_upper(),
                                    method.snake_name()));
                            });
                        });
                    }
                });
            });
    }

    fn write_server(&self, w: &mut CodeWriter) {
        w.write_line(&format!("pub struct {};", self.server_name()));

        w.write_line("");

        w.write_line("");

        w.impl_self_block(&self.server_name(), |w| {
            w.pub_fn(&format!("new_service_def<H : {} + 'static + Sync + Send + 'static>(handler: H) -> ::grpc::rt::ServerServiceDefinition", self.server_intf_name()), |w| {
                w.write_line("let handler_arc = ::std::sync::Arc::new(handler);");

                self.write_service_definition("", "", "handler_arc", w);
            });
        });
    }

    fn write_dispatcher(&self, w: &mut CodeWriter) {
        w.pub_fn(&format!("dispatch(node: &mut {}, grpc_method_name: &str, grpc_channel: &mut oak::Channel)", self.server_intf_name()), |w| {
            w.block("match grpc_method_name {", "};", |w| {
                for method in &self.methods {
                    let full_path = format!("{}/{}", method.service_path, method.proto.get_name());
                    w.block(&format!("\"{}\" => {{", full_path), "}", |w| {
                        method.write_dispatch(w);
                    });
                }
                w.block("_ => {", "}", |w| {
                    w.write_line("writeln!(oak::logging_channel(), \"unknown method name: {}\", grpc_method_name).unwrap();");
                    w.write_line("panic!(\"unknown method name\");");
                });
            });
        });
    }

    fn write(&self, w: &mut CodeWriter) {
        w.write_line("use protobuf::Message;");
        w.write_line("use std::io::Write;");
        w.write_line("");
        w.comment("Oak node server interface");
        self.write_server_intf(w);
        w.write_line("");
        w.comment("Oak node gRPC method dispatcher");
        self.write_dispatcher(w);
    }
}

fn gen_file(
    file: &FileDescriptorProto,
    root_scope: &RootScope,
) -> Option<compiler_plugin::GenResult> {
    if file.get_service().is_empty() {
        return None;
    }

    let base = protobuf::descriptorx::proto_path_to_rust_mod(file.get_name());

    let mut v = Vec::new();
    {
        let mut w = CodeWriter::new(&mut v);
        w.write_generated();
        w.write_line("");

        for service in file.get_service() {
            w.write_line("");
            ServiceGen::new(service, file, root_scope).write(&mut w);
        }
    }

    Some(compiler_plugin::GenResult {
        name: base + "_grpc.rs",
        content: v,
    })
}

pub fn gen(
    file_descriptors: &[FileDescriptorProto],
    files_to_generate: &[String],
) -> Vec<compiler_plugin::GenResult> {
    let files_map: HashMap<&str, &FileDescriptorProto> =
        file_descriptors.iter().map(|f| (f.get_name(), f)).collect();

    let root_scope = RootScope {
        file_descriptors: file_descriptors,
    };

    let mut results = Vec::new();

    for file_name in files_to_generate {
        let file = files_map[&file_name[..]];

        if file.get_service().is_empty() {
            continue;
        }

        results.extend(gen_file(file, &root_scope).into_iter());
    }

    results
}

pub fn protoc_gen_grpc_rust_main() {
    compiler_plugin::plugin_main(gen);
}

#[cfg(test)]
mod test {
    #[test]
    fn test_snake_name() {
        let cases = vec![
            ("AsyncRequest", "async_request"),
            ("asyncRequest", "async_request"),
            ("async_request", "async_request"),
            ("createID", "create_id"),
            ("CreateIDForReq", "create_id_for_req"),
            ("Create_ID_For_Req", "create_id_for_req"),
            ("ID", "id"),
            ("id", "id"),
        ];

        for (origin, exp) in cases {
            let res = super::snake_name(&origin);
            assert_eq!(res, exp);
        }
    }
}
<commit_msg>grpc-rust: drop now-unused code generation methods<commit_after>use std::collections::HashMap;

use protobuf;
use protobuf::compiler_plugin;
use protobuf::descriptor::*;
use protobuf::descriptorx::*;
use protobuf::Message;
use protobuf_codegen::code_writer::CodeWriter;

/// Adjust method name to follow Rust style.
fn snake_name(name: &str) -> String {
    let mut snake_method_name = String::with_capacity(name.len());
    let mut chars = name.chars();
    // initial char can be any char except '_'.
    let mut last_char = '.';
    'outer: while let Some(c) = chars.next() {
        // Please note that '_' is neither uppercase nor lowercase.
        if !c.is_uppercase() {
            last_char = c;
            snake_method_name.push(c);
            continue;
        }
        let mut can_append_underscore = false;
        // check if it's the first char.
        if !snake_method_name.is_empty() && last_char != '_' {
            snake_method_name.push('_');
        }
        last_char = c;
        // find all continous upper case char and append an underscore before
        // last upper case char if neccessary.
        while let Some(c) = chars.next() {
            if !c.is_uppercase() {
                if can_append_underscore && c != '_' {
                    snake_method_name.push('_');
                }
                snake_method_name.extend(last_char.to_lowercase());
                snake_method_name.push(c);
                last_char = c;
                continue 'outer;
            }
            snake_method_name.extend(last_char.to_lowercase());
            last_char = c;
            can_append_underscore = true;
        }
        snake_method_name.extend(last_char.to_lowercase());
    }
    snake_method_name
}

struct MethodGen<'a> {
    proto: &'a MethodDescriptorProto,
    service_path: String,
    root_scope: &'a RootScope<'a>,
}

impl<'a> MethodGen<'a> {
    fn new(
        proto: &'a MethodDescriptorProto,
        service_path: String,
        root_scope: &'a RootScope<'a>,
    ) -> MethodGen<'a> {
        MethodGen {
            proto: proto,
            service_path: service_path,
            root_scope: root_scope,
        }
    }

    fn snake_name(&self) -> String {
        snake_name(self.proto.get_name())
    }

    fn input_empty(&self) -> bool {
        self.root_scope
            .find_message(self.proto.get_input_type())
            .message
            == protobuf::well_known_types::Empty::descriptor_static().get_proto()
    }

    fn output_empty(&self) -> bool {
        self.root_scope
            .find_message(self.proto.get_output_type())
            .message
            == protobuf::well_known_types::Empty::descriptor_static().get_proto()
    }

    fn input_message(&self) -> String {
        let msg = self.root_scope.find_message(self.proto.get_input_type());
        let empty = protobuf::well_known_types::Empty::descriptor_static();
        if msg.message == empty.get_proto() {
            "()".to_string()
        } else {
            format!("super::{}", msg.rust_fq_name())
        }
    }

    fn output_message(&self) -> String {
        let msg = self.root_scope.find_message(self.proto.get_output_type());
        let empty = protobuf::well_known_types::Empty::descriptor_static();
        if msg.message == empty.get_proto() {
            "()".to_string()
        } else {
            format!("super::{}", msg.rust_fq_name())
        }
    }

    fn server_req_type(&self) -> String {
        match self.proto.get_client_streaming() {
            false => format!("{}", self.input_message()),
            // TODO: better streaming
            true => format!("Vec<{}>", self.input_message()),
        }
    }

    fn server_resp_type(&self) -> String {
        match self.proto.get_server_streaming() {
            false => format!("{}", self.output_message()),
            // TODO: better streaming
            true => format!("Vec<{}>", self.output_message()),
        }
    }

    fn server_sig(&self) -> String {
        let arg;
        if self.input_empty() {
            arg = "".to_string();
        } else {
            arg = format!(
                ", {}: {}",
                if self.proto.get_client_streaming() {
                    "reqs"
                } else {
                    "req"
                },
                self.server_req_type(),
            );
        }
        let result;
        if self.output_empty() {
            result = "".to_string();
        } else {
            result = format!(" -> {}", self.server_resp_type());
        }
        format!("{}(&mut self{}){}", self.snake_name(), arg, result)
    }

    fn write_server_intf(&self, w: &mut CodeWriter) {
        w.fn_def(&self.server_sig())
    }

    fn write_dispatch(&self, w: &mut CodeWriter) {
        // TODO: rather than explicitly generating dispatch() boilerplate, instead
        // invoke a generic method that accepts the relevant request/response types.
        let param_in;
        if self.input_empty() {
            param_in = "";
        } else {
            match self.proto.get_client_streaming() {
                false => {
                    param_in = "req";
                    w.write_line("let req = protobuf::parse_from_reader(grpc_channel).unwrap();")
                }
                true => {
                    param_in = "reqs";
                    w.write_line("let mut reqs = vec![];");
                    w.block("loop {", "}", |w| {
                        w.block(
                            "match protobuf::parse_from_reader(grpc_channel) {",
                            "}",
                            |w| {
                                w.write_line("Err(_) => break,");
                                w.write_line("Ok(req) => reqs.push(req),");
                            },
                        );
                    });
                }
            }
        }
        if self.output_empty() {
            w.write_line(&format!("node.{}({});", self.snake_name(), param_in));
        } else {
            match self.proto.get_server_streaming() {
                false => {
                    w.write_line(&format!(
                        "let rsp = node.{}({});",
                        self.snake_name(),
                        param_in
                    ));
                    w.write_line("rsp.write_to_writer(grpc_channel).unwrap();");
                }
                true => {
                    w.write_line(&format!(
                        "let rsps = node.{}({});",
                        self.snake_name(),
                        param_in
                    ));
                    w.block("for rsp in rsps {", "}", |w| {
                        w.write_line("rsp.write_to_writer(grpc_channel).unwrap();");
                    });
                }
            }
        }
    }
}

struct ServiceGen<'a> {
    proto: &'a ServiceDescriptorProto,
    _root_scope: &'a RootScope<'a>,
    methods: Vec<MethodGen<'a>>,
    _package: String,
}

impl<'a> ServiceGen<'a> {
    fn new(
        proto: &'a ServiceDescriptorProto,
        file: &FileDescriptorProto,
        root_scope: &'a RootScope,
    ) -> ServiceGen<'a> {
        let service_path = if file.get_package().is_empty() {
            format!("/{}", proto.get_name())
        } else {
            format!("/{}.{}", file.get_package(), proto.get_name())
        };
        let methods = proto
            .get_method()
            .into_iter()
            .map(|m| MethodGen::new(m, service_path.clone(), root_scope))
            .collect();

        ServiceGen {
            proto,
            _root_scope: root_scope,
            methods,
            _package: file.get_package().to_string(),
        }
    }

    // trait name
    fn server_intf_name(&self) -> String {
        format!("{}Node", self.proto.get_name())
    }

    fn write_server_intf(&self, w: &mut CodeWriter) {
        w.pub_trait(&self.server_intf_name(), |w| {
            for (i, method) in self.methods.iter().enumerate() {
                if i != 0 {
                    w.write_line("");
                }

                method.write_server_intf(w);
            }
        });
    }

    fn write_dispatcher(&self, w: &mut CodeWriter) {
        w.pub_fn(&format!("dispatch(node: &mut {}, grpc_method_name: &str, grpc_channel: &mut oak::Channel)", self.server_intf_name()), |w| {
            w.block("match grpc_method_name {", "};", |w| {
                for method in &self.methods {
                    let full_path = format!("{}/{}", method.service_path, method.proto.get_name());
                    w.block(&format!("\"{}\" => {{", full_path), "}", |w| {
                        method.write_dispatch(w);
                    });
                }
                w.block("_ => {", "}", |w| {
                    w.write_line("writeln!(oak::logging_channel(), \"unknown method name: {}\", grpc_method_name).unwrap();");
                    w.write_line("panic!(\"unknown method name\");");
                });
            });
        });
    }

    fn write(&self, w: &mut CodeWriter) {
        w.write_line("use protobuf::Message;");
        w.write_line("use std::io::Write;");
        w.write_line("");
        w.comment("Oak node server interface");
        self.write_server_intf(w);
        w.write_line("");
        w.comment("Oak node gRPC method dispatcher");
        self.write_dispatcher(w);
    }
}

fn gen_file(
    file: &FileDescriptorProto,
    root_scope: &RootScope,
) -> Option<compiler_plugin::GenResult> {
    if file.get_service().is_empty() {
        return None;
    }

    let base = protobuf::descriptorx::proto_path_to_rust_mod(file.get_name());

    let mut v = Vec::new();
    {
        let mut w = CodeWriter::new(&mut v);
        w.write_generated();
        w.write_line("");

        for service in file.get_service() {
            w.write_line("");
            ServiceGen::new(service, file, root_scope).write(&mut w);
        }
    }

    Some(compiler_plugin::GenResult {
        name: base + "_grpc.rs",
        content: v,
    })
}

pub fn gen(
    file_descriptors: &[FileDescriptorProto],
    files_to_generate: &[String],
) -> Vec<compiler_plugin::GenResult> {
    let files_map: HashMap<&str, &FileDescriptorProto> =
        file_descriptors.iter().map(|f| (f.get_name(), f)).collect();

    let root_scope = RootScope {
        file_descriptors: file_descriptors,
    };

    let mut results = Vec::new();

    for file_name in files_to_generate {
        let file = files_map[&file_name[..]];

        if file.get_service().is_empty() {
            continue;
        }

        results.extend(gen_file(file, &root_scope).into_iter());
    }

    results
}

pub fn protoc_gen_grpc_rust_main() {
    compiler_plugin::plugin_main(gen);
}

#[cfg(test)]
mod test {
    #[test]
    fn test_snake_name() {
        let cases = vec![
            ("AsyncRequest", "async_request"),
            ("asyncRequest", "async_request"),
            ("async_request", "async_request"),
            ("createID", "create_id"),
            ("CreateIDForReq", "create_id_for_req"),
            ("Create_ID_For_Req", "create_id_for_req"),
            ("ID", "id"),
            ("id", "id"),
        ];

        for (origin, exp) in cases {
            let res = super::snake_name(&origin);
            assert_eq!(res, exp);
        }
    }
}
<|endoftext|>


<commit_before>extern crate sorting;

use std::fmt::Debug;

/// Verify order of input vector as sorted by indices.
///
/// # Details
///
/// This function takes as arguments a vector of data and a vector representing the indices of the
/// first vector making it sorted.
///
/// The elements of the sorted vector are compared to the next ones to make sure they are less
/// or equal.
///
/// # Panics
///
/// The sorting of the data vector is enforced using `assert!()`.
///
/// # Examples
///
/// ```
/// let data: Vec<i32> = vec![4, 2, 3, 1];
/// let sorted_indices: Vec<usize> = vec![3, 1, 2, 0];
/// verify_sorting(&data, &sorted_indices);
/// ```
///
fn verify_sorting<T: Debug + PartialOrd>(array: &Vec<T>, sorted_indices: &Vec<usize>) {
    let n = array.len();
    assert_eq!(n , sorted_indices.len());

    if !array.is_empty() {
        for i in 0..n-1 {
            println!("array[sorted_indices[i={:?}]]={:?}   array[sorted_indices[i+1={:?}]]={:?}",
                i, array[sorted_indices[i]], i+1, array[sorted_indices[i+1]]);
            assert!(array[sorted_indices[i]] <= array[sorted_indices[i+1]]);
        }
    }
}

/// Validate against empty vector.
#[test]
fn simple_insertion_empty() {
    let to_sort: Vec<i32> = vec![];

    let sorted_indices = sorting::simplesorts::insertion::sort(&to_sort);

    verify_sorting(&to_sort, &sorted_indices);

    assert_eq!(sorted_indices, vec![]);
}

/// Validate a vector of double precision values.
#[test]
fn simple_insertion_multiple_sizes_f64() {
    let to_sort: Vec<f64> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
                                 3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];

    let sorted_indices = sorting::simplesorts::insertion::sort(&to_sort);

    verify_sorting(&to_sort, &sorted_indices);

    assert_eq!(sorted_indices, vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12]);
}
<commit_msg>Use a generis fonction to validante empty vectors on integers.<commit_after>extern crate sorting;

use std::fmt::Debug;

/// Verify order of input vector as sorted by indices.
///
/// # Details
///
/// This function takes as arguments a vector of data and a vector representing the indices of the
/// first vector making it sorted.
///
/// The elements of the sorted vector are compared to the next ones to make sure they are less
/// or equal.
///
/// # Panics
///
/// The sorting of the data vector is enforced using `assert!()`.
///
/// # Examples
///
/// ```
/// let data: Vec<i32> = vec![4, 2, 3, 1];
/// let sorted_indices: Vec<usize> = vec![3, 1, 2, 0];
/// verify_sorting(&data, &sorted_indices);
/// ```
///
fn verify_sorting<T: Debug + PartialOrd>(array: &Vec<T>, sorted_indices: &Vec<usize>) {
    let n = array.len();
    assert_eq!(n , sorted_indices.len());

    if !array.is_empty() {
        for i in 0..n-1 {
            println!("array[sorted_indices[i={:?}]]={:?}   array[sorted_indices[i+1={:?}]]={:?}",
                i, array[sorted_indices[i]], i+1, array[sorted_indices[i+1]]);
            assert!(array[sorted_indices[i]] <= array[sorted_indices[i+1]]);
        }
    }
}

fn test_empty_vec<T: PartialOrd>(sorting_fct: fn(&Vec<T>) -> Vec<usize>) {
    let to_sort: Vec<T> = vec![];
    let sorted_indices = sorting_fct(&to_sort);
    assert_eq!(sorted_indices, vec![]);
}

/// Validate against empty vector (i8).
#[test]
fn simple_insertion_empty_vec_i8() {
    test_empty_vec::<i8>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i32).
#[test]
fn simple_insertion_empty_vec_i16() {
    test_empty_vec::<i16>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i32).
#[test]
fn simple_insertion_empty_vec_i32() {
    test_empty_vec::<i32>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i64).
#[test]
fn simple_insertion_empty_vec_i64() {
    test_empty_vec::<i64>(sorting::simplesorts::insertion::sort);
}

/// Validate against empty vector (u8).
#[test]
fn simple_insertion_empty_vec_u8() {
    test_empty_vec::<u8>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u32).
#[test]
fn simple_insertion_empty_vec_u16() {
    test_empty_vec::<u16>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u32).
#[test]
fn simple_insertion_empty_vec_u32() {
    test_empty_vec::<u32>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u64).
#[test]
fn simple_insertion_empty_vec_u64() {
    test_empty_vec::<u64>(sorting::simplesorts::insertion::sort);
}

/// Validate a vector of double precision values.
#[test]
fn simple_insertion_multiple_sizes_f64() {
    let to_sort: Vec<f64> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
                                 3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];

    let sorted_indices = sorting::simplesorts::insertion::sort(&to_sort);

    verify_sorting(&to_sort, &sorted_indices);

    assert_eq!(sorted_indices, vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12]);
}
<|endoftext|>


<commit_before>use std::io::net::udp::UdpSocket;
use std::io::net::ip::{Ipv4Addr, SocketAddr};

#[allow(dead_code)]
struct UtpPacketHeader {
    ver_type: u8, // ver: u4, type: u4
    extension: u8,
    connection_id: u16,
    timestamp_microseconds: u32,
    timestamp_difference_microseconds: u32,
    wnd_size: u32,
    seq_nr: u16,
    ack_nr: u16,
}

impl UtpPacketHeader {
    fn bytes(&self) -> &[u8] {
        unsafe {
            let buf: &[u8, ..20] = std::mem::transmute(self);
            return buf.as_slice();
        }
    }

    fn len(&self) -> uint {
        return 24;
    }
}

#[allow(dead_code)]
struct UtpPacket {
    header: UtpPacketHeader,
    payload: Vec<u8>,
}

impl UtpPacket {
    /// Constructs a new, empty UtpPacket.
    fn new() -> UtpPacket {
        UtpPacket {
            header: UtpPacketHeader {
                ver_type: 0 | 0 << 4,
                extension: 0,
                connection_id: 0,
                timestamp_microseconds: 0,
                timestamp_difference_microseconds: 0,
                wnd_size: 0,
                seq_nr: 0,
                ack_nr: 0,
            },
            payload: Vec::new(),
        }
    }

    fn bytes(&self) -> Vec<u8> {
        let mut buf: Vec<u8> = Vec::with_capacity(self.len());
        buf.push_all(self.header.bytes());
        buf.push_all(self.payload.as_slice());
        return buf;
    }

    fn len(&self) -> uint {
        self.header.len() + self.payload.len()
    }
}

fn main() {
    let mut buf = [0, ..512];
    let mut sock = UdpSocket::bind(SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 }).unwrap();

    match sock.recvfrom(buf) {
        Ok((_, src)) => {
            let mut packet = UtpPacket::new();
            packet.payload = String::from_str("Hello\n").into_bytes();

            let _ = sock.sendto(packet.bytes().as_slice(), src);
        }
        Err(_) => {}
    }
    drop(sock);
}
<commit_msg>Add UtpPacketType.<commit_after>use std::io::net::udp::UdpSocket;
use std::io::net::ip::{Ipv4Addr, SocketAddr};

#[allow(dead_code,non_camel_case_types)]
enum UtpPacketType {
    ST_DATA  = 0,
    ST_FIN   = 1,
    ST_STATE = 2,
    ST_RESET = 3,
    ST_SYN   = 4,
}

#[allow(dead_code)]
struct UtpPacketHeader {
    ver_type: u8, // ver: u4, type: u4
    extension: u8,
    connection_id: u16,
    timestamp_microseconds: u32,
    timestamp_difference_microseconds: u32,
    wnd_size: u32,
    seq_nr: u16,
    ack_nr: u16,
}

impl UtpPacketHeader {
    fn bytes(&self) -> &[u8] {
        unsafe {
            let buf: &[u8, ..20] = std::mem::transmute(self);
            return buf.as_slice();
        }
    }

    fn len(&self) -> uint {
        return 24;
    }
}

#[allow(dead_code)]
struct UtpPacket {
    header: UtpPacketHeader,
    payload: Vec<u8>,
}

impl UtpPacket {
    /// Constructs a new, empty UtpPacket.
    fn new() -> UtpPacket {
        UtpPacket {
            header: UtpPacketHeader {
                ver_type: 0 | 0 << 4,
                extension: 0,
                connection_id: 0,
                timestamp_microseconds: 0,
                timestamp_difference_microseconds: 0,
                wnd_size: 0,
                seq_nr: 0,
                ack_nr: 0,
            },
            payload: Vec::new(),
        }
    }

    fn bytes(&self) -> Vec<u8> {
        let mut buf: Vec<u8> = Vec::with_capacity(self.len());
        buf.push_all(self.header.bytes());
        buf.push_all(self.payload.as_slice());
        return buf;
    }

    fn len(&self) -> uint {
        self.header.len() + self.payload.len()
    }
}

fn main() {
    let mut buf = [0, ..512];
    let mut sock = UdpSocket::bind(SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 }).unwrap();

    match sock.recvfrom(buf) {
        Ok((_, src)) => {
            let mut packet = UtpPacket::new();
            packet.payload = String::from_str("Hello\n").into_bytes();

            let _ = sock.sendto(packet.bytes().as_slice(), src);
        }
        Err(_) => {}
    }
    drop(sock);
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/k-th-smallest-prime-fraction/
pub fn kth_smallest_prime_fraction(arr: Vec<i32>, k: i32) -> Vec<i32> {
    todo!()
}

fn main() {
    println!("{:?}", kth_smallest_prime_fraction(vec![1, 2, 3, 5], 3)); // [2,5]
    println!("{:?}", kth_smallest_prime_fraction(vec![1, 7], 1)); // [1,7]
}
<commit_msg>Solve problem 786<commit_after>// https://leetcode.com/problems/k-th-smallest-prime-fraction/
pub fn kth_smallest_prime_fraction(arr: Vec<i32>, k: i32) -> Vec<i32> {
    struct Fraction(i32, i32);
    let mut fractions: Vec<Fraction> = vec![];
    for i in 0..arr.len() {
        for j in i + 1..arr.len() {
            // println!("{} / {} = {}", arr[i], arr[j], i as f64 / j as f64);
            fractions.push(Fraction(arr[i], arr[j]));
        }
    }
    fractions.sort_by(|a, b| {
        (a.0 as f64 / a.1 as f64)
            .partial_cmp(&(b.0 as f64 / b.1 as f64))
            .unwrap()
    });
    let answer = &fractions[(k - 1) as usize];
    vec![answer.0, answer.1]
}

fn main() {
    println!("{:?}", kth_smallest_prime_fraction(vec![1, 2, 3, 5], 3)); // [2,5]
    println!("{:?}", kth_smallest_prime_fraction(vec![1, 7], 1)); // [1,7]
}
<|endoftext|>


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

use std::cmp::ApproxEq;
use std::num;
use std::num::{NumCast, One, Zero};

pub fn Matrix4<T:Add<T,T> + Clone + ApproxEq<T> + Mul<T,T> + One + Zero>(
        m11: T, m12: T, m13: T, m14: T,
        m21: T, m22: T, m23: T, m24: T,
        m31: T, m32: T, m33: T, m34: T,
        m41: T, m42: T, m43: T, m44: T)
     -> Matrix4<T> {
    Matrix4 {
        m11: m11, m12: m12, m13: m13, m14: m14,
        m21: m21, m22: m22, m23: m23, m24: m24,
        m31: m31, m32: m32, m33: m33, m34: m34,
        m41: m41, m42: m42, m43: m43, m44: m44
    }
}

pub struct Matrix4<T> {
    m11: T, m12: T, m13: T, m14: T,
    m21: T, m22: T, m23: T, m24: T,
    m31: T, m32: T, m33: T, m34: T,
    m41: T, m42: T, m43: T, m44: T,
}

impl<T:Add<T,T> + Clone + ApproxEq<T> + Mul<T,T> + One + Zero> Matrix4<T> {
    pub fn approx_eq(&self, other: &Matrix4<T>) -> bool {
        self.m11.approx_eq(&other.m11) && self.m12.approx_eq(&other.m12) &&
        self.m13.approx_eq(&other.m13) && self.m14.approx_eq(&other.m14) &&
        self.m21.approx_eq(&other.m21) && self.m22.approx_eq(&other.m22) &&
        self.m23.approx_eq(&other.m23) && self.m24.approx_eq(&other.m24) &&
        self.m31.approx_eq(&other.m31) && self.m32.approx_eq(&other.m32) &&
        self.m33.approx_eq(&other.m33) && self.m34.approx_eq(&other.m34) &&
        self.m41.approx_eq(&other.m41) && self.m42.approx_eq(&other.m42) &&
        self.m43.approx_eq(&other.m43) && self.m44.approx_eq(&other.m44)
    }

    pub fn mul(&self, m: &Matrix4<T>) -> Matrix4<T> {
        Matrix4(m.m11*self.m11 + m.m12*self.m21 + m.m13*self.m31 + m.m14*self.m41,
                m.m11*self.m12 + m.m12*self.m22 + m.m13*self.m32 + m.m14*self.m42,
                m.m11*self.m13 + m.m12*self.m23 + m.m13*self.m33 + m.m14*self.m43,
                m.m11*self.m14 + m.m12*self.m24 + m.m13*self.m34 + m.m14*self.m44,
                m.m21*self.m11 + m.m22*self.m21 + m.m23*self.m31 + m.m24*self.m41,
                m.m21*self.m12 + m.m22*self.m22 + m.m23*self.m32 + m.m24*self.m42,
                m.m21*self.m13 + m.m22*self.m23 + m.m23*self.m33 + m.m24*self.m43,
                m.m21*self.m14 + m.m22*self.m24 + m.m23*self.m34 + m.m24*self.m44,
                m.m31*self.m11 + m.m32*self.m21 + m.m33*self.m31 + m.m34*self.m41,
                m.m31*self.m12 + m.m32*self.m22 + m.m33*self.m32 + m.m34*self.m42,
                m.m31*self.m13 + m.m32*self.m23 + m.m33*self.m33 + m.m34*self.m43,
                m.m31*self.m14 + m.m32*self.m24 + m.m33*self.m34 + m.m34*self.m44,
                m.m41*self.m11 + m.m42*self.m21 + m.m43*self.m31 + m.m44*self.m41,
                m.m41*self.m12 + m.m42*self.m22 + m.m43*self.m32 + m.m44*self.m42,
                m.m41*self.m13 + m.m42*self.m23 + m.m43*self.m33 + m.m44*self.m43,
                m.m41*self.m14 + m.m42*self.m24 + m.m43*self.m34 + m.m44*self.m44)
    }

    pub fn mul_s(&self, x: T) -> Matrix4<T> {
        Matrix4(self.m11 * x, self.m12 * x, self.m13 * x, self.m14 * x,
                self.m21 * x, self.m22 * x, self.m23 * x, self.m24 * x,
                self.m31 * x, self.m32 * x, self.m33 * x, self.m34 * x,
                self.m41 * x, self.m42 * x, self.m43 * x, self.m44 * x)
    }

    pub fn scale(&self, x: T, y: T, z: T) -> Matrix4<T> {
        Matrix4(self.m11 * x,     self.m12.clone(), self.m13.clone(), self.m14.clone(),
                self.m21.clone(), self.m22 * y,     self.m23.clone(), self.m24.clone(),
                self.m31.clone(), self.m32.clone(), self.m33 * z,     self.m34.clone(),
                self.m41.clone(), self.m42.clone(), self.m43.clone(), self.m44.clone())
    }

    pub fn to_array(&self) -> [T, ..16] {
        [
            self.m11.clone(), self.m12.clone(), self.m13.clone(), self.m14.clone(),
            self.m21.clone(), self.m22.clone(), self.m23.clone(), self.m24.clone(),
            self.m31.clone(), self.m32.clone(), self.m33.clone(), self.m34.clone(),
            self.m41.clone(), self.m42.clone(), self.m43.clone(), self.m44.clone()
        ]
    }

    pub fn translate(&self, x: T, y: T, z: T) -> Matrix4<T> {
        let (_0, _1): (T, T) = (Zero::zero(), One::one());
        let matrix = Matrix4(_1.clone(), _0.clone(), _0.clone(), _0.clone(),
                             _0.clone(), _1.clone(), _0.clone(), _0.clone(),
                             _0.clone(), _0.clone(), _1.clone(), _0.clone(),
                             x,  y,  z,  _1.clone());

        return self.mul(&matrix);
    }
}

pub fn ortho<T:Add<T,T> + Clone + Div<T,T> + ApproxEq<T> + Mul<T,T> + Neg<T> + NumCast + One +
               Sub<T,T> + Zero>
        (left: T,
         right: T,
         bottom: T,
         top: T,
         near: T,
         far: T)
      -> Matrix4<T> {
    let _2: T = num::cast(2).unwrap();
    let _1: T = One::one();
    let _0: T = Zero::zero();

    let tx = -((right + left) / (right - left));
    let ty = -((top + bottom) / (top - bottom));
    let tz = -((far + near) / (far - near));

    Matrix4(_2 / (right - left), _0.clone(),          _0.clone(),         _0.clone(),
            _0.clone(),          _2 / (top - bottom), _0.clone(),         _0.clone(),
            _0.clone(),          _0.clone(),          -_2 / (far - near), _0.clone(),
            tx,                  ty,                  tz,                 _1.clone())
}

pub fn identity<T:Add<T,T> + Clone + ApproxEq<T> + Mul<T,T> + One + Zero>() -> Matrix4<T> {
    let (_0, _1): (T, T) = (Zero::zero(), One::one());
    Matrix4(_1.clone(), _0.clone(), _0.clone(), _0.clone(),
            _0.clone(), _1.clone(), _0.clone(), _0.clone(),
            _0.clone(), _0.clone(), _1.clone(), _0.clone(),
            _0.clone(), _0.clone(), _0.clone(), _1.clone())
}

#[test]
pub fn test_ortho() {
    let (left, right, bottom, top) = (0.0, 1.0, 0.1, 1.0);
    let (near, far) = (-1.0, 1.0);
    let result = ortho(left, right, bottom, top, near, far);
    let expected = Matrix4(2.0,  0.0,         0.0,  0.0,
                           0.0,  2.22222222,  0.0,  0.0,
                           0.0,  0.0,         -1.0, 0.0,
                           -1.0, -1.22222222, -0.0, 1.0);
    debug!("result=%? expected=%?", result, expected);
    assert!(result.approx_eq(&expected));
}

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

use std::cmp::ApproxEq;
use std::num;
use std::num::{NumCast, One, Zero};

pub fn Matrix4<T:Add<T,T> + Clone + ApproxEq<T> + Mul<T,T> + One + Zero>(
        m11: T, m12: T, m13: T, m14: T,
        m21: T, m22: T, m23: T, m24: T,
        m31: T, m32: T, m33: T, m34: T,
        m41: T, m42: T, m43: T, m44: T)
     -> Matrix4<T> {
    Matrix4 {
        m11: m11, m12: m12, m13: m13, m14: m14,
        m21: m21, m22: m22, m23: m23, m24: m24,
        m31: m31, m32: m32, m33: m33, m34: m34,
        m41: m41, m42: m42, m43: m43, m44: m44
    }
}

pub struct Matrix4<T> {
    m11: T, m12: T, m13: T, m14: T,
    m21: T, m22: T, m23: T, m24: T,
    m31: T, m32: T, m33: T, m34: T,
    m41: T, m42: T, m43: T, m44: T,
}

impl<T:Add<T,T> + Clone + ApproxEq<T> + Mul<T,T> + One + Zero> Matrix4<T> {
    pub fn approx_eq(&self, other: &Matrix4<T>) -> bool {
        self.m11.approx_eq(&other.m11) && self.m12.approx_eq(&other.m12) &&
        self.m13.approx_eq(&other.m13) && self.m14.approx_eq(&other.m14) &&
        self.m21.approx_eq(&other.m21) && self.m22.approx_eq(&other.m22) &&
        self.m23.approx_eq(&other.m23) && self.m24.approx_eq(&other.m24) &&
        self.m31.approx_eq(&other.m31) && self.m32.approx_eq(&other.m32) &&
        self.m33.approx_eq(&other.m33) && self.m34.approx_eq(&other.m34) &&
        self.m41.approx_eq(&other.m41) && self.m42.approx_eq(&other.m42) &&
        self.m43.approx_eq(&other.m43) && self.m44.approx_eq(&other.m44)
    }

    pub fn mul(&self, m: &Matrix4<T>) -> Matrix4<T> {
        Matrix4(m.m11*self.m11 + m.m12*self.m21 + m.m13*self.m31 + m.m14*self.m41,
                m.m11*self.m12 + m.m12*self.m22 + m.m13*self.m32 + m.m14*self.m42,
                m.m11*self.m13 + m.m12*self.m23 + m.m13*self.m33 + m.m14*self.m43,
                m.m11*self.m14 + m.m12*self.m24 + m.m13*self.m34 + m.m14*self.m44,
                m.m21*self.m11 + m.m22*self.m21 + m.m23*self.m31 + m.m24*self.m41,
                m.m21*self.m12 + m.m22*self.m22 + m.m23*self.m32 + m.m24*self.m42,
                m.m21*self.m13 + m.m22*self.m23 + m.m23*self.m33 + m.m24*self.m43,
                m.m21*self.m14 + m.m22*self.m24 + m.m23*self.m34 + m.m24*self.m44,
                m.m31*self.m11 + m.m32*self.m21 + m.m33*self.m31 + m.m34*self.m41,
                m.m31*self.m12 + m.m32*self.m22 + m.m33*self.m32 + m.m34*self.m42,
                m.m31*self.m13 + m.m32*self.m23 + m.m33*self.m33 + m.m34*self.m43,
                m.m31*self.m14 + m.m32*self.m24 + m.m33*self.m34 + m.m34*self.m44,
                m.m41*self.m11 + m.m42*self.m21 + m.m43*self.m31 + m.m44*self.m41,
                m.m41*self.m12 + m.m42*self.m22 + m.m43*self.m32 + m.m44*self.m42,
                m.m41*self.m13 + m.m42*self.m23 + m.m43*self.m33 + m.m44*self.m43,
                m.m41*self.m14 + m.m42*self.m24 + m.m43*self.m34 + m.m44*self.m44)
    }

    pub fn mul_s(&self, x: T) -> Matrix4<T> {
        Matrix4(self.m11 * x, self.m12 * x, self.m13 * x, self.m14 * x,
                self.m21 * x, self.m22 * x, self.m23 * x, self.m24 * x,
                self.m31 * x, self.m32 * x, self.m33 * x, self.m34 * x,
                self.m41 * x, self.m42 * x, self.m43 * x, self.m44 * x)
    }

    pub fn scale(&self, x: T, y: T, z: T) -> Matrix4<T> {
        Matrix4(self.m11 * x,     self.m12.clone(), self.m13.clone(), self.m14.clone(),
                self.m21.clone(), self.m22 * y,     self.m23.clone(), self.m24.clone(),
                self.m31.clone(), self.m32.clone(), self.m33 * z,     self.m34.clone(),
                self.m41.clone(), self.m42.clone(), self.m43.clone(), self.m44.clone())
    }

    pub fn to_array(&self) -> [T, ..16] {
        [
            self.m11.clone(), self.m12.clone(), self.m13.clone(), self.m14.clone(),
            self.m21.clone(), self.m22.clone(), self.m23.clone(), self.m24.clone(),
            self.m31.clone(), self.m32.clone(), self.m33.clone(), self.m34.clone(),
            self.m41.clone(), self.m42.clone(), self.m43.clone(), self.m44.clone()
        ]
    }

    pub fn translate(&self, x: T, y: T, z: T) -> Matrix4<T> {
        let (_0, _1): (T, T) = (Zero::zero(), One::one());
        let matrix = Matrix4(_1.clone(), _0.clone(), _0.clone(), _0.clone(),
                             _0.clone(), _1.clone(), _0.clone(), _0.clone(),
                             _0.clone(), _0.clone(), _1.clone(), _0.clone(),
                             x,  y,  z,  _1.clone());

        return self.mul(&matrix);
    }
}

pub fn ortho<T:Add<T,T> + Clone + Div<T,T> + ApproxEq<T> + Mul<T,T> + Neg<T> + NumCast + One +
               Sub<T,T> + Zero>
        (left: T,
         right: T,
         bottom: T,
         top: T,
         near: T,
         far: T)
      -> Matrix4<T> {
    let _2: T = num::cast(2).unwrap();
    let _1: T = One::one();
    let _0: T = Zero::zero();

    let tx = -((right + left) / (right - left));
    let ty = -((top + bottom) / (top - bottom));
    let tz = -((far + near) / (far - near));

    Matrix4(_2 / (right - left), _0.clone(),          _0.clone(),         _0.clone(),
            _0.clone(),          _2 / (top - bottom), _0.clone(),         _0.clone(),
            _0.clone(),          _0.clone(),          -_2 / (far - near), _0.clone(),
            tx,                  ty,                  tz,                 _1.clone())
}

pub fn identity<T:Add<T,T> + Clone + ApproxEq<T> + Mul<T,T> + One + Zero>() -> Matrix4<T> {
    let (_0, _1): (T, T) = (Zero::zero(), One::one());
    Matrix4(_1.clone(), _0.clone(), _0.clone(), _0.clone(),
            _0.clone(), _1.clone(), _0.clone(), _0.clone(),
            _0.clone(), _0.clone(), _1.clone(), _0.clone(),
            _0.clone(), _0.clone(), _0.clone(), _1.clone())
}

#[test]
pub fn test_ortho() {
    let (left, right, bottom, top) = (0.0, 1.0, 0.1, 1.0);
    let (near, far) = (-1.0, 1.0);
    let result = ortho(left, right, bottom, top, near, far);
    let expected = Matrix4(2.0,  0.0,         0.0,  0.0,
                           0.0,  2.22222222,  0.0,  0.0,
                           0.0,  0.0,         -1.0, 0.0,
                           -1.0, -1.22222222, -0.0, 1.0);
    debug!("result={:?} expected={:?}", result, expected);
    assert!(result.approx_eq(&expected));
}

<|endoftext|>


<commit_before>extern crate serenity;

use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
use serenity::prelude::*;
use std::env;

struct Handler;

impl EventHandler for Handler {
    fn message(&self, _: Context, msg: Message) {
        if msg.content == "!hello" {
            // The create message builder allows you to easily create embeds and messages
            // using a builder syntax.
            // This example will create a message that says "Hello, World!", with an embed that has
            // a title, description, and footer.
            if let Err(why) = msg.channel_id.send_message(|m| m
                .content("Hello, World!")
                .embed(|e| e
                    .title("This is a title")
                    .description("This is a description")
                    .footer(|f| f
                        .text("This is a footer")))) {
                println!("Error sending message: {:?}", why);
            }
        }
    }

    fn ready(&self, _: Context, ready: Ready) {
        println!("{} is connected!", ready.user.name);
    }
}

fn main() {
    // Configure the client with your Discord bot token in the environment.
    let token = env::var("DISCORD_TOKEN")
        .expect("Expected a token in the environment");
    let mut client = Client::new(&token, Handler).expect("Err creating client");

    if let Err(why) = client.start() {
        println!("Client error: {:?}", why);
    }
}
<commit_msg>Add CreateEmbed::Field/s to 11_create_message_builder example (#338)<commit_after>extern crate serenity;

use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
use serenity::prelude::*;
use std::env;

struct Handler;

impl EventHandler for Handler {
    fn message(&self, _: Context, msg: Message) {
        if msg.content == "!hello" {
            // The create message builder allows you to easily create embeds and messages
            // using a builder syntax.
            // This example will create a message that says "Hello, World!", with an embed that has
            // a title, description, three fields, and footer.
            if let Err(why) = msg.channel_id.send_message(|m| m
                .content("Hello, World!")
                .embed(|e| e
                    .title("This is a title")
                    .description("This is a description")
                    .fields(vec![
                        ("This is the first field", "This is a field body", true),
                        ("This is the second field", "Both of these fields are inline", true),
                    ])
                    .field("This is the third field", "This is not an inline field", false)
                    .footer(|f| f
                        .text("This is a footer")))) {
                println!("Error sending message: {:?}", why);
            }
        }
    }

    fn ready(&self, _: Context, ready: Ready) {
        println!("{} is connected!", ready.user.name);
    }
}

fn main() {
    // Configure the client with your Discord bot token in the environment.
    let token = env::var("DISCORD_TOKEN")
        .expect("Expected a token in the environment");
    let mut client = Client::new(&token, Handler).expect("Err creating client");

    if let Err(why) = client.start() {
        println!("Client error: {:?}", why);
    }
}
<|endoftext|>


<commit_before>use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;
use std::env;

fn main() {
    let mut tab: Vec<_> = env::args().collect();

    if tab.len()==1 {
        tab[1] = "./".to_string();
    }
}
<commit_msg>change position in the tab<commit_after>use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;
use std::env;

fn main() {
    let mut tab: Vec<_> = env::args().collect();

    if tab.len()==1 {
        tab[0] = "./".to_string();
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate diesel;

use std::time::SystemTime;

use diesel::prelude::*;
#[cfg(test)]
use diesel::debug_query;
#[cfg(test)]
use diesel::pg::Pg;

table! {
    posts {
        id -> BigInt,
        title -> Text,
        body -> Text,
        draft -> Bool,
        publish_at -> Timestamp,
        visit_count -> Integer,
    }
}

#[derive(Queryable, Identifiable, AsChangeset)]
pub struct Post {
    pub id: i64,
    pub title: String,
    pub body: String,
    pub draft: bool,
    pub publish_at: SystemTime,
    pub visit_count: i32,
}

pub fn publish_all_posts(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;

    diesel::update(posts).set(draft.eq(false)).execute(conn)
}

#[test]
fn examine_sql_from_publish_all_posts() {
    use posts::dsl::*;

    assert_eq!(
        "UPDATE \"posts\" SET \"draft\" = $1 -- binds: [false]",
        debug_query(&diesel::update(posts).set(draft.eq(false))).to_string()
    );
}

pub fn publish_pending_posts(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;
    use diesel::dsl::now;

    diesel::update(posts)
        .filter(publish_at.lt(now))
        .set(draft.eq(false))
        .execute(conn)
}

#[test]
fn examine_sql_from_publish_pending_posts() {
    use posts::dsl::*;
    use diesel::dsl::now;

    let query = diesel::update(posts)
        .filter(publish_at.lt(now))
        .set(draft.eq(false));
    assert_eq!(
        "UPDATE \"posts\" SET \"draft\" = $1 \
         WHERE \"posts\".\"publish_at\" < CURRENT_TIMESTAMP \
         -- binds: [false]",
        debug_query::<Pg, _>(&query).to_string()
    );
}

pub fn publish_post(post: Post, conn: &PgConnection) -> QueryResult<usize> {
    diesel::update(&post)
        .set(posts::draft.eq(false))
        .execute(conn)
}

#[test]
fn examine_sql_from_publish_post() {
    let post = Post {
        id: 1,
        title: "".into(),
        body: "".into(),
        draft: false,
        publish_at: SystemTime::now(),
        visit_count: 0,
    };
    assert_eq!(
        "UPDATE \"posts\" SET \"draft\" = $1 WHERE \"posts\".\"id\" = $2 \
         -- binds: [false, 1]",
        debug_query::<Pg, _>(&diesel::update(&post).set(posts::draft.eq(false))).to_string()
    );
}

pub fn increment_visit_counts(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;

    diesel::update(posts)
        .set(visit_count.eq(visit_count + 1))
        .execute(conn)
}

#[test]
fn examine_sql_from_increment_visit_counts() {
    use posts::dsl::*;

    assert_eq!(
        "UPDATE \"posts\" SET \"visit_count\" = \"posts\".\"visit_count\" + $1 \
         -- binds: [1]",
        debug_query::<Pg, _>(&diesel::update(posts).set(visit_count.eq(visit_count + 1)))
            .to_string()
    );
}

pub fn hide_everything(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;

    diesel::update(posts)
        .set((
            title.eq("[REDACTED]"),
            body.eq("This post has been classified"),
        ))
        .execute(conn)
}

#[test]
fn examine_sql_from_hide_everything() {
    use posts::dsl::*;

    let query = diesel::update(posts).set((
        title.eq("[REDACTED]"),
        body.eq("This post has been classified"),
    ));
    assert_eq!(
        "UPDATE \"posts\" SET \"title\" = $1, \"body\" = $2 \
         -- binds: [\"[REDACTED]\", \"This post has been classified\"]",
        debug_query::<Pg, _>(&query).to_string()
    );
}

pub fn update_from_post_fields(post: Post, conn: &PgConnection) -> QueryResult<usize> {
    diesel::update(posts::table).set(&post).execute(conn)
}

#[test]
fn examine_sql_from_update_post_fields() {
    let now = SystemTime::now();
    let post = Post {
        id: 1,
        title: "".into(),
        body: "".into(),
        draft: false,
        publish_at: now,
        visit_count: 0,
    };
    let sql = format!(
        "UPDATE \"posts\" SET \
         \"title\" = $1, \
         \"body\" = $2, \
         \"draft\" = $3, \
         \"publish_at\" = $4, \
         \"visit_count\" = $5 \
         -- binds: [\
         \"\", \
         \"\", \
         false, \
         {:?}, \
         0\
         ]",
        now
    );
    assert_eq!(
        sql,
        debug_query::<Pg, _>(&diesel::update(posts::table).set(&post)).to_string()
    );
}

pub fn update_with_option(conn: &PgConnection) -> QueryResult<usize> {
    #[derive(AsChangeset)]
    #[table_name = "posts"]
    struct PostForm<'a> {
        title: Option<&'a str>,
        body: Option<&'a str>,
    }

    diesel::update(posts::table)
        .set(&PostForm {
            title: None,
            body: Some("My new post"),
        })
        .execute(conn)
}

#[test]
fn examine_sql_from_update_with_option() {
    #[derive(AsChangeset)]
    #[table_name = "posts"]
    struct PostForm<'a> {
        title: Option<&'a str>,
        body: Option<&'a str>,
    }

    let post_form = PostForm {
        title: None,
        body: Some("My new post"),
    };
    let query = diesel::update(posts::table).set(&post_form);
    assert_eq!(
        "UPDATE \"posts\" SET \"body\" = $1 \
         -- binds: [\"My new post\"]",
        debug_query::<Pg, _>(&query).to_string()
    );
}
<commit_msg>Remove needless `Pg` parameters<commit_after>#[macro_use]
extern crate diesel;

use std::time::SystemTime;

use diesel::prelude::*;
#[cfg(test)]
use diesel::debug_query;
#[cfg(test)]
use diesel::pg::Pg;

table! {
    posts {
        id -> BigInt,
        title -> Text,
        body -> Text,
        draft -> Bool,
        publish_at -> Timestamp,
        visit_count -> Integer,
    }
}

#[derive(Queryable, Identifiable, AsChangeset)]
pub struct Post {
    pub id: i64,
    pub title: String,
    pub body: String,
    pub draft: bool,
    pub publish_at: SystemTime,
    pub visit_count: i32,
}

pub fn publish_all_posts(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;

    diesel::update(posts).set(draft.eq(false)).execute(conn)
}

#[test]
fn examine_sql_from_publish_all_posts() {
    use posts::dsl::*;

    assert_eq!(
        "UPDATE \"posts\" SET \"draft\" = $1 -- binds: [false]",
        debug_query(&diesel::update(posts).set(draft.eq(false))).to_string()
    );
}

pub fn publish_pending_posts(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;
    use diesel::dsl::now;

    diesel::update(posts)
        .filter(publish_at.lt(now))
        .set(draft.eq(false))
        .execute(conn)
}

#[test]
fn examine_sql_from_publish_pending_posts() {
    use posts::dsl::*;
    use diesel::dsl::now;

    let query = diesel::update(posts)
        .filter(publish_at.lt(now))
        .set(draft.eq(false));
    assert_eq!(
        "UPDATE \"posts\" SET \"draft\" = $1 \
         WHERE \"posts\".\"publish_at\" < CURRENT_TIMESTAMP \
         -- binds: [false]",
        debug_query(&query).to_string()
    );
}

pub fn publish_post(post: Post, conn: &PgConnection) -> QueryResult<usize> {
    diesel::update(&post)
        .set(posts::draft.eq(false))
        .execute(conn)
}

#[test]
fn examine_sql_from_publish_post() {
    let post = Post {
        id: 1,
        title: "".into(),
        body: "".into(),
        draft: false,
        publish_at: SystemTime::now(),
        visit_count: 0,
    };
    assert_eq!(
        "UPDATE \"posts\" SET \"draft\" = $1 WHERE \"posts\".\"id\" = $2 \
         -- binds: [false, 1]",
        debug_query(&diesel::update(&post).set(posts::draft.eq(false))).to_string()
    );
}

pub fn increment_visit_counts(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;

    diesel::update(posts)
        .set(visit_count.eq(visit_count + 1))
        .execute(conn)
}

#[test]
fn examine_sql_from_increment_visit_counts() {
    use posts::dsl::*;

    assert_eq!(
        "UPDATE \"posts\" SET \"visit_count\" = \"posts\".\"visit_count\" + $1 \
         -- binds: [1]",
        debug_query::<Pg, _>(&diesel::update(posts).set(visit_count.eq(visit_count + 1)))
            .to_string()
    );
}

pub fn hide_everything(conn: &PgConnection) -> QueryResult<usize> {
    use posts::dsl::*;

    diesel::update(posts)
        .set((
            title.eq("[REDACTED]"),
            body.eq("This post has been classified"),
        ))
        .execute(conn)
}

#[test]
fn examine_sql_from_hide_everything() {
    use posts::dsl::*;

    let query = diesel::update(posts).set((
        title.eq("[REDACTED]"),
        body.eq("This post has been classified"),
    ));
    assert_eq!(
        "UPDATE \"posts\" SET \"title\" = $1, \"body\" = $2 \
         -- binds: [\"[REDACTED]\", \"This post has been classified\"]",
        debug_query::<Pg, _>(&query).to_string()
    );
}

pub fn update_from_post_fields(post: Post, conn: &PgConnection) -> QueryResult<usize> {
    diesel::update(posts::table).set(&post).execute(conn)
}

#[test]
fn examine_sql_from_update_post_fields() {
    let now = SystemTime::now();
    let post = Post {
        id: 1,
        title: "".into(),
        body: "".into(),
        draft: false,
        publish_at: now,
        visit_count: 0,
    };
    let sql = format!(
        "UPDATE \"posts\" SET \
         \"title\" = $1, \
         \"body\" = $2, \
         \"draft\" = $3, \
         \"publish_at\" = $4, \
         \"visit_count\" = $5 \
         -- binds: [\
         \"\", \
         \"\", \
         false, \
         {:?}, \
         0\
         ]",
        now
    );
    assert_eq!(
        sql,
        debug_query(&diesel::update(posts::table).set(&post)).to_string()
    );
}

pub fn update_with_option(conn: &PgConnection) -> QueryResult<usize> {
    #[derive(AsChangeset)]
    #[table_name = "posts"]
    struct PostForm<'a> {
        title: Option<&'a str>,
        body: Option<&'a str>,
    }

    diesel::update(posts::table)
        .set(&PostForm {
            title: None,
            body: Some("My new post"),
        })
        .execute(conn)
}

#[test]
fn examine_sql_from_update_with_option() {
    #[derive(AsChangeset)]
    #[table_name = "posts"]
    struct PostForm<'a> {
        title: Option<&'a str>,
        body: Option<&'a str>,
    }

    let post_form = PostForm {
        title: None,
        body: Some("My new post"),
    };
    let query = diesel::update(posts::table).set(&post_form);
    assert_eq!(
        "UPDATE \"posts\" SET \"body\" = $1 \
         -- binds: [\"My new post\"]",
        debug_query::<Pg, _>(&query).to_string()
    );
}
<|endoftext|>