<commit_before>//! Stack slots.
//!
//! The `StackSlotData` struct keeps track of a single stack slot in a function.
//!

use entity::{PrimaryMap, Keys};
use ir::{Type, StackSlot};
use packed_option::PackedOption;
use std::fmt;
use std::ops::Index;
use std::str::FromStr;

/// The size of an object on the stack, or the size of a stack frame.
///
/// We don't use `usize` to represent object sizes on the target platform because Cretonne supports
/// cross-compilation, and `usize` is a type that depends on the host platform, not the target
/// platform.
pub type StackSize = u32;

/// A stack offset.
///
/// The location of a stack offset relative to a stack pointer or frame pointer.
pub type StackOffset = i32;

/// The kind of a stack slot.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StackSlotKind {
    /// A spill slot. This is a stack slot created by the register allocator.
    SpillSlot,

    /// A local variable. This is a chunk of local stack memory for use by the `stack_load` and
    /// `stack_store` instructions.
    Local,

    /// An incoming function argument.
    ///
    /// If the current function has more arguments than fits in registers, the remaining arguments
    /// are passed on the stack by the caller. These incoming arguments are represented as SSA
    /// values assigned to incoming stack slots.
    IncomingArg,

    /// An outgoing function argument.
    ///
    /// When preparing to call a function whose arguments don't fit in registers, outgoing argument
    /// stack slots are used to represent individual arguments in the outgoing call frame. These
    /// stack slots are only valid while setting up a call.
    OutgoingArg,

    /// An emergency spill slot.
    ///
    /// Emergency slots are allocated late when the register's constraint solver needs extra space
    /// to shuffle registers around. The are only used briefly, and can be reused.
    EmergencySlot,
}

impl FromStr for StackSlotKind {
    type Err = ();

    fn from_str(s: &str) -> Result<StackSlotKind, ()> {
        use self::StackSlotKind::*;
        match s {
            "local" => Ok(Local),
            "spill_slot" => Ok(SpillSlot),
            "incoming_arg" => Ok(IncomingArg),
            "outgoing_arg" => Ok(OutgoingArg),
            "emergency_slot" => Ok(EmergencySlot),
            _ => Err(()),
        }
    }
}

impl fmt::Display for StackSlotKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::StackSlotKind::*;
        f.write_str(match *self {
            Local => "local",
            SpillSlot => "spill_slot",
            IncomingArg => "incoming_arg",
            OutgoingArg => "outgoing_arg",
            EmergencySlot => "emergency_slot",
        })
    }
}

/// Contents of a stack slot.
#[derive(Clone, Debug)]
pub struct StackSlotData {
    /// The kind of stack slot.
    pub kind: StackSlotKind,

    /// Size of stack slot in bytes.
    pub size: StackSize,

    /// Offset of stack slot relative to the stack pointer in the caller.
    ///
    /// On Intel ISAs, the base address is the stack pointer *before* the return address was
    /// pushed. On RISC ISAs, the base address is the value of the stack pointer on entry to the
    /// function.
    ///
    /// For `OutgoingArg` stack slots, the offset is relative to the current function's stack
    /// pointer immediately before the call.
    pub offset: StackOffset,
}

impl StackSlotData {
    /// Create a stack slot with the specified byte size.
    pub fn new(kind: StackSlotKind, size: StackSize) -> StackSlotData {
        StackSlotData {
            kind,
            size,
            offset: 0,
        }
    }

    /// Get the alignment in bytes of this stack slot given the stack pointer alignment.
    pub fn alignment(&self, max_align: StackSize) -> StackSize {
        debug_assert!(max_align.is_power_of_two());
        // We want to find the largest power of two that divides both `self.size` and `max_align`.
        // That is the same as isolating the rightmost bit in `x`.
        let x = self.size | max_align;
        // C.f. Hacker's delight.
        x & x.wrapping_neg()
    }
}

impl fmt::Display for StackSlotData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {}", self.kind, self.size)?;
        if self.offset != 0 {
            write!(f, ", offset {}", self.offset)?;
        }
        Ok(())
    }
}

/// Stack frame manager.
///
/// Keep track of all the stack slots used by a function.
#[derive(Clone, Debug)]
pub struct StackSlots {
    /// All allocated stack slots.
    slots: PrimaryMap<StackSlot, StackSlotData>,

    /// All the outgoing stack slots, ordered by offset.
    outgoing: Vec<StackSlot>,

    /// All the emergency slots.
    emergency: Vec<StackSlot>,

    /// The total size of the stack frame.
    ///
    /// This is the distance from the stack pointer in the current function to the stack pointer in
    /// the calling function, so it includes a pushed return address as well as space for outgoing
    /// call arguments.
    ///
    /// This is computed by the `layout()` method.
    pub frame_size: Option<StackSize>,
}

/// Stack slot manager functions that behave mostly like an entity map.
impl StackSlots {
    /// Create an empty stack slot manager.
    pub fn new() -> StackSlots {
        StackSlots {
            slots: PrimaryMap::new(),
            outgoing: Vec::new(),
            emergency: Vec::new(),
            frame_size: None,
        }
    }

    /// Clear out everything.
    pub fn clear(&mut self) {
        self.slots.clear();
        self.outgoing.clear();
        self.emergency.clear();
        self.frame_size = None;
    }

    /// Allocate a new stack slot.
    ///
    /// This function should be primarily used by the text format parser. There are more convenient
    /// functions for creating specific kinds of stack slots below.
    pub fn push(&mut self, data: StackSlotData) -> StackSlot {
        self.slots.push(data)
    }

    /// Check if `ss` is a valid stack slot reference.
    pub fn is_valid(&self, ss: StackSlot) -> bool {
        self.slots.is_valid(ss)
    }

    /// Set the offset of a stack slot.
    pub fn set_offset(&mut self, ss: StackSlot, offset: StackOffset) {
        self.slots[ss].offset = offset;
    }

    /// Get an iterator over all the stack slot keys.
    pub fn keys(&self) -> Keys<StackSlot> {
        self.slots.keys()
    }

    /// Get a reference to the next stack slot that would be created by `push()`.
    ///
    /// This should just be used by the parser.
    pub fn next_key(&self) -> StackSlot {
        self.slots.next_key()
    }
}

impl Index<StackSlot> for StackSlots {
    type Output = StackSlotData;

    fn index(&self, ss: StackSlot) -> &StackSlotData {
        &self.slots[ss]
    }
}

/// Higher-level stack frame manipulation functions.
impl StackSlots {
    /// Create a new spill slot for spilling values of type `ty`.
    pub fn make_spill_slot(&mut self, ty: Type) -> StackSlot {
        self.push(StackSlotData::new(StackSlotKind::SpillSlot, ty.bytes()))
    }

    /// Create a stack slot representing an incoming function argument.
    pub fn make_incoming_arg(&mut self, ty: Type, offset: StackOffset) -> StackSlot {
        let mut data = StackSlotData::new(StackSlotKind::IncomingArg, ty.bytes());
        assert!(offset <= StackOffset::max_value() - data.size as StackOffset);
        data.offset = offset;
        self.push(data)
    }

    /// Get a stack slot representing an outgoing argument.
    ///
    /// This may create a new stack slot, or reuse an existing outgoing stack slot with the
    /// requested offset and size.
    ///
    /// The requested offset is relative to this function's stack pointer immediately before making
    /// the call.
    pub fn get_outgoing_arg(&mut self, ty: Type, offset: StackOffset) -> StackSlot {
        let size = ty.bytes();

        // Look for an existing outgoing stack slot with the same offset and size.
        let inspos = match self.outgoing.binary_search_by_key(&(offset, size), |&ss| {
            (self[ss].offset, self[ss].size)
        }) {
            Ok(idx) => return self.outgoing[idx],
            Err(idx) => idx,
        };

        // No existing slot found. Make one and insert it into `outgoing`.
        let mut data = StackSlotData::new(StackSlotKind::OutgoingArg, size);
        assert!(offset <= StackOffset::max_value() - size as StackOffset);
        data.offset = offset;
        let ss = self.slots.push(data);
        self.outgoing.insert(inspos, ss);
        ss
    }

    /// Get an emergency spill slot that can be used to store a `ty` value.
    ///
    /// This may allocate a new slot, or it may reuse an existing emergency spill slot, excluding
    /// any slots in the `in_use` list.
    pub fn get_emergency_slot(
        &mut self,
        ty: Type,
        in_use: &[PackedOption<StackSlot>],
    ) -> StackSlot {
        let size = ty.bytes();

        // Find the smallest existing slot that can fit the type.
        if let Some(&ss) = self.emergency
            .iter()
            .filter(|&&ss| self[ss].size >= size && !in_use.contains(&ss.into()))
            .min_by_key(|&&ss| self[ss].size)
        {
            return ss;
        }

        // Alternatively, use the largest available slot and make it larger.
        if let Some(&ss) = self.emergency
            .iter()
            .filter(|&&ss| !in_use.contains(&ss.into()))
            .max_by_key(|&&ss| self[ss].size)
        {
            self.slots[ss].size = size;
            return ss;
        }

        // No existing slot found. Make one and insert it into `emergency`.
        let data = StackSlotData::new(StackSlotKind::EmergencySlot, size);
        let ss = self.slots.push(data);
        self.emergency.push(ss);
        ss
    }
}

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

    #[test]
    fn stack_slot() {
        let mut func = Function::new();

        let ss0 = func.create_stack_slot(StackSlotData::new(StackSlotKind::IncomingArg, 4));
        let ss1 = func.create_stack_slot(StackSlotData::new(StackSlotKind::SpillSlot, 8));
        assert_eq!(ss0.to_string(), "ss0");
        assert_eq!(ss1.to_string(), "ss1");

        assert_eq!(func.stack_slots[ss0].size, 4);
        assert_eq!(func.stack_slots[ss1].size, 8);

        assert_eq!(func.stack_slots[ss0].to_string(), "incoming_arg 4");
        assert_eq!(func.stack_slots[ss1].to_string(), "spill_slot 8");
    }

    #[test]
    fn outgoing() {
        let mut sss = StackSlots::new();

        let ss0 = sss.get_outgoing_arg(types::I32, 8);
        let ss1 = sss.get_outgoing_arg(types::I32, 4);
        let ss2 = sss.get_outgoing_arg(types::I64, 8);

        assert_eq!(sss[ss0].offset, 8);
        assert_eq!(sss[ss0].size, 4);

        assert_eq!(sss[ss1].offset, 4);
        assert_eq!(sss[ss1].size, 4);

        assert_eq!(sss[ss2].offset, 8);
        assert_eq!(sss[ss2].size, 8);

        assert_eq!(sss.get_outgoing_arg(types::I32, 8), ss0);
        assert_eq!(sss.get_outgoing_arg(types::I32, 4), ss1);
        assert_eq!(sss.get_outgoing_arg(types::I64, 8), ss2);
    }

    #[test]
    fn alignment() {
        let slot = StackSlotData::new(StackSlotKind::SpillSlot, 8);

        assert_eq!(slot.alignment(4), 4);
        assert_eq!(slot.alignment(8), 8);
        assert_eq!(slot.alignment(16), 8);

        let slot2 = StackSlotData::new(StackSlotKind::Local, 24);

        assert_eq!(slot2.alignment(4), 4);
        assert_eq!(slot2.alignment(8), 8);
        assert_eq!(slot2.alignment(16), 8);
        assert_eq!(slot2.alignment(32), 8);
    }

    #[test]
    fn emergency() {
        let mut sss = StackSlots::new();

        let ss0 = sss.get_emergency_slot(types::I32, &[]);
        assert_eq!(sss[ss0].size, 4);

        // When a smaller size is requested, we should simply get the same slot back.
        assert_eq!(sss.get_emergency_slot(types::I8, &[]), ss0);
        assert_eq!(sss[ss0].size, 4);
        assert_eq!(sss.get_emergency_slot(types::F32, &[]), ss0);
        assert_eq!(sss[ss0].size, 4);

        // Ask for a larger size and the slot should grow.
        assert_eq!(sss.get_emergency_slot(types::F64, &[]), ss0);
        assert_eq!(sss[ss0].size, 8);

        // When one slot is in use, we should get a new one.
        let ss1 = sss.get_emergency_slot(types::I32, &[None.into(), ss0.into()]);
        assert_eq!(sss[ss0].size, 8);
        assert_eq!(sss[ss1].size, 4);

        // Now we should get the smallest fit of the two available slots.
        assert_eq!(sss.get_emergency_slot(types::F32, &[]), ss1);
        assert_eq!(sss.get_emergency_slot(types::F64, &[]), ss0);
    }
}
<commit_msg>Enforce a 4-byte minimum spill slot size.<commit_after>//! Stack slots.
//!
//! The `StackSlotData` struct keeps track of a single stack slot in a function.
//!

use entity::{PrimaryMap, Keys};
use ir::{Type, StackSlot};
use packed_option::PackedOption;
use std::cmp;
use std::fmt;
use std::ops::Index;
use std::str::FromStr;

/// The size of an object on the stack, or the size of a stack frame.
///
/// We don't use `usize` to represent object sizes on the target platform because Cretonne supports
/// cross-compilation, and `usize` is a type that depends on the host platform, not the target
/// platform.
pub type StackSize = u32;

/// A stack offset.
///
/// The location of a stack offset relative to a stack pointer or frame pointer.
pub type StackOffset = i32;

/// The minimum size of a spill slot in bytes.
///
/// ISA implementations are allowed to assume that small types like `b1` and `i8` get a full 4-byte
/// spill slot.
const MIN_SPILL_SLOT_SIZE: StackSize = 4;

/// Get the spill slot size to use for `ty`.
fn spill_size(ty: Type) -> StackSize {
    cmp::max(MIN_SPILL_SLOT_SIZE, ty.bytes())
}

/// The kind of a stack slot.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StackSlotKind {
    /// A spill slot. This is a stack slot created by the register allocator.
    SpillSlot,

    /// A local variable. This is a chunk of local stack memory for use by the `stack_load` and
    /// `stack_store` instructions.
    Local,

    /// An incoming function argument.
    ///
    /// If the current function has more arguments than fits in registers, the remaining arguments
    /// are passed on the stack by the caller. These incoming arguments are represented as SSA
    /// values assigned to incoming stack slots.
    IncomingArg,

    /// An outgoing function argument.
    ///
    /// When preparing to call a function whose arguments don't fit in registers, outgoing argument
    /// stack slots are used to represent individual arguments in the outgoing call frame. These
    /// stack slots are only valid while setting up a call.
    OutgoingArg,

    /// An emergency spill slot.
    ///
    /// Emergency slots are allocated late when the register's constraint solver needs extra space
    /// to shuffle registers around. The are only used briefly, and can be reused.
    EmergencySlot,
}

impl FromStr for StackSlotKind {
    type Err = ();

    fn from_str(s: &str) -> Result<StackSlotKind, ()> {
        use self::StackSlotKind::*;
        match s {
            "local" => Ok(Local),
            "spill_slot" => Ok(SpillSlot),
            "incoming_arg" => Ok(IncomingArg),
            "outgoing_arg" => Ok(OutgoingArg),
            "emergency_slot" => Ok(EmergencySlot),
            _ => Err(()),
        }
    }
}

impl fmt::Display for StackSlotKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::StackSlotKind::*;
        f.write_str(match *self {
            Local => "local",
            SpillSlot => "spill_slot",
            IncomingArg => "incoming_arg",
            OutgoingArg => "outgoing_arg",
            EmergencySlot => "emergency_slot",
        })
    }
}

/// Contents of a stack slot.
#[derive(Clone, Debug)]
pub struct StackSlotData {
    /// The kind of stack slot.
    pub kind: StackSlotKind,

    /// Size of stack slot in bytes.
    pub size: StackSize,

    /// Offset of stack slot relative to the stack pointer in the caller.
    ///
    /// On Intel ISAs, the base address is the stack pointer *before* the return address was
    /// pushed. On RISC ISAs, the base address is the value of the stack pointer on entry to the
    /// function.
    ///
    /// For `OutgoingArg` stack slots, the offset is relative to the current function's stack
    /// pointer immediately before the call.
    pub offset: StackOffset,
}

impl StackSlotData {
    /// Create a stack slot with the specified byte size.
    pub fn new(kind: StackSlotKind, size: StackSize) -> StackSlotData {
        StackSlotData {
            kind,
            size,
            offset: 0,
        }
    }

    /// Get the alignment in bytes of this stack slot given the stack pointer alignment.
    pub fn alignment(&self, max_align: StackSize) -> StackSize {
        debug_assert!(max_align.is_power_of_two());
        // We want to find the largest power of two that divides both `self.size` and `max_align`.
        // That is the same as isolating the rightmost bit in `x`.
        let x = self.size | max_align;
        // C.f. Hacker's delight.
        x & x.wrapping_neg()
    }
}

impl fmt::Display for StackSlotData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {}", self.kind, self.size)?;
        if self.offset != 0 {
            write!(f, ", offset {}", self.offset)?;
        }
        Ok(())
    }
}

/// Stack frame manager.
///
/// Keep track of all the stack slots used by a function.
#[derive(Clone, Debug)]
pub struct StackSlots {
    /// All allocated stack slots.
    slots: PrimaryMap<StackSlot, StackSlotData>,

    /// All the outgoing stack slots, ordered by offset.
    outgoing: Vec<StackSlot>,

    /// All the emergency slots.
    emergency: Vec<StackSlot>,

    /// The total size of the stack frame.
    ///
    /// This is the distance from the stack pointer in the current function to the stack pointer in
    /// the calling function, so it includes a pushed return address as well as space for outgoing
    /// call arguments.
    ///
    /// This is computed by the `layout()` method.
    pub frame_size: Option<StackSize>,
}

/// Stack slot manager functions that behave mostly like an entity map.
impl StackSlots {
    /// Create an empty stack slot manager.
    pub fn new() -> StackSlots {
        StackSlots {
            slots: PrimaryMap::new(),
            outgoing: Vec::new(),
            emergency: Vec::new(),
            frame_size: None,
        }
    }

    /// Clear out everything.
    pub fn clear(&mut self) {
        self.slots.clear();
        self.outgoing.clear();
        self.emergency.clear();
        self.frame_size = None;
    }

    /// Allocate a new stack slot.
    ///
    /// This function should be primarily used by the text format parser. There are more convenient
    /// functions for creating specific kinds of stack slots below.
    pub fn push(&mut self, data: StackSlotData) -> StackSlot {
        self.slots.push(data)
    }

    /// Check if `ss` is a valid stack slot reference.
    pub fn is_valid(&self, ss: StackSlot) -> bool {
        self.slots.is_valid(ss)
    }

    /// Set the offset of a stack slot.
    pub fn set_offset(&mut self, ss: StackSlot, offset: StackOffset) {
        self.slots[ss].offset = offset;
    }

    /// Get an iterator over all the stack slot keys.
    pub fn keys(&self) -> Keys<StackSlot> {
        self.slots.keys()
    }

    /// Get a reference to the next stack slot that would be created by `push()`.
    ///
    /// This should just be used by the parser.
    pub fn next_key(&self) -> StackSlot {
        self.slots.next_key()
    }
}

impl Index<StackSlot> for StackSlots {
    type Output = StackSlotData;

    fn index(&self, ss: StackSlot) -> &StackSlotData {
        &self.slots[ss]
    }
}

/// Higher-level stack frame manipulation functions.
impl StackSlots {
    /// Create a new spill slot for spilling values of type `ty`.
    pub fn make_spill_slot(&mut self, ty: Type) -> StackSlot {
        self.push(StackSlotData::new(StackSlotKind::SpillSlot, spill_size(ty)))
    }

    /// Create a stack slot representing an incoming function argument.
    pub fn make_incoming_arg(&mut self, ty: Type, offset: StackOffset) -> StackSlot {
        let mut data = StackSlotData::new(StackSlotKind::IncomingArg, ty.bytes());
        assert!(offset <= StackOffset::max_value() - data.size as StackOffset);
        data.offset = offset;
        self.push(data)
    }

    /// Get a stack slot representing an outgoing argument.
    ///
    /// This may create a new stack slot, or reuse an existing outgoing stack slot with the
    /// requested offset and size.
    ///
    /// The requested offset is relative to this function's stack pointer immediately before making
    /// the call.
    pub fn get_outgoing_arg(&mut self, ty: Type, offset: StackOffset) -> StackSlot {
        let size = ty.bytes();

        // Look for an existing outgoing stack slot with the same offset and size.
        let inspos = match self.outgoing.binary_search_by_key(&(offset, size), |&ss| {
            (self[ss].offset, self[ss].size)
        }) {
            Ok(idx) => return self.outgoing[idx],
            Err(idx) => idx,
        };

        // No existing slot found. Make one and insert it into `outgoing`.
        let mut data = StackSlotData::new(StackSlotKind::OutgoingArg, size);
        assert!(offset <= StackOffset::max_value() - size as StackOffset);
        data.offset = offset;
        let ss = self.slots.push(data);
        self.outgoing.insert(inspos, ss);
        ss
    }

    /// Get an emergency spill slot that can be used to store a `ty` value.
    ///
    /// This may allocate a new slot, or it may reuse an existing emergency spill slot, excluding
    /// any slots in the `in_use` list.
    pub fn get_emergency_slot(
        &mut self,
        ty: Type,
        in_use: &[PackedOption<StackSlot>],
    ) -> StackSlot {
        let size = spill_size(ty);

        // Find the smallest existing slot that can fit the type.
        if let Some(&ss) = self.emergency
            .iter()
            .filter(|&&ss| self[ss].size >= size && !in_use.contains(&ss.into()))
            .min_by_key(|&&ss| self[ss].size)
        {
            return ss;
        }

        // Alternatively, use the largest available slot and make it larger.
        if let Some(&ss) = self.emergency
            .iter()
            .filter(|&&ss| !in_use.contains(&ss.into()))
            .max_by_key(|&&ss| self[ss].size)
        {
            self.slots[ss].size = size;
            return ss;
        }

        // No existing slot found. Make one and insert it into `emergency`.
        let data = StackSlotData::new(StackSlotKind::EmergencySlot, size);
        let ss = self.slots.push(data);
        self.emergency.push(ss);
        ss
    }
}

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

    #[test]
    fn stack_slot() {
        let mut func = Function::new();

        let ss0 = func.create_stack_slot(StackSlotData::new(StackSlotKind::IncomingArg, 4));
        let ss1 = func.create_stack_slot(StackSlotData::new(StackSlotKind::SpillSlot, 8));
        assert_eq!(ss0.to_string(), "ss0");
        assert_eq!(ss1.to_string(), "ss1");

        assert_eq!(func.stack_slots[ss0].size, 4);
        assert_eq!(func.stack_slots[ss1].size, 8);

        assert_eq!(func.stack_slots[ss0].to_string(), "incoming_arg 4");
        assert_eq!(func.stack_slots[ss1].to_string(), "spill_slot 8");
    }

    #[test]
    fn outgoing() {
        let mut sss = StackSlots::new();

        let ss0 = sss.get_outgoing_arg(types::I32, 8);
        let ss1 = sss.get_outgoing_arg(types::I32, 4);
        let ss2 = sss.get_outgoing_arg(types::I64, 8);

        assert_eq!(sss[ss0].offset, 8);
        assert_eq!(sss[ss0].size, 4);

        assert_eq!(sss[ss1].offset, 4);
        assert_eq!(sss[ss1].size, 4);

        assert_eq!(sss[ss2].offset, 8);
        assert_eq!(sss[ss2].size, 8);

        assert_eq!(sss.get_outgoing_arg(types::I32, 8), ss0);
        assert_eq!(sss.get_outgoing_arg(types::I32, 4), ss1);
        assert_eq!(sss.get_outgoing_arg(types::I64, 8), ss2);
    }

    #[test]
    fn alignment() {
        let slot = StackSlotData::new(StackSlotKind::SpillSlot, 8);

        assert_eq!(slot.alignment(4), 4);
        assert_eq!(slot.alignment(8), 8);
        assert_eq!(slot.alignment(16), 8);

        let slot2 = StackSlotData::new(StackSlotKind::Local, 24);

        assert_eq!(slot2.alignment(4), 4);
        assert_eq!(slot2.alignment(8), 8);
        assert_eq!(slot2.alignment(16), 8);
        assert_eq!(slot2.alignment(32), 8);
    }

    #[test]
    fn emergency() {
        let mut sss = StackSlots::new();

        let ss0 = sss.get_emergency_slot(types::I32, &[]);
        assert_eq!(sss[ss0].size, 4);

        // When a smaller size is requested, we should simply get the same slot back.
        assert_eq!(sss.get_emergency_slot(types::I8, &[]), ss0);
        assert_eq!(sss[ss0].size, 4);
        assert_eq!(sss.get_emergency_slot(types::F32, &[]), ss0);
        assert_eq!(sss[ss0].size, 4);

        // Ask for a larger size and the slot should grow.
        assert_eq!(sss.get_emergency_slot(types::F64, &[]), ss0);
        assert_eq!(sss[ss0].size, 8);

        // When one slot is in use, we should get a new one.
        let ss1 = sss.get_emergency_slot(types::I32, &[None.into(), ss0.into()]);
        assert_eq!(sss[ss0].size, 8);
        assert_eq!(sss[ss1].size, 4);

        // Now we should get the smallest fit of the two available slots.
        assert_eq!(sss.get_emergency_slot(types::F32, &[]), ss1);
        assert_eq!(sss.get_emergency_slot(types::F64, &[]), ss0);
    }
}
<|endoftext|>


<commit_before>use nes::nes::NESRuntimeOptions;

/// Logs a message to stdout with a given prefix if the emulator was started
/// with the verbose flag set.
pub fn log<P, T>(prefix: P, text: T, runtime_options: &NESRuntimeOptions) where P: Into<String>, T: Into<String> {
    if runtime_options.verbose {
        println!("[{}] {}", prefix.into(), text.into());
    }
}
<commit_msg>Added missing copyright notice<commit_after>// Copyright 2016 Walter Kuppens.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use nes::nes::NESRuntimeOptions;

/// Logs a message to stdout with a given prefix if the emulator was started
/// with the verbose flag set.
pub fn log<P, T>(prefix: P, text: T, runtime_options: &NESRuntimeOptions) where P: Into<String>, T: Into<String> {
    if runtime_options.verbose {
        println!("[{}] {}", prefix.into(), text.into());
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "mysql")]
extern crate dotenv;

use std::collections::HashMap;

#[cfg(feature = "mysql")]
use diesel::prelude::*;

#[cfg(feature = "mysql")]
use diesel::mysql::MysqlConnection;

use chrono::NaiveDateTime;

pub enum DbResponse {
    Success,
    Failed(&'static str),
}

#[cfg_attr(feature = "mysql", derive(Queryable))]
#[derive(Clone, Debug)]
pub struct Factoid {
    pub name: String,
    pub idx: i32,
    pub content: String,
    pub author: String,
    pub created: NaiveDateTime,
}

#[cfg(feature = "mysql")]
use self::mysql::factoids;
#[cfg_attr(feature = "mysql", derive(Insertable))]
#[cfg_attr(feature = "mysql", table_name="factoids")]
pub struct NewFactoid<'a> {
    pub name: &'a str,
    pub idx: i32,
    pub content: &'a str,
    pub author: &'a str,
    pub created: NaiveDateTime,
}

pub trait Database: Send {
    fn insert(&mut self, factoid: &NewFactoid) -> DbResponse;
    fn get(&self, name: &str, idx: i32) -> Option<Factoid>;
    fn delete(&mut self, name: &str, idx: i32) -> DbResponse;
    fn count(&self, name: &str) -> Result<i32, &'static str>;
}

// HashMap
impl Database for HashMap<(String, i32), Factoid> {
    fn insert(&mut self, factoid: &NewFactoid) -> DbResponse {
        let factoid = Factoid {
            name: String::from(factoid.name),
            idx: factoid.idx,
            content: factoid.content.to_string(),
            author: factoid.author.to_string(),
            created: factoid.created,
        };

        let name = String::from(factoid.name.clone());
        match self.insert((name, factoid.idx), factoid) {
            None => DbResponse::Success,
            Some(_) => DbResponse::Failed("Factoid was overwritten"),
        }
    }

    fn get(&self, name: &str, idx: i32) -> Option<Factoid> {
        self.get(&(String::from(name), idx)).map(|f| f.clone())
    }

    fn delete(&mut self, name: &str, idx: i32) -> DbResponse {
        match self.remove(&(String::from(name), idx)) {
            Some(_) => DbResponse::Success,
            None => DbResponse::Failed("Factoid not found"),
        }
    }

    fn count(&self, name: &str) -> Result<i32, &'static str> {
        Ok(self.iter()
               .filter(|&(&(ref n, _), _)| n == name)
               .count() as i32)
    }
}

// Diesel automatically define the factoids module as public.
// For now this is how we keep it private.
#[cfg(feature = "mysql")]
mod mysql {
    table! {
        factoids (name, idx) {
            name -> Varchar,
            idx -> Integer,
            content -> Text,
            author -> Varchar,
            created -> Timestamp,
        }
    }
}

#[cfg(feature = "mysql")]
impl Database for MysqlConnection {
    fn insert(&mut self, factoid: &NewFactoid) -> DbResponse {
        use diesel;
        match diesel::insert_into(factoids::table)
                  .values(factoid)
                  .execute(self) {
            Ok(_) => DbResponse::Success,
            Err(e) => {
                error!("DB Insertion Error: \"{}\"", e);
                DbResponse::Failed("Failed to add factoid")
            }
        }
    }

    fn get(&self, name: &str, idx: i32) -> Option<Factoid> {
        factoids::table.find((name, idx)).first(self).ok()
    }

    fn delete(&mut self, name: &str, idx: i32) -> DbResponse {
        use diesel;
        use self::factoids::columns;
        match diesel::delete(factoids::table
                                 .filter(columns::name.eq(name))
                                 .filter(columns::idx.eq(idx)))
                      .execute(self) {
            Ok(v) => {
                if v > 0 {
                    DbResponse::Success
                } else {
                    DbResponse::Failed("Could not find any factoid with that name")
                }
            }
            Err(e) => {
                error!("DB Deletion Error: \"{}\"", e);
                DbResponse::Failed("Failed to delete factoid")
            }
        }
    }

    fn count(&self, name: &str) -> Result<i32, &'static str> {
        let count: Result<i64, _> = factoids::table
            .filter(factoids::columns::name.eq(name))
            .count()
            .first(self);

        match count {
            Ok(c) => Ok(c as i32),
            Err(_) => Err("Database Error"),
        }
    }
}
<commit_msg>Log all database errors<commit_after>#[cfg(feature = "mysql")]
extern crate dotenv;

use std::collections::HashMap;

#[cfg(feature = "mysql")]
use diesel::prelude::*;

#[cfg(feature = "mysql")]
use diesel::mysql::MysqlConnection;

use chrono::NaiveDateTime;

pub enum DbResponse {
    Success,
    Failed(&'static str),
}

#[cfg_attr(feature = "mysql", derive(Queryable))]
#[derive(Clone, Debug)]
pub struct Factoid {
    pub name: String,
    pub idx: i32,
    pub content: String,
    pub author: String,
    pub created: NaiveDateTime,
}

#[cfg(feature = "mysql")]
use self::mysql::factoids;
#[cfg_attr(feature = "mysql", derive(Insertable))]
#[cfg_attr(feature = "mysql", table_name="factoids")]
pub struct NewFactoid<'a> {
    pub name: &'a str,
    pub idx: i32,
    pub content: &'a str,
    pub author: &'a str,
    pub created: NaiveDateTime,
}

pub trait Database: Send {
    fn insert(&mut self, factoid: &NewFactoid) -> DbResponse;
    fn get(&self, name: &str, idx: i32) -> Option<Factoid>;
    fn delete(&mut self, name: &str, idx: i32) -> DbResponse;
    fn count(&self, name: &str) -> Result<i32, &'static str>;
}

// HashMap
impl Database for HashMap<(String, i32), Factoid> {
    fn insert(&mut self, factoid: &NewFactoid) -> DbResponse {
        let factoid = Factoid {
            name: String::from(factoid.name),
            idx: factoid.idx,
            content: factoid.content.to_string(),
            author: factoid.author.to_string(),
            created: factoid.created,
        };

        let name = String::from(factoid.name.clone());
        match self.insert((name, factoid.idx), factoid) {
            None => DbResponse::Success,
            Some(_) => DbResponse::Failed("Factoid was overwritten"),
        }
    }

    fn get(&self, name: &str, idx: i32) -> Option<Factoid> {
        self.get(&(String::from(name), idx)).map(|f| f.clone())
    }

    fn delete(&mut self, name: &str, idx: i32) -> DbResponse {
        match self.remove(&(String::from(name), idx)) {
            Some(_) => DbResponse::Success,
            None => DbResponse::Failed("Factoid not found"),
        }
    }

    fn count(&self, name: &str) -> Result<i32, &'static str> {
        Ok(self.iter()
               .filter(|&(&(ref n, _), _)| n == name)
               .count() as i32)
    }
}

// Diesel automatically define the factoids module as public.
// For now this is how we keep it private.
#[cfg(feature = "mysql")]
mod mysql {
    table! {
        factoids (name, idx) {
            name -> Varchar,
            idx -> Integer,
            content -> Text,
            author -> Varchar,
            created -> Timestamp,
        }
    }
}

#[cfg(feature = "mysql")]
impl Database for MysqlConnection {
    fn insert(&mut self, factoid: &NewFactoid) -> DbResponse {
        use diesel;
        match diesel::insert_into(factoids::table)
                  .values(factoid)
                  .execute(self) {
            Ok(_) => DbResponse::Success,
            Err(e) => {
                error!("DB Insertion Error: {}", e);
                DbResponse::Failed("Failed to add factoid")
            }
        }
    }

    fn get(&self, name: &str, idx: i32) -> Option<Factoid> {
        match factoids::table.find((name, idx)).first(self) {
            Ok(f) => Ok(f),
            Err(e) => {
                error!("DB Count Error: {}", e);
                None
            },
        }
    }

    fn delete(&mut self, name: &str, idx: i32) -> DbResponse {
        use diesel;
        use self::factoids::columns;
        match diesel::delete(factoids::table
                                 .filter(columns::name.eq(name))
                                 .filter(columns::idx.eq(idx)))
                      .execute(self) {
            Ok(v) => {
                if v > 0 {
                    DbResponse::Success
                } else {
                    DbResponse::Failed("Could not find any factoid with that name")
                }
            }
            Err(e) => {
                error!("DB Deletion Error: {}", e);
                DbResponse::Failed("Failed to delete factoid")
            }
        }
    }

    fn count(&self, name: &str) -> Result<i32, &'static str> {
        let count: Result<i64, _> = factoids::table
            .filter(factoids::columns::name.eq(name))
            .count()
            .first(self);

        match count {
            Ok(c) => Ok(c as i32),
            Err(e) => {
                error!("DB Count Error: {}", e);
                Err("Database Error")
            },
        }
    }
}
<|endoftext|>


<commit_before>//use Tensor;
//use tensor;

/// To use this macro, import Numeric as follows:
///
/// ```text
/// #[macro_use(tensor)]
/// extern crate numeric;
/// ```
///
/// # Examples
///
/// 1D tensor (vector):
///
/// ```
/// # #[macro_use] extern crate numeric; fn main() {
/// let x = tensor![1.0, 2.0, 3.0];
/// # assert!(x == numeric::Tensor::new(vec![1.0, 2.0, 3.0]));
/// # }
/// ```
///
/// 2D tensor (matrix):
///
/// ```
/// # #[macro_use] extern crate numeric; use numeric::tensor; fn main() {
/// let x = tensor![1, 0; 3, 2; 5, 4];
/// # assert!(x == numeric::Tensor::new(vec![1, 0, 3, 2, 5, 4]).reshape(&[3, 2]));
/// # }
/// ```
///
/// 1D tensor filled with a single value:
///
/// ```
/// # #[macro_use] extern crate numeric; use numeric::tensor; fn main() {
/// let x = tensor![2.0; 5];
/// # assert!(x == numeric::Tensor::new(vec![2.0, 2.0, 2.0, 2.0, 2.0]));
/// # }
/// ```
#[macro_export]
macro_rules! tensor {
    ($elem:expr; $n:expr) => (
        numeric::Tensor::filled(&[$n], $elem)
    );
    ($($x:expr),*) => (
        numeric::Tensor::new(vec![$($x),*])
    );
    ($($($x:expr),*);*) => ({
        let mut v = Vec::new();
        let mut n = 0;
        $(
            n += 1;
            $(v.push($x);)*
        )*
        numeric::Tensor::new(v).reshape(&[n, -1])
    });
}
<commit_msg>DOC: Minor fix for tensor!<commit_after>//use Tensor;
//use tensor;

/// Macro for creating vectors and matrices.
///
/// To use this macro, import Numeric as follows:
///
/// ```text
/// #[macro_use(tensor)]
/// extern crate numeric;
/// ```
///
/// # Examples
///
/// 1D tensor (vector):
///
/// ```
/// # #[macro_use] extern crate numeric; fn main() {
/// let x = tensor![1.0, 2.0, 3.0];
/// # assert!(x == numeric::Tensor::new(vec![1.0, 2.0, 3.0]));
/// # }
/// ```
///
/// 2D tensor (matrix):
///
/// ```
/// # #[macro_use] extern crate numeric; use numeric::tensor; fn main() {
/// let x = tensor![1, 0; 3, 2; 5, 4];
/// # assert!(x == numeric::Tensor::new(vec![1, 0, 3, 2, 5, 4]).reshape(&[3, 2]));
/// # }
/// ```
///
/// 1D tensor filled with a single value:
///
/// ```
/// # #[macro_use] extern crate numeric; use numeric::tensor; fn main() {
/// let x = tensor![2.0; 5];
/// # assert!(x == numeric::Tensor::new(vec![2.0, 2.0, 2.0, 2.0, 2.0]));
/// # }
/// ```
#[macro_export]
macro_rules! tensor {
    ($elem:expr; $n:expr) => (
        numeric::Tensor::filled(&[$n], $elem)
    );
    ($($x:expr),*) => (
        numeric::Tensor::new(vec![$($x),*])
    );
    ($($($x:expr),*);*) => ({
        let mut v = Vec::new();
        let mut n = 0;
        $(
            n += 1;
            $(v.push($x);)*
        )*
        numeric::Tensor::new(v).reshape(&[n, -1])
    });
}
<|endoftext|>


<commit_before>macro_rules! attrs {
    ($($name:ident = $value:expr),+) => {
        ($crate::AttributeSet::new(::std::borrow::Cow::Owned(vec![
            $($crate::Attribute {
                name: ::std::borrow::Cow::from(stringify!($name)),
                value: ::std::borrow::Cow::from($value),
            }),+
        ])))
    }
}

#[macro_export]
macro_rules! start_tag {
    ($name:expr) => {
        ($crate::Event::StartTag {
            name: ::std::borrow::Cow::from($name),
            attrs: $crate::AttributeSet::empty(),
            self_closing: false,
        })
    };
    ($name:expr, $($aname:ident = $aval:expr),+) => {
        start_tag!($name).with_attrs(attrs!($($aname = $aval),+))
    };
}

#[macro_export]
macro_rules! end_tag {
    ($name:expr) => {
        ($crate::Event::EndTag {
            name: ::std::borrow::Cow::from($name),
        })
    };
}

#[macro_export]
macro_rules! text {
    ($text:expr) => {
        ($crate::Event::Text(::std::borrow::Cow::from($text)))
    };
}

#[macro_export]
macro_rules! raw_html {
    ($html:expr) => {
        ($crate::Event::RawHtml(::std::borrow::Cow::from($html)))
    };
}
<commit_msg>Export attrs!<commit_after>#[macro_export]
macro_rules! attrs {
    ($($name:ident = $value:expr),+) => {
        ($crate::AttributeSet::new(::std::borrow::Cow::Owned(vec![
            $($crate::Attribute {
                name: ::std::borrow::Cow::from(stringify!($name)),
                value: ::std::borrow::Cow::from($value),
            }),+
        ])))
    }
}

#[macro_export]
macro_rules! start_tag {
    ($name:expr) => {
        ($crate::Event::StartTag {
            name: ::std::borrow::Cow::from($name),
            attrs: $crate::AttributeSet::empty(),
            self_closing: false,
        })
    };
    ($name:expr, $($aname:ident = $aval:expr),+) => {
        start_tag!($name).with_attrs(attrs!($($aname = $aval),+))
    };
}

#[macro_export]
macro_rules! end_tag {
    ($name:expr) => {
        ($crate::Event::EndTag {
            name: ::std::borrow::Cow::from($name),
        })
    };
}

#[macro_export]
macro_rules! text {
    ($text:expr) => {
        ($crate::Event::Text(::std::borrow::Cow::from($text)))
    };
}

#[macro_export]
macro_rules! raw_html {
    ($html:expr) => {
        ($crate::Event::RawHtml(::std::borrow::Cow::from($html)))
    };
}
<|endoftext|>


<commit_before>// De-duplication macro used in src/app.rs
macro_rules! get_help {
	($opt:ident) => {
		if let Some(h) = $opt.help {
	        format!("{}{}", h,
	            if let Some(ref pv) = $opt.possible_vals {
	                let mut pv_s = pv.iter().fold(String::with_capacity(50), |acc, name| acc + &format!(" {}",name)[..]);
	                pv_s.shrink_to_fit();
	                format!(" [values:{}]", &pv_s[..])
	            }else{"".to_owned()})
	    } else {
	        "    ".to_owned()
	    }
	};
}

// Thanks to bluss and flan3002 in #rust IRC
//
// Helps with rightward drift when iterating over something and matching each item.
macro_rules! for_match {
	($it:ident, $($p:pat => $($e:expr);+),*) => {
		for i in $it {
			match i {
			$(
			    $p => { $($e)+ }
			)*
			}
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `Result<T,String>` which allows you as the developer to decide
/// what you'd like to do on a failed parse. There are two types of errors, parse failures
/// and those where the argument wasn't present (such as a non-required argument).
///
/// You can use it to get a single value, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t!(matches.value_of("length"), u32)
/// 				.unwrap_or_else(|e|{
///						println!("{}",e);
///						std::process::exit(1)
///					});
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///				  .get_matches();
/// for v in value_t!(matches.values_of("seq"), u32)
///				.unwrap_or_else(|e|{
///					println!("{}",e);
///					std::process::exit(1)
///				}) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => Ok(val),
					Err(_)  => Err(format!("{} isn't a valid {}",v,stringify!($t))),
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				let mut err = None;
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(e) => {
							err = Some(format!("{} isn't a valid {}\n{}",pv,stringify!($t),e));
							break
						}
					}
				}
				match err {
					Some(e) => Err(e),
					None => Ok(tmp)
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `T` or `Vec<T>` or exits with a usage string upon failure. This
/// removes some of the boiler plate to handle failures from value_t! above.
///
/// You can use it to get a single value `T`, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** This should only be used on required arguments, as it can be confusing to the user
/// why they are getting error messages when it appears they're entering all required argumetns.
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t_or_exit!(matches.value_of("length"), u32);
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///                   .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///					  .get_matches();
/// for v in value_t_or_exit!(matches.values_of("seq"), u32) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t_or_exit {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => val,
					Err(e)  => {
						println!("{} isn't a valid {}\n{}\n{}\nPlease re-run with --help for more information",
							v,
							stringify!($t),
							e,
							$m.usage());
						::std::process::exit(1);
					}
				}
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(_)  => {
							println!("{} isn't a valid {}\n{}\nPlease re-run with --help for more information",
								pv,
								stringify!($t),
								$m.usage());
							::std::process::exit(1);
						}
					}
				}
				tmp
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
}

/// Convenience macro generated a simple enum with variants to be used as a type when parsing
/// arguments.
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// simple_enum!{Foo => Bar, Baz, Qux}
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg(Arg::from_usage("<foo> 'the foo'")
///						.possible_values(vec!["Bar", "Baz", "Qux"]))
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! simple_enum {
	($e:ident => $($v:ident),+) => {
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}

/// Convenience macro to generate more complete enums with variants to be used as a type when parsing
/// arguments.
///
/// These enums support pub (or not) and use of the #[derive()] traits
///
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// arg_enum!{
/// 	#[derive(Debug)]
///		pub enum Foo {
///			Bar,
///			Baz,
///			Qux
///		}
/// }
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg_from_usage("<foo> 'the foo'")
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! arg_enum {
	(enum $e:ident { $($v:ident),+ } ) => {
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(pub enum $e:ident { $($v:ident),+ } ) => {
		pub enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] pub enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		pub enum $e {
			$($v),+
		}

		impl std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}
<commit_msg>fix(macros.rs): fix use statements for trait impls<commit_after>// De-duplication macro used in src/app.rs
macro_rules! get_help {
	($opt:ident) => {
		if let Some(h) = $opt.help {
	        format!("{}{}", h,
	            if let Some(ref pv) = $opt.possible_vals {
	                let mut pv_s = pv.iter().fold(String::with_capacity(50), |acc, name| acc + &format!(" {}",name)[..]);
	                pv_s.shrink_to_fit();
	                format!(" [values:{}]", &pv_s[..])
	            }else{"".to_owned()})
	    } else {
	        "    ".to_owned()
	    }
	};
}

// Thanks to bluss and flan3002 in #rust IRC
//
// Helps with rightward drift when iterating over something and matching each item.
macro_rules! for_match {
	($it:ident, $($p:pat => $($e:expr);+),*) => {
		for i in $it {
			match i {
			$(
			    $p => { $($e)+ }
			)*
			}
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `Result<T,String>` which allows you as the developer to decide
/// what you'd like to do on a failed parse. There are two types of errors, parse failures
/// and those where the argument wasn't present (such as a non-required argument).
///
/// You can use it to get a single value, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t!(matches.value_of("length"), u32)
/// 				.unwrap_or_else(|e|{
///						println!("{}",e);
///						std::process::exit(1)
///					});
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///				  .get_matches();
/// for v in value_t!(matches.values_of("seq"), u32)
///				.unwrap_or_else(|e|{
///					println!("{}",e);
///					std::process::exit(1)
///				}) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => Ok(val),
					Err(_)  => Err(format!("{} isn't a valid {}",v,stringify!($t))),
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				let mut err = None;
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(e) => {
							err = Some(format!("{} isn't a valid {}\n{}",pv,stringify!($t),e));
							break
						}
					}
				}
				match err {
					Some(e) => Err(e),
					None => Ok(tmp)
				}
			},
			None => Err(format!("Argument \"{}\" not found", $v))
		}
	};
}

/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
/// This macro returns a `T` or `Vec<T>` or exits with a usage string upon failure. This
/// removes some of the boiler plate to handle failures from value_t! above.
///
/// You can use it to get a single value `T`, or a `Vec<T>` with the `values_of()`
///
/// **NOTE:** This should only be used on required arguments, as it can be confusing to the user
/// why they are getting error messages when it appears they're entering all required argumetns.
///
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
/// standard syntax.
///
///
/// # Example single value
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///               .arg_from_usage("[length] 'Set the length to use as a pos whole num, i.e. 20'")
///				  .get_matches();
/// let len = value_t_or_exit!(matches.value_of("length"), u32);
///
/// println!("{} + 2: {}", len, len + 2);
/// # }
/// ```
///
///
/// # Example multiple values
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let matches = App::new("myapp")
///                   .arg_from_usage("[seq]... 'A sequence of pos whole nums, i.e. 20 45'")
///					  .get_matches();
/// for v in value_t_or_exit!(matches.values_of("seq"), u32) {
/// 	println!("{} + 2: {}", v, v + 2);
///	}
/// # }
/// ```
#[macro_export]
macro_rules! value_t_or_exit {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => val,
					Err(e)  => {
						println!("{} isn't a valid {}\n{}\n{}\nPlease re-run with --help for more information",
							v,
							stringify!($t),
							e,
							$m.usage());
						::std::process::exit(1);
					}
				}
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
	($m:ident.values_of($v:expr), $t:ty) => {
		match $m.values_of($v) {
			Some(ref v) => {
				let mut tmp = Vec::with_capacity(v.len());
				for pv in v {
					match pv.parse::<$t>() {
						Ok(rv) => tmp.push(rv),
						Err(_)  => {
							println!("{} isn't a valid {}\n{}\nPlease re-run with --help for more information",
								pv,
								stringify!($t),
								$m.usage());
							::std::process::exit(1);
						}
					}
				}
				tmp
			},
			None => {
				println!("Argument \"{}\" not found or is not valid\n{}\nPlease re-run with --help for more information",
					$v,
					$m.usage());
				::std::process::exit(1);
			}
		}
	};
}

/// Convenience macro generated a simple enum with variants to be used as a type when parsing
/// arguments.
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// simple_enum!{Foo => Bar, Baz, Qux}
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg(Arg::from_usage("<foo> 'the foo'")
///						.possible_values(vec!["Bar", "Baz", "Qux"]))
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! simple_enum {
	($e:ident => $($v:ident),+) => {
		enum $e {
			$($v),+
		}

		impl ::std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}

/// Convenience macro to generate more complete enums with variants to be used as a type when parsing
/// arguments.
///
/// These enums support pub (or not) and use of the #[derive()] traits
///
///
/// # Example
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::{App, Arg};
/// arg_enum!{
/// 	#[derive(Debug)]
///		pub enum Foo {
///			Bar,
///			Baz,
///			Qux
///		}
/// }
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
/// // and implements std::str::FromStr to use with the value_t! macros
/// fn main() {
/// 	let m = App::new("app")
///					.arg_from_usage("<foo> 'the foo'")
///					.get_matches();
/// 	let f = value_t_or_exit!(m.value_of("foo"), Foo);
///
///		// Use f like any other Foo variant...
/// }
/// ```
#[macro_export]
macro_rules! arg_enum {
	(enum $e:ident { $($v:ident),+ } ) => {
		enum $e {
			$($v),+
		}

		impl ::std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(pub enum $e:ident { $($v:ident),+ } ) => {
		pub enum $e {
			$($v),+
		}

		impl ::std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		enum $e {
			$($v),+
		}

		impl ::std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
	(#[derive($($d:ident),+)] pub enum $e:ident { $($v:ident),+ } ) => {
		#[derive($($d,)+)]
		pub enum $e {
			$($v),+
		}

		impl ::std::str::FromStr for $e {
			type Err = String;

			fn from_str(s: &str) -> Result<Self,Self::Err> {
				match s {
					$(stringify!($v) => Ok($e::$v),)+
					_                => Err({
											let v = vec![
								        		$(stringify!($v),)+
								    		];
								    		format!("valid:{}", v.iter().fold(String::new(),|a, i| a + &format!(" {}", i)[..]))
										})
				}
			}
		}
	};
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/// Connect events to sending a message.
///
/// ## Rules
/// 1. Send `$msg` to `$other_component` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Optionally send `$msg.0` when the GTK+ `$event` is emitted on `$widget`.
/// Return `$msg.1` in the GTK+ callback.
/// This variant gives more control to the caller since it expects a `$msg` returning `(Option<MSG>,
/// ReturnValue)` where the `ReturnValue` is the value to return in the GTK+ callback.
/// Option<MSG> can be None if no message needs to be emitted.
///
/// 3. Send `$msg` when the GTK+ `$event` is emitted on `$widget`.
///
/// 4. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect {
    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_component:expr, $msg:expr) => {
        connect_stream!($widget, $event($($args),*), $other_component.stream(), $msg);
    };

    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), return $msg:expr) => {{
        connect_stream!(return $relm.stream(), $widget, $event($($args),*), $msg);
    }};

    // Connect to a GTK+ widget event.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $relm.stream().clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    }};

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_component:ident @ $message:pat, $dst_component:expr, $msg:expr) => {
        let stream = $src_component.stream().clone();
        connect_stream!(stream@$message, $dst_component.stream(), $msg);
    };
}

/// Connect events to sending a message.
/// Similar to `connect!` but wants a stream instead of a component.
///
/// ## Rules
/// 1. Send `$msg` to `$other_stream` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect_stream {
    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    (return $stream:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let (msg, return_value) = $crate::IntoPair::into_pair($msg);
            let msg: Option<_> = $crate::IntoOption::into_option(msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
            return_value
        });
    }};

    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_stream:expr, $msg:expr) => {
        let stream = $other_stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    };

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_stream:ident @ $message:pat, $dst_stream:expr, $msg:expr) => {
        let stream = $dst_stream.clone();
        $src_stream.observe(move |msg| {
            #[allow(unreachable_patterns)]
            match msg {
                &$message =>  {
                    let msg: Option<_> = $crate::IntoOption::into_option($msg);
                    if let Some(msg) = msg {
                        stream.emit(msg);
                    }
                },
                _ => (),
            }
        });
    };
}

/// Connect an asynchronous method call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async {
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr) => {
        connect_async!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let stream = $relm.stream().clone();
        $object.$async_method($($args,)* None, move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $object.$async_method($($args,)* None, move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });
    }};
}

/// Connect an asynchronous function call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async_func {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:expr) => {
        connect_async_func!($class::$async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let stream = $relm.stream().clone();
        $class::$async_func($($args,)* None, move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async_func!($class::$async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $class::$async_func($($args,)* None, move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

    }};
}

/// Like `connect_async!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_full {
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr) => {
        connect_async_full!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let stream = $relm.stream().clone();
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
        cancellable
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async_full!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

        cancellable
    }};
}

/// Like `connect_async_func!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_func_full {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:expr) => {
        connect_async!($async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let stream = $relm.stream().clone();
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
        cancellable
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async!($async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

        cancellable
    }};
}
<commit_msg>Revert "Temporary fix to publish the crate"<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

include!("../relm-state/src/macros.rs");
<|endoftext|>


<commit_before>#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! ast_struct {
    (
        $(#[$attr:meta])*
        pub struct $name:ident #full $($rest:tt)*
    ) => {
        #[cfg(feature = "full")]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*

        #[cfg(not(feature = "full"))]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name {
            _noconstruct: (),
        }
    };

    (
        $(#[$attr:meta])*
        pub struct $name:ident #manual_extra_traits $($rest:tt)*
    ) => {
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*
    };

    (
        $(#[$attr:meta])*
        pub struct $name:ident $($rest:tt)*
    ) => {
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*
    };
}

#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! ast_enum {
    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident $(# $tags:ident)* { $($variants:tt)* }
    ) => (
        $(#[$enum_attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub enum $name {
            $($variants)*
        }
    )
}

#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! ast_enum_of_structs {
    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident {
            $(
                $(#[$variant_attr:meta])*
                pub $variant:ident $( ($member:ident $($rest:tt)*) )*,
            )*
        }

        $($remaining:tt)*
    ) => (
        ast_enum! {
            $(#[$enum_attr])*
            pub enum $name {
                $(
                    $(#[$variant_attr])*
                    $variant $( ($member) )*,
                )*
            }
        }

        $(
            maybe_ast_struct! {
                $(#[$variant_attr])*
                $(
                    pub struct $member $($rest)*
                )*
            }

            $(
                impl From<$member> for $name {
                    fn from(e: $member) -> $name {
                        $name::$variant(e)
                    }
                }
            )*
        )*

        #[cfg(feature = "printing")]
        generate_to_tokens! {
            $($remaining)*
            ()
            tokens
            $name { $($variant $( [$($rest)*] )*,)* }
        }
    )
}

#[cfg(all(feature = "printing", any(feature = "full", feature = "derive")))]
macro_rules! generate_to_tokens {
    (do_not_generate_to_tokens $($foo:tt)*) => ();

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident, $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant => {})
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident [$($rest:tt)*], $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant(ref _e) => to_tokens_call!(_e, $tokens, $($rest)*),)
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident {}) => {
        impl ::quote::ToTokens for $name {
            fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
                match *self {
                    $($arms)*
                }
            }
        }
    };
}

#[cfg(all(feature = "printing", feature = "full"))]
macro_rules! to_tokens_call {
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

#[cfg(all(feature = "printing", feature = "derive", not(feature = "full")))]
macro_rules! to_tokens_call {
    // If the variant is marked as #full, don't auto-generate to-tokens for it.
    ($e:ident, $tokens:ident, #full $($rest:tt)*) => {
        unreachable!()
    };
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! maybe_ast_struct {
    (
        $(#[$attr:meta])*
        $(
            pub struct $name:ident
        )*
    ) => ();

    ($($rest:tt)*) => (ast_struct! { $($rest)* });
}
<commit_msg>Make rustdoc generate the correct [src] links by perserving spans in our macros<commit_after>#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! ast_struct {
    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident #full $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        #[cfg(feature = "full")]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*

        #[cfg(not(feature = "full"))]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name {
            _noconstruct: (),
        }
    };

    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident #manual_extra_traits $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*
    };

    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*
    };
}

#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! ast_enum {
    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident $(# $tags:ident)* { $($variants:tt)* }
    ) => (
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(enum $enum);

        $(#[$enum_attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $enum $name {
            $($variants)*
        }
    )
}

#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! ast_enum_of_structs {
    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident {
            $(
                $(#[$variant_attr:meta])*
                $vpub:ident $variant:ident $( ($member:ident $($rest:tt)*) )*,
            )*
        }

        $($remaining:tt)*
    ) => (
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(enum $enum);

        ast_enum! {
            $(#[$enum_attr])*
            $pub $enum $name {
                $(
                    $(#[$variant_attr])*
                    $variant $( ($member) )*,
                )*
            }
        }

        $(
            check_keyword_matches!(pub $vpub);
            maybe_ast_struct! {
                $(#[$variant_attr])*
                $(
                    $vpub struct $member $($rest)*
                )*
            }

            $(
                impl From<$member> for $name {
                    fn from(e: $member) -> $name {
                        $name::$variant(e)
                    }
                }
            )*
        )*

        #[cfg(feature = "printing")]
        generate_to_tokens! {
            $($remaining)*
            ()
            tokens
            $name { $($variant $( [$($rest)*] )*,)* }
        }
    )
}

#[cfg(all(feature = "printing", any(feature = "full", feature = "derive")))]
macro_rules! generate_to_tokens {
    (do_not_generate_to_tokens $($foo:tt)*) => ();

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident, $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant => {})
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident [$($rest:tt)*], $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant(ref _e) => to_tokens_call!(_e, $tokens, $($rest)*),)
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident {}) => {
        impl ::quote::ToTokens for $name {
            fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
                match *self {
                    $($arms)*
                }
            }
        }
    };
}

#[cfg(all(feature = "printing", feature = "full"))]
macro_rules! to_tokens_call {
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

#[cfg(all(feature = "printing", feature = "derive", not(feature = "full")))]
macro_rules! to_tokens_call {
    // If the variant is marked as #full, don't auto-generate to-tokens for it.
    ($e:ident, $tokens:ident, #full $($rest:tt)*) => {
        unreachable!()
    };
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! maybe_ast_struct {
    (
        $(#[$attr:meta])*
        $(
            pub struct $name:ident
        )*
    ) => ();

    ($($rest:tt)*) => (ast_struct! { $($rest)* });
}

#[cfg(any(feature = "full", feature = "derive"))]
macro_rules! check_keyword_matches {
    (struct struct) => {};
    (enum enum) => {};
    (pub pub) => {};
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! Q_OBJECT(
    (
        $t:ty :
            $(
                slot fn $name:ident ($($at:ty),*);
            )*,
            $(
                signal fn $sname:ident ( );
            )*
    ) => (
/*
        impl $t {
            #[allow(dead_code, unused_mut, unused_variables, unused_assignments)]
            fn __qmlrs_signal_id(&self, name: &str) -> u32 {
                let mut id = 0;
                $(
                    if stringify!($sname) == name {
                        return id;
                    }
                    id += 1;
                )+
                panic!("__qmlrs_signal_id called with invalid signal name!");
            }

            $(
                #[allow(dead_code)]
                fn $sname (&self) {
                    qmlrs::__qobject_emit(self, self.__qmlrs_signal_id(stringify!($sname)));
                }
            )+
        }
*/
        impl qmlrs::Object for $t {
            #[allow(unused_mut, unused_variables)]
            fn qt_metaobject(&self) -> qmlrs::MetaObject {
                let x = qmlrs::MetaObject::new();
/*
                $(
                    let x = x.signal(stringify!($sname), 0);
                )+
*/
                $(
                    let mut argc = 0;
                    $(
                        let _: $at;
                        argc += 1;
                    )*
                    let x = x.slot(stringify!($name), argc);
                )+
                x
            }

            #[allow(unused_assignments, unused_mut, unused_variables)]
            fn qt_metacall(&mut self, slot: i32, args: *const *const qmlrs::OpaqueQVariant) {
                use qmlrs::ToQVariant;
                let mut i = 0;
/*
                $(
                    let _ = stringify!($sname);
                    i += 1;
                )+
*/
                $(
                    if i == slot {
                        let mut argi = 1u8; /* 0 is for return value */
                        let ret = self.$name(
                            $(
                                {
                                    let _: $at;
                                    match qmlrs::FromQVariant::from_qvariant(unsafe { *args.offset(argi as isize) }) {
                                        Some(arg) => { argi += 1; arg }
                                        None      => {
                                            println!("qmlrs: Invalid argument {} type for slot {}", argi, stringify!($name));
                                            return;
                                        }
                                    }
                                }
                            ),*
                        );
                        ret.to_qvariant(unsafe { *args.offset(0) as *mut qmlrs::OpaqueQVariant });
                        return
                    }
                    i += 1;
                )+
            }
        }
    )
);
<commit_msg>update<commit_after>#[macro_export]
macro_rules! Q_OBJECT(
    (
        $t:ty :
            $(slot fn $name:ident ($($at:ty),*);)*
            $(signal fn $sname:ident ( );)*
    ) => (
/*
        impl $t {
            #[allow(dead_code, unused_mut, unused_variables, unused_assignments)]
            fn __qmlrs_signal_id(&self, name: &str) -> u32 {
                let mut id = 0;
                $(
                    if stringify!($sname) == name {
                        return id;
                    }
                    id += 1;
                )+
                panic!("__qmlrs_signal_id called with invalid signal name!");
            }

            $(
                #[allow(dead_code)]
                fn $sname (&self) {
                    qmlrs::__qobject_emit(self, self.__qmlrs_signal_id(stringify!($sname)));
                }
            )+
        }
*/
        impl qmlrs::Object for $t {
            #[allow(unused_mut, unused_variables)]
            fn qt_metaobject(&self) -> qmlrs::MetaObject {
                let x = qmlrs::MetaObject::new();
/*
                $(
                    let x = x.signal(stringify!($sname), 0);
                )+
*/
                $(
                    let mut argc = 0;
                    $(
                        let _: $at;
                        argc += 1;
                    )*
                    let x = x.slot(stringify!($name), argc);
                )+
                x
            }

            #[allow(unused_assignments, unused_mut, unused_variables)]
            fn qt_metacall(&mut self, slot: i32, args: *const *const qmlrs::OpaqueQVariant) {
                use qmlrs::ToQVariant;
                let mut i = 0;
/*
                $(
                    let _ = stringify!($sname);
                    i += 1;
                )+
*/
                $(
                    if i == slot {
                        let mut argi = 1u8; /* 0 is for return value */
                        let ret = self.$name(
                            $(
                                {
                                    let _: $at;
                                    match qmlrs::FromQVariant::from_qvariant(unsafe { *args.offset(argi as isize) }) {
                                        Some(arg) => { argi += 1; arg }
                                        None      => {
                                            println!("qmlrs: Invalid argument {} type for slot {}", argi, stringify!($name));
                                            return;
                                        }
                                    }
                                }
                            ),*
                        );
                        ret.to_qvariant(unsafe { *args.offset(0) as *mut qmlrs::OpaqueQVariant });
                        return
                    }
                    i += 1;
                )+
            }
        }
    )
);
<|endoftext|>


<commit_before>//! The HTTP request method
use std::fmt;
use std::str::FromStr;

use error::HttpError;
use self::Method::{Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch,
                   Extension};

/// The Request Method (VERB)
///
/// Currently includes 8 variants representing the 8 methods defined in
/// [RFC 7230](https://tools.ietf.org/html/rfc7231#section-4.1), plus PATCH,
/// and an Extension variant for all extensions.
///
/// It may make sense to grow this to include all variants currently
/// registered with IANA, if they are at all common to use.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Method {
    /// OPTIONS
    Options,
    /// GET
    Get,
    /// POST
    Post,
    /// PUT
    Put,
    /// DELETE
    Delete,
    /// HEAD
    Head,
    /// TRACE
    Trace,
    /// CONNECT
    Connect,
    /// PATCH
    Patch,
    /// Method extentions. An example would be `let m = Extension("FOO".to_string())`.
    Extension(String)
}

impl Method {
    /// Whether a method is considered "safe", meaning the request is
    /// essentially read-only.
    ///
    /// See [the spec](https://tools.ietf.org/html/rfc7231#section-4.2.1)
    /// for more words.
    pub fn safe(&self) -> bool {
        match *self {
            Get | Head | Options | Trace => true,
            _ => false
        }
    }

    /// Whether a method is considered "idempotent", meaning the request has
    /// the same result is executed multiple times.
    ///
    /// See [the spec](https://tools.ietf.org/html/rfc7231#section-4.2.2) for
    /// more words.
    pub fn idempotent(&self) -> bool {
        if self.safe() {
            true
        } else {
            match *self {
                Put | Delete => true,
                _ => false
            }
        }
    }
}

impl FromStr for Method {
    type Err = HttpError;
    fn from_str(s: &str) -> Result<Method, HttpError> {
        if s == "" {
            Err(HttpError::HttpMethodError)
        } else {
            Ok(match s {
                "OPTIONS" => Options,
                "GET" => Get,
                "POST" => Post,
                "PUT" => Put,
                "DELETE" => Delete,
                "HEAD" => Head,
                "TRACE" => Trace,
                "CONNECT" => Connect,
                "PATCH" => Patch,
                _ => Extension(s.to_string())
            })
        }
    }
}

impl fmt::Display for Method {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            Options => "OPTIONS",
            Get => "GET",
            Post => "POST",
            Put => "PUT",
            Delete => "DELETE",
            Head => "HEAD",
            Trace => "TRACE",
            Connect => "CONNECT",
            Patch => "PATCH",
            Extension(ref s) => s.as_ref()
        })
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use std::str::FromStr;
    use super::Method;
    use super::Method::{Get, Post, Put, Extension};

    #[test]
    fn test_safe() {
        assert_eq!(true, Get.safe());
        assert_eq!(false, Post.safe());
    }

    #[test]
    fn test_idempotent() {
        assert_eq!(true, Get.idempotent());
        assert_eq!(true, Put.idempotent());
        assert_eq!(false, Post.idempotent());
    }

    #[test]
    fn test_from_str() {
        assert_eq!(Get, FromStr::from_str("GET").unwrap());
        assert_eq!(Extension("MOVE".to_string()),
                   FromStr::from_str("MOVE").unwrap());
    }

    #[test]
    fn test_fmt() {
        assert_eq!("GET".to_string(), format!("{}", Get));
        assert_eq!("MOVE".to_string(),
                   format!("{}", Extension("MOVE".to_string())));
    }

    #[test]
    fn test_hashable() {
        let mut counter: HashMap<Method,usize> = HashMap::new();
        counter.insert(Get, 1);
        assert_eq!(Some(&1), counter.get(&Get));
    }
}
<commit_msg>feat(method): implement `AsRef<str>` for `Method`<commit_after>//! The HTTP request method
use std::fmt;
use std::str::FromStr;
use std::convert::AsRef;

use error::HttpError;
use self::Method::{Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch,
                   Extension};

/// The Request Method (VERB)
///
/// Currently includes 8 variants representing the 8 methods defined in
/// [RFC 7230](https://tools.ietf.org/html/rfc7231#section-4.1), plus PATCH,
/// and an Extension variant for all extensions.
///
/// It may make sense to grow this to include all variants currently
/// registered with IANA, if they are at all common to use.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Method {
    /// OPTIONS
    Options,
    /// GET
    Get,
    /// POST
    Post,
    /// PUT
    Put,
    /// DELETE
    Delete,
    /// HEAD
    Head,
    /// TRACE
    Trace,
    /// CONNECT
    Connect,
    /// PATCH
    Patch,
    /// Method extentions. An example would be `let m = Extension("FOO".to_string())`.
    Extension(String)
}

impl AsRef<str> for Method {
    fn as_ref(&self) -> &str {
        match *self {
            Options => "OPTIONS",
            Get => "GET",
            Post => "POST",
            Put => "PUT",
            Delete => "DELETE",
            Head => "HEAD",
            Trace => "TRACE",
            Connect => "CONNECT",
            Patch => "PATCH",
            Extension(ref s) => s.as_ref()
        }
    }
}

impl Method {
    /// Whether a method is considered "safe", meaning the request is
    /// essentially read-only.
    ///
    /// See [the spec](https://tools.ietf.org/html/rfc7231#section-4.2.1)
    /// for more words.
    pub fn safe(&self) -> bool {
        match *self {
            Get | Head | Options | Trace => true,
            _ => false
        }
    }

    /// Whether a method is considered "idempotent", meaning the request has
    /// the same result is executed multiple times.
    ///
    /// See [the spec](https://tools.ietf.org/html/rfc7231#section-4.2.2) for
    /// more words.
    pub fn idempotent(&self) -> bool {
        if self.safe() {
            true
        } else {
            match *self {
                Put | Delete => true,
                _ => false
            }
        }
    }
}

impl FromStr for Method {
    type Err = HttpError;
    fn from_str(s: &str) -> Result<Method, HttpError> {
        if s == "" {
            Err(HttpError::HttpMethodError)
        } else {
            Ok(match s {
                "OPTIONS" => Options,
                "GET" => Get,
                "POST" => Post,
                "PUT" => Put,
                "DELETE" => Delete,
                "HEAD" => Head,
                "TRACE" => Trace,
                "CONNECT" => Connect,
                "PATCH" => Patch,
                _ => Extension(s.to_string())
            })
        }
    }
}

impl fmt::Display for Method {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            Options => "OPTIONS",
            Get => "GET",
            Post => "POST",
            Put => "PUT",
            Delete => "DELETE",
            Head => "HEAD",
            Trace => "TRACE",
            Connect => "CONNECT",
            Patch => "PATCH",
            Extension(ref s) => s.as_ref()
        })
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use std::str::FromStr;
    use super::Method;
    use super::Method::{Get, Post, Put, Extension};

    #[test]
    fn test_safe() {
        assert_eq!(true, Get.safe());
        assert_eq!(false, Post.safe());
    }

    #[test]
    fn test_idempotent() {
        assert_eq!(true, Get.idempotent());
        assert_eq!(true, Put.idempotent());
        assert_eq!(false, Post.idempotent());
    }

    #[test]
    fn test_from_str() {
        assert_eq!(Get, FromStr::from_str("GET").unwrap());
        assert_eq!(Extension("MOVE".to_string()),
                   FromStr::from_str("MOVE").unwrap());
    }

    #[test]
    fn test_fmt() {
        assert_eq!("GET".to_string(), format!("{}", Get));
        assert_eq!("MOVE".to_string(),
                   format!("{}", Extension("MOVE".to_string())));
    }

    #[test]
    fn test_hashable() {
        let mut counter: HashMap<Method,usize> = HashMap::new();
        counter.insert(Get, 1);
        assert_eq!(Some(&1), counter.get(&Get));
    }

    #[test]
    fn test_as_str() {
        assert_eq!(Get.as_ref(), "GET");
        assert_eq!(Post.as_ref(), "POST");
        assert_eq!(Put.as_ref(), "PUT");
        assert_eq!(Extension("MOVE".to_string()).as_ref(), "MOVE");
    }
}
<|endoftext|>