<commit_before>use llvm_sys::core::{LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile};
use llvm_sys::LLVMOpcode;
use llvm_sys::prelude::LLVMValueRef;

use basic_block::BasicBlock;
use values::traits::AsValueRef;
use values::Value;

// REVIEW: Split up into structs for SubTypes on InstructionValues?
// REVIEW: This should maybe be split up into InstructionOpcode and ConstOpcode?
// see LLVMGetConstOpcode
#[derive(Debug, PartialEq, Eq)]
pub enum InstructionOpcode {
    // Actual Instructions:
    Add,
    AddrSpaceCast,
    Alloca,
    And,
    AShr,
    AtomicCmpXchg,
    AtomicRMW,
    BitCast,
    Br,
    Call,
    // Later versions:
    // CatchPad,
    // CatchRet,
    // CatchSwitch,
    // CleanupPad,
    // CleanupRet,
    ExtractElement,
    ExtractValue,
    FAdd,
    FCmp,
    FDiv,
    Fence,
    FMul,
    FPExt,
    FPToSI,
    FPToUI,
    FPTrunc,
    FRem,
    FSub,
    GetElementPtr,
    ICmp,
    IndirectBr,
    InsertElement,
    InsertValue,
    IntToPtr,
    Invoke,
    LandingPad,
    Load,
    LShr,
    Mul,
    Or,
    Phi,
    PtrToInt,
    Resume,
    Return,
    SDiv,
    Select,
    SExt,
    Shl,
    ShuffleVector,
    SIToFP,
    SRem,
    Store,
    Sub,
    Switch,
    Trunc,
    UDiv,
    UIToFP,
    Unreachable,
    URem,
    UserOp1,
    UserOp2,
    VAArg,
    Xor,
    ZExt,
}

impl InstructionOpcode {
    fn new(opcode: LLVMOpcode) -> Self {
        match opcode {
            LLVMOpcode::LLVMAdd => InstructionOpcode::Add,
            LLVMOpcode::LLVMAddrSpaceCast => InstructionOpcode::AddrSpaceCast,
            LLVMOpcode::LLVMAlloca => InstructionOpcode::Alloca,
            LLVMOpcode::LLVMAnd => InstructionOpcode::And,
            LLVMOpcode::LLVMAShr => InstructionOpcode::AShr,
            LLVMOpcode::LLVMAtomicCmpXchg => InstructionOpcode::AtomicCmpXchg,
            LLVMOpcode::LLVMAtomicRMW => InstructionOpcode::AtomicRMW,
            LLVMOpcode::LLVMBitCast => InstructionOpcode::BitCast,
            LLVMOpcode::LLVMBr => InstructionOpcode::Br,
            LLVMOpcode::LLVMCall => InstructionOpcode::Call,
            // Newer versions:
            // LLVMOpcode::LLVMCatchPad => InstructionOpcode::CatchPad,
            // LLVMOpcode::LLVMCatchRet => InstructionOpcode::CatchRet,
            // LLVMOpcode::LLVMCatchSwitch => InstructionOpcode::CatchSwitch,
            // LLVMOpcode::LLVMCleanupPad => InstructionOpcode::CleanupPad,
            // LLVMOpcode::LLVMCleanupRet => InstructionOpcode::CleanupRet,
            LLVMOpcode::LLVMExtractElement => InstructionOpcode::ExtractElement,
            LLVMOpcode::LLVMExtractValue => InstructionOpcode::ExtractValue,
            LLVMOpcode::LLVMFAdd => InstructionOpcode::FAdd,
            LLVMOpcode::LLVMFCmp => InstructionOpcode::FCmp,
            LLVMOpcode::LLVMFDiv => InstructionOpcode::FDiv,
            LLVMOpcode::LLVMFence => InstructionOpcode::Fence,
            LLVMOpcode::LLVMFMul => InstructionOpcode::FMul,
            LLVMOpcode::LLVMFPExt => InstructionOpcode::FPExt,
            LLVMOpcode::LLVMFPToSI => InstructionOpcode::FPToSI,
            LLVMOpcode::LLVMFPToUI => InstructionOpcode::FPToUI,
            LLVMOpcode::LLVMFPTrunc => InstructionOpcode::FPTrunc,
            LLVMOpcode::LLVMFRem => InstructionOpcode::FRem,
            LLVMOpcode::LLVMFSub => InstructionOpcode::FSub,
            LLVMOpcode::LLVMGetElementPtr => InstructionOpcode::GetElementPtr,
            LLVMOpcode::LLVMICmp => InstructionOpcode::ICmp,
            LLVMOpcode::LLVMIndirectBr => InstructionOpcode::IndirectBr,
            LLVMOpcode::LLVMInsertElement => InstructionOpcode::InsertElement,
            LLVMOpcode::LLVMInsertValue => InstructionOpcode::InsertValue,
            LLVMOpcode::LLVMIntToPtr => InstructionOpcode::IntToPtr,
            LLVMOpcode::LLVMInvoke => InstructionOpcode::Invoke,
            LLVMOpcode::LLVMLandingPad => InstructionOpcode::LandingPad,
            LLVMOpcode::LLVMLoad => InstructionOpcode::Load,
            LLVMOpcode::LLVMLShr => InstructionOpcode::LShr,
            LLVMOpcode::LLVMMul => InstructionOpcode::Mul,
            LLVMOpcode::LLVMOr => InstructionOpcode::Or,
            LLVMOpcode::LLVMPHI => InstructionOpcode::Phi,
            LLVMOpcode::LLVMPtrToInt => InstructionOpcode::PtrToInt,
            LLVMOpcode::LLVMResume => InstructionOpcode::Resume,
            LLVMOpcode::LLVMRet => InstructionOpcode::Return,
            LLVMOpcode::LLVMSDiv => InstructionOpcode::SDiv,
            LLVMOpcode::LLVMSelect => InstructionOpcode::Select,
            LLVMOpcode::LLVMSExt => InstructionOpcode::SExt,
            LLVMOpcode::LLVMShl => InstructionOpcode::Shl,
            LLVMOpcode::LLVMShuffleVector => InstructionOpcode::ShuffleVector,
            LLVMOpcode::LLVMSIToFP => InstructionOpcode::SIToFP,
            LLVMOpcode::LLVMSRem => InstructionOpcode::SRem,
            LLVMOpcode::LLVMStore => InstructionOpcode::Store,
            LLVMOpcode::LLVMSub => InstructionOpcode::Sub,
            LLVMOpcode::LLVMSwitch => InstructionOpcode::Switch,
            LLVMOpcode::LLVMTrunc => InstructionOpcode::Trunc,
            LLVMOpcode::LLVMUDiv => InstructionOpcode::UDiv,
            LLVMOpcode::LLVMUIToFP => InstructionOpcode::UIToFP,
            LLVMOpcode::LLVMUnreachable => InstructionOpcode::Unreachable,
            LLVMOpcode::LLVMURem => InstructionOpcode::URem,
            LLVMOpcode::LLVMUserOp1 => InstructionOpcode::UserOp1,
            LLVMOpcode::LLVMUserOp2 => InstructionOpcode::UserOp2,
            LLVMOpcode::LLVMVAArg => InstructionOpcode::VAArg,
            LLVMOpcode::LLVMXor => InstructionOpcode::Xor,
            LLVMOpcode::LLVMZExt => InstructionOpcode::ZExt,
        }
    }
}

#[derive(Debug, PartialEq, Eq, Copy)]
pub struct InstructionValue {
    instruction_value: Value,
}

impl InstructionValue {
    pub(crate) fn new(instruction_value: LLVMValueRef) -> Self {
        assert!(!instruction_value.is_null());

        let value = Value::new(instruction_value);

        assert!(value.is_instruction());

        InstructionValue {
            instruction_value: value,
        }
    }

    pub fn get_opcode(&self) -> InstructionOpcode {
        let opcode = unsafe {
            LLVMGetInstructionOpcode(self.as_value_ref())
        };

        InstructionOpcode::new(opcode)
    }

    pub fn get_previous_instruction(&self) -> Option<Self> {
        let value = unsafe {
            LLVMGetPreviousInstruction(self.as_value_ref())
        };

        if value.is_null() {
            return None;
        }

        Some(InstructionValue::new(value))
    }

    pub fn get_next_instruction(&self) -> Option<Self> {
        let value = unsafe {
            LLVMGetNextInstruction(self.as_value_ref())
        };

        if value.is_null() {
            return None;
        }

        Some(InstructionValue::new(value))
    }

    // REVIEW: Potentially unsafe if parent BB or grandparent fn were removed?
    // REVIEW: Is this actually an erase and should be (self)?
    pub fn remove_from_basic_block(&self) {
        unsafe {
            LLVMInstructionEraseFromParent(self.as_value_ref())
        }
    }

    // REVIEW: Potentially unsafe is parent BB or grandparent fn was deleted
    // REVIEW: Should this *not* be an option? Parent should always exist,
    // but I doubt LLVM returns null if the parent BB (or grandparent FN)
    // was deleted... Invalid memory is more likely
    pub fn get_parent(&self) -> Option<BasicBlock> {
        let value = unsafe {
            LLVMGetInstructionParent(self.as_value_ref())
        };

        BasicBlock::new(value)
    }

    // REVIEW: See if necessary to check opcode == Call first.
    // Does it always return false otherwise?
    pub fn is_tail_call(&self) -> bool {
        unsafe {
            LLVMIsTailCall(self.as_value_ref()) == 1
        }
    }

    pub fn replace_all_uses_with(&self, other: &InstructionValue) {
        self.instruction_value.replace_all_uses_with(other.as_value_ref())
    }

    // SubTypes: Only apply to memory access instructions
    /// Returns whether or not a memory access instruction is volatile.
    pub fn get_volatile(&self) -> bool {
        unsafe {
            LLVMGetVolatile(self.as_value_ref()) == 1
        }
    }

    // SubTypes: Only apply to memory access instructions
    /// Sets whether or not a memory access instruction is volatile.
    pub fn set_volatile(&self, volatile: bool) {
        unsafe {
            LLVMSetVolatile(self.as_value_ref(), volatile as i32)
        }
    }
}

impl Clone for InstructionValue {
    /// Creates a clone of this `InstructionValue`, and returns it.
    /// The clone will have no parent, and no name.
    fn clone(&self) -> Self {
        let value = unsafe {
            LLVMInstructionClone(self.as_value_ref())
        };

        InstructionValue::new(value)
    }
}

impl AsValueRef for InstructionValue {
    fn as_value_ref(&self) -> LLVMValueRef {
        self.instruction_value.value
    }
}
<commit_msg>Forgot to commit instruction value opcode conversion<commit_after>use llvm_sys::core::{LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile};
use llvm_sys::LLVMOpcode;
use llvm_sys::prelude::LLVMValueRef;

use basic_block::BasicBlock;
use values::traits::AsValueRef;
use values::Value;

// REVIEW: Split up into structs for SubTypes on InstructionValues?
// REVIEW: This should maybe be split up into InstructionOpcode and ConstOpcode?
// see LLVMGetConstOpcode
#[derive(Debug, PartialEq, Eq)]
pub enum InstructionOpcode {
    // Actual Instructions:
    Add,
    AddrSpaceCast,
    Alloca,
    And,
    AShr,
    AtomicCmpXchg,
    AtomicRMW,
    BitCast,
    Br,
    Call,
    // Later versions:
    // CatchPad,
    // CatchRet,
    // CatchSwitch,
    // CleanupPad,
    // CleanupRet,
    ExtractElement,
    ExtractValue,
    FAdd,
    FCmp,
    FDiv,
    Fence,
    FMul,
    FPExt,
    FPToSI,
    FPToUI,
    FPTrunc,
    FRem,
    FSub,
    GetElementPtr,
    ICmp,
    IndirectBr,
    InsertElement,
    InsertValue,
    IntToPtr,
    Invoke,
    LandingPad,
    Load,
    LShr,
    Mul,
    Or,
    Phi,
    PtrToInt,
    Resume,
    Return,
    SDiv,
    Select,
    SExt,
    Shl,
    ShuffleVector,
    SIToFP,
    SRem,
    Store,
    Sub,
    Switch,
    Trunc,
    UDiv,
    UIToFP,
    Unreachable,
    URem,
    UserOp1,
    UserOp2,
    VAArg,
    Xor,
    ZExt,
}

impl InstructionOpcode {
    fn new(opcode: LLVMOpcode) -> Self {
        match opcode {
            LLVMOpcode::LLVMAdd => InstructionOpcode::Add,
            LLVMOpcode::LLVMAddrSpaceCast => InstructionOpcode::AddrSpaceCast,
            LLVMOpcode::LLVMAlloca => InstructionOpcode::Alloca,
            LLVMOpcode::LLVMAnd => InstructionOpcode::And,
            LLVMOpcode::LLVMAShr => InstructionOpcode::AShr,
            LLVMOpcode::LLVMAtomicCmpXchg => InstructionOpcode::AtomicCmpXchg,
            LLVMOpcode::LLVMAtomicRMW => InstructionOpcode::AtomicRMW,
            LLVMOpcode::LLVMBitCast => InstructionOpcode::BitCast,
            LLVMOpcode::LLVMBr => InstructionOpcode::Br,
            LLVMOpcode::LLVMCall => InstructionOpcode::Call,
            // Newer versions:
            // LLVMOpcode::LLVMCatchPad => InstructionOpcode::CatchPad,
            // LLVMOpcode::LLVMCatchRet => InstructionOpcode::CatchRet,
            // LLVMOpcode::LLVMCatchSwitch => InstructionOpcode::CatchSwitch,
            // LLVMOpcode::LLVMCleanupPad => InstructionOpcode::CleanupPad,
            // LLVMOpcode::LLVMCleanupRet => InstructionOpcode::CleanupRet,
            LLVMOpcode::LLVMExtractElement => InstructionOpcode::ExtractElement,
            LLVMOpcode::LLVMExtractValue => InstructionOpcode::ExtractValue,
            LLVMOpcode::LLVMFAdd => InstructionOpcode::FAdd,
            LLVMOpcode::LLVMFCmp => InstructionOpcode::FCmp,
            LLVMOpcode::LLVMFDiv => InstructionOpcode::FDiv,
            LLVMOpcode::LLVMFence => InstructionOpcode::Fence,
            LLVMOpcode::LLVMFMul => InstructionOpcode::FMul,
            LLVMOpcode::LLVMFPExt => InstructionOpcode::FPExt,
            LLVMOpcode::LLVMFPToSI => InstructionOpcode::FPToSI,
            LLVMOpcode::LLVMFPToUI => InstructionOpcode::FPToUI,
            LLVMOpcode::LLVMFPTrunc => InstructionOpcode::FPTrunc,
            LLVMOpcode::LLVMFRem => InstructionOpcode::FRem,
            LLVMOpcode::LLVMFSub => InstructionOpcode::FSub,
            LLVMOpcode::LLVMGetElementPtr => InstructionOpcode::GetElementPtr,
            LLVMOpcode::LLVMICmp => InstructionOpcode::ICmp,
            LLVMOpcode::LLVMIndirectBr => InstructionOpcode::IndirectBr,
            LLVMOpcode::LLVMInsertElement => InstructionOpcode::InsertElement,
            LLVMOpcode::LLVMInsertValue => InstructionOpcode::InsertValue,
            LLVMOpcode::LLVMIntToPtr => InstructionOpcode::IntToPtr,
            LLVMOpcode::LLVMInvoke => InstructionOpcode::Invoke,
            LLVMOpcode::LLVMLandingPad => InstructionOpcode::LandingPad,
            LLVMOpcode::LLVMLoad => InstructionOpcode::Load,
            LLVMOpcode::LLVMLShr => InstructionOpcode::LShr,
            LLVMOpcode::LLVMMul => InstructionOpcode::Mul,
            LLVMOpcode::LLVMOr => InstructionOpcode::Or,
            LLVMOpcode::LLVMPHI => InstructionOpcode::Phi,
            LLVMOpcode::LLVMPtrToInt => InstructionOpcode::PtrToInt,
            LLVMOpcode::LLVMResume => InstructionOpcode::Resume,
            LLVMOpcode::LLVMRet => InstructionOpcode::Return,
            LLVMOpcode::LLVMSDiv => InstructionOpcode::SDiv,
            LLVMOpcode::LLVMSelect => InstructionOpcode::Select,
            LLVMOpcode::LLVMSExt => InstructionOpcode::SExt,
            LLVMOpcode::LLVMShl => InstructionOpcode::Shl,
            LLVMOpcode::LLVMShuffleVector => InstructionOpcode::ShuffleVector,
            LLVMOpcode::LLVMSIToFP => InstructionOpcode::SIToFP,
            LLVMOpcode::LLVMSRem => InstructionOpcode::SRem,
            LLVMOpcode::LLVMStore => InstructionOpcode::Store,
            LLVMOpcode::LLVMSub => InstructionOpcode::Sub,
            LLVMOpcode::LLVMSwitch => InstructionOpcode::Switch,
            LLVMOpcode::LLVMTrunc => InstructionOpcode::Trunc,
            LLVMOpcode::LLVMUDiv => InstructionOpcode::UDiv,
            LLVMOpcode::LLVMUIToFP => InstructionOpcode::UIToFP,
            LLVMOpcode::LLVMUnreachable => InstructionOpcode::Unreachable,
            LLVMOpcode::LLVMURem => InstructionOpcode::URem,
            LLVMOpcode::LLVMUserOp1 => InstructionOpcode::UserOp1,
            LLVMOpcode::LLVMUserOp2 => InstructionOpcode::UserOp2,
            LLVMOpcode::LLVMVAArg => InstructionOpcode::VAArg,
            LLVMOpcode::LLVMXor => InstructionOpcode::Xor,
            LLVMOpcode::LLVMZExt => InstructionOpcode::ZExt,
        }
    }

    pub(crate) fn as_llvm_opcode(&self) -> LLVMOpcode {
        match *self {
            InstructionOpcode::Add => LLVMOpcode::LLVMAdd,
            InstructionOpcode::AddrSpaceCast => LLVMOpcode::LLVMAddrSpaceCast,
            InstructionOpcode::Alloca => LLVMOpcode::LLVMAlloca,
            InstructionOpcode::And => LLVMOpcode::LLVMAnd,
            InstructionOpcode::AShr => LLVMOpcode::LLVMAShr,
            InstructionOpcode::AtomicCmpXchg => LLVMOpcode::LLVMAtomicCmpXchg,
            InstructionOpcode::AtomicRMW => LLVMOpcode::LLVMAtomicRMW,
            InstructionOpcode::BitCast => LLVMOpcode::LLVMBitCast,
            InstructionOpcode::Br => LLVMOpcode::LLVMBr,
            InstructionOpcode::Call => LLVMOpcode::LLVMCall,
            // Newer versions:
            // InstructionOpcode::CatchPad => LLVMOpcode::LLVMCatchPad,
            // InstructionOpcode::CatchRet => LLVMOpcode::LLVMCatchRet,
            // InstructionOpcode::CatchSwitch => LLVMOpcode::LLVMCatchSwitch,
            // InstructionOpcode::CleanupPad => LLVMOpcode::LLVMCleanupPad,
            // InstructionOpcode::CleanupRet => LLVMOpcode::LLVMCleanupRet,
            InstructionOpcode::ExtractElement => LLVMOpcode::LLVMExtractElement,
            InstructionOpcode::ExtractValue => LLVMOpcode::LLVMExtractValue,
            InstructionOpcode::FAdd => LLVMOpcode::LLVMFAdd,
            InstructionOpcode::FCmp => LLVMOpcode::LLVMFCmp,
            InstructionOpcode::FDiv => LLVMOpcode::LLVMFDiv,
            InstructionOpcode::Fence => LLVMOpcode::LLVMFence,
            InstructionOpcode::FMul => LLVMOpcode::LLVMFMul,
            InstructionOpcode::FPExt => LLVMOpcode::LLVMFPExt,
            InstructionOpcode::FPToSI => LLVMOpcode::LLVMFPToSI,
            InstructionOpcode::FPToUI => LLVMOpcode::LLVMFPToUI,
            InstructionOpcode::FPTrunc => LLVMOpcode::LLVMFPTrunc,
            InstructionOpcode::FRem => LLVMOpcode::LLVMFRem,
            InstructionOpcode::FSub => LLVMOpcode::LLVMFSub,
            InstructionOpcode::GetElementPtr => LLVMOpcode::LLVMGetElementPtr,
            InstructionOpcode::ICmp => LLVMOpcode::LLVMICmp,
            InstructionOpcode::IndirectBr => LLVMOpcode::LLVMIndirectBr,
            InstructionOpcode::InsertElement => LLVMOpcode::LLVMInsertElement,
            InstructionOpcode::InsertValue => LLVMOpcode::LLVMInsertValue,
            InstructionOpcode::IntToPtr => LLVMOpcode::LLVMIntToPtr,
            InstructionOpcode::Invoke => LLVMOpcode::LLVMInvoke,
            InstructionOpcode::LandingPad => LLVMOpcode::LLVMLandingPad,
            InstructionOpcode::Load => LLVMOpcode::LLVMLoad,
            InstructionOpcode::LShr => LLVMOpcode::LLVMLShr,
            InstructionOpcode::Mul => LLVMOpcode::LLVMMul,
            InstructionOpcode::Or => LLVMOpcode::LLVMOr,
            InstructionOpcode::Phi => LLVMOpcode::LLVMPHI,
            InstructionOpcode::PtrToInt => LLVMOpcode::LLVMPtrToInt,
            InstructionOpcode::Resume => LLVMOpcode::LLVMResume,
            InstructionOpcode::Return => LLVMOpcode::LLVMRet,
            InstructionOpcode::SDiv => LLVMOpcode::LLVMSDiv,
            InstructionOpcode::Select => LLVMOpcode::LLVMSelect,
            InstructionOpcode::SExt => LLVMOpcode::LLVMSExt,
            InstructionOpcode::Shl => LLVMOpcode::LLVMShl,
            InstructionOpcode::ShuffleVector => LLVMOpcode::LLVMShuffleVector,
            InstructionOpcode::SIToFP => LLVMOpcode::LLVMSIToFP,
            InstructionOpcode::SRem => LLVMOpcode::LLVMSRem,
            InstructionOpcode::Store => LLVMOpcode::LLVMStore,
            InstructionOpcode::Sub => LLVMOpcode::LLVMSub,
            InstructionOpcode::Switch => LLVMOpcode::LLVMSwitch,
            InstructionOpcode::Trunc => LLVMOpcode::LLVMTrunc,
            InstructionOpcode::UDiv => LLVMOpcode::LLVMUDiv,
            InstructionOpcode::UIToFP => LLVMOpcode::LLVMUIToFP,
            InstructionOpcode::Unreachable => LLVMOpcode::LLVMUnreachable,
            InstructionOpcode::URem => LLVMOpcode::LLVMURem,
            InstructionOpcode::UserOp1 => LLVMOpcode::LLVMUserOp1,
            InstructionOpcode::UserOp2 => LLVMOpcode::LLVMUserOp2,
            InstructionOpcode::VAArg => LLVMOpcode::LLVMVAArg,
            InstructionOpcode::Xor => LLVMOpcode::LLVMXor,
            InstructionOpcode::ZExt => LLVMOpcode::LLVMZExt,
        }
    }
}

#[derive(Debug, PartialEq, Eq, Copy)]
pub struct InstructionValue {
    instruction_value: Value,
}

impl InstructionValue {
    pub(crate) fn new(instruction_value: LLVMValueRef) -> Self {
        assert!(!instruction_value.is_null());

        let value = Value::new(instruction_value);

        assert!(value.is_instruction());

        InstructionValue {
            instruction_value: value,
        }
    }

    pub fn get_opcode(&self) -> InstructionOpcode {
        let opcode = unsafe {
            LLVMGetInstructionOpcode(self.as_value_ref())
        };

        InstructionOpcode::new(opcode)
    }

    pub fn get_previous_instruction(&self) -> Option<Self> {
        let value = unsafe {
            LLVMGetPreviousInstruction(self.as_value_ref())
        };

        if value.is_null() {
            return None;
        }

        Some(InstructionValue::new(value))
    }

    pub fn get_next_instruction(&self) -> Option<Self> {
        let value = unsafe {
            LLVMGetNextInstruction(self.as_value_ref())
        };

        if value.is_null() {
            return None;
        }

        Some(InstructionValue::new(value))
    }

    // REVIEW: Potentially unsafe if parent BB or grandparent fn were removed?
    // REVIEW: Is this actually an erase and should be (self)?
    pub fn remove_from_basic_block(&self) {
        unsafe {
            LLVMInstructionEraseFromParent(self.as_value_ref())
        }
    }

    // REVIEW: Potentially unsafe is parent BB or grandparent fn was deleted
    // REVIEW: Should this *not* be an option? Parent should always exist,
    // but I doubt LLVM returns null if the parent BB (or grandparent FN)
    // was deleted... Invalid memory is more likely
    pub fn get_parent(&self) -> Option<BasicBlock> {
        let value = unsafe {
            LLVMGetInstructionParent(self.as_value_ref())
        };

        BasicBlock::new(value)
    }

    // REVIEW: See if necessary to check opcode == Call first.
    // Does it always return false otherwise?
    pub fn is_tail_call(&self) -> bool {
        unsafe {
            LLVMIsTailCall(self.as_value_ref()) == 1
        }
    }

    pub fn replace_all_uses_with(&self, other: &InstructionValue) {
        self.instruction_value.replace_all_uses_with(other.as_value_ref())
    }

    // SubTypes: Only apply to memory access instructions
    /// Returns whether or not a memory access instruction is volatile.
    pub fn get_volatile(&self) -> bool {
        unsafe {
            LLVMGetVolatile(self.as_value_ref()) == 1
        }
    }

    // SubTypes: Only apply to memory access instructions
    /// Sets whether or not a memory access instruction is volatile.
    pub fn set_volatile(&self, volatile: bool) {
        unsafe {
            LLVMSetVolatile(self.as_value_ref(), volatile as i32)
        }
    }
}

impl Clone for InstructionValue {
    /// Creates a clone of this `InstructionValue`, and returns it.
    /// The clone will have no parent, and no name.
    fn clone(&self) -> Self {
        let value = unsafe {
            LLVMInstructionClone(self.as_value_ref())
        };

        InstructionValue::new(value)
    }
}

impl AsValueRef for InstructionValue {
    fn as_value_ref(&self) -> LLVMValueRef {
        self.instruction_value.value
    }
}
<|endoftext|>


<commit_before>//! MD5 (Message-Digest Algorithm version 5)
//!
//! # WARNING!!!
//!
//! This hash function has been severely compromised. **Do not use!**
//!
//! Instead you should use SHA-2 or SHA-3 family (if security required) or Tiger (if speed required).
//!
//! # General info
//!
//! | Name | Digest size | Block size | Rounds | Structure            | Reference           |
//! | ---- | ----------: | ---------: | ------:| -------------------- | ------------------- |
//! | MD5  |    128 bits |   512 bits |      4 | [Merkle–Damgård][md] | [RFC 1321][rfc1321] |
//!
//! [rfc1321]: https://tools.ietf.org/html/rfc1321 "The MD5 Message-Digest Algorithm"
//! [md]: https://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction

use byteorder::{ByteOrder, LittleEndian};
use typenum::consts::{U16, U64, U128};
use static_buffer::{FixedBuffer64, FixedBuf, StandardPadding};

use Digest;
use wrapping::*;

#[derive(Copy, Clone, Debug)]
struct State {
    a: w32,
    b: w32,
    c: w32,
    d: w32,
}

macro_rules! process {
    ($w:expr, $x:expr, $y:expr, $z:expr, $m:expr, $s:expr, $f:tt) => {
        $w = ($w + ($f($x, $y, $z)) + $m).rotate_left($s) + $x
    }
}

#[inline(always)]
fn f(u: w32, v: w32, w: w32) -> w32 {
    (u & v) | (!u & w)
}
#[inline(always)]
fn g(u: w32, v: w32, w: w32) -> w32 {
    (u & w) | (v & !w)
}
#[inline(always)]
fn h(u: w32, v: w32, w: w32) -> w32 {
    u ^ v ^ w
}
#[inline(always)]
fn i(u: w32, v: w32, w: w32) -> w32 {
    v ^ (u | !w)
}

impl State {
    fn new() -> Self {
        State {
            a: W(0x67452301),
            b: W(0xefcdab89),
            c: W(0x98badcfe),
            d: W(0x10325476),
        }
    }

    #[inline(always)]
    fn compress(&mut self, input: &[u8]) {
        let State { mut a, mut b, mut c, mut d } = *self;

        let mut data = [W(0); 16];

        for (v, c) in data.iter_mut().zip(input.chunks(4)) {
            *v = W(LittleEndian::read_u32(c));
        }

        // round 1
        process!(a, b, c, d, data[0] + CONSTS[0][0], 7, f);
        process!(d, a, b, c, data[1] + CONSTS[0][1], 12, f);
        process!(c, d, a, b, data[2] + CONSTS[0][2], 17, f);
        process!(b, c, d, a, data[3] + CONSTS[0][3], 22, f);

        process!(a, b, c, d, data[4] + CONSTS[0][4], 7, f);
        process!(d, a, b, c, data[5] + CONSTS[0][5], 12, f);
        process!(c, d, a, b, data[6] + CONSTS[0][6], 17, f);
        process!(b, c, d, a, data[7] + CONSTS[0][7], 22, f);

        process!(a, b, c, d, data[8] + CONSTS[0][8], 7, f);
        process!(d, a, b, c, data[9] + CONSTS[0][9], 12, f);
        process!(c, d, a, b, data[10] + CONSTS[0][10], 17, f);
        process!(b, c, d, a, data[11] + CONSTS[0][11], 22, f);

        process!(a, b, c, d, data[12] + CONSTS[0][12], 7, f);
        process!(d, a, b, c, data[13] + CONSTS[0][13], 12, f);
        process!(c, d, a, b, data[14] + CONSTS[0][14], 17, f);
        process!(b, c, d, a, data[15] + CONSTS[0][15], 22, f);

        // round 2
        process!(a, b, c, d, data[1] + CONSTS[1][0], 5, g);
        process!(d, a, b, c, data[6] + CONSTS[1][1], 9, g);
        process!(c, d, a, b, data[11] + CONSTS[1][2], 14, g);
        process!(b, c, d, a, data[0] + CONSTS[1][3], 20, g);

        process!(a, b, c, d, data[5] + CONSTS[1][4], 5, g);
        process!(d, a, b, c, data[10] + CONSTS[1][5], 9, g);
        process!(c, d, a, b, data[15] + CONSTS[1][6], 14, g);
        process!(b, c, d, a, data[4] + CONSTS[1][7], 20, g);

        process!(a, b, c, d, data[9] + CONSTS[1][8], 5, g);
        process!(d, a, b, c, data[14] + CONSTS[1][9], 9, g);
        process!(c, d, a, b, data[3] + CONSTS[1][10], 14, g);
        process!(b, c, d, a, data[8] + CONSTS[1][11], 20, g);

        process!(a, b, c, d, data[13] + CONSTS[1][12], 5, g);
        process!(d, a, b, c, data[2] + CONSTS[1][13], 9, g);
        process!(c, d, a, b, data[7] + CONSTS[1][14], 14, g);
        process!(b, c, d, a, data[12] + CONSTS[1][15], 20, g);

        // round 3
        process!(a, b, c, d, data[5] + CONSTS[2][0], 4, h);
        process!(d, a, b, c, data[8] + CONSTS[2][1], 11, h);
        process!(c, d, a, b, data[11] + CONSTS[2][2], 16, h);
        process!(b, c, d, a, data[14] + CONSTS[2][3], 23, h);

        process!(a, b, c, d, data[1] + CONSTS[2][4], 4, h);
        process!(d, a, b, c, data[4] + CONSTS[2][5], 11, h);
        process!(c, d, a, b, data[7] + CONSTS[2][6], 16, h);
        process!(b, c, d, a, data[10] + CONSTS[2][7], 23, h);

        process!(a, b, c, d, data[13] + CONSTS[2][8], 4, h);
        process!(d, a, b, c, data[0] + CONSTS[2][9], 11, h);
        process!(c, d, a, b, data[3] + CONSTS[2][10], 16, h);
        process!(b, c, d, a, data[6] + CONSTS[2][11], 23, h);

        process!(a, b, c, d, data[9] + CONSTS[2][12], 4, h);
        process!(d, a, b, c, data[12] + CONSTS[2][13], 11, h);
        process!(c, d, a, b, data[15] + CONSTS[2][14], 16, h);
        process!(b, c, d, a, data[2] + CONSTS[2][15], 23, h);

        // round 4
        process!(a, b, c, d, data[0] + CONSTS[3][0], 6, i);
        process!(d, a, b, c, data[7] + CONSTS[3][1], 10, i);
        process!(c, d, a, b, data[14] + CONSTS[3][2], 15, i);
        process!(b, c, d, a, data[5] + CONSTS[3][3], 21, i);

        process!(a, b, c, d, data[12] + CONSTS[3][4], 6, i);
        process!(d, a, b, c, data[3] + CONSTS[3][5], 10, i);
        process!(c, d, a, b, data[10] + CONSTS[3][6], 15, i);
        process!(b, c, d, a, data[1] + CONSTS[3][7], 21, i);

        process!(a, b, c, d, data[8] + CONSTS[3][8], 6, i);
        process!(d, a, b, c, data[15] + CONSTS[3][9], 10, i);
        process!(c, d, a, b, data[6] + CONSTS[3][10], 15, i);
        process!(b, c, d, a, data[13] + CONSTS[3][11], 21, i);

        process!(a, b, c, d, data[4] + CONSTS[3][12], 6, i);
        process!(d, a, b, c, data[11] + CONSTS[3][13], 10, i);
        process!(c, d, a, b, data[2] + CONSTS[3][14], 15, i);
        process!(b, c, d, a, data[9] + CONSTS[3][15], 21, i);

        self.a += a;
        self.b += b;
        self.c += c;
        self.d += d;
    }
}

static CONSTS: [[w32; 16]; 4] = [[W(0xd76aa478),
                                  W(0xe8c7b756),
                                  W(0x242070db),
                                  W(0xc1bdceee),
                                  W(0xf57c0faf),
                                  W(0x4787c62a),
                                  W(0xa8304613),
                                  W(0xfd469501),
                                  W(0x698098d8),
                                  W(0x8b44f7af),
                                  W(0xffff5bb1),
                                  W(0x895cd7be),
                                  W(0x6b901122),
                                  W(0xfd987193),
                                  W(0xa679438e),
                                  W(0x49b40821)],
                                 [W(0xf61e2562),
                                  W(0xc040b340),
                                  W(0x265e5a51),
                                  W(0xe9b6c7aa),
                                  W(0xd62f105d),
                                  W(0x02441453),
                                  W(0xd8a1e681),
                                  W(0xe7d3fbc8),
                                  W(0x21e1cde6),
                                  W(0xc33707d6),
                                  W(0xf4d50d87),
                                  W(0x455a14ed),
                                  W(0xa9e3e905),
                                  W(0xfcefa3f8),
                                  W(0x676f02d9),
                                  W(0x8d2a4c8a)],
                                 [W(0xfffa3942),
                                  W(0x8771f681),
                                  W(0x6d9d6122),
                                  W(0xfde5380c),
                                  W(0xa4beea44),
                                  W(0x4bdecfa9),
                                  W(0xf6bb4b60),
                                  W(0xbebfbc70),
                                  W(0x289b7ec6),
                                  W(0xeaa127fa),
                                  W(0xd4ef3085),
                                  W(0x04881d05),
                                  W(0xd9d4d039),
                                  W(0xe6db99e5),
                                  W(0x1fa27cf8),
                                  W(0xc4ac5665)],
                                 [W(0xf4292244),
                                  W(0x432aff97),
                                  W(0xab9423a7),
                                  W(0xfc93a039),
                                  W(0x655b59c3),
                                  W(0x8f0ccc92),
                                  W(0xffeff47d),
                                  W(0x85845dd1),
                                  W(0x6fa87e4f),
                                  W(0xfe2ce6e0),
                                  W(0xa3014314),
                                  W(0x4e0811a1),
                                  W(0xf7537e82),
                                  W(0xbd3af235),
                                  W(0x2ad7d2bb),
                                  W(0xeb86d391)]];

/// MD5 implementation
///
/// For more details check [module docs](index.html)
#[derive(Clone)]
pub struct Md5 {
    state: State,
    length: u64,
    buffer: FixedBuffer64,
}

impl Default for Md5 {
    fn default() -> Self {
        Md5 {
            state: State::new(),
            length: 0,
            buffer: FixedBuffer64::new(),
        }
    }
}

impl Digest for Md5 {
    type OutputBits = U128;
    type OutputBytes = U16;

    type BlockSize = U64;

    fn update<T>(&mut self, input: T)
        where T: AsRef<[u8]>
    {
        let input = input.as_ref();
        self.length += input.len() as u64;

        let state = &mut self.state;
        self.buffer.input(&input[..], |d| state.compress(d));
    }

    fn result<T: AsMut<[u8]>>(mut self, mut out: T) {
        let state = &mut self.state;

        self.buffer.standard_padding(8, |d| state.compress(d));
        LittleEndian::write_u64(self.buffer.next(8), self.length << 3);
        state.compress(self.buffer.full_buffer());

        let mut out = out.as_mut();
        assert!(out.len() >= Self::output_bytes());
        LittleEndian::write_u32(&mut out[0..4], state.a.0);
        LittleEndian::write_u32(&mut out[4..8], state.b.0);
        LittleEndian::write_u32(&mut out[8..12], state.c.0);
        LittleEndian::write_u32(&mut out[12..16], state.d.0);
    }
}
<commit_msg>fix(digest): use ident instead of tt in macro<commit_after>//! MD5 (Message-Digest Algorithm version 5)
//!
//! # WARNING!!!
//!
//! This hash function has been severely compromised. **Do not use!**
//!
//! Instead you should use SHA-2 or SHA-3 family (if security required) or Tiger (if speed required).
//!
//! # General info
//!
//! | Name | Digest size | Block size | Rounds | Structure            | Reference           |
//! | ---- | ----------: | ---------: | ------:| -------------------- | ------------------- |
//! | MD5  |    128 bits |   512 bits |      4 | [Merkle–Damgård][md] | [RFC 1321][rfc1321] |
//!
//! [rfc1321]: https://tools.ietf.org/html/rfc1321 "The MD5 Message-Digest Algorithm"
//! [md]: https://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction

use byteorder::{ByteOrder, LittleEndian};
use typenum::consts::{U16, U64, U128};
use static_buffer::{FixedBuffer64, FixedBuf, StandardPadding};

use Digest;
use wrapping::*;

#[derive(Copy, Clone, Debug)]
struct State {
    a: w32,
    b: w32,
    c: w32,
    d: w32,
}

macro_rules! process {
    ($w:expr, $x:expr, $y:expr, $z:expr, $m:expr, $s:expr, $f:ident) => {
        $w = ($w + $f($x, $y, $z) + $m).rotate_left($s) + $x
    }
}

#[inline(always)]
fn f(u: w32, v: w32, w: w32) -> w32 {
    (u & v) | (!u & w)
}
#[inline(always)]
fn g(u: w32, v: w32, w: w32) -> w32 {
    (u & w) | (v & !w)
}
#[inline(always)]
fn h(u: w32, v: w32, w: w32) -> w32 {
    u ^ v ^ w
}
#[inline(always)]
fn i(u: w32, v: w32, w: w32) -> w32 {
    v ^ (u | !w)
}

impl State {
    fn new() -> Self {
        State {
            a: W(0x67452301),
            b: W(0xefcdab89),
            c: W(0x98badcfe),
            d: W(0x10325476),
        }
    }

    #[inline(always)]
    fn compress(&mut self, input: &[u8]) {
        let State { mut a, mut b, mut c, mut d } = *self;

        let mut data = [W(0); 16];

        for (v, c) in data.iter_mut().zip(input.chunks(4)) {
            *v = W(LittleEndian::read_u32(c));
        }

        // round 1
        process!(a, b, c, d, data[0] + CONSTS[0][0], 7, f);
        process!(d, a, b, c, data[1] + CONSTS[0][1], 12, f);
        process!(c, d, a, b, data[2] + CONSTS[0][2], 17, f);
        process!(b, c, d, a, data[3] + CONSTS[0][3], 22, f);

        process!(a, b, c, d, data[4] + CONSTS[0][4], 7, f);
        process!(d, a, b, c, data[5] + CONSTS[0][5], 12, f);
        process!(c, d, a, b, data[6] + CONSTS[0][6], 17, f);
        process!(b, c, d, a, data[7] + CONSTS[0][7], 22, f);

        process!(a, b, c, d, data[8] + CONSTS[0][8], 7, f);
        process!(d, a, b, c, data[9] + CONSTS[0][9], 12, f);
        process!(c, d, a, b, data[10] + CONSTS[0][10], 17, f);
        process!(b, c, d, a, data[11] + CONSTS[0][11], 22, f);

        process!(a, b, c, d, data[12] + CONSTS[0][12], 7, f);
        process!(d, a, b, c, data[13] + CONSTS[0][13], 12, f);
        process!(c, d, a, b, data[14] + CONSTS[0][14], 17, f);
        process!(b, c, d, a, data[15] + CONSTS[0][15], 22, f);

        // round 2
        process!(a, b, c, d, data[1] + CONSTS[1][0], 5, g);
        process!(d, a, b, c, data[6] + CONSTS[1][1], 9, g);
        process!(c, d, a, b, data[11] + CONSTS[1][2], 14, g);
        process!(b, c, d, a, data[0] + CONSTS[1][3], 20, g);

        process!(a, b, c, d, data[5] + CONSTS[1][4], 5, g);
        process!(d, a, b, c, data[10] + CONSTS[1][5], 9, g);
        process!(c, d, a, b, data[15] + CONSTS[1][6], 14, g);
        process!(b, c, d, a, data[4] + CONSTS[1][7], 20, g);

        process!(a, b, c, d, data[9] + CONSTS[1][8], 5, g);
        process!(d, a, b, c, data[14] + CONSTS[1][9], 9, g);
        process!(c, d, a, b, data[3] + CONSTS[1][10], 14, g);
        process!(b, c, d, a, data[8] + CONSTS[1][11], 20, g);

        process!(a, b, c, d, data[13] + CONSTS[1][12], 5, g);
        process!(d, a, b, c, data[2] + CONSTS[1][13], 9, g);
        process!(c, d, a, b, data[7] + CONSTS[1][14], 14, g);
        process!(b, c, d, a, data[12] + CONSTS[1][15], 20, g);

        // round 3
        process!(a, b, c, d, data[5] + CONSTS[2][0], 4, h);
        process!(d, a, b, c, data[8] + CONSTS[2][1], 11, h);
        process!(c, d, a, b, data[11] + CONSTS[2][2], 16, h);
        process!(b, c, d, a, data[14] + CONSTS[2][3], 23, h);

        process!(a, b, c, d, data[1] + CONSTS[2][4], 4, h);
        process!(d, a, b, c, data[4] + CONSTS[2][5], 11, h);
        process!(c, d, a, b, data[7] + CONSTS[2][6], 16, h);
        process!(b, c, d, a, data[10] + CONSTS[2][7], 23, h);

        process!(a, b, c, d, data[13] + CONSTS[2][8], 4, h);
        process!(d, a, b, c, data[0] + CONSTS[2][9], 11, h);
        process!(c, d, a, b, data[3] + CONSTS[2][10], 16, h);
        process!(b, c, d, a, data[6] + CONSTS[2][11], 23, h);

        process!(a, b, c, d, data[9] + CONSTS[2][12], 4, h);
        process!(d, a, b, c, data[12] + CONSTS[2][13], 11, h);
        process!(c, d, a, b, data[15] + CONSTS[2][14], 16, h);
        process!(b, c, d, a, data[2] + CONSTS[2][15], 23, h);

        // round 4
        process!(a, b, c, d, data[0] + CONSTS[3][0], 6, i);
        process!(d, a, b, c, data[7] + CONSTS[3][1], 10, i);
        process!(c, d, a, b, data[14] + CONSTS[3][2], 15, i);
        process!(b, c, d, a, data[5] + CONSTS[3][3], 21, i);

        process!(a, b, c, d, data[12] + CONSTS[3][4], 6, i);
        process!(d, a, b, c, data[3] + CONSTS[3][5], 10, i);
        process!(c, d, a, b, data[10] + CONSTS[3][6], 15, i);
        process!(b, c, d, a, data[1] + CONSTS[3][7], 21, i);

        process!(a, b, c, d, data[8] + CONSTS[3][8], 6, i);
        process!(d, a, b, c, data[15] + CONSTS[3][9], 10, i);
        process!(c, d, a, b, data[6] + CONSTS[3][10], 15, i);
        process!(b, c, d, a, data[13] + CONSTS[3][11], 21, i);

        process!(a, b, c, d, data[4] + CONSTS[3][12], 6, i);
        process!(d, a, b, c, data[11] + CONSTS[3][13], 10, i);
        process!(c, d, a, b, data[2] + CONSTS[3][14], 15, i);
        process!(b, c, d, a, data[9] + CONSTS[3][15], 21, i);

        self.a += a;
        self.b += b;
        self.c += c;
        self.d += d;
    }
}

static CONSTS: [[w32; 16]; 4] = [[W(0xd76aa478),
                                  W(0xe8c7b756),
                                  W(0x242070db),
                                  W(0xc1bdceee),
                                  W(0xf57c0faf),
                                  W(0x4787c62a),
                                  W(0xa8304613),
                                  W(0xfd469501),
                                  W(0x698098d8),
                                  W(0x8b44f7af),
                                  W(0xffff5bb1),
                                  W(0x895cd7be),
                                  W(0x6b901122),
                                  W(0xfd987193),
                                  W(0xa679438e),
                                  W(0x49b40821)],
                                 [W(0xf61e2562),
                                  W(0xc040b340),
                                  W(0x265e5a51),
                                  W(0xe9b6c7aa),
                                  W(0xd62f105d),
                                  W(0x02441453),
                                  W(0xd8a1e681),
                                  W(0xe7d3fbc8),
                                  W(0x21e1cde6),
                                  W(0xc33707d6),
                                  W(0xf4d50d87),
                                  W(0x455a14ed),
                                  W(0xa9e3e905),
                                  W(0xfcefa3f8),
                                  W(0x676f02d9),
                                  W(0x8d2a4c8a)],
                                 [W(0xfffa3942),
                                  W(0x8771f681),
                                  W(0x6d9d6122),
                                  W(0xfde5380c),
                                  W(0xa4beea44),
                                  W(0x4bdecfa9),
                                  W(0xf6bb4b60),
                                  W(0xbebfbc70),
                                  W(0x289b7ec6),
                                  W(0xeaa127fa),
                                  W(0xd4ef3085),
                                  W(0x04881d05),
                                  W(0xd9d4d039),
                                  W(0xe6db99e5),
                                  W(0x1fa27cf8),
                                  W(0xc4ac5665)],
                                 [W(0xf4292244),
                                  W(0x432aff97),
                                  W(0xab9423a7),
                                  W(0xfc93a039),
                                  W(0x655b59c3),
                                  W(0x8f0ccc92),
                                  W(0xffeff47d),
                                  W(0x85845dd1),
                                  W(0x6fa87e4f),
                                  W(0xfe2ce6e0),
                                  W(0xa3014314),
                                  W(0x4e0811a1),
                                  W(0xf7537e82),
                                  W(0xbd3af235),
                                  W(0x2ad7d2bb),
                                  W(0xeb86d391)]];

/// MD5 implementation
///
/// For more details check [module docs](index.html)
#[derive(Clone)]
pub struct Md5 {
    state: State,
    length: u64,
    buffer: FixedBuffer64,
}

impl Default for Md5 {
    fn default() -> Self {
        Md5 {
            state: State::new(),
            length: 0,
            buffer: FixedBuffer64::new(),
        }
    }
}

impl Digest for Md5 {
    type OutputBits = U128;
    type OutputBytes = U16;

    type BlockSize = U64;

    fn update<T>(&mut self, input: T)
        where T: AsRef<[u8]>
    {
        let input = input.as_ref();
        self.length += input.len() as u64;

        let state = &mut self.state;
        self.buffer.input(&input[..], |d| state.compress(d));
    }

    fn result<T: AsMut<[u8]>>(mut self, mut out: T) {
        let state = &mut self.state;

        self.buffer.standard_padding(8, |d| state.compress(d));
        LittleEndian::write_u64(self.buffer.next(8), self.length << 3);
        state.compress(self.buffer.full_buffer());

        let mut out = out.as_mut();
        assert!(out.len() >= Self::output_bytes());
        LittleEndian::write_u32(&mut out[0..4], state.a.0);
        LittleEndian::write_u32(&mut out[4..8], state.b.0);
        LittleEndian::write_u32(&mut out[8..12], state.c.0);
        LittleEndian::write_u32(&mut out[12..16], state.d.0);
    }
}
<|endoftext|>


<commit_before>use action::Action;
use config;
use context::base::BaseContext;
use dispatcher::Response;
use dispatcher::response::ResponseSender;
use message::{Builder, Message};
use std::cell::RefCell;
use std::rc::Rc;
use state::State;

#[derive(Clone)]
pub struct MessageAction {
    pub sender: Rc<RefCell<Box<ResponseSender<Response>>>>,
    pub action: config::action::MessageAction
}

#[derive(Debug)]
pub struct MessageResponse {
    message: Message,
    internal: bool
}

impl Action for MessageAction {
    fn execute(&self, _state: &State, _context: &BaseContext) {
        println!("MessageAction is executed");
        let mut message = Builder::new("d6621bd6-4898-4b8c-a4ff-36d0eed7d8dc")
                                .pair(".context.uuid", &_context.uuid().to_hyphenated_string())
                                .pair(".context.len", &_state.messages().len().to_string())
                                .build();
        if let Some(name) = _context.name() {
            message.insert(".context.name", name);
        }
        let response = MessageResponse {
            message: message,
            internal: true
        };
        self.sender.borrow_mut().send_response(Response::Message(response));
    }
}
<commit_msg>MessageResponse: remove 'internal' field<commit_after>use action::Action;
use config;
use context::base::BaseContext;
use dispatcher::Response;
use dispatcher::response::ResponseSender;
use message::{Builder, Message};
use std::cell::RefCell;
use std::rc::Rc;
use state::State;

#[derive(Clone)]
pub struct MessageAction {
    pub sender: Rc<RefCell<Box<ResponseSender<Response>>>>,
    pub action: config::action::MessageAction
}

#[derive(Debug)]
pub struct MessageResponse {
    message: Message,
}

impl Action for MessageAction {
    fn execute(&self, _state: &State, _context: &BaseContext) {
        println!("MessageAction is executed");
        let mut message = Builder::new("d6621bd6-4898-4b8c-a4ff-36d0eed7d8dc")
                                .pair(".context.uuid", &_context.uuid().to_hyphenated_string())
                                .pair(".context.len", &_state.messages().len().to_string())
                                .build();
        if let Some(name) = _context.name() {
            message.insert(".context.name", name);
        }
        let response = MessageResponse {
            message: message,
        };
        self.sender.borrow_mut().send_response(Response::Message(response));
    }
}
<|endoftext|>


<commit_before>#[allow(unused_imports)]
use quick_xml::events::Event;
#[allow(unused_imports)]
use quick_xml::Reader;

#[cfg(feature = "encoding")]
mod decode {
    use encoding_rs::{UTF_16BE, UTF_16LE, UTF_8};
    use quick_xml::encoding::*;
    use std::borrow::Cow;

    static UTF16BE_TEXT_WITH_BOM: &[u8] = include_bytes!("./documents/utf16be.xml");
    static UTF16LE_TEXT_WITH_BOM: &[u8] = include_bytes!("./documents/utf16le.xml");
    static UTF8_TEXT_WITH_BOM: &[u8] = include_bytes!("./documents/utf8.xml");

    static UTF8_TEXT: &str = r#"<?xml version="1.0"?>
<project name="project-name">
</project>
"#;

    #[test]
    fn test_removes_bom() {
        // No BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT.as_bytes()).unwrap(),
            Cow::Borrowed(UTF8_TEXT)
        );
        // BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT_WITH_BOM).unwrap(),
            Cow::Borrowed(UTF8_TEXT)
        );
        assert_eq!(
            decode_with_bom_removal(UTF16BE_TEXT_WITH_BOM).unwrap(),
            Cow::Borrowed(UTF8_TEXT).into_owned()
        );
        assert_eq!(
            decode_with_bom_removal(UTF16LE_TEXT_WITH_BOM).unwrap(),
            Cow::Borrowed(UTF8_TEXT).into_owned()
        );
    }

    #[test]
    fn test_detect_encoding() {
        // No BOM
        assert_eq!(detect_encoding(UTF8_TEXT.as_bytes()), Some(UTF_8));
        // BOM
        assert_eq!(detect_encoding(UTF8_TEXT_WITH_BOM), Some(UTF_8));
        assert_eq!(detect_encoding(UTF16BE_TEXT_WITH_BOM), Some(UTF_16BE));
        assert_eq!(detect_encoding(UTF16LE_TEXT_WITH_BOM), Some(UTF_16LE));
    }

    #[test]
    fn test_decode_with_bom_removal() {
        // No BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT.as_bytes()).unwrap(),
            UTF8_TEXT
        );
        // BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT_WITH_BOM).unwrap(),
            UTF8_TEXT
        );
        assert_eq!(
            decode_with_bom_removal(UTF16BE_TEXT_WITH_BOM).unwrap(),
            UTF8_TEXT
        );
        assert_eq!(
            decode_with_bom_removal(UTF16LE_TEXT_WITH_BOM).unwrap(),
            UTF8_TEXT
        );
    }
}

#[test]
#[cfg(feature = "encoding")]
fn test_koi8_r_encoding() {
    let src = include_bytes!("documents/opennews_all.rss").as_ref();
    let mut buf = vec![];
    let mut r = Reader::from_reader(src);
    r.trim_text(true).expand_empty_elements(false);
    loop {
        match r.read_event_into(&mut buf) {
            Ok(Event::Text(e)) => {
                e.unescape().unwrap();
            }
            Ok(Event::Eof) => break,
            _ => (),
        }
    }
}

#[test]
#[cfg(feature = "encoding")]
fn fuzz_53() {
    use std::io::Cursor;

    let data: &[u8] = b"\xe9\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\n(\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\
\x00<>\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<<\x00\x00\x00";
    let cursor = Cursor::new(data);
    let mut reader = Reader::from_reader(cursor);
    let mut buf = vec![];
    loop {
        match reader.read_event_into(&mut buf) {
            Ok(Event::Eof) | Err(..) => break,
            _ => buf.clear(),
        }
    }
}

#[test]
#[cfg(feature = "encoding")]
fn fuzz_101() {
    use std::io::Cursor;

    let data: &[u8] = b"\x00\x00<\x00\x00\x0a>&#44444444401?#\x0a413518\
                       #\x0a\x0a\x0a;<:<)(<:\x0a\x0a\x0a\x0a;<:\x0a\x0a\
                       <:\x0a\x0a\x0a\x0a\x0a<\x00*\x00\x00\x00\x00";
    let cursor = Cursor::new(data);
    let mut reader = Reader::from_reader(cursor);
    let mut buf = vec![];
    loop {
        match reader.read_event_into(&mut buf) {
            Ok(Event::Start(e)) | Ok(Event::Empty(e)) => {
                for a in e.attributes() {
                    if a.ok()
                        .map_or(true, |a| a.decode_and_unescape_value(&reader).is_err())
                    {
                        break;
                    }
                }
            }
            Ok(Event::Text(e)) => {
                if e.unescape().is_err() {
                    break;
                }
            }
            Ok(Event::Eof) | Err(..) => break,
            _ => (),
        }
        buf.clear();
    }
}
<commit_msg>Use pretty_assertions for encoding tests<commit_after>#[allow(unused_imports)]
use quick_xml::events::Event;
#[allow(unused_imports)]
use quick_xml::Reader;

#[cfg(feature = "encoding")]
mod decode {
    use encoding_rs::{UTF_16BE, UTF_16LE, UTF_8};
    use pretty_assertions::assert_eq;
    use quick_xml::encoding::*;
    use std::borrow::Cow;

    static UTF16BE_TEXT_WITH_BOM: &[u8] = include_bytes!("./documents/utf16be.xml");
    static UTF16LE_TEXT_WITH_BOM: &[u8] = include_bytes!("./documents/utf16le.xml");
    static UTF8_TEXT_WITH_BOM: &[u8] = include_bytes!("./documents/utf8.xml");

    static UTF8_TEXT: &str = r#"<?xml version="1.0"?>
<project name="project-name">
</project>
"#;

    #[test]
    fn test_removes_bom() {
        // No BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT.as_bytes()).unwrap(),
            Cow::Borrowed(UTF8_TEXT)
        );
        // BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT_WITH_BOM).unwrap(),
            Cow::Borrowed(UTF8_TEXT)
        );
        assert_eq!(
            decode_with_bom_removal(UTF16BE_TEXT_WITH_BOM).unwrap(),
            Cow::Borrowed(UTF8_TEXT).into_owned()
        );
        assert_eq!(
            decode_with_bom_removal(UTF16LE_TEXT_WITH_BOM).unwrap(),
            Cow::Borrowed(UTF8_TEXT).into_owned()
        );
    }

    #[test]
    fn test_detect_encoding() {
        // No BOM
        assert_eq!(detect_encoding(UTF8_TEXT.as_bytes()), Some(UTF_8));
        // BOM
        assert_eq!(detect_encoding(UTF8_TEXT_WITH_BOM), Some(UTF_8));
        assert_eq!(detect_encoding(UTF16BE_TEXT_WITH_BOM), Some(UTF_16BE));
        assert_eq!(detect_encoding(UTF16LE_TEXT_WITH_BOM), Some(UTF_16LE));
    }

    #[test]
    fn test_decode_with_bom_removal() {
        // No BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT.as_bytes()).unwrap(),
            UTF8_TEXT
        );
        // BOM
        assert_eq!(
            decode_with_bom_removal(UTF8_TEXT_WITH_BOM).unwrap(),
            UTF8_TEXT
        );
        assert_eq!(
            decode_with_bom_removal(UTF16BE_TEXT_WITH_BOM).unwrap(),
            UTF8_TEXT
        );
        assert_eq!(
            decode_with_bom_removal(UTF16LE_TEXT_WITH_BOM).unwrap(),
            UTF8_TEXT
        );
    }
}

#[test]
#[cfg(feature = "encoding")]
fn test_koi8_r_encoding() {
    let src = include_bytes!("documents/opennews_all.rss").as_ref();
    let mut buf = vec![];
    let mut r = Reader::from_reader(src);
    r.trim_text(true).expand_empty_elements(false);
    loop {
        match r.read_event_into(&mut buf) {
            Ok(Event::Text(e)) => {
                e.unescape().unwrap();
            }
            Ok(Event::Eof) => break,
            _ => (),
        }
    }
}

#[test]
#[cfg(feature = "encoding")]
fn fuzz_53() {
    use std::io::Cursor;

    let data: &[u8] = b"\xe9\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\n(\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\
\x00<>\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<<\x00\x00\x00";
    let cursor = Cursor::new(data);
    let mut reader = Reader::from_reader(cursor);
    let mut buf = vec![];
    loop {
        match reader.read_event_into(&mut buf) {
            Ok(Event::Eof) | Err(..) => break,
            _ => buf.clear(),
        }
    }
}

#[test]
#[cfg(feature = "encoding")]
fn fuzz_101() {
    use std::io::Cursor;

    let data: &[u8] = b"\x00\x00<\x00\x00\x0a>&#44444444401?#\x0a413518\
                       #\x0a\x0a\x0a;<:<)(<:\x0a\x0a\x0a\x0a;<:\x0a\x0a\
                       <:\x0a\x0a\x0a\x0a\x0a<\x00*\x00\x00\x00\x00";
    let cursor = Cursor::new(data);
    let mut reader = Reader::from_reader(cursor);
    let mut buf = vec![];
    loop {
        match reader.read_event_into(&mut buf) {
            Ok(Event::Start(e)) | Ok(Event::Empty(e)) => {
                for a in e.attributes() {
                    if a.ok()
                        .map_or(true, |a| a.decode_and_unescape_value(&reader).is_err())
                    {
                        break;
                    }
                }
            }
            Ok(Event::Text(e)) => {
                if e.unescape().is_err() {
                    break;
                }
            }
            Ok(Event::Eof) | Err(..) => break,
            _ => (),
        }
        buf.clear();
    }
}
<|endoftext|>


<commit_before>#![allow(clippy::vec_init_then_push)]

use std::path::PathBuf;

use xshell::pushd;

use crate::{cmd, Metadata, Result};

const MSRV: &str = "1.45";

/// Task to run CI tests.
pub struct CiTask {
    /// Which version of Rust to test against.
    version: Option<String>,

    /// The root of the workspace.
    project_root: PathBuf,
}

impl CiTask {
    pub(crate) fn new(version: Option<String>) -> Result<Self> {
        let project_root = Metadata::load()?.workspace_root;
        Ok(Self { version, project_root })
    }

    pub(crate) fn run(self) -> Result<()> {
        let _p = xshell::pushd(&self.project_root)?;

        match self.version.as_deref() {
            Some("msrv") => self.build_msrv()?,
            Some("stable") => self.build_stable()?,
            Some("nightly") => self.build_nightly()?,
            Some(_) => return Err("Wrong Rust version specified.".into()),
            None => {
                self.build_msrv().and(self.build_stable()).and(self.build_nightly())?;
            }
        }

        Ok(())
    }

    fn build_msrv(&self) -> xshell::Result<()> {
        let _p = pushd("ruma")?;
        cmd!("rustup run {MSRV} cargo build --features full --quiet").run()
    }

    fn build_stable(&self) -> xshell::Result<()> {
        let mut r = Vec::new();
        r.push(cmd!("rustup run stable cargo test --workspace --quiet").run());

        {
            let _p = pushd("ruma-identifiers")?;
            r.push(cmd!("rustup run stable cargo test --no-default-features --quiet").run());
            r.push(cmd!("rustup run stable cargo test --all-features --quiet").run());
        }

        {
            let _p = pushd("ruma-client-api");
            r.push(cmd!("rustup run stable cargo test --all-features --quiet").run());
        }

        {
            let _p = pushd("ruma-client")?;
            r.push(
                cmd!(
                    "rustup run stable cargo check
                        --no-default-features --features http1,http2 --quiet"
                )
                .run(),
            );
            r.push(
                cmd!(
                    "rustup run stable cargo check
                        --no-default-features --features http1,http2,tls-rustls-native-roots
                        --quiet"
                )
                .run(),
            );
            r.push(
                cmd!(
                    "rustup run stable cargo check
                        --no-default-features --features http1,http2,tls-rustls-webpki-roots
                        --quiet"
                )
                .run(),
            );
        }

        r.into_iter().collect()
    }

    fn build_nightly(&self) -> xshell::Result<()> {
        let mut r = Vec::new();
        r.push(cmd!("rustup run nightly cargo fmt --all").run());

        {
            let _p = pushd("ruma");
            r.push(
                cmd!(
                    "rustup run nightly cargo clippy
                        --all-targets --all-features --quiet -- -D warnings"
                )
                .run(),
            );
        }

        {
            let _p = pushd("ruma-client");
            r.push(
                cmd!("rustup run nightly cargo clippy --all-targets --quiet -- -D warnings").run(),
            );
        }

        r.into_iter().collect()
    }
}
<commit_msg>xtask: Fix cargo fmt usage<commit_after>#![allow(clippy::vec_init_then_push)]

use std::path::PathBuf;

use xshell::pushd;

use crate::{cmd, Metadata, Result};

const MSRV: &str = "1.45";

/// Task to run CI tests.
pub struct CiTask {
    /// Which version of Rust to test against.
    version: Option<String>,

    /// The root of the workspace.
    project_root: PathBuf,
}

impl CiTask {
    pub(crate) fn new(version: Option<String>) -> Result<Self> {
        let project_root = Metadata::load()?.workspace_root;
        Ok(Self { version, project_root })
    }

    pub(crate) fn run(self) -> Result<()> {
        let _p = xshell::pushd(&self.project_root)?;

        match self.version.as_deref() {
            Some("msrv") => self.build_msrv()?,
            Some("stable") => self.build_stable()?,
            Some("nightly") => self.build_nightly()?,
            Some(_) => return Err("Wrong Rust version specified.".into()),
            None => {
                self.build_msrv().and(self.build_stable()).and(self.build_nightly())?;
            }
        }

        Ok(())
    }

    fn build_msrv(&self) -> xshell::Result<()> {
        let _p = pushd("ruma")?;
        cmd!("rustup run {MSRV} cargo build --features full --quiet").run()
    }

    fn build_stable(&self) -> xshell::Result<()> {
        let mut r = Vec::new();
        r.push(cmd!("rustup run stable cargo test --workspace --quiet").run());

        {
            let _p = pushd("ruma-identifiers")?;
            r.push(cmd!("rustup run stable cargo test --no-default-features --quiet").run());
            r.push(cmd!("rustup run stable cargo test --all-features --quiet").run());
        }

        {
            let _p = pushd("ruma-client-api");
            r.push(cmd!("rustup run stable cargo test --all-features --quiet").run());
        }

        {
            let _p = pushd("ruma-client")?;
            r.push(
                cmd!(
                    "rustup run stable cargo check
                        --no-default-features --features http1,http2 --quiet"
                )
                .run(),
            );
            r.push(
                cmd!(
                    "rustup run stable cargo check
                        --no-default-features --features http1,http2,tls-rustls-native-roots
                        --quiet"
                )
                .run(),
            );
            r.push(
                cmd!(
                    "rustup run stable cargo check
                        --no-default-features --features http1,http2,tls-rustls-webpki-roots
                        --quiet"
                )
                .run(),
            );
        }

        r.into_iter().collect()
    }

    fn build_nightly(&self) -> xshell::Result<()> {
        let mut r = Vec::new();
        r.push(cmd!("rustup run nightly cargo fmt -- --check").run());

        {
            let _p = pushd("ruma");
            r.push(
                cmd!(
                    "rustup run nightly cargo clippy
                        --all-targets --all-features --quiet -- -D warnings"
                )
                .run(),
            );
        }

        {
            let _p = pushd("ruma-client");
            r.push(
                cmd!("rustup run nightly cargo clippy --all-targets --quiet -- -D warnings").run(),
            );
        }

        r.into_iter().collect()
    }
}
<|endoftext|>


<commit_before>//#![feature(trace_macros)]
#![allow(dead_code)]
#![cfg_attr(feature = "cargo-clippy", allow(redundant_closure))]

#[macro_use]
extern crate nom;

use nom::{space, Err, IResult, Needed, ErrorKind, le_u64, is_digit};
use nom::types::{CompleteStr, CompleteByteSlice};

#[allow(dead_code)]
struct Range {
  start: char,
  end: char,
}

pub fn take_char(input: &[u8]) -> IResult<&[u8], char> {
  if !input.is_empty() {
    Ok((&input[1..], input[0] as char))
  } else {
    Err(Err::Incomplete(Needed::Size(1)))
  }
}

//trace_macros!(true);

#[allow(dead_code)]
named!(range<&[u8], Range>,
    alt!(
        do_parse!(
            start: take_char >>
            tag!("-")        >>
            end: take_char   >>
            (Range {
                start: start,
                end:   end,
            })
        ) |
        map!(
            take_char,
            |c| {
                Range {
                    start: c,
                    end:   c,
                }
            }
        )
    )
);

#[allow(dead_code)]
named!(literal<&[u8], Vec<char> >,
    map!(
        many1!(take_char),
        |cs| {
          cs
        }
    )
);

#[test]
fn issue_58() {
  let _ = range(&b"abcd"[..]);
  let _ = literal(&b"abcd"[..]);
}

//trace_macros!(false);

#[cfg(feature = "std")]
mod parse_int {
  use nom::HexDisplay;
  use nom::{digit, space, IResult};
  use std::str;

  named!(parse_ints<Vec<i32>>, many0!(spaces_or_int));

  fn spaces_or_int(input: &[u8]) -> IResult<&[u8], i32> {
    println!("{}", input.to_hex(8));
    do_parse!(
      input,
      opt!(complete!(space)) >> res: map!(complete!(digit), |x| {
        println!("x: {:?}", x);
        let result = str::from_utf8(x).unwrap();
        println!("Result: {}", result);
        println!("int is empty?: {}", x.is_empty());
        match result.parse() {
          Ok(i) => i,
          Err(e) => panic!("UH OH! NOT A DIGIT! {:?}", e),
        }
      }) >> (res)
    )
  }

  #[test]
  fn issue_142() {
    let subject = parse_ints(&b"12 34 5689a"[..]);
    let expected = Ok((&b"a"[..], vec![12, 34, 5689]));
    assert_eq!(subject, expected);

    let subject = parse_ints(&b"12 34 5689 "[..]);
    let expected = Ok((&b" "[..], vec![12, 34, 5689]));
    assert_eq!(subject, expected)
  }
}

#[test]
fn usize_length_bytes_issue() {
  use nom::be_u16;
  let _: IResult<&[u8], &[u8], (&[u8], ErrorKind)> = length_bytes!(b"012346", be_u16);
}

/*
 DOES NOT COMPILE
#[test]
fn issue_152() {
  named!(take4, take!(4));
  named!(xyz, tag!("XYZ"));
  named!(abc, tag!("abc"));

  named!(sw,
    switch!(take4,
      b"abcd" => xyz |
      b"efgh" => abc
    )
  );
}
*/

#[test]
fn take_till_issue() {
  named!(nothing, take_till!(call!(|_| true)));

  assert_eq!(nothing(b""), Err(Err::Incomplete(Needed::Size(1))));
  assert_eq!(nothing(b"abc"), Ok((&b"abc"[..], &b""[..])));
}

named!(
  issue_498<Vec<&[u8]>>,
  separated_nonempty_list!(opt!(space), tag!("abcd"))
);

named!(issue_308(&str) -> bool,
    do_parse! (
        tag! ("foo") >>
        b: alt_complete! (
            map! (tag! ("1"), |_: &str|->bool {true}) |
            value! (false)
        ) >>
        (b) ));

#[cfg(feature = "alloc")]
fn issue_302(input: &[u8]) -> IResult<&[u8], Option<Vec<u64>>> {
  do_parse!(input, entries: cond!(true, count!(le_u64, 3)) >> (entries))
}

#[test]
fn issue_655() {
  use nom::{line_ending, not_line_ending};
  named!(twolines(&str) -> (&str, &str),
    do_parse!(
      l1 : not_line_ending >>
           line_ending >>
      l2 : not_line_ending >>
           line_ending >>
      ((l1, l2))
    )
  );

  assert_eq!(twolines("foo\nbar\n"), Ok(("", ("foo", "bar"))));
  assert_eq!(twolines("féo\nbar\n"), Ok(("", ("féo", "bar"))));
  assert_eq!(twolines("foé\nbar\n"), Ok(("", ("foé", "bar"))));
  assert_eq!(twolines("foé\r\nbar\n"), Ok(("", ("foé", "bar"))));
}

#[cfg(feature = "std")]
named!(issue_666 <CompleteByteSlice, CompleteByteSlice>, dbg_dmp!(tag!("abc")));

#[test]
fn issue_667() {
  use nom::alpha;

  named!(foo <CompleteByteSlice, Vec<CompleteByteSlice>>,
    many0!(
      alt!(alpha | is_a!("_"))
    )
  );
  assert_eq!(
    foo(CompleteByteSlice(b"")),
    Ok((CompleteByteSlice(b""), vec![]))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"loremipsum")),
    Ok((
      CompleteByteSlice(b""),
      vec![CompleteByteSlice(b"loremipsum")]
    ))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"lorem_ipsum")),
    Ok((
      CompleteByteSlice(b""),
      vec![
        CompleteByteSlice(b"lorem"),
        CompleteByteSlice(b"_"),
        CompleteByteSlice(b"ipsum"),
      ]
    ))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"_lorem_ipsum")),
    Ok((
      CompleteByteSlice(b""),
      vec![
        CompleteByteSlice(b"_"),
        CompleteByteSlice(b"lorem"),
        CompleteByteSlice(b"_"),
        CompleteByteSlice(b"ipsum"),
      ]
    ))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"!@#$")),
    Ok((CompleteByteSlice(b"!@#$"), vec![]))
  );
}

#[test]
fn issue_721() {
  named!(f1<&str, u16>, parse_to!(u16));
  named!(f2<&str, String>, parse_to!(String));
  assert_eq!(f1("1234"), Ok(("", 1234)));
  assert_eq!(f2("foo"), Ok(("", "foo".to_string())));
  //assert_eq!(parse_to!("1234", u16), Ok(("", 1234)));
  //assert_eq!(parse_to!("foo", String), Ok(("", "foo".to_string())));
}

#[cfg(feature = "alloc")]
named!(issue_717<&[u8], Vec<&[u8]> >,
  separated_list!(tag!([0x0]), is_not!([0x0u8]))
);

struct NoPartialEq {
  value: i32,
}

named!(issue_724<&str, i32>,
  do_parse!(
    metadata: permutation!(
      map!(tag!("hello"), |_| NoPartialEq { value: 1 }),
      map!(tag!("world"), |_| NoPartialEq { value: 2 })
    ) >>
    (metadata.0.value + metadata.1.value)
  )
);

named!(issue_741_str<CompleteStr, CompleteStr>, re_match!(r"^_?[A-Za-z][0-9A-Z_a-z-]*"));
named!(issue_741_bytes<CompleteByteSlice, CompleteByteSlice>, re_bytes_match!(r"^_?[A-Za-z][0-9A-Z_a-z-]*"));

#[test]
fn issue_752() {
    assert_eq!(
        Err::Error(("ab", nom::ErrorKind::ParseTo)),
        parse_to!("ab", usize).unwrap_err()
    )
}

fn atom_specials(c: u8) -> bool {
    c == b'q'
}

named!(
    capability<&str>,
    do_parse!(tag!(" ") >> _atom: map_res!(take_till1!(atom_specials), std::str::from_utf8) >> ("a"))
);

#[test]
fn issue_759() {
    assert_eq!(capability(b" abcqd"), Ok((&b"qd"[..], "a")));
}

named_args!(issue_771(count: usize)<Vec<u32>>,
  length_count!(value!(count), call!(nom::be_u32))
);

#[test]
fn issue_768() {
  named!(bit_vec8<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 8))));
  named!(bit_vec4<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 4))));
  named!(bit_vec3<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 3))));
  named!(bit_vec11<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 11))));

  let m: Vec<u8> = vec![70, 97, 106, 121, 86, 66, 105, 98, 86, 106, 101];
  assert_eq!(
    bit_vec8(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![70, 97, 106, 121, 86, 66, 105, 98, 86, 106, 101]))
  );
  assert_eq!(
    bit_vec4(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![4, 6, 6, 1, 6, 10, 7, 9, 5, 6, 4, 2, 6, 9, 6, 2, 5, 6, 6, 10, 6, 5]))
  );
  assert_eq!(
    bit_vec3(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![2, 1, 4, 6, 0, 5, 5, 2, 3, 6, 2, 5, 3, 1, 0, 2, 3, 2, 2, 6, 1, 1, 2, 6, 3, 2, 4, 6, 2]))
  );
  assert_eq!(
    bit_vec11(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![563, 90, 1266, 1380, 308, 1417, 717, 613]))
  );
}

/// This test is in a separate module to check that all required symbols are imported in
/// `escaped_transform!()`. Without the module, the `use`-es of the current module would
/// mask the error ('"Use of undeclared type or module `Needed`" in escaped_transform!').
mod issue_780 {
  named!(issue_780<&str, String>,
    escaped_transform!(call!(::nom::alpha), '\\', tag!("n"))
  );
}

// issue 617
named!(digits, take_while1!( is_digit ));
named!(multi_617<&[u8], () >, fold_many0!( digits, (), |_, _| {}));

// Sad :(
named!(multi_617_fails<&[u8], () >, fold_many0!( take_while1!( is_digit ), (), |_, _| {}));

mod issue_647 {
  use nom::{Err,be_f64, ErrorKind};
  pub type Input<'a> = &'a [u8];

  #[derive(PartialEq, Debug, Clone)]
  struct Data {
      c: f64,
      v: Vec<f64>
  }

  fn list<'a,'b>(input: Input<'a>, _cs: &'b f64) -> Result<(Input<'a>,Vec<f64>), Err<(&'a [u8], ErrorKind)>> {
      separated_list_complete!(input, tag!(","),be_f64)
  }

  named!(data<Input,Data>, map!(
      do_parse!(
          c: be_f64 >>
          tag!("\n") >>
          v: call!(list,&c) >>
          (c,v)
      ), |(c,v)| {
          Data {
              c: c,
              v: v
          }
      }
  ));
}

named!(issue_775, take_till1!(|_| true));

#[test]
fn issue_848_overflow_incomplete_bits_to_bytes() {
  named!(parser<&[u8], &[u8]>, bits!(bytes!(take!(0x2000000000000000))));
  assert_eq!(parser(&b""[..]), Err(Err::Failure(error_position!(&b""[..], ErrorKind::TooLarge))));
}
<commit_msg>fix some tests<commit_after>//#![feature(trace_macros)]
#![allow(dead_code)]
#![cfg_attr(feature = "cargo-clippy", allow(redundant_closure))]

#[macro_use]
extern crate nom;

use nom::{character::{is_digit, streaming::space}, Err, IResult, Needed, error::ErrorKind, number::streaming::le_u64};
use nom::types::{CompleteStr, CompleteByteSlice};

#[allow(dead_code)]
struct Range {
  start: char,
  end: char,
}

pub fn take_char(input: &[u8]) -> IResult<&[u8], char> {
  if !input.is_empty() {
    Ok((&input[1..], input[0] as char))
  } else {
    Err(Err::Incomplete(Needed::Size(1)))
  }
}

//trace_macros!(true);

#[allow(dead_code)]
named!(range<&[u8], Range>,
    alt!(
        do_parse!(
            start: take_char >>
            tag!("-")        >>
            end: take_char   >>
            (Range {
                start: start,
                end:   end,
            })
        ) |
        map!(
            take_char,
            |c| {
                Range {
                    start: c,
                    end:   c,
                }
            }
        )
    )
);

#[allow(dead_code)]
named!(literal<&[u8], Vec<char> >,
    map!(
        many1!(take_char),
        |cs| {
          cs
        }
    )
);

#[test]
fn issue_58() {
  let _ = range(&b"abcd"[..]);
  let _ = literal(&b"abcd"[..]);
}

//trace_macros!(false);

#[cfg(feature = "std")]
mod parse_int {
  use nom::HexDisplay;
  use nom::{IResult, character::streaming::{digit, space}};
  use std::str;

  named!(parse_ints<Vec<i32>>, many0!(spaces_or_int));

  fn spaces_or_int(input: &[u8]) -> IResult<&[u8], i32> {
    println!("{}", input.to_hex(8));
    do_parse!(
      input,
      opt!(complete!(space)) >> res: map!(complete!(digit), |x| {
        println!("x: {:?}", x);
        let result = str::from_utf8(x).unwrap();
        println!("Result: {}", result);
        println!("int is empty?: {}", x.is_empty());
        match result.parse() {
          Ok(i) => i,
          Err(e) => panic!("UH OH! NOT A DIGIT! {:?}", e),
        }
      }) >> (res)
    )
  }

  #[test]
  fn issue_142() {
    let subject = parse_ints(&b"12 34 5689a"[..]);
    let expected = Ok((&b"a"[..], vec![12, 34, 5689]));
    assert_eq!(subject, expected);

    let subject = parse_ints(&b"12 34 5689 "[..]);
    let expected = Ok((&b" "[..], vec![12, 34, 5689]));
    assert_eq!(subject, expected)
  }
}

#[test]
fn usize_length_bytes_issue() {
  use nom::number::streaming::be_u16;
  let _: IResult<&[u8], &[u8], (&[u8], ErrorKind)> = length_bytes!(b"012346", be_u16);
}

/*
 DOES NOT COMPILE
#[test]
fn issue_152() {
  named!(take4, take!(4));
  named!(xyz, tag!("XYZ"));
  named!(abc, tag!("abc"));

  named!(sw,
    switch!(take4,
      b"abcd" => xyz |
      b"efgh" => abc
    )
  );
}
*/

#[test]
fn take_till_issue() {
  named!(nothing, take_till!(call!(|_| true)));

  assert_eq!(nothing(b""), Err(Err::Incomplete(Needed::Size(1))));
  assert_eq!(nothing(b"abc"), Ok((&b"abc"[..], &b""[..])));
}

named!(
  issue_498<Vec<&[u8]>>,
  separated_nonempty_list!(opt!(space), tag!("abcd"))
);

named!(issue_308(&str) -> bool,
    do_parse! (
        tag! ("foo") >>
        b: alt_complete! (
            map! (tag! ("1"), |_: &str|->bool {true}) |
            value! (false)
        ) >>
        (b) ));

#[cfg(feature = "alloc")]
fn issue_302(input: &[u8]) -> IResult<&[u8], Option<Vec<u64>>> {
  do_parse!(input, entries: cond!(true, count!(le_u64, 3)) >> (entries))
}

#[test]
fn issue_655() {
  use nom::character::streaming::{line_ending, not_line_ending};
  named!(twolines(&str) -> (&str, &str),
    do_parse!(
      l1 : not_line_ending >>
           line_ending >>
      l2 : not_line_ending >>
           line_ending >>
      ((l1, l2))
    )
  );

  assert_eq!(twolines("foo\nbar\n"), Ok(("", ("foo", "bar"))));
  assert_eq!(twolines("féo\nbar\n"), Ok(("", ("féo", "bar"))));
  assert_eq!(twolines("foé\nbar\n"), Ok(("", ("foé", "bar"))));
  assert_eq!(twolines("foé\r\nbar\n"), Ok(("", ("foé", "bar"))));
}

#[cfg(feature = "std")]
named!(issue_666 <CompleteByteSlice, CompleteByteSlice>, dbg_dmp!(tag!("abc")));

#[test]
fn issue_667() {
  use nom::character::streaming::alpha;

  named!(foo <CompleteByteSlice, Vec<CompleteByteSlice>>,
    many0!(
      alt!(alpha | is_a!("_"))
    )
  );
  assert_eq!(
    foo(CompleteByteSlice(b"")),
    Ok((CompleteByteSlice(b""), vec![]))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"loremipsum")),
    Ok((
      CompleteByteSlice(b""),
      vec![CompleteByteSlice(b"loremipsum")]
    ))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"lorem_ipsum")),
    Ok((
      CompleteByteSlice(b""),
      vec![
        CompleteByteSlice(b"lorem"),
        CompleteByteSlice(b"_"),
        CompleteByteSlice(b"ipsum"),
      ]
    ))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"_lorem_ipsum")),
    Ok((
      CompleteByteSlice(b""),
      vec![
        CompleteByteSlice(b"_"),
        CompleteByteSlice(b"lorem"),
        CompleteByteSlice(b"_"),
        CompleteByteSlice(b"ipsum"),
      ]
    ))
  );
  assert_eq!(
    foo(CompleteByteSlice(b"!@#$")),
    Ok((CompleteByteSlice(b"!@#$"), vec![]))
  );
}

#[test]
fn issue_721() {
  named!(f1<&str, u16>, parse_to!(u16));
  named!(f2<&str, String>, parse_to!(String));
  assert_eq!(f1("1234"), Ok(("", 1234)));
  assert_eq!(f2("foo"), Ok(("", "foo".to_string())));
  //assert_eq!(parse_to!("1234", u16), Ok(("", 1234)));
  //assert_eq!(parse_to!("foo", String), Ok(("", "foo".to_string())));
}

#[cfg(feature = "alloc")]
named!(issue_717<&[u8], Vec<&[u8]> >,
  separated_list!(tag!([0x0]), is_not!([0x0u8]))
);

struct NoPartialEq {
  value: i32,
}

named!(issue_724<&str, i32>,
  do_parse!(
    metadata: permutation!(
      map!(tag!("hello"), |_| NoPartialEq { value: 1 }),
      map!(tag!("world"), |_| NoPartialEq { value: 2 })
    ) >>
    (metadata.0.value + metadata.1.value)
  )
);

named!(issue_741_str<CompleteStr, CompleteStr>, re_match!(r"^_?[A-Za-z][0-9A-Z_a-z-]*"));
named!(issue_741_bytes<CompleteByteSlice, CompleteByteSlice>, re_bytes_match!(r"^_?[A-Za-z][0-9A-Z_a-z-]*"));

#[test]
fn issue_752() {
    assert_eq!(
        Err::Error(("ab", nom::error::ErrorKind::ParseTo)),
        parse_to!("ab", usize).unwrap_err()
    )
}

fn atom_specials(c: u8) -> bool {
    c == b'q'
}

named!(
    capability<&str>,
    do_parse!(tag!(" ") >> _atom: map_res!(take_till1!(atom_specials), std::str::from_utf8) >> ("a"))
);

#[test]
fn issue_759() {
    assert_eq!(capability(b" abcqd"), Ok((&b"qd"[..], "a")));
}

named_args!(issue_771(count: usize)<Vec<u32>>,
  length_count!(value!(count), call!(nom::number::streaming::be_u32))
);

#[test]
fn issue_768() {
  named!(bit_vec8<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 8))));
  named!(bit_vec4<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 4))));
  named!(bit_vec3<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 3))));
  named!(bit_vec11<CompleteByteSlice, Vec<u16>>, bits!(many0!(take_bits!(u16, 11))));

  let m: Vec<u8> = vec![70, 97, 106, 121, 86, 66, 105, 98, 86, 106, 101];
  assert_eq!(
    bit_vec8(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![70, 97, 106, 121, 86, 66, 105, 98, 86, 106, 101]))
  );
  assert_eq!(
    bit_vec4(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![4, 6, 6, 1, 6, 10, 7, 9, 5, 6, 4, 2, 6, 9, 6, 2, 5, 6, 6, 10, 6, 5]))
  );
  assert_eq!(
    bit_vec3(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![2, 1, 4, 6, 0, 5, 5, 2, 3, 6, 2, 5, 3, 1, 0, 2, 3, 2, 2, 6, 1, 1, 2, 6, 3, 2, 4, 6, 2]))
  );
  assert_eq!(
    bit_vec11(CompleteByteSlice(m.as_slice())),
    Ok((CompleteByteSlice(&[]), vec![563, 90, 1266, 1380, 308, 1417, 717, 613]))
  );
}

/// This test is in a separate module to check that all required symbols are imported in
/// `escaped_transform!()`. Without the module, the `use`-es of the current module would
/// mask the error ('"Use of undeclared type or module `Needed`" in escaped_transform!').
mod issue_780 {
  named!(issue_780<&str, String>,
    escaped_transform!(call!(::nom::character::streaming::alpha), '\\', tag!("n"))
  );
}

// issue 617
named!(digits, take_while1!( is_digit ));
named!(multi_617<&[u8], () >, fold_many0!( digits, (), |_, _| {}));

// Sad :(
named!(multi_617_fails<&[u8], () >, fold_many0!( take_while1!( is_digit ), (), |_, _| {}));

mod issue_647 {
  use nom::{Err, number::streaming::be_f64, error::ErrorKind};
  pub type Input<'a> = &'a [u8];

  #[derive(PartialEq, Debug, Clone)]
  struct Data {
      c: f64,
      v: Vec<f64>
  }

  fn list<'a,'b>(input: Input<'a>, _cs: &'b f64) -> Result<(Input<'a>,Vec<f64>), Err<(&'a [u8], ErrorKind)>> {
      separated_list_complete!(input, tag!(","),be_f64)
  }

  named!(data<Input,Data>, map!(
      do_parse!(
          c: be_f64 >>
          tag!("\n") >>
          v: call!(list,&c) >>
          (c,v)
      ), |(c,v)| {
          Data {
              c: c,
              v: v
          }
      }
  ));
}

named!(issue_775, take_till1!(|_| true));

#[test]
fn issue_848_overflow_incomplete_bits_to_bytes() {
  named!(parser<&[u8], &[u8]>, bits!(bytes!(take!(0x2000000000000000))));
  assert_eq!(parser(&b""[..]), Err(Err::Failure(error_position!(&b""[..], ErrorKind::TooLarge))));
}
<|endoftext|>


<commit_before>#[cfg(not(lib_build))]
#[macro_use]
extern crate log;

macro_rules! all_log_macros {
    ($($arg:tt)*) => ({
        trace!($($arg)*);
        debug!($($arg)*);
        info!($($arg)*);
        warn!($($arg)*);
        error!($($arg)*);
    });
}

#[test]
fn no_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello");
        log!(lvl, "hello",);

        log!(target: "my_target", lvl, "hello");
        log!(target: "my_target", lvl, "hello",);

        log!(lvl; "hello");
        log!(lvl; "hello",);

        log!(target = "my_target", lvl; "hello");
        log!(target = "my_target", lvl; "hello",);
    }

    all_log_macros!("hello");
    all_log_macros!("hello",);

    all_log_macros!(target = "my_target"; "hello");
    all_log_macros!(target = "my_target"; "hello",);

    all_log_macros!(target: "my_target", "hello");
    all_log_macros!(target: "my_target", "hello",);
}

#[test]
fn anonymous_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {}", "world");
        log!(lvl, "hello {}", "world",);

        log!(target: "my_target", lvl, "hello {}", "world");
        log!(target: "my_target", lvl, "hello {}", "world",);

        log!(lvl; "hello {}", "world");
        log!(lvl; "hello {}", "world",);

        log!(target = "my_target", lvl; "hello {}", "world");
        log!(target = "my_target", lvl; "hello {}", "world",);
    }

    all_log_macros!("hello {}", "world");
    all_log_macros!("hello {}", "world",);

    all_log_macros!(target = "my_target"; "hello {}", "world");
    all_log_macros!(target = "my_target"; "hello {}", "world",);

    all_log_macros!(target: "my_target", "hello {}", "world");
    all_log_macros!(target: "my_target", "hello {}", "world",);
}

#[test]
fn named_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {world}", world = "world");
        log!(lvl, "hello {world}", world = "world",);

        log!(target: "my_target", lvl, "hello {world}", world = "world");
        log!(target: "my_target", lvl, "hello {world}", world = "world",);

        log!(lvl; "hello {world}", world = "world");
        log!(lvl; "hello {world}", world = "world",);

        log!(target = "my_target", lvl; "hello {world}", world = "world");
        log!(target = "my_target", lvl; "hello {world}", world = "world",);
    }

    all_log_macros!("hello {world}", world = "world");
    all_log_macros!("hello {world}", world = "world",);

    all_log_macros!(target = "my_target"; "hello {world}", world = "world");
    all_log_macros!(target = "my_target"; "hello {world}", world = "world",);

    all_log_macros!(target: "my_target", "hello {world}", world = "world");
    all_log_macros!(target: "my_target", "hello {world}", world = "world",);
}

#[test]
#[rustversion::since(1.58)]
fn implicit_named_args() {
    let world = "world";

    for lvl in log::Level::iter() {
        log!(lvl, "hello {world}");
        log!(lvl, "hello {world}",);

        log!(target: "my_target", lvl, "hello {world}");
        log!(target: "my_target", lvl, "hello {world}",);

        log!(lvl; "hello {world}");
        log!(lvl; "hello {world}",);

        log!(target = "my_target", lvl; "hello {world}");
        log!(target = "my_target", lvl; "hello {world}",);
    }

    all_log_macros!("hello {world}");
    all_log_macros!("hello {world}",);

    all_log_macros!(target = "my_target"; "hello {world}");
    all_log_macros!(target = "my_target"; "hello {world}",);

    all_log_macros!(target: "my_target", "hello {world}");
    all_log_macros!(target: "my_target", "hello {world}",);
}

#[test]
fn enabled() {
    for lvl in log::Level::iter() {
        let _enabled = if log_enabled!(target: "my_target", lvl) {
            true
        } else {
            false
        };

        let _enabled = if log_enabled!(target = "my_target", lvl) {
            true
        } else {
            false
        };
    }
}

#[test]
fn expr() {
    for lvl in log::Level::iter() {
        let _ = log!(lvl; "hello");
    }
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_no_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_anonymous_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_named_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
#[rustversion::since(1.58)]
fn kv_implicit_named_args() {
    let world = "world";

    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello {world}");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello {world}");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_expr_context() {
    match "chashu" {
        cat_1 => {
            info!(target = "target"; cat_1 = cat_1, cat_2 = "nori"; "hello {}", "cats")
        }
    };
}
<commit_msg>move implicit arg tests into module<commit_after>#[cfg(not(lib_build))]
#[macro_use]
extern crate log;

macro_rules! all_log_macros {
    ($($arg:tt)*) => ({
        trace!($($arg)*);
        debug!($($arg)*);
        info!($($arg)*);
        warn!($($arg)*);
        error!($($arg)*);
    });
}

#[test]
fn no_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello");
        log!(lvl, "hello",);

        log!(target: "my_target", lvl, "hello");
        log!(target: "my_target", lvl, "hello",);

        log!(lvl; "hello");
        log!(lvl; "hello",);

        log!(target = "my_target", lvl; "hello");
        log!(target = "my_target", lvl; "hello",);
    }

    all_log_macros!("hello");
    all_log_macros!("hello",);

    all_log_macros!(target = "my_target"; "hello");
    all_log_macros!(target = "my_target"; "hello",);

    all_log_macros!(target: "my_target", "hello");
    all_log_macros!(target: "my_target", "hello",);
}

#[test]
fn anonymous_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {}", "world");
        log!(lvl, "hello {}", "world",);

        log!(target: "my_target", lvl, "hello {}", "world");
        log!(target: "my_target", lvl, "hello {}", "world",);

        log!(lvl; "hello {}", "world");
        log!(lvl; "hello {}", "world",);

        log!(target = "my_target", lvl; "hello {}", "world");
        log!(target = "my_target", lvl; "hello {}", "world",);
    }

    all_log_macros!("hello {}", "world");
    all_log_macros!("hello {}", "world",);

    all_log_macros!(target = "my_target"; "hello {}", "world");
    all_log_macros!(target = "my_target"; "hello {}", "world",);

    all_log_macros!(target: "my_target", "hello {}", "world");
    all_log_macros!(target: "my_target", "hello {}", "world",);
}

#[test]
fn named_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {world}", world = "world");
        log!(lvl, "hello {world}", world = "world",);

        log!(target: "my_target", lvl, "hello {world}", world = "world");
        log!(target: "my_target", lvl, "hello {world}", world = "world",);

        log!(lvl; "hello {world}", world = "world");
        log!(lvl; "hello {world}", world = "world",);

        log!(target = "my_target", lvl; "hello {world}", world = "world");
        log!(target = "my_target", lvl; "hello {world}", world = "world",);
    }

    all_log_macros!("hello {world}", world = "world");
    all_log_macros!("hello {world}", world = "world",);

    all_log_macros!(target = "my_target"; "hello {world}", world = "world");
    all_log_macros!(target = "my_target"; "hello {world}", world = "world",);

    all_log_macros!(target: "my_target", "hello {world}", world = "world");
    all_log_macros!(target: "my_target", "hello {world}", world = "world",);
}

#[test]
fn enabled() {
    for lvl in log::Level::iter() {
        let _enabled = if log_enabled!(target: "my_target", lvl) {
            true
        } else {
            false
        };

        let _enabled = if log_enabled!(target = "my_target", lvl) {
            true
        } else {
            false
        };
    }
}

#[test]
fn expr() {
    for lvl in log::Level::iter() {
        let _ = log!(lvl; "hello");
    }
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_no_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_anonymous_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_named_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello {world}", world = "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_expr_context() {
    match "chashu" {
        cat_1 => {
            info!(target = "target"; cat_1 = cat_1, cat_2 = "nori"; "hello {}", "cats")
        }
    };
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_shadow_target() {
    all_log_macros!(target = "kv_target"; "hello {}", "world");
    all_log_macros!(target = "kv_target", cat_1 = "chashu", cat_2 = "nori"; "hello {}", "world");
}

#[rustversion::since(1.58)]
mod implicit_args {
    use super::*;

    #[test]
    fn implicit_named_args() {
        let world = "world";

        for lvl in log::Level::iter() {
            log!(lvl, "hello {world}");
            log!(lvl, "hello {world}",);

            log!(target: "my_target", lvl, "hello {world}");
            log!(target: "my_target", lvl, "hello {world}",);

            log!(lvl; "hello {world}");
            log!(lvl; "hello {world}",);

            log!(target = "my_target", lvl; "hello {world}");
            log!(target = "my_target", lvl; "hello {world}",);
        }

        all_log_macros!("hello {world}");
        all_log_macros!("hello {world}",);

        all_log_macros!(target = "my_target"; "hello {world}");
        all_log_macros!(target = "my_target"; "hello {world}",);

        all_log_macros!(target: "my_target", "hello {world}");
        all_log_macros!(target: "my_target", "hello {world}",);
    }

    #[test]
    #[cfg(feature = "kv_unstable")]
    fn kv_implicit_named_args() {
        let world = "world";

        for lvl in log::Level::iter() {
            log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}");

            log!(lvl; cat_1 = "chashu", cat_2 = "nori"; "hello {world}");
        }

        all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori"; "hello {world}");
        all_log_macros!(cat_1 = "chashu", cat_2 = "nori"; "hello {world}");
    }
}
<|endoftext|>


<commit_before>

extern crate thunderdome;

#[cfg(test)]
mod parser_tests {
    use thunderdome::parser::*;
    use thunderdome::steps::*;

    fn validate(q: &str) -> Option<GraphQuery> {
        let result = parse(q);
        assert!(result.is_ok());
        result.ok()
    }

    #[test]
    fn global_graph_query() {
        validate("g.V");
    }

    #[test]
    fn vertex_query() {
        validate("g.v(1)");
        validate("g.v(1,2)");
        validate("g.v(1, 2)");
    }

    #[test]
    fn simple_step_test() {
        validate("g.v(1).outV()");
    }
}
<commit_msg>steps parsing working<commit_after>

extern crate thunderdome;

#[cfg(test)]
mod parser_tests {
    use thunderdome::parser::*;
    use thunderdome::steps::*;

    fn validate(q: &str) -> Option<GraphQuery> {
        let result = parse(q);
        assert!(result.is_ok());
        result.ok()
    }

    #[test]
    fn global_graph_query() {
        validate("g.V");
    }

    #[test]
    fn vertex_query() {
        validate("g.v(1)");
        validate("g.v(1,2)");
        validate("g.v(1, 2)");
    }

    #[test]
    fn simple_step_test() {
        validate("g.v(1).outV()");
        validate("g.v(1).outV().inE()");
    }
}
<|endoftext|>


<commit_before>use cxx_gen::{generate_header_and_cc, Opt};
use std::str;

const BRIDGE0: &str = r#"
    #[cxx::bridge]
    mod ffi {
        extern "C" {
            pub fn do_cpp_thing(foo: &str);
        }
    }
"#;

#[test]
fn test_extern_c_function() {
    let opt = Opt::default();
    let source = BRIDGE0.parse().unwrap();
    let generated = generate_header_and_cc(source, &opt).unwrap();
    let output = str::from_utf8(&generated.implementation).unwrap();
    // To avoid continual breakage we won't test every byte.
    // Let's look for the major features.
    assert!(output.contains("void cxxbridge05$do_cpp_thing(::rust::repr::PtrLen foo)"));
}

#[test]
fn test_impl_annotation() {
    let mut opt = Opt::default();
    opt.cxx_impl_annotations = Some("ANNOTATION".to_owned());
    let source = BRIDGE0.parse().unwrap();
    let generated = generate_header_and_cc(source, &opt).unwrap();
    let output = str::from_utf8(&generated.implementation).unwrap();
    assert!(output.contains("ANNOTATION void cxxbridge05$do_cpp_thing(::rust::repr::PtrLen foo)"));
}
<commit_msg>Ignore field_reassign_with_default<commit_after>#![allow(clippy::field_reassign_with_default)]

use cxx_gen::{generate_header_and_cc, Opt};
use std::str;

const BRIDGE0: &str = r#"
    #[cxx::bridge]
    mod ffi {
        extern "C" {
            pub fn do_cpp_thing(foo: &str);
        }
    }
"#;

#[test]
fn test_extern_c_function() {
    let opt = Opt::default();
    let source = BRIDGE0.parse().unwrap();
    let generated = generate_header_and_cc(source, &opt).unwrap();
    let output = str::from_utf8(&generated.implementation).unwrap();
    // To avoid continual breakage we won't test every byte.
    // Let's look for the major features.
    assert!(output.contains("void cxxbridge05$do_cpp_thing(::rust::repr::PtrLen foo)"));
}

#[test]
fn test_impl_annotation() {
    let mut opt = Opt::default();
    opt.cxx_impl_annotations = Some("ANNOTATION".to_owned());
    let source = BRIDGE0.parse().unwrap();
    let generated = generate_header_and_cc(source, &opt).unwrap();
    let output = str::from_utf8(&generated.implementation).unwrap();
    assert!(output.contains("ANNOTATION void cxxbridge05$do_cpp_thing(::rust::repr::PtrLen foo)"));
}
<|endoftext|>