<commit_before>use core::{char, mem, slice};
use core::ops::{Deref, DerefMut};

pub const EVENT_NONE: i64 = 0;
pub const EVENT_KEY: i64 = 1;
pub const EVENT_MOUSE: i64 = 2;
pub const EVENT_SCROLL: i64 = 3;
pub const EVENT_QUIT: i64 = 4;
pub const EVENT_FOCUS: i64 = 5;
pub const EVENT_MOVE: i64 = 6;
pub const EVENT_RESIZE: i64 = 7;

/// An optional event
#[derive(Copy, Clone, Debug)]
pub enum EventOption {
    /// A key event
    Key(KeyEvent),
    /// A mouse event
    Mouse(MouseEvent),
    /// A scroll event
    Scroll(ScrollEvent),
    /// A quit request event
    Quit(QuitEvent),
    /// A focus event
    Focus(FocusEvent),
    /// A move event
    Move(MoveEvent),
    /// A resize event
    Resize(ResizeEvent),
    /// An unknown event
    Unknown(Event),
    /// No event
    None,
}

/// An event
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
pub struct Event {
    pub code: i64,
    pub a: i64,
    pub b: i64,
    pub c: i64,
}

impl Event {
    /// Create a null event
    pub fn new() -> Event {
        Event {
            code: 0,
            a: 0,
            b: 0,
            c: 0,
        }
    }

    /// Convert the event ot an optional event
    // TODO: Consider doing this via a From trait.
    pub fn to_option(self) -> EventOption {
        match self.code {
            EVENT_NONE => EventOption::None,
            EVENT_KEY => EventOption::Key(KeyEvent::from_event(self)),
            EVENT_MOUSE => EventOption::Mouse(MouseEvent::from_event(self)),
            EVENT_SCROLL => EventOption::Scroll(ScrollEvent::from_event(self)),
            EVENT_QUIT => EventOption::Quit(QuitEvent::from_event(self)),
            EVENT_FOCUS => EventOption::Focus(FocusEvent::from_event(self)),
            EVENT_MOVE => EventOption::Move(MoveEvent::from_event(self)),
            EVENT_RESIZE => EventOption::Resize(ResizeEvent::from_event(self)),
            _ => EventOption::Unknown(self),
        }
    }
}

impl Deref for Event {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::<Event>()) as &[u8]
        }
    }
}

impl DerefMut for Event {
    fn deref_mut(&mut self) -> &mut [u8] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::<Event>()) as &mut [u8]
        }
    }
}

pub const K_A: u8 = 0x1E;
pub const K_B: u8 = 0x30;
pub const K_C: u8 = 0x2E;
pub const K_D: u8 = 0x20;
pub const K_E: u8 = 0x12;
pub const K_F: u8 = 0x21;
pub const K_G: u8 = 0x22;
pub const K_H: u8 = 0x23;
pub const K_I: u8 = 0x17;
pub const K_J: u8 = 0x24;
pub const K_K: u8 = 0x25;
pub const K_L: u8 = 0x26;
pub const K_M: u8 = 0x32;
pub const K_N: u8 = 0x31;
pub const K_O: u8 = 0x18;
pub const K_P: u8 = 0x19;
pub const K_Q: u8 = 0x10;
pub const K_R: u8 = 0x13;
pub const K_S: u8 = 0x1F;
pub const K_T: u8 = 0x14;
pub const K_U: u8 = 0x16;
pub const K_V: u8 = 0x2F;
pub const K_W: u8 = 0x11;
pub const K_X: u8 = 0x2D;
pub const K_Y: u8 = 0x15;
pub const K_Z: u8 = 0x2C;
pub const K_0: u8 = 0x0B;
pub const K_1: u8 = 0x02;
pub const K_2: u8 = 0x03;
pub const K_3: u8 = 0x04;
pub const K_4: u8 = 0x05;
pub const K_5: u8 = 0x06;
pub const K_6: u8 = 0x07;
pub const K_7: u8 = 0x08;
pub const K_8: u8 = 0x09;
pub const K_9: u8 = 0x0A;

/// Tick/tilde key
pub const K_TICK: u8 = 0x29;
/// Minus/underline key
pub const K_MINUS: u8 = 0x0C;
/// Equals/plus key
pub const K_EQUALS: u8 = 0x0D;
/// Backslash/pipe key
pub const K_BACKSLASH: u8 = 0x2B;
/// Bracket open key
pub const K_BRACE_OPEN: u8 = 0x1A;
/// Bracket close key
pub const K_BRACE_CLOSE: u8 = 0x1B;
/// Semicolon key
pub const K_SEMICOLON: u8 = 0x27;
/// Quote key
pub const K_QUOTE: u8 = 0x28;
/// Comma key
pub const K_COMMA: u8 = 0x33;
/// Period key
pub const K_PERIOD: u8 = 0x34;
/// Slash key
pub const K_SLASH: u8 = 0x35;
/// Backspace key
pub const K_BKSP: u8 = 0x0E;
/// Space key
pub const K_SPACE: u8 = 0x39;
/// Tab key
pub const K_TAB: u8 = 0x0F;
/// Capslock
pub const K_CAPS: u8 = 0x3A;
/// Left shift
pub const K_LEFT_SHIFT: u8 = 0x2A;
/// Right shift
pub const K_RIGHT_SHIFT: u8 = 0x36;
/// Control key
pub const K_CTRL: u8 = 0x1D;
/// Alt key
pub const K_ALT: u8 = 0x38;
/// Enter key
pub const K_ENTER: u8 = 0x1C;
/// Escape key
pub const K_ESC: u8 = 0x01;
/// F1 key
pub const K_F1: u8 = 0x3B;
/// F2 key
pub const K_F2: u8 = 0x3C;
/// F3 key
pub const K_F3: u8 = 0x3D;
/// F4 key
pub const K_F4: u8 = 0x3E;
/// F5 key
pub const K_F5: u8 = 0x3F;
/// F6 key
pub const K_F6: u8 = 0x40;
/// F7 key
pub const K_F7: u8 = 0x41;
/// F8 key
pub const K_F8: u8 = 0x42;
/// F9 key
pub const K_F9: u8 = 0x43;
/// F10 key
pub const K_F10: u8 = 0x44;
/// Home key
pub const K_HOME: u8 = 0x47;
/// Up key
pub const K_UP: u8 = 0x48;
/// Page up key
pub const K_PGUP: u8 = 0x49;
/// Left key
pub const K_LEFT: u8 = 0x4B;
/// Right key
pub const K_RIGHT: u8 = 0x4D;
/// End key
pub const K_END: u8 = 0x4F;
/// Down key
pub const K_DOWN: u8 = 0x50;
/// Page down key
pub const K_PGDN: u8 = 0x51;
/// Delete key
pub const K_DEL: u8 = 0x53;
/// F11 key
pub const K_F11: u8 = 0x57;
/// F12 key
pub const K_F12: u8 = 0x58;

/// A key event (such as a pressed key)
#[derive(Copy, Clone, Debug)]
pub struct KeyEvent {
    /// The charecter of the key
    pub character: char,
    /// The scancode of the key
    pub scancode: u8,
    /// Was it pressed?
    pub pressed: bool,
}

impl KeyEvent {
    /// Convert to an `Event`
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_KEY,
            a: self.character as i64,
            b: self.scancode as i64,
            c: self.pressed as i64,
        }
    }

    /// Convert from an `Event`
    pub fn from_event(event: Event) -> KeyEvent {
        KeyEvent {
            character: char::from_u32(event.a as u32).unwrap_or('\0'),
            scancode: event.b as u8,
            pressed: event.c > 0,
        }
    }
}

/// A event related to the mouse
#[derive(Copy, Clone, Debug)]
pub struct MouseEvent {
    /// The x coordinate of the mouse
    pub x: i32,
    /// The y coordinate of the mouse
    pub y: i32,
    /// Was the left button pressed?
    pub left_button: bool,
    /// Was the middle button pressed?
    pub middle_button: bool,
    /// Was the right button pressed?
    pub right_button: bool,
}

impl MouseEvent {
    /// Convert to an `Event`
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_MOUSE,
            a: self.x as i64,
            b: self.y as i64,
            c: self.left_button as i64 | (self.middle_button as i64) << 1 |
               (self.right_button as i64) << 2,
        }
    }

    /// Convert an `Event` to a `MouseEvent`
    pub fn from_event(event: Event) -> MouseEvent {
        MouseEvent {
            x: event.a as i32,
            y: event.b as i32,
            left_button: event.c & 1 == 1,
            middle_button: event.c & 2 == 2,
            right_button: event.c & 4 == 4,
        }
    }
}

/// A event for scrolling the mouse
#[derive(Copy, Clone, Debug)]
pub struct ScrollEvent {
    /// The x distance of the scroll
    pub x: i32,
    /// The y distance of the scroll
    pub y: i32,
}

impl ScrollEvent {
    /// Convert to an `Event`
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_SCROLL,
            a: self.x as i64,
            b: self.y as i64,
            c: 0,
        }
    }

    /// Convert an `Event` to a `ScrollEvent`
    pub fn from_event(event: Event) -> ScrollEvent {
        ScrollEvent {
            x: event.a as i32,
            y: event.b as i32,
        }
    }
}

#[derive(Copy, Clone, Debug)]
pub struct QuitEvent;

impl QuitEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_QUIT,
            a: 0,
            b: 0,
            c: 0,
        }
    }

    pub fn from_event(_: Event) -> QuitEvent {
        QuitEvent
    }
}

/// A focus event
#[derive(Copy, Clone, Debug)]
pub struct FocusEvent {
    /// True if window has been focused, false if not
    pub focused: bool
}

impl FocusEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_FOCUS,
            a: self.focused as i64,
            b: 0,
            c: 0,
        }
    }

    pub fn from_event(event: Event) -> FocusEvent {
        FocusEvent {
            focused: event.a > 0
        }
    }
}

/// A move event
#[derive(Copy, Clone, Debug)]
pub struct MoveEvent {
    pub x: i32,
    pub y: i32
}

impl MoveEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_MOVE,
            a: self.x as i64,
            b: self.y as i64,
            c: 0,
        }
    }

    pub fn from_event(event: Event) -> MoveEvent {
        MoveEvent {
            x: event.a as i32,
            y: event.b as i32
        }
    }
}

/// A resize event
#[derive(Copy, Clone, Debug)]
pub struct ResizeEvent {
    pub width: u32,
    pub height: u32
}

impl ResizeEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_RESIZE,
            a: self.width as i64,
            b: self.height as i64,
            c: 0,
        }
    }

    pub fn from_event(event: Event) -> ResizeEvent {
        ResizeEvent {
            width: event.a as u32,
            height: event.b as u32
        }
    }
}
<commit_msg>Refactor events to seperate mouse and buttons<commit_after>use core::{char, mem, slice};
use core::ops::{Deref, DerefMut};

pub const EVENT_NONE: i64 = 0;
pub const EVENT_KEY: i64 = 1;
pub const EVENT_MOUSE: i64 = 2;
pub const EVENT_BUTTON: i64 = 3;
pub const EVENT_SCROLL: i64 = 4;
pub const EVENT_QUIT: i64 = 5;
pub const EVENT_FOCUS: i64 = 6;
pub const EVENT_MOVE: i64 = 7;
pub const EVENT_RESIZE: i64 = 8;

/// An optional event
#[derive(Copy, Clone, Debug)]
pub enum EventOption {
    /// A key event
    Key(KeyEvent),
    /// A mouse event
    Mouse(MouseEvent),
    /// A mouse button event
    Button(ButtonEvent),
    /// A mouse scroll event
    Scroll(ScrollEvent),
    /// A quit request event
    Quit(QuitEvent),
    /// A focus event
    Focus(FocusEvent),
    /// A move event
    Move(MoveEvent),
    /// A resize event
    Resize(ResizeEvent),
    /// An unknown event
    Unknown(Event),
    /// No event
    None,
}

/// An event
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
pub struct Event {
    pub code: i64,
    pub a: i64,
    pub b: i64,
}

impl Event {
    /// Create a null event
    pub fn new() -> Event {
        Event {
            code: 0,
            a: 0,
            b: 0,
        }
    }

    /// Convert the event ot an optional event
    // TODO: Consider doing this via a From trait.
    pub fn to_option(self) -> EventOption {
        match self.code {
            EVENT_NONE => EventOption::None,
            EVENT_KEY => EventOption::Key(KeyEvent::from_event(self)),
            EVENT_MOUSE => EventOption::Mouse(MouseEvent::from_event(self)),
            EVENT_BUTTON => EventOption::Button(ButtonEvent::from_event(self)),
            EVENT_SCROLL => EventOption::Scroll(ScrollEvent::from_event(self)),
            EVENT_QUIT => EventOption::Quit(QuitEvent::from_event(self)),
            EVENT_FOCUS => EventOption::Focus(FocusEvent::from_event(self)),
            EVENT_MOVE => EventOption::Move(MoveEvent::from_event(self)),
            EVENT_RESIZE => EventOption::Resize(ResizeEvent::from_event(self)),
            _ => EventOption::Unknown(self),
        }
    }
}

impl Deref for Event {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::<Event>()) as &[u8]
        }
    }
}

impl DerefMut for Event {
    fn deref_mut(&mut self) -> &mut [u8] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::<Event>()) as &mut [u8]
        }
    }
}

pub const K_A: u8 = 0x1E;
pub const K_B: u8 = 0x30;
pub const K_C: u8 = 0x2E;
pub const K_D: u8 = 0x20;
pub const K_E: u8 = 0x12;
pub const K_F: u8 = 0x21;
pub const K_G: u8 = 0x22;
pub const K_H: u8 = 0x23;
pub const K_I: u8 = 0x17;
pub const K_J: u8 = 0x24;
pub const K_K: u8 = 0x25;
pub const K_L: u8 = 0x26;
pub const K_M: u8 = 0x32;
pub const K_N: u8 = 0x31;
pub const K_O: u8 = 0x18;
pub const K_P: u8 = 0x19;
pub const K_Q: u8 = 0x10;
pub const K_R: u8 = 0x13;
pub const K_S: u8 = 0x1F;
pub const K_T: u8 = 0x14;
pub const K_U: u8 = 0x16;
pub const K_V: u8 = 0x2F;
pub const K_W: u8 = 0x11;
pub const K_X: u8 = 0x2D;
pub const K_Y: u8 = 0x15;
pub const K_Z: u8 = 0x2C;
pub const K_0: u8 = 0x0B;
pub const K_1: u8 = 0x02;
pub const K_2: u8 = 0x03;
pub const K_3: u8 = 0x04;
pub const K_4: u8 = 0x05;
pub const K_5: u8 = 0x06;
pub const K_6: u8 = 0x07;
pub const K_7: u8 = 0x08;
pub const K_8: u8 = 0x09;
pub const K_9: u8 = 0x0A;

/// Tick/tilde key
pub const K_TICK: u8 = 0x29;
/// Minus/underline key
pub const K_MINUS: u8 = 0x0C;
/// Equals/plus key
pub const K_EQUALS: u8 = 0x0D;
/// Backslash/pipe key
pub const K_BACKSLASH: u8 = 0x2B;
/// Bracket open key
pub const K_BRACE_OPEN: u8 = 0x1A;
/// Bracket close key
pub const K_BRACE_CLOSE: u8 = 0x1B;
/// Semicolon key
pub const K_SEMICOLON: u8 = 0x27;
/// Quote key
pub const K_QUOTE: u8 = 0x28;
/// Comma key
pub const K_COMMA: u8 = 0x33;
/// Period key
pub const K_PERIOD: u8 = 0x34;
/// Slash key
pub const K_SLASH: u8 = 0x35;
/// Backspace key
pub const K_BKSP: u8 = 0x0E;
/// Space key
pub const K_SPACE: u8 = 0x39;
/// Tab key
pub const K_TAB: u8 = 0x0F;
/// Capslock
pub const K_CAPS: u8 = 0x3A;
/// Left shift
pub const K_LEFT_SHIFT: u8 = 0x2A;
/// Right shift
pub const K_RIGHT_SHIFT: u8 = 0x36;
/// Control key
pub const K_CTRL: u8 = 0x1D;
/// Alt key
pub const K_ALT: u8 = 0x38;
/// Enter key
pub const K_ENTER: u8 = 0x1C;
/// Escape key
pub const K_ESC: u8 = 0x01;
/// F1 key
pub const K_F1: u8 = 0x3B;
/// F2 key
pub const K_F2: u8 = 0x3C;
/// F3 key
pub const K_F3: u8 = 0x3D;
/// F4 key
pub const K_F4: u8 = 0x3E;
/// F5 key
pub const K_F5: u8 = 0x3F;
/// F6 key
pub const K_F6: u8 = 0x40;
/// F7 key
pub const K_F7: u8 = 0x41;
/// F8 key
pub const K_F8: u8 = 0x42;
/// F9 key
pub const K_F9: u8 = 0x43;
/// F10 key
pub const K_F10: u8 = 0x44;
/// Home key
pub const K_HOME: u8 = 0x47;
/// Up key
pub const K_UP: u8 = 0x48;
/// Page up key
pub const K_PGUP: u8 = 0x49;
/// Left key
pub const K_LEFT: u8 = 0x4B;
/// Right key
pub const K_RIGHT: u8 = 0x4D;
/// End key
pub const K_END: u8 = 0x4F;
/// Down key
pub const K_DOWN: u8 = 0x50;
/// Page down key
pub const K_PGDN: u8 = 0x51;
/// Delete key
pub const K_DEL: u8 = 0x53;
/// F11 key
pub const K_F11: u8 = 0x57;
/// F12 key
pub const K_F12: u8 = 0x58;

/// A key event (such as a pressed key)
#[derive(Copy, Clone, Debug)]
pub struct KeyEvent {
    /// The charecter of the key
    pub character: char,
    /// The scancode of the key
    pub scancode: u8,
    /// Was it pressed?
    pub pressed: bool,
}

impl KeyEvent {
    /// Convert to an `Event`
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_KEY,
            a: self.character as i64,
            b: self.scancode as i64 | (self.pressed as i64) << 8,
        }
    }

    /// Convert from an `Event`
    pub fn from_event(event: Event) -> KeyEvent {
        KeyEvent {
            character: char::from_u32(event.a as u32).unwrap_or('\0'),
            scancode: event.b as u8,
            pressed: event.b & 1 << 8 == 1 << 8,
        }
    }
}

/// A event related to the mouse
#[derive(Copy, Clone, Debug)]
pub struct MouseEvent {
    /// The x coordinate of the mouse
    pub x: i32,
    /// The y coordinate of the mouse
    pub y: i32,
}

impl MouseEvent {
    /// Convert to an `Event`
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_MOUSE,
            a: self.x as i64,
            b: self.y as i64,
        }
    }

    /// Convert an `Event` to a `MouseEvent`
    pub fn from_event(event: Event) -> MouseEvent {
        MouseEvent {
            x: event.a as i32,
            y: event.b as i32,
        }
    }
}

/// A event for clicking the mouse
#[derive(Copy, Clone, Debug)]
pub struct ButtonEvent {
    /// Was the left button pressed?
    pub left: bool,
    /// Was the middle button pressed?
    pub middle: bool,
    /// Was the right button pressed?
    pub right: bool,
}

impl ButtonEvent {
    /// Convert to an `Event`
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_BUTTON,
            a: self.left as i64 | (self.middle as i64) << 1 |
               (self.right as i64) << 2,
            b: 0,
        }
    }

    /// Convert an `Event` to a `ButtonEvent`
    pub fn from_event(event: Event) -> ButtonEvent {
        ButtonEvent {
            left: event.a & 1 == 1,
            middle: event.a & 2 == 2,
            right: event.a & 4 == 4,
        }
    }
}

/// A event for scrolling the mouse
#[derive(Copy, Clone, Debug)]
pub struct ScrollEvent {
    /// The x distance of the scroll
    pub x: i32,
    /// The y distance of the scroll
    pub y: i32,
}

impl ScrollEvent {
    /// Convert to an `Event`
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_SCROLL,
            a: self.x as i64,
            b: self.y as i64,
        }
    }

    /// Convert an `Event` to a `ScrollEvent`
    pub fn from_event(event: Event) -> ScrollEvent {
        ScrollEvent {
            x: event.a as i32,
            y: event.b as i32,
        }
    }
}

#[derive(Copy, Clone, Debug)]
pub struct QuitEvent;

impl QuitEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_QUIT,
            a: 0,
            b: 0,
        }
    }

    pub fn from_event(_: Event) -> QuitEvent {
        QuitEvent
    }
}

/// A focus event
#[derive(Copy, Clone, Debug)]
pub struct FocusEvent {
    /// True if window has been focused, false if not
    pub focused: bool
}

impl FocusEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_FOCUS,
            a: self.focused as i64,
            b: 0,
        }
    }

    pub fn from_event(event: Event) -> FocusEvent {
        FocusEvent {
            focused: event.a > 0
        }
    }
}

/// A move event
#[derive(Copy, Clone, Debug)]
pub struct MoveEvent {
    pub x: i32,
    pub y: i32
}

impl MoveEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_MOVE,
            a: self.x as i64,
            b: self.y as i64,
        }
    }

    pub fn from_event(event: Event) -> MoveEvent {
        MoveEvent {
            x: event.a as i32,
            y: event.b as i32
        }
    }
}

/// A resize event
#[derive(Copy, Clone, Debug)]
pub struct ResizeEvent {
    pub width: u32,
    pub height: u32
}

impl ResizeEvent {
    pub fn to_event(&self) -> Event {
        Event {
            code: EVENT_RESIZE,
            a: self.width as i64,
            b: self.height as i64,
        }
    }

    pub fn from_event(event: Event) -> ResizeEvent {
        ResizeEvent {
            width: event.a as u32,
            height: event.b as u32
        }
    }
}
<|endoftext|>


<commit_before>
use utils::clampf32;
use std::default::Default;
use std::num::abs;
use std::rand::random;

/// A basic color struct for general color use
/// made of red, green, blue and alpha elements.
pub struct Color(pub [f32, ..4]);

impl Color {

    /// Basic constructor for a Color struct.
    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color {
        Color([r, g, b, a])
    }

    /// Returns the red component of the color.
    #[inline(always)]
    pub fn r(&self) -> f32 {
        let &Color(c) = self;
        c[0]
    }

    /// Returns the green component of the color.
    #[inline(always)]
    pub fn g(&self) -> f32 {
        let &Color(c) = self;
        c[1]
    }

    /// Returns the blue component of the color.
    #[inline(always)]
    pub fn b(&self) -> f32 {
        let &Color(c) = self;
        c[2]
    }

    /// Sets the red component of the color.
    #[inline(always)]
    pub fn set_r(&mut self, r: f32) {
        let &Color(ref mut c) = self;
        c[0] = r;
    }

    /// Sets the green component of the color.
    #[inline(always)]
    pub fn set_g(&mut self, g: f32) {
        let &Color(ref mut c) = self;
        c[1] = g;
    }

    /// Sets the blue component of the color.
    #[inline(always)]
    pub fn set_b(&mut self, b: f32) {
        let &Color(ref mut c) = self;
        c[2] = b;
    }

    /// Sets the alpha component of the color.
    #[inline(always)]
    pub fn set_a(&mut self, a: f32) {
        let &Color(ref mut c) = self;
        c[3] = a;
    }

    /// Returns the alpha component of the color.
    #[inline(always)]
    pub fn a(&self) -> f32 {
        let &Color(c) = self;
        c[3]
    }

    /// Basic constructor for a Black Color struct.
    pub fn black() -> Color {
        Color([0f32, 0f32, 0f32, 1f32])
    }

    /// Basic constructor for a White Color struct.
    pub fn white() -> Color {
        Color([1f32, 1f32, 1f32, 1f32])
    }

    /// Return color as a vector.
    pub fn as_vec(&self) -> Vec<f32> {
        vec![self.r(), self.g(), self.b(), self.a()]
    }

    /// Return color as a tuple.
    pub fn as_tuple(&self) -> (f32, f32, f32, f32) {
        let &Color(c) = self;
        (c[0], c[1], c[2], c[3])
    }

    /// Clamp the Color's values between 0f32 and 1f32.
    fn clamp(c: Color) -> Color {
        Color([
            clampf32(c.r()),
            clampf32(c.g()),
            clampf32(c.b()),
            clampf32(c.a())
        ])
    }

    /// Return a highlighted version of the current Color.
    pub fn highlighted(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r() - 0.2,
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.2,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.5f32 * self.r() + self.r()),
                 clampf32((1f32 - self.g()) * 0.1f32 * self.g() + self.g()),
                 clampf32((1f32 - self.b()) * 0.1f32 * self.b() + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.5f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a clicked version of the current Color.
    pub fn clicked(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r(),
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.4,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.75f32 + self.r()),
                 clampf32((1f32 - self.g()) * 0.25f32 + self.g()),
                 clampf32((1f32 - self.b()) * 0.25f32 + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.75f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a random color.
    pub fn random() -> Color {
        let r = random::<f32>();
        let g = random::<f32>();
        let b = random::<f32>();
        let a = 1f32;
        Color::new(r, g, b, a)
    }

    /// Return an inverted version of the color.
    pub fn invert(&self) -> Color {
        let r = abs(1f32 - self.r());
        let g = abs(1f32 - self.g());
        let b = abs(1f32 - self.b());
        Color::new(r, g, b, self.a())
    }

    /// Return either black or white, depending which contrasts
    /// the Color the most. This will be useful for determining
    /// a readable color for text on any given background Color.
    pub fn plain_contrast(&self) -> Color {
        if self.luminance() > 0.5f32 { Color::black() }
        else { Color::white() }
    }

    /// Return the luminance of the color.
    pub fn luminance(&self) -> f32 {
        (self.r() + self.g() + self.b()) / 3f32
    }

    pub fn to_32_bit(&self) -> [u8, ..4] {
        [
            to_8_bit(self.r()),
            to_8_bit(self.g()),
            to_8_bit(self.b()),
            to_8_bit(self.a()),
        ]
    }
}

fn to_8_bit(f32: chan) -> u8 {
    let chan = clampf32(chan);
    (chan * 255.0) as u8
}

impl Clone for Color {
    fn clone(&self) -> Color {
        *self
    }
}

impl Default for Color {
    /// Default constructor for a Color struct.
    fn default() -> Color {
        Color([0.5, 0.8, 0.6, 1.0])
    }
}

impl Add<Color, Color> for Color {
    fn add(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() + rhs.r(),
                self.g() + rhs.g(),
                self.b() + rhs.b(),
                self.a()
            ])
        )
    }
}

impl Sub<Color, Color> for Color {
    fn sub(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() - rhs.r(),
                self.g() - rhs.g(),
                self.b() - rhs.b(),
                self.a()
            ])
        )
    }
}

impl Div<Color, Color> for Color {
    fn div(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() / rhs.r(),
                self.g() / rhs.g(),
                self.b() / rhs.b(),
                self.a() / rhs.a(),
            ])
        )
    }
}

impl Mul<Color, Color> for Color {
    fn mul(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() * rhs.r(),
                self.g() * rhs.g(),
                self.b() * rhs.b(),
                self.a() * rhs.a(),
            ])
        )
    }
}
<commit_msg>Implement Show for Color, closes #57<commit_after>
use utils::clampf32;
use std::default::Default;
use std::fmt::{Show, Formatter, FormatError};
use std::num::abs;
use std::rand::random;
use std::ascii::OwnedAsciiExt;
use serialize::hex::ToHex;

/// A basic color struct for general color use
/// made of red, green, blue and alpha elements.
pub struct Color(pub [f32, ..4]);

impl Color {

    /// Basic constructor for a Color struct.
    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color {
        Color([r, g, b, a])
    }

    /// Returns the red component of the color.
    #[inline(always)]
    pub fn r(&self) -> f32 {
        let &Color(c) = self;
        c[0]
    }

    /// Returns the green component of the color.
    #[inline(always)]
    pub fn g(&self) -> f32 {
        let &Color(c) = self;
        c[1]
    }

    /// Returns the blue component of the color.
    #[inline(always)]
    pub fn b(&self) -> f32 {
        let &Color(c) = self;
        c[2]
    }

    /// Sets the red component of the color.
    #[inline(always)]
    pub fn set_r(&mut self, r: f32) {
        let &Color(ref mut c) = self;
        c[0] = r;
    }

    /// Sets the green component of the color.
    #[inline(always)]
    pub fn set_g(&mut self, g: f32) {
        let &Color(ref mut c) = self;
        c[1] = g;
    }

    /// Sets the blue component of the color.
    #[inline(always)]
    pub fn set_b(&mut self, b: f32) {
        let &Color(ref mut c) = self;
        c[2] = b;
    }

    /// Sets the alpha component of the color.
    #[inline(always)]
    pub fn set_a(&mut self, a: f32) {
        let &Color(ref mut c) = self;
        c[3] = a;
    }

    /// Returns the alpha component of the color.
    #[inline(always)]
    pub fn a(&self) -> f32 {
        let &Color(c) = self;
        c[3]
    }

    /// Basic constructor for a Black Color struct.
    pub fn black() -> Color {
        Color([0f32, 0f32, 0f32, 1f32])
    }

    /// Basic constructor for a White Color struct.
    pub fn white() -> Color {
        Color([1f32, 1f32, 1f32, 1f32])
    }

    /// Return color as a vector.
    pub fn as_vec(&self) -> Vec<f32> {
        vec![self.r(), self.g(), self.b(), self.a()]
    }

    /// Return color as a tuple.
    pub fn as_tuple(&self) -> (f32, f32, f32, f32) {
        let &Color(c) = self;
        (c[0], c[1], c[2], c[3])
    }

    /// Clamp the Color's values between 0f32 and 1f32.
    fn clamp(c: Color) -> Color {
        Color([
            clampf32(c.r()),
            clampf32(c.g()),
            clampf32(c.b()),
            clampf32(c.a())
        ])
    }

    /// Return a highlighted version of the current Color.
    pub fn highlighted(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r() - 0.2,
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.2,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.5f32 * self.r() + self.r()),
                 clampf32((1f32 - self.g()) * 0.1f32 * self.g() + self.g()),
                 clampf32((1f32 - self.b()) * 0.1f32 * self.b() + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.5f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a clicked version of the current Color.
    pub fn clicked(&self) -> Color {
        let luminance = self.luminance();
        let (r, g, b) = {
            if luminance > 0.8 {
                (self.r(),
                 self.g() - 0.2,
                 self.b() - 0.2)
            }
            else if luminance < 0.2 {
                (self.r() + 0.4,
                 self.g() + 0.2,
                 self.b() + 0.2)
            }
            else {
                (clampf32((1f32 - self.r()) * 0.75f32 + self.r()),
                 clampf32((1f32 - self.g()) * 0.25f32 + self.g()),
                 clampf32((1f32 - self.b()) * 0.25f32 + self.b()))
            }
        };
        let a = clampf32((1f32 - self.a()) * 0.75f32 + self.a());
        Color::new(r, g, b, a)
    }

    /// Return a random color.
    pub fn random() -> Color {
        let r = random::<f32>();
        let g = random::<f32>();
        let b = random::<f32>();
        let a = 1f32;
        Color::new(r, g, b, a)
    }

    /// Return an inverted version of the color.
    pub fn invert(&self) -> Color {
        let r = abs(1f32 - self.r());
        let g = abs(1f32 - self.g());
        let b = abs(1f32 - self.b());
        Color::new(r, g, b, self.a())
    }

    /// Return either black or white, depending which contrasts
    /// the Color the most. This will be useful for determining
    /// a readable color for text on any given background Color.
    pub fn plain_contrast(&self) -> Color {
        if self.luminance() > 0.5f32 { Color::black() }
        else { Color::white() }
    }

    /// Return the luminance of the color.
    pub fn luminance(&self) -> f32 {
        (self.r() + self.g() + self.b()) / 3f32
    }

    pub fn to_32_bit(&self) -> [u8, ..4] {
        [
            to_8_bit(self.r()),
            to_8_bit(self.g()),
            to_8_bit(self.b()),
            to_8_bit(self.a()),
        ]
    }
}

fn to_8_bit(chan: f32) -> u8 {
    let chan = clampf32(chan);
    (chan * 255.0) as u8
}

impl Clone for Color {
    fn clone(&self) -> Color {
        *self
    }
}

impl Default for Color {
    /// Default constructor for a Color struct.
    fn default() -> Color {
        Color([0.5, 0.8, 0.6, 1.0])
    }
}

impl Add<Color, Color> for Color {
    fn add(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() + rhs.r(),
                self.g() + rhs.g(),
                self.b() + rhs.b(),
                self.a()
            ])
        )
    }
}

impl Sub<Color, Color> for Color {
    fn sub(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() - rhs.r(),
                self.g() - rhs.g(),
                self.b() - rhs.b(),
                self.a()
            ])
        )
    }
}

impl Div<Color, Color> for Color {
    fn div(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() / rhs.r(),
                self.g() / rhs.g(),
                self.b() / rhs.b(),
                self.a() / rhs.a(),
            ])
        )
    }
}

impl Mul<Color, Color> for Color {
    fn mul(&self, rhs: &Color) -> Color {
        Color::clamp(
            Color([
                self.r() * rhs.r(),
                self.g() * rhs.g(),
                self.b() * rhs.b(),
                self.a() * rhs.a(),
            ])
        )
    }
}

impl Show for Color {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), FormatError> {
        let vals = self.to_32_bit();
        // Hex colors are always uppercased
        let hex = vals.as_slice().to_hex().into_ascii_upper();
        write!(fmt, "#{}", hex.as_slice())
    }
}
<|endoftext|>


<commit_before>
//! A color type, with utility methods for modifying colors and parsing colors from hex integers and strings.

use gl;
use gl::types::*;
use std;
use shader::UniformValue;
use buffer::VertexData;

/// A color with red, green, blue and alpha components. All components are expected to be
/// between 0 and 1, both inclusinve.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32,
}

impl Color {
    /// Creates a new, completly opaque (alpha = 1), color.
    ///
    /// All parameters are clamped so that they are between 0 and 1, both inclusive.
    pub fn rgb(r: f32, g: f32, b: f32) -> Color {
        Color {
            r: clamp(r, 0.0, 1.0),
            g: clamp(g, 0.0, 1.0),
            b: clamp(b, 0.0, 1.0),
            a: 1.0
        }
    }

    /// Creates a new color.
    ///
    /// All parameters are clamped so that they are between 0 and 1, both inclusive.
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Color {
        Color {
            r: clamp(r, 0.0, 1.0),
            g: clamp(g, 0.0, 1.0),
            b: clamp(b, 0.0, 1.0),
            a: clamp(a, 0.0, 1.0)
        }
    }

    /// Creates a new color, converting the given values to rgb. The returned color will be
    /// completly opaque. `saturation` and `lightness` given values are clamped to be between
    /// 0 and 1, both inclusive.
    pub fn hsl(hue: f32, saturation: f32, lightness: f32) -> Color {
        let saturation = clamp(saturation, 0.0, 1.0);
        let lightness = clamp(lightness, 0.0, 1.0);
        let hue = hue % 1.0;

        if saturation <= 0.0 {
            return Color { r: lightness, g: lightness, b: lightness, a: 1.0 };
        }

        let q = if lightness < 0.5 {
            lightness * (1.0 + saturation)
        } else {
            lightness + saturation - lightness*saturation
        };
        let p = 2.0*lightness - q;

        let hue_to_rgb = |hue| {
            let hue = hue % 1.0;
            if hue < 1.0/6.0 { return p + (q - p)*6.0*hue }
            if hue < 1.0/2.0 { return q }
            if hue < 2.0/3.0 { return p + (q - p)*(2.0/3.0 - hue)*6.0 }
            return p;
        };

        Color {
            r: hue_to_rgb(hue + 1.0/3.0),
            g: hue_to_rgb(hue),
            b: hue_to_rgb(hue - 1.0/3.0),
            a: 1.0,
        }
    }

    /// Creates a color from a hex string. The string should be of the format "#rrggbb" or
    /// "rrggbb", where each of r, g and b is a hexadecimal digit. Note that this currently does
    /// not support loading colors with a alpha channel. All colors created will be completly
    /// opaque.
    pub fn hex(string: &str) -> Option<Color> {
        let value = {
            if string.len() == 6 {
                u32::from_str_radix(string, 16)
            } else if string.len() == 7 {
                u32::from_str_radix(&string[1..], 16)
            } else {
                return None
            }
        };

        match value {
            Ok(value) => Some(Color::hex_int(value)),
            Err(_) =>    None,
        }
    }

    /// Creates a color from a hex int. Bit `0..8` (The eight least significant bits) are the
    /// red channel. Bit `8..16` are the green channel. Bit `16..24` are the blue channel. Note
    /// that this function currently ignores the alpha channel.
    ///
    /// # Example
    /// ```rust
    /// # use gondola::Color;
    /// let color = Color::hex_int(0xff00ff);
    ///
    /// assert_eq!(color, Color::rgb(1.0, 0.0, 1.0));
    /// ```
    pub fn hex_int(value: u32) -> Color {
        let r = value >> 16 & 0xff;
        let g = value >> 8 & 0xff;
        let b = value & 0xff;

        let r = r as f32 / 255.0;
        let g = g as f32 / 255.0;
        let b = b as f32 / 255.0;

        Color { r: r, g: g, b: b, a: 1.0 }
    }

    /// Same as [`hex_int`], but allows specifying the alpha channel. `alpha` should be between 0
    /// and 1, both inclusive.
    ///
    /// [`hex_int`]: struct.Color.html#method.hex_int
    pub fn hex_int_alpha(value: u32, alpha: f32) -> Color {
        let r = value >> 16 & 0xff;
        let g = value >> 8 & 0xff;
        let b = value & 0xff;

        let r = r as f32 / 255.0;
        let g = g as f32 / 255.0;
        let b = b as f32 / 255.0;

        Color { r: r, g: g, b: b, a: alpha }
    }

    /// Converts this color to a hex string like "#ffa13b". Note that this function currently
    /// ignores the alpha channel.
    pub fn to_hex(&self) -> String {
        let r = (self.r * 255.0) as u32;
        let g = (self.g * 255.0) as u32;
        let b = (self.b * 255.0) as u32;
        let value = r << 16 | g << 8 | b;
        format!("#{:06x}", value)
    }

    /// Creates a new color based on this color, with the red, green and blue components multiplied
    /// by the given factor.
    pub fn with_lightness(&self, factor: f32) -> Color {
        Color {
            r: clamp(self.r*factor, 0.0, 1.0),
            g: clamp(self.g*factor, 0.0, 1.0),
            b: clamp(self.b*factor, 0.0, 1.0),
            a: self.a
        }
    }

    /// Linearly interpolates between this color and the given other color. `t` should be between
    /// 0 and 1. Values outside of this range will lead to extrapolation.
    pub fn lerp(self, other: Color, t: f32) -> Color {
        Color {
            r: self.r*(1.0 - t) + other.r*t,
            g: self.g*(1.0 - t) + other.g*t,
            b: self.b*(1.0 - t) + other.b*t,
            a: self.a*(1.0 - t) + other.a*t,
        }
    }
}

// Does not properly handle NaN, which should not really matter
fn clamp(value: f32, min: f32, max: f32) -> f32 {
    if value < min {
        return min;
    }
    if value > max {
        return max;
    }
    value
}

impl VertexData for Color {
    type Primitive = f32;
    fn bytes() -> usize { std::mem::size_of::<f32>() * 4 }
    fn primitives() -> usize { 4 }
}
impl UniformValue for Color {
    unsafe fn set_uniform(color: &Color, location: GLint) {
        gl::Uniform4f(location, color.r, color.g, color.b, color.a);
    }

    unsafe fn set_uniform_slice(colors: &[Color], location: GLint) {
        gl::Uniform4fv(location, colors.len() as GLsizei, colors.as_ptr() as *const GLfloat);
    }
}

// Custom serialization
#[cfg(feature = "serialize")]
mod serialize {
    use super::*;

    use std::fmt;
    use serde::{Serialize, Deserialize, Serializer, Deserializer};
    use serde::de::{Visitor, Error};

    impl Serialize for Color {
        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
            s.serialize_str(&self.to_hex())
        }
    }

    impl<'de> Deserialize<'de> for Color {
        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
            d.deserialize_str(ColorVisitor)
        }
    }

    struct ColorVisitor;
    impl<'de> Visitor<'de> for ColorVisitor {
        type Value = Color;

        fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.write_str("A string representing a valid hex color")
        }

        fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
            match Color::hex(v) {
                Some(color) => Ok(color),
                None =>        Err(E::custom(format!("\"{}\" is not a valid color string", v))),
            }
        }
    }
}

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

    #[test]
    fn test_to_hex() {
        assert_eq!("#ffa3b1", Color::hex("#ffa3b1").unwrap().to_hex());
        assert_eq!("#a300f1", Color::hex("#a300f1").unwrap().to_hex());
        assert_eq!("#000000", Color::hex("#000000").unwrap().to_hex());
        assert_eq!("#000001", Color::hex("#000001").unwrap().to_hex());
        assert_eq!("#100000", Color::hex("#100000").unwrap().to_hex());
    }
}

<commit_msg>From<u32> for color (conversion from hex color)<commit_after>
//! A color type, with utility methods for modifying colors and parsing colors from hex integers and strings.

use gl;
use gl::types::*;
use std;
use shader::UniformValue;
use buffer::VertexData;

/// A color with red, green, blue and alpha components. All components are expected to be
/// between 0 and 1, both inclusinve.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32,
}

impl Color {
    /// Creates a new, completly opaque (alpha = 1), color.
    ///
    /// All parameters are clamped so that they are between 0 and 1, both inclusive.
    pub fn rgb(r: f32, g: f32, b: f32) -> Color {
        Color {
            r: clamp(r, 0.0, 1.0),
            g: clamp(g, 0.0, 1.0),
            b: clamp(b, 0.0, 1.0),
            a: 1.0
        }
    }

    /// Creates a new color.
    ///
    /// All parameters are clamped so that they are between 0 and 1, both inclusive.
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Color {
        Color {
            r: clamp(r, 0.0, 1.0),
            g: clamp(g, 0.0, 1.0),
            b: clamp(b, 0.0, 1.0),
            a: clamp(a, 0.0, 1.0)
        }
    }

    /// Creates a new color, converting the given values to rgb. The returned color will be
    /// completly opaque. `saturation` and `lightness` given values are clamped to be between
    /// 0 and 1, both inclusive.
    pub fn hsl(hue: f32, saturation: f32, lightness: f32) -> Color {
        let saturation = clamp(saturation, 0.0, 1.0);
        let lightness = clamp(lightness, 0.0, 1.0);
        let hue = hue % 1.0;

        if saturation <= 0.0 {
            return Color { r: lightness, g: lightness, b: lightness, a: 1.0 };
        }

        let q = if lightness < 0.5 {
            lightness * (1.0 + saturation)
        } else {
            lightness + saturation - lightness*saturation
        };
        let p = 2.0*lightness - q;

        let hue_to_rgb = |hue| {
            let hue = hue % 1.0;
            if hue < 1.0/6.0 { return p + (q - p)*6.0*hue }
            if hue < 1.0/2.0 { return q }
            if hue < 2.0/3.0 { return p + (q - p)*(2.0/3.0 - hue)*6.0 }
            return p;
        };

        Color {
            r: hue_to_rgb(hue + 1.0/3.0),
            g: hue_to_rgb(hue),
            b: hue_to_rgb(hue - 1.0/3.0),
            a: 1.0,
        }
    }

    /// Creates a color from a hex string. The string should be of the format "#rrggbb" or
    /// "rrggbb", where each of r, g and b is a hexadecimal digit. Note that this currently does
    /// not support loading colors with a alpha channel. All colors created will be completly
    /// opaque.
    pub fn hex(string: &str) -> Option<Color> {
        let value = {
            if string.len() == 6 {
                u32::from_str_radix(string, 16)
            } else if string.len() == 7 {
                u32::from_str_radix(&string[1..], 16)
            } else {
                return None
            }
        };

        match value {
            Ok(value) => Some(Color::hex_int(value)),
            Err(_) =>    None,
        }
    }

    /// Creates a color from a hex int. Bit `0..8` (The eight least significant bits) are the
    /// red channel. Bit `8..16` are the green channel. Bit `16..24` are the blue channel. Note
    /// that this function currently ignores the alpha channel.
    ///
    /// # Example
    /// ```rust
    /// # use gondola::Color;
    /// let color = Color::hex_int(0xff00ff);
    ///
    /// assert_eq!(color, Color::rgb(1.0, 0.0, 1.0));
    /// ```
    pub fn hex_int(value: u32) -> Color {
        let r = value >> 16 & 0xff;
        let g = value >> 8 & 0xff;
        let b = value & 0xff;

        let r = r as f32 / 255.0;
        let g = g as f32 / 255.0;
        let b = b as f32 / 255.0;

        Color { r: r, g: g, b: b, a: 1.0 }
    }

    /// Same as [`hex_int`], but allows specifying the alpha channel. `alpha` should be between 0
    /// and 1, both inclusive.
    ///
    /// [`hex_int`]: struct.Color.html#method.hex_int
    pub fn hex_int_alpha(value: u32, alpha: f32) -> Color {
        let r = value >> 16 & 0xff;
        let g = value >> 8 & 0xff;
        let b = value & 0xff;

        let r = r as f32 / 255.0;
        let g = g as f32 / 255.0;
        let b = b as f32 / 255.0;

        Color { r: r, g: g, b: b, a: alpha }
    }

    /// Converts this color to a hex string like "#ffa13b". Note that this function currently
    /// ignores the alpha channel.
    pub fn to_hex(&self) -> String {
        let r = (self.r * 255.0) as u32;
        let g = (self.g * 255.0) as u32;
        let b = (self.b * 255.0) as u32;
        let value = r << 16 | g << 8 | b;
        format!("#{:06x}", value)
    }

    /// Creates a new color based on this color, with the red, green and blue components multiplied
    /// by the given factor.
    pub fn with_lightness(&self, factor: f32) -> Color {
        Color {
            r: clamp(self.r*factor, 0.0, 1.0),
            g: clamp(self.g*factor, 0.0, 1.0),
            b: clamp(self.b*factor, 0.0, 1.0),
            a: self.a
        }
    }

    /// Linearly interpolates between this color and the given other color. `t` should be between
    /// 0 and 1. Values outside of this range will lead to extrapolation.
    pub fn lerp(self, other: Color, t: f32) -> Color {
        Color {
            r: self.r*(1.0 - t) + other.r*t,
            g: self.g*(1.0 - t) + other.g*t,
            b: self.b*(1.0 - t) + other.b*t,
            a: self.a*(1.0 - t) + other.a*t,
        }
    }
}

// Does not properly handle NaN, which should not really matter
fn clamp(value: f32, min: f32, max: f32) -> f32 {
    if value < min {
        return min;
    }
    if value > max {
        return max;
    }
    value
}

impl VertexData for Color {
    type Primitive = f32;
    fn bytes() -> usize { std::mem::size_of::<f32>() * 4 }
    fn primitives() -> usize { 4 }
}

impl UniformValue for Color {
    unsafe fn set_uniform(color: &Color, location: GLint) {
        gl::Uniform4f(location, color.r, color.g, color.b, color.a);
    }

    unsafe fn set_uniform_slice(colors: &[Color], location: GLint) {
        gl::Uniform4fv(location, colors.len() as GLsizei, colors.as_ptr() as *const GLfloat);
    }
}

impl From<u32> for Color {
    fn from(v: u32) -> Color {
        Color::hex_int(v)
    }
}

// Custom serialization
#[cfg(feature = "serialize")]
mod serialize {
    use super::*;

    use std::fmt;
    use serde::{Serialize, Deserialize, Serializer, Deserializer};
    use serde::de::{Visitor, Error};

    impl Serialize for Color {
        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
            s.serialize_str(&self.to_hex())
        }
    }

    impl<'de> Deserialize<'de> for Color {
        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
            d.deserialize_str(ColorVisitor)
        }
    }

    struct ColorVisitor;
    impl<'de> Visitor<'de> for ColorVisitor {
        type Value = Color;

        fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.write_str("A string representing a valid hex color")
        }

        fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
            match Color::hex(v) {
                Some(color) => Ok(color),
                None =>        Err(E::custom(format!("\"{}\" is not a valid color string", v))),
            }
        }
    }
}

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

    #[test]
    fn test_to_hex() {
        assert_eq!("#ffa3b1", Color::hex("#ffa3b1").unwrap().to_hex());
        assert_eq!("#a300f1", Color::hex("#a300f1").unwrap().to_hex());
        assert_eq!("#000000", Color::hex("#000000").unwrap().to_hex());
        assert_eq!("#000001", Color::hex("#000001").unwrap().to_hex());
        assert_eq!("#100000", Color::hex("#100000").unwrap().to_hex());
    }
}

<|endoftext|>


<commit_before>extern crate redis;

fn main() {
    println!("24 days of Rust - redis (day 18)");
}
<commit_msg>Fleshing out Redis example.<commit_after>extern crate redis;

use redis::{Client, Commands, Connection, RedisResult};
use std::collections::HashSet;

type UserId = u64;

fn add_friend(conn: &Connection, my_id: UserId, their_id: UserId) -> RedisResult<()> {
    let my_key = format!("friends:{}", my_id);
    let their_key = format!("friends:{}", their_id);
    let _: () = try!(conn.sadd(my_key, their_id));
    let _: () = try!(conn.sadd(their_key, my_id));
    Ok(())
}

fn friends_in_common(conn: &Connection, my_id: UserId, their_id: UserId) -> RedisResult<HashSet<UserId>> {
    let my_key = format!("friends:{}", my_id);
    let their_key = format!("friends:{}", their_id);
    let result: HashSet<UserId> = try!(conn.sinter((my_key, their_key)));
    Ok(result)
}

fn main() {
    println!("24 days of Rust - redis (day 18)");
    let client = Client::open("redis://127.0.0.1/").unwrap();
    let conn = client.get_connection().unwrap();
    let _: () = conn.set("answer", 42i).unwrap();
    let answer: int = conn.get("answer").unwrap();
    println!("Answer: {}", answer);

    for i in range(1, 10u64) {
        add_friend(&conn, i, i + 2).ok().expect("Friendship failed :(");
    }
    println!("{}", friends_in_common(&conn, 2, 3));
}
<|endoftext|>


<commit_before>// http://smallcultfollowing.com/babysteps/blog/2015/04/06/modeling-graphs-in-rust-using-vector-indices/

pub struct Graph {
    nodes: Vec<NodeData>,
    edges: Vec<EdgeData>,
}

impl Graph {
    pub fn add_node(&mut self) -> NodeIndex {
        let index = self.nodes.len();
        self.nodes.push(NodeData { first_outgoing_edge: None });
        index
    }

    pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex) {
        let edge_index = self.edges.len();
        let node_data = &mut self.nodes[source];
        self.edges.push(EdgeData {
            target: target,
            next_outgoing_edge: node_data.first_outgoing_edge
        });
        node_data.first_outgoing_edge = Some(edge_index);
    }

    pub fn successors(&self, source: NodeIndex) -> Successors {
        let first_outgoing_edge = self.nodes[source].first_outgoing_edge;
        Successors { graph: self, current_edge_index: first_outgoing_edge }
    }

    pub fn print(self) {
        for n in 0..self.nodes.len() {
            print!("Node {} goes to: ", n);
            let mut suc = self.successors(n);
            loop {
                match suc.next() {
                    Some(s) => { print!("{}, ", s) },
                    None => { print!("\n"); break },
                }
            }
        }
    }
}

pub type NodeIndex = usize;
pub struct NodeData {
    first_outgoing_edge: Option<EdgeIndex>,
}

pub type EdgeIndex = usize;
pub struct EdgeData {
    target: NodeIndex,
    next_outgoing_edge: Option<EdgeIndex>
}

pub struct Successors<'graph> {
    graph: &'graph Graph,
    current_edge_index: Option<EdgeIndex>,
}

impl<'graph> Iterator for Successors<'graph> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        match self.current_edge_index {
            None => None,
            Some(edge_num) => {
                let edge = &self.graph.edges[edge_num];
                self.current_edge_index = edge.next_outgoing_edge;
                Some(edge.target)
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn create_small_graph() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };
        let node0 = graph.add_node();
        let node1 = graph.add_node();
        graph.add_edge(node0, node1);

        assert_eq!(graph.nodes.len(), 2);
        assert_eq!(graph.edges.len(), 1);
        match graph.nodes[0].first_outgoing_edge {
            Some(index) => assert_eq!(graph.edges[index].target, 1),
            None => assert!(false),
        }
    }

    #[test]
    fn create_list_graph() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };
        let node0 = graph.add_node();
        let node1 = graph.add_node();
        let node2 = graph.add_node();
        let node3 = graph.add_node();
        graph.add_edge(node0, node1);
        graph.add_edge(node1, node2);
        graph.add_edge(node2, node3);

        let mut targets = vec![];
        for e in graph.edges {
            targets.push(e.target);
        }
        assert_eq!(targets, [1,2,3]);
    }

    #[test]
    fn list_node_edges() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };
        let node0 = graph.add_node();
        graph.add_edge(node0, node0);
        graph.add_edge(node0, node0);
        graph.add_edge(node0, node0);
        let mut targets = vec![];
        let mut successors = graph.successors(0);
        loop {
            match successors.next() {
                Some(edge) => targets.push(edge),
                None => break,
            }
        }
        assert_eq!(targets, [0,0,0]);
    }
}
<commit_msg>Add identifier and hashmap attrs to nodes + edges<commit_after>use std::collections::HashMap;
// http://smallcultfollowing.com/babysteps/blog/2015/04/06/modeling-graphs-in-rust-using-vector-indices/

pub struct Graph {
    nodes: Vec<NodeData>,
    edges: Vec<EdgeData>,
}

impl Graph {
    pub fn add_node(&mut self, identifier: String, attributes: Option<HashMap<String,String>>)
        -> NodeIndex {
        let index = self.nodes.len();
        self.nodes.push(NodeData { identifier: identifier, first_outgoing_edge: None, attributes: attributes });
        index
    }

    pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex, identifier: String, attributes: Option<HashMap<String,String>>) {
        let edge_index = self.edges.len();
        let node_data = &mut self.nodes[source];
        self.edges.push(EdgeData {
            identifier: identifier,
            target: target,
            next_outgoing_edge: node_data.first_outgoing_edge,
            attributes: attributes,
        });
        node_data.first_outgoing_edge = Some(edge_index);
    }

    pub fn successors(&self, source: NodeIndex) -> Successors {
        let first_outgoing_edge = self.nodes[source].first_outgoing_edge;
        Successors { graph: self, current_edge_index: first_outgoing_edge }
    }

    pub fn print(self) {
        for n in 0..self.nodes.len() {
            print!("Node {} goes to: ", n);
            let mut suc = self.successors(n);
            loop {
                match suc.next() {
                    Some(s) => { print!("{}, ", s) },
                    None => { print!("\n"); break },
                }
            }
        }
    }
}

pub type NodeIndex = usize;
pub struct NodeData {
    identifier: String,
    attributes: Option<HashMap<String, String>>,
    first_outgoing_edge: Option<EdgeIndex>,
}

pub type EdgeIndex = usize;
pub struct EdgeData {
    identifier: String,
    target: NodeIndex,
    attributes: Option<HashMap<String, String>>,
    next_outgoing_edge: Option<EdgeIndex>,
}

pub struct Successors<'graph> {
    graph: &'graph Graph,
    current_edge_index: Option<EdgeIndex>,
}

impl<'graph> Iterator for Successors<'graph> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        match self.current_edge_index {
            None => None,
            Some(edge_num) => {
                let edge = &self.graph.edges[edge_num];
                self.current_edge_index = edge.next_outgoing_edge;
                Some(edge.target)
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use super::*;
    #[test]
    fn create_small_graph() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };
        let node0 = graph.add_node("node0".to_string(), None);
        let node1 = graph.add_node("node1".to_string(), None);
        graph.add_edge(node0, node1, "edge0".to_string(), None);

        assert_eq!(graph.nodes.len(), 2);
        assert_eq!(graph.edges.len(), 1);
        match graph.nodes[0].first_outgoing_edge {
            Some(index) => assert_eq!(graph.edges[index].target, 1),
            None => assert!(false),
        }
    }

    #[test]
    fn create_list_graph() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };
        let node0 = graph.add_node("node0".to_string(), None);
        let node1 = graph.add_node("node1".to_string(), None);
        let node2 = graph.add_node("node2".to_string(), None);
        let node3 = graph.add_node("node3".to_string(), None);
        graph.add_edge(node0, node1, "edge0".to_string(), None);
        graph.add_edge(node1, node2, "edge1".to_string(), None);
        graph.add_edge(node2, node3, "edge2".to_string(), None);

        let mut targets = vec![];
        for e in graph.edges {
            targets.push(e.target);
        }
        assert_eq!(targets, [1,2,3]);
    }

    #[test]
    fn list_node_edges() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };
        let node0 = graph.add_node("node0".to_string(), None);
        graph.add_edge(node0, node0, "edge0".to_string(), None);
        graph.add_edge(node0, node0, "edge1".to_string(), None);
        graph.add_edge(node0, node0, "edge2".to_string(), None);
        let mut targets = vec![];
        let mut successors = graph.successors(0);
        loop {
            match successors.next() {
                Some(edge) => targets.push(edge),
                None => break,
            }
        }
        assert_eq!(targets, [0,0,0]);
    }

    #[test]
    fn node_attributes() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };

        let mut attributes = HashMap::new();
        attributes.insert("key".to_string(), "value".to_string());

        let node0 = graph.add_node("node0".to_string(), Some(attributes));
        match graph.nodes[node0].attributes {
            Some(ref attrs) => {
                match attrs.get("key") {
                    Some(value) => assert_eq!(value, &"value".to_string()),
                    None => assert!(false),
                }
            },
            None => assert!(false),
        }
    }

    #[test]
    fn edge_attributes() {
        let mut graph = Graph { nodes: vec![], edges: vec![] };

        let mut attributes = HashMap::new();
        attributes.insert("key".to_string(), "value".to_string());

        let node0 = graph.add_node("node0".to_string(), None);
        graph.add_edge(node0, node0, "edge0".to_string(), Some(attributes));
        match graph.edges[0].attributes {
            Some(ref attrs) => {
                match attrs.get("key") {
                    Some(value) => assert_eq!(value, &"value".to_string()),
                    None => assert!(false),
                }
            },
            None => assert!(false),
        }
    }
}
<|endoftext|>


<commit_before>
use std::fmt;

#[derive(Debug)]
/// nccl Error type.
pub enum ErrorKind {
    KeyNotFound,
    IndentationError,
    NameError,
    NoValue,
    ParseError,
    FileError,
}

#[derive(Debug)]
pub struct NcclError {
    kind: ErrorKind,
    line: u64,
    message: String,
}

impl NcclError {
    pub fn new(kind: ErrorKind, message: &str, line: u64) -> Self {
        NcclError {
            kind: kind,
            message: message.to_owned(),
            line: line,
        }
    }
}

impl fmt::Display for NcclError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "An error has ocurred: {:?} on line {}\n\t{}", self.kind, self.line, self.message)
    }
}

//impl ::std::fmt::Display for ErrorKind {
//    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
//        write!(f, "An error has ocurred: {:?}", self)
//    }
//}
//
//impl ::std::error::Error for Error {
//    fn description(&self) -> &str {
//        match *self {
//            Error::KeyNotFound => "Key not found.",
//            Error::IndentationError => "Incorrect indentation: Not 4 spaces.",
//            Error::NameError => "Schema not found.",
//            Error::NoValue => "No value associated with key.",
//            Error::ParseError => "Unable to parse value.",
//            Error::FileError => "Could not open file.",
//        }
//    }
//}

<commit_msg>clean up<commit_after>
use std::fmt;

#[derive(Debug)]
/// nccl Error type.
pub enum ErrorKind {
    KeyNotFound,
    IndentationError,
    NameError,
    NoValue,
    ParseError,
    FileError,
}

#[derive(Debug)]
pub struct NcclError {
    kind: ErrorKind,
    line: u64,
    message: String,
}

impl NcclError {
    pub fn new(kind: ErrorKind, message: &str, line: u64) -> Self {
        let r = NcclError {
            kind: kind,
            message: message.to_owned(),
            line: line,
        };
        println!("{}", &r);
        r
    }
}

impl fmt::Display for NcclError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "An error has ocurred: {:?} on line {}\n\t{}", self.kind, self.line, self.message)
    }
}

<|endoftext|>


<commit_before>//! Define Errors

use std::error;
use std::fmt;

#[derive(Debug)]
pub struct LapackError {
    pub return_code: i32,
}

impl fmt::Display for LapackError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LAPACK: return_code = {}", self.return_code)
    }
}

impl error::Error for LapackError {
    fn description(&self) -> &str {
        "LAPACK subroutine returns non-zero code"
    }
}

impl From<i32> for LapackError {
    fn from(code: i32) -> LapackError {
        LapackError { return_code: code }
    }
}

#[derive(Debug)]
pub struct NotSquareError {
    pub rows: usize,
    pub cols: usize,
}

impl fmt::Display for NotSquareError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Not square: rows({}) != cols({})", self.rows, self.cols)
    }
}

impl error::Error for NotSquareError {
    fn description(&self) -> &str {
        "Matrix is not square"
    }
}

#[derive(Debug)]
pub enum LinalgError {
    NotSquare(NotSquareError),
    Lapack(LapackError),
}

impl fmt::Display for LinalgError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LinalgError::NotSquare(ref err) => err.fmt(f),
            LinalgError::Lapack(ref err) => err.fmt(f),
        }
    }
}

impl error::Error for LinalgError {
    fn description(&self) -> &str {
        match *self {
            LinalgError::NotSquare(ref err) => err.description(),
            LinalgError::Lapack(ref err) => err.description(),
        }
    }
}

impl From<NotSquareError> for LinalgError {
    fn from(err: NotSquareError) -> LinalgError {
        LinalgError::NotSquare(err)
    }
}

impl From<LapackError> for LinalgError {
    fn from(err: LapackError) -> LinalgError {
        LinalgError::Lapack(err)
    }
}
<commit_msg>Add StrideError<commit_after>//! Define Errors

use std::error;
use std::fmt;

#[derive(Debug)]
pub struct LapackError {
    pub return_code: i32,
}

impl fmt::Display for LapackError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LAPACK: return_code = {}", self.return_code)
    }
}

impl error::Error for LapackError {
    fn description(&self) -> &str {
        "LAPACK subroutine returns non-zero code"
    }
}

impl From<i32> for LapackError {
    fn from(code: i32) -> LapackError {
        LapackError { return_code: code }
    }
}

#[derive(Debug)]
pub struct NotSquareError {
    pub rows: usize,
    pub cols: usize,
}

impl fmt::Display for NotSquareError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Not square: rows({}) != cols({})", self.rows, self.cols)
    }
}

impl error::Error for NotSquareError {
    fn description(&self) -> &str {
        "Matrix is not square"
    }
}

#[derive(Debug)]
pub struct StrideError {}

impl fmt::Display for StrideError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "invalid stride")
    }
}

impl error::Error for StrideError {
    fn description(&self) -> &str {
        "invalid stride"
    }
}

#[derive(Debug)]
pub enum LinalgError {
    NotSquare(NotSquareError),
    Lapack(LapackError),
    Stride(StrideError),
}

impl fmt::Display for LinalgError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LinalgError::NotSquare(ref err) => err.fmt(f),
            LinalgError::Lapack(ref err) => err.fmt(f),
            LinalgError::Stride(ref err) => err.fmt(f),
        }
    }
}

impl error::Error for LinalgError {
    fn description(&self) -> &str {
        match *self {
            LinalgError::NotSquare(ref err) => err.description(),
            LinalgError::Lapack(ref err) => err.description(),
            LinalgError::Stride(ref err) => err.description(),
        }
    }
}

impl From<NotSquareError> for LinalgError {
    fn from(err: NotSquareError) -> LinalgError {
        LinalgError::NotSquare(err)
    }
}

impl From<LapackError> for LinalgError {
    fn from(err: LapackError) -> LinalgError {
        LinalgError::Lapack(err)
    }
}

impl From<StrideError> for LinalgError {
    fn from(err: StrideError) -> LinalgError {
        LinalgError::Stride(err)
    }
}
<|endoftext|>


<commit_before>//! # Drains
//!
//! Drains are responsible for filtering, formatting and writing the log records
//! into given destination.
use std::io;
use std::sync::Mutex;
use std::sync::{mpsc, Arc};
use std::thread;
use std::mem;

use super::{Level, Logger};
use super::format;
use super::logger::RecordInfo;
use super::{OwnedKeyValue, BorrowedKeyValue};

use crossbeam::sync::ArcCell;

#[allow(missing_docs)]
mod error {
    use super::super::format;
    use std::io;

    error_chain! {
        types {
            Error, ErrorKind, ChainErr, Result;
        }
        links {
            format::Error, format::ErrorKind, Format;
        }
        foreign_links {
            io::Error, Io, "io error";
        }
        errors {
            SendError {
                description("sending to another thread failed")
                    display("sending to another thread failed")
            }
            LockError {
                description("locking mutex failed")
                    display("locking mutex failed")
            }
            FailoverExhausted {
                description("failover drains exhausted")
                    display("failover drains exhausted")
            }

        }
    }
}

pub use self::error::{Error, Result, ErrorKind};

/// Drain for Loggers
///
/// Implementing this trait allows writing own Drains
pub trait Drain: Send + Sync {
    /// Write one logging record
    /// As an optimization (avoiding allocations), loggers are responsible for
    /// providing a byte buffer, that `Drain` can use for their own needs.
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo, &[OwnedKeyValue], &[BorrowedKeyValue]) -> Result<()>;

}

/// Convenience trait allowing turning drain into root `Logger`
///
/// `Logger::new_root` shortcut
pub trait IntoLogger : Drain+Sized+'static {
    /// Turn drain into root `Logger`
    fn into_logger(self, values: &[OwnedKeyValue]) -> Logger {
        Logger::new_root(values, self)
    }
}

impl<D : Drain+Sized+'static> IntoLogger for D {}

impl<D:Drain> Drain for Box<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo, o : &[OwnedKeyValue], b : &[BorrowedKeyValue]) -> Result<()> {
        (**self).log(buf, info, o, b)
    }
}

impl<D:Drain> Drain for Arc<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo, o : &[OwnedKeyValue], b : &[BorrowedKeyValue]) -> Result<()> {
        (**self).log(buf, info, o, b)
    }
}

/// Drain discarding everything
pub struct Discard;

impl Drain for Discard {
    fn log(&self,
           _: &mut Vec<u8>,
           _: &RecordInfo, _: &[OwnedKeyValue], _: &[BorrowedKeyValue]) -> Result<()> {
        Ok(())
    }
}

/// A handle to `AtomicSwitch` allowing to switch it's sub-drain
pub struct AtomicSwitchCtrl(Arc<ArcCell<Box<Drain>>>);

/// A drain allowing to atomically switch a sub-drain at runtime
pub struct AtomicSwitch(Arc<ArcCell<Box<Drain>>>);

impl AtomicSwitchCtrl {
    /// Create new `AtomicSwitchCtrl`
    pub fn new<D: Drain+'static>(d : D) -> Self{
        let a = Arc::new(ArcCell::new(Arc::new(Box::new(d) as Box<Drain>)));
        AtomicSwitchCtrl(a)
    }

    /// Create new `AtomicSwitchCtrl` from an existing `Arc<...>`
    pub fn new_from_arc(d : Arc<ArcCell<Box<Drain>>>) -> Self{
        AtomicSwitchCtrl(d)
    }

    /// Get a `AtomicSwitch` drain controlled by this `AtomicSwitchCtrl`
    pub fn drain(&self) -> AtomicSwitch {
        AtomicSwitch(self.0.clone())
    }

    /// Set the drain
    pub fn set<D: Drain>(&self, drain: D) {
        let _ = self.0.set(Arc::new(Box::new(drain)));
    }

    /// Swap the existing drain with a new one
    pub fn swap(&self, drain: Arc<Box<Drain>>) -> Arc<Box<Drain>> {
        self.0.set(drain)
    }
}
impl Drain for AtomicSwitch {
    fn log(&self,
           mut buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
            self.0.get().log(buf, info, logger_values, values)
    }
}

/// Drain formating records and writing them to a byte-stream (io::Write)
///
/// Uses mutex to serialize writes.
/// TODO: Add one that does not serialize?
pub struct Streamer<W: io::Write, F: format::Format> {
    io: Mutex<W>,
    format: F,
}

impl<W: io::Write, F: format::Format> Streamer<W, F> {
    /// Create new `Streamer` writing to `io` using `format`
    pub fn new(io: W, format: F) -> Self {
        Streamer {
            io: Mutex::new(io),
            format: format,
        }
    }
}

impl<W: 'static + io::Write + Send, F: format::Format + Send> Drain for Streamer<W, F> {
    fn log(&self,
           mut buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        try!(self.format.format(&mut buf, info, logger_values, values));
        {
            let mut io = try!(self.io.lock().map_err(|_| -> Error { ErrorKind::LockError.into() }));
            try!(io.write_all(&buf));
        }
        Ok(())
    }
}

/// Drain formating records and writing them to a byte-stream (io::Write)
/// asynchronously.
///
/// Internally, new thread will be spawned taking care of actually writing
/// the data.
pub struct AsyncStreamer<F: format::Format> {
    format: F,
    io: Mutex<AsyncIoWriter>,
}

impl<F: format::Format> AsyncStreamer<F> {
    /// Create new `AsyncStreamer` writing to `io` using `format`
    pub fn new<W: io::Write + Send + 'static>(io: W, format: F) -> Self {
        AsyncStreamer {
            io: Mutex::new(AsyncIoWriter::new(io)),
            format: format,
        }
    }
}

impl<F: format::Format + Send> Drain for AsyncStreamer<F> {
    fn log(&self,
           mut buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        try!(self.format.format(&mut buf, info, logger_values, values));
        {
            let mut io = try!(self.io.lock().map_err(|_| -> Error { ErrorKind::LockError.into() }));
            let mut new_buf = Vec::with_capacity(128);
            mem::swap(buf, &mut new_buf);
            try!(io.write_nocopy(new_buf));
        }
        Ok(())
    }
}

/// Filter log record
///
/// Wraps a drain and passes records to it, only if their `RecordInfo`
/// satisifies a condition `cond`.
pub struct Filter<D: Drain> {
    drain: D,
    // eliminated dynamic dispatch, after rust learns `-> impl Trait`
    cond: Box<Fn(&RecordInfo) -> bool + 'static + Send + Sync>,
}

impl<D: Drain> Filter<D> {
    /// Create Filter wrapping given `subdrain` and passing to it records
    /// only the `cond` is true
    pub fn new<F: 'static + Sync + Send + Fn(&RecordInfo) -> bool>(drain: D, cond: F) -> Self {
        Filter {
            drain: drain,
            cond: Box::new(cond),
        }
    }
}

impl<D: Drain> Drain for Filter<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        if (self.cond)(&info) {
            self.drain.log(buf, info, logger_values, values)
        } else {
            Ok(())
        }
    }
}

/// Record log level filter
///
/// Wraps a drain and passes records to it, only
/// if their level is at least given level.
///
/// TODO: Remove this type. This drain is a special case of `Filter`, but
/// because `Filter` can not use static dispatch ATM due to Rust limitations
/// that will be lifted in the future, it is a standalone type.
pub struct FilterLevel<D: Drain> {
    level: Level,
    drain: D,
}

impl<D: Drain> FilterLevel<D> {
    /// Create `FilterLevel`
    pub fn new(drain: D, level: Level) -> Self {
        FilterLevel {
            level: level,
            drain: drain,
        }
    }
}

impl<D: Drain> Drain for FilterLevel<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        if info.level().is_at_least(self.level) {
            self.drain.log(buf, info, logger_values, values)
        } else {
            Ok(())
        }
    }
}

/// Duplicate records into two drains
pub struct Duplicate<D1: Drain, D2: Drain> {
    drain1: D1,
    drain2: D2,
}

impl<D1: Drain, D2: Drain> Duplicate<D1, D2> {
    /// Create `Duplicate`
    pub fn new(drain1: D1, drain2: D2) -> Self {
        Duplicate {
            drain1: drain1,
            drain2: drain2,
        }
    }
}

impl<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        let res1 = self.drain1.log(buf, info, logger_values, values);
        let res2 = self.drain2.log(buf, info, logger_values, values);

        // TODO: Don't discard e2 in case of two errors at once?
        match (res1, res2) {
            (Ok(_), Ok(_)) => Ok(()),
            (Ok(_), Err(e)) => Err(e),
            (Err(e), Ok(_)) => Err(e),
            (Err(e1), Err(_)) => Err(e1),
        }
    }
}

/// Failover drain
///
/// Log everything to logger `D1`, but in case of it reporting error,
/// try logging to `D2`. If it also returned an error, forward it up.
pub struct Failover<D1: Drain, D2: Drain> {
    drain1: D1,
    drain2: D2,
}

impl<D1: Drain, D2: Drain> Failover<D1, D2> {
    /// Create `Failover`
    pub fn new(drain1: D1, drain2: D2) -> Self {
        Failover {
            drain1: drain1,
            drain2: drain2,
        }
    }
}

impl<D1: Drain, D2: Drain> Drain for Failover<D1, D2> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        match self.drain1.log(buf, info, logger_values, values) {
            Ok(_) => Ok(()),
            Err(_) => self.drain2.log(buf, info, logger_values, values),
        }
    }
}

enum AsyncIoMsg {
    Bytes(Vec<u8>),
    Flush,
    Eof,
}

/// Asynchronous io::Writer
///
/// TODO: Publish as a different create / use existing one?
///
/// Wraps an `io::Writer` and writes to it in separate thread
/// using channel to send the data.
///
/// This makes logging not block on potentially-slow IO operations.
///
/// Note: Dropping `AsyncIoWriter` waits for it's io-thread to finish.
/// If you can't tolerate the delay, make sure to use `Logger::
struct AsyncIoWriter {
    sender: mpsc::Sender<AsyncIoMsg>,
    join: Option<thread::JoinHandle<()>>,
}

impl AsyncIoWriter {
    /// Create `AsyncIoWriter`
    pub fn new<W: io::Write + Send + 'static>(mut io: W) -> Self {
        let (tx, rx) = mpsc::channel();
        let join = thread::spawn(move || {
            loop {
                match rx.recv().unwrap() {
                    AsyncIoMsg::Bytes(buf) => io.write_all(&buf).unwrap(),
                    AsyncIoMsg::Flush => io.flush().unwrap(),
                    AsyncIoMsg::Eof => return,
                }
            }
        });

        AsyncIoWriter {
            sender: tx,
            join: Some(join),
        }
    }

    /// Write data to IO, without copying
    ///
    /// As an optimization, when `buf` is already an owned
    /// `Vec`, it can be sent over channel without copying.
    pub fn write_nocopy(&mut self, buf: Vec<u8>) -> Result<()> {
        try!(self.sender
            .send(AsyncIoMsg::Bytes(buf))
            .map_err(|_| -> Error { ErrorKind::SendError.into() }));
        Ok(())
    }
}

impl io::Write for AsyncIoWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let _ = self.sender.send(AsyncIoMsg::Bytes(buf.to_vec())).unwrap();
        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        let _ = self.sender.send(AsyncIoMsg::Flush);
        Ok(())
    }
}

impl Drop for AsyncIoWriter {
    fn drop(&mut self) {
        let _ = self.sender.send(AsyncIoMsg::Eof);
        let _ = self.join.take().unwrap().join();
    }
}

/// Create `Streamer` drain
pub fn stream<W: io::Write + Send, F: format::Format>(io: W, format: F) -> Streamer<W, F> {
    Streamer::new(io, format)
}

/// Create `AsyncStreamer` drain
pub fn async_stream<W: io::Write + Send, F: format::Format>(io: W, format: F) -> Streamer<W, F> {
    Streamer::new(io, format)
}

/// Create a Discard drain
pub fn discard() -> Discard {
    Discard
}

/// Filter by `cond` closure
pub fn filter<D: Drain, F: 'static + Send + Sync + Fn(&RecordInfo) -> bool>(cond: F,
                                                                            d: D)
                                                                            -> Filter<D> {
    Filter::new(d, cond)
}

/// Filter by log level
pub fn filter_level<D: Drain>(level: Level, d: D) -> FilterLevel<D> {
    FilterLevel::new(d, level)
}

/// Create Duplicate drain
pub fn duplicate<D1: Drain, D2: Drain>(d1: D1, d2: D2) -> Duplicate<D1, D2> {
    Duplicate::new(d1, d2)
}

/// Create Failover drain
pub fn failover<D1: Drain, D2: Drain>(d1: D1, d2: D2) -> Failover<D1, D2> {
    Failover::new(d1, d2)
}
<commit_msg>Fix duplicate drain<commit_after>//! # Drains
//!
//! Drains are responsible for filtering, formatting and writing the log records
//! into given destination.
use std::io;
use std::sync::Mutex;
use std::sync::{mpsc, Arc};
use std::thread;
use std::mem;

use super::{Level, Logger};
use super::format;
use super::logger::RecordInfo;
use super::{OwnedKeyValue, BorrowedKeyValue};

use crossbeam::sync::ArcCell;

#[allow(missing_docs)]
mod error {
    use super::super::format;
    use std::io;

    error_chain! {
        types {
            Error, ErrorKind, ChainErr, Result;
        }
        links {
            format::Error, format::ErrorKind, Format;
        }
        foreign_links {
            io::Error, Io, "io error";
        }
        errors {
            SendError {
                description("sending to another thread failed")
                    display("sending to another thread failed")
            }
            LockError {
                description("locking mutex failed")
                    display("locking mutex failed")
            }
            FailoverExhausted {
                description("failover drains exhausted")
                    display("failover drains exhausted")
            }

        }
    }
}

pub use self::error::{Error, Result, ErrorKind};

/// Drain for Loggers
///
/// Implementing this trait allows writing own Drains
pub trait Drain: Send + Sync {
    /// Write one logging record
    /// As an optimization (avoiding allocations), loggers are responsible for
    /// providing a byte buffer, that `Drain` can use for their own needs.
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo, &[OwnedKeyValue], &[BorrowedKeyValue]) -> Result<()>;

}

/// Convenience trait allowing turning drain into root `Logger`
///
/// `Logger::new_root` shortcut
pub trait IntoLogger : Drain+Sized+'static {
    /// Turn drain into root `Logger`
    fn into_logger(self, values: &[OwnedKeyValue]) -> Logger {
        Logger::new_root(values, self)
    }
}

impl<D : Drain+Sized+'static> IntoLogger for D {}

impl<D:Drain> Drain for Box<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo, o : &[OwnedKeyValue], b : &[BorrowedKeyValue]) -> Result<()> {
        (**self).log(buf, info, o, b)
    }
}

impl<D:Drain> Drain for Arc<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo, o : &[OwnedKeyValue], b : &[BorrowedKeyValue]) -> Result<()> {
        (**self).log(buf, info, o, b)
    }
}

/// Drain discarding everything
pub struct Discard;

impl Drain for Discard {
    fn log(&self,
           _: &mut Vec<u8>,
           _: &RecordInfo, _: &[OwnedKeyValue], _: &[BorrowedKeyValue]) -> Result<()> {
        Ok(())
    }
}

/// A handle to `AtomicSwitch` allowing to switch it's sub-drain
pub struct AtomicSwitchCtrl(Arc<ArcCell<Box<Drain>>>);

/// A drain allowing to atomically switch a sub-drain at runtime
pub struct AtomicSwitch(Arc<ArcCell<Box<Drain>>>);

impl AtomicSwitchCtrl {
    /// Create new `AtomicSwitchCtrl`
    pub fn new<D: Drain+'static>(d : D) -> Self{
        let a = Arc::new(ArcCell::new(Arc::new(Box::new(d) as Box<Drain>)));
        AtomicSwitchCtrl(a)
    }

    /// Create new `AtomicSwitchCtrl` from an existing `Arc<...>`
    pub fn new_from_arc(d : Arc<ArcCell<Box<Drain>>>) -> Self{
        AtomicSwitchCtrl(d)
    }

    /// Get a `AtomicSwitch` drain controlled by this `AtomicSwitchCtrl`
    pub fn drain(&self) -> AtomicSwitch {
        AtomicSwitch(self.0.clone())
    }

    /// Set the drain
    pub fn set<D: Drain>(&self, drain: D) {
        let _ = self.0.set(Arc::new(Box::new(drain)));
    }

    /// Swap the existing drain with a new one
    pub fn swap(&self, drain: Arc<Box<Drain>>) -> Arc<Box<Drain>> {
        self.0.set(drain)
    }
}
impl Drain for AtomicSwitch {
    fn log(&self,
           mut buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
            self.0.get().log(buf, info, logger_values, values)
    }
}

/// Drain formating records and writing them to a byte-stream (io::Write)
///
/// Uses mutex to serialize writes.
/// TODO: Add one that does not serialize?
pub struct Streamer<W: io::Write, F: format::Format> {
    io: Mutex<W>,
    format: F,
}

impl<W: io::Write, F: format::Format> Streamer<W, F> {
    /// Create new `Streamer` writing to `io` using `format`
    pub fn new(io: W, format: F) -> Self {
        Streamer {
            io: Mutex::new(io),
            format: format,
        }
    }
}

impl<W: 'static + io::Write + Send, F: format::Format + Send> Drain for Streamer<W, F> {
    fn log(&self,
           mut buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        try!(self.format.format(&mut buf, info, logger_values, values));
        {
            let mut io = try!(self.io.lock().map_err(|_| -> Error { ErrorKind::LockError.into() }));
            try!(io.write_all(&buf));
        }
        Ok(())
    }
}

/// Drain formating records and writing them to a byte-stream (io::Write)
/// asynchronously.
///
/// Internally, new thread will be spawned taking care of actually writing
/// the data.
pub struct AsyncStreamer<F: format::Format> {
    format: F,
    io: Mutex<AsyncIoWriter>,
}

impl<F: format::Format> AsyncStreamer<F> {
    /// Create new `AsyncStreamer` writing to `io` using `format`
    pub fn new<W: io::Write + Send + 'static>(io: W, format: F) -> Self {
        AsyncStreamer {
            io: Mutex::new(AsyncIoWriter::new(io)),
            format: format,
        }
    }
}

impl<F: format::Format + Send> Drain for AsyncStreamer<F> {
    fn log(&self,
           mut buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        try!(self.format.format(&mut buf, info, logger_values, values));
        {
            let mut io = try!(self.io.lock().map_err(|_| -> Error { ErrorKind::LockError.into() }));
            let mut new_buf = Vec::with_capacity(128);
            mem::swap(buf, &mut new_buf);
            try!(io.write_nocopy(new_buf));
        }
        Ok(())
    }
}

/// Filter log record
///
/// Wraps a drain and passes records to it, only if their `RecordInfo`
/// satisifies a condition `cond`.
pub struct Filter<D: Drain> {
    drain: D,
    // eliminated dynamic dispatch, after rust learns `-> impl Trait`
    cond: Box<Fn(&RecordInfo) -> bool + 'static + Send + Sync>,
}

impl<D: Drain> Filter<D> {
    /// Create Filter wrapping given `subdrain` and passing to it records
    /// only the `cond` is true
    pub fn new<F: 'static + Sync + Send + Fn(&RecordInfo) -> bool>(drain: D, cond: F) -> Self {
        Filter {
            drain: drain,
            cond: Box::new(cond),
        }
    }
}

impl<D: Drain> Drain for Filter<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        if (self.cond)(&info) {
            self.drain.log(buf, info, logger_values, values)
        } else {
            Ok(())
        }
    }
}

/// Record log level filter
///
/// Wraps a drain and passes records to it, only
/// if their level is at least given level.
///
/// TODO: Remove this type. This drain is a special case of `Filter`, but
/// because `Filter` can not use static dispatch ATM due to Rust limitations
/// that will be lifted in the future, it is a standalone type.
pub struct FilterLevel<D: Drain> {
    level: Level,
    drain: D,
}

impl<D: Drain> FilterLevel<D> {
    /// Create `FilterLevel`
    pub fn new(drain: D, level: Level) -> Self {
        FilterLevel {
            level: level,
            drain: drain,
        }
    }
}

impl<D: Drain> Drain for FilterLevel<D> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        if info.level().is_at_least(self.level) {
            self.drain.log(buf, info, logger_values, values)
        } else {
            Ok(())
        }
    }
}

/// Duplicate records into two drains
pub struct Duplicate<D1: Drain, D2: Drain> {
    drain1: D1,
    drain2: D2,
}

impl<D1: Drain, D2: Drain> Duplicate<D1, D2> {
    /// Create `Duplicate`
    pub fn new(drain1: D1, drain2: D2) -> Self {
        Duplicate {
            drain1: drain1,
            drain2: drain2,
        }
    }
}

impl<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        let res1 = self.drain1.log(buf, info, logger_values, values);
        buf.clear();
        let res2 = self.drain2.log(buf, info, logger_values, values);

        // TODO: Don't discard e2 in case of two errors at once?
        match (res1, res2) {
            (Ok(_), Ok(_)) => Ok(()),
            (Ok(_), Err(e)) => Err(e),
            (Err(e), Ok(_)) => Err(e),
            (Err(e1), Err(_)) => Err(e1),
        }
    }
}

/// Failover drain
///
/// Log everything to logger `D1`, but in case of it reporting error,
/// try logging to `D2`. If it also returned an error, forward it up.
pub struct Failover<D1: Drain, D2: Drain> {
    drain1: D1,
    drain2: D2,
}

impl<D1: Drain, D2: Drain> Failover<D1, D2> {
    /// Create `Failover`
    pub fn new(drain1: D1, drain2: D2) -> Self {
        Failover {
            drain1: drain1,
            drain2: drain2,
        }
    }
}

impl<D1: Drain, D2: Drain> Drain for Failover<D1, D2> {
    fn log(&self,
           buf : &mut Vec<u8>,
           info: &RecordInfo,
           logger_values: &[OwnedKeyValue],
           values: &[BorrowedKeyValue])
           -> Result<()> {
        match self.drain1.log(buf, info, logger_values, values) {
            Ok(_) => Ok(()),
            Err(_) => self.drain2.log(buf, info, logger_values, values),
        }
    }
}

enum AsyncIoMsg {
    Bytes(Vec<u8>),
    Flush,
    Eof,
}

/// Asynchronous io::Writer
///
/// TODO: Publish as a different create / use existing one?
///
/// Wraps an `io::Writer` and writes to it in separate thread
/// using channel to send the data.
///
/// This makes logging not block on potentially-slow IO operations.
///
/// Note: Dropping `AsyncIoWriter` waits for it's io-thread to finish.
/// If you can't tolerate the delay, make sure to use `Logger::
struct AsyncIoWriter {
    sender: mpsc::Sender<AsyncIoMsg>,
    join: Option<thread::JoinHandle<()>>,
}

impl AsyncIoWriter {
    /// Create `AsyncIoWriter`
    pub fn new<W: io::Write + Send + 'static>(mut io: W) -> Self {
        let (tx, rx) = mpsc::channel();
        let join = thread::spawn(move || {
            loop {
                match rx.recv().unwrap() {
                    AsyncIoMsg::Bytes(buf) => io.write_all(&buf).unwrap(),
                    AsyncIoMsg::Flush => io.flush().unwrap(),
                    AsyncIoMsg::Eof => return,
                }
            }
        });

        AsyncIoWriter {
            sender: tx,
            join: Some(join),
        }
    }

    /// Write data to IO, without copying
    ///
    /// As an optimization, when `buf` is already an owned
    /// `Vec`, it can be sent over channel without copying.
    pub fn write_nocopy(&mut self, buf: Vec<u8>) -> Result<()> {
        try!(self.sender
            .send(AsyncIoMsg::Bytes(buf))
            .map_err(|_| -> Error { ErrorKind::SendError.into() }));
        Ok(())
    }
}

impl io::Write for AsyncIoWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let _ = self.sender.send(AsyncIoMsg::Bytes(buf.to_vec())).unwrap();
        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        let _ = self.sender.send(AsyncIoMsg::Flush);
        Ok(())
    }
}

impl Drop for AsyncIoWriter {
    fn drop(&mut self) {
        let _ = self.sender.send(AsyncIoMsg::Eof);
        let _ = self.join.take().unwrap().join();
    }
}

/// Create `Streamer` drain
pub fn stream<W: io::Write + Send, F: format::Format>(io: W, format: F) -> Streamer<W, F> {
    Streamer::new(io, format)
}

/// Create `AsyncStreamer` drain
pub fn async_stream<W: io::Write + Send, F: format::Format>(io: W, format: F) -> Streamer<W, F> {
    Streamer::new(io, format)
}

/// Create a Discard drain
pub fn discard() -> Discard {
    Discard
}

/// Filter by `cond` closure
pub fn filter<D: Drain, F: 'static + Send + Sync + Fn(&RecordInfo) -> bool>(cond: F,
                                                                            d: D)
                                                                            -> Filter<D> {
    Filter::new(d, cond)
}

/// Filter by log level
pub fn filter_level<D: Drain>(level: Level, d: D) -> FilterLevel<D> {
    FilterLevel::new(d, level)
}

/// Create Duplicate drain
pub fn duplicate<D1: Drain, D2: Drain>(d1: D1, d2: D2) -> Duplicate<D1, D2> {
    Duplicate::new(d1, d2)
}

/// Create Failover drain
pub fn failover<D1: Drain, D2: Drain>(d1: D1, d2: D2) -> Failover<D1, D2> {
    Failover::new(d1, d2)
}
<|endoftext|>