<commit_before>use rustc::hir::*;
use rustc::lint::*;
use rustc::{declare_lint, lint_array};
use syntax::source_map::Spanned;
use crate::utils::SpanlessEq;
use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty};

/// **What it does:** Checks for string appends of the form `x = x + y` (without
/// `let`!).
///
/// **Why is this bad?** It's not really bad, but some people think that the
/// `.push_str(_)` method is more readable. Also creates a new heap allocation and throws
/// away the old one.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// let mut x = "Hello".to_owned();
/// x = x + ", World";
/// ```
declare_clippy_lint! {
    pub STRING_ADD_ASSIGN,
    pedantic,
    "using `x = x + ..` where x is a `String` instead of `push_str()`"
}

/// **What it does:** Checks for all instances of `x + _` where `x` is of type
/// `String`, but only if [`string_add_assign`](#string_add_assign) does *not*
/// match.
///
/// **Why is this bad?** It's not bad in and of itself. However, this particular
/// `Add` implementation is asymmetric (the other operand need not be `String`,
/// but `x` does), while addition as mathematically defined is symmetric, also
/// the `String::push_str(_)` function is a perfectly good replacement.
/// Therefore some dislike it and wish not to have it in their code.
///
/// That said, other people think that string addition, having a long tradition
/// in other languages is actually fine, which is why we decided to make this
/// particular lint `allow` by default.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// let x = "Hello".to_owned();
/// x + ", World"
/// ```
declare_clippy_lint! {
    pub STRING_ADD,
    restriction,
    "using `x + ..` where x is a `String` instead of `push_str()`"
}

/// **What it does:** Checks for the `as_bytes` method called on string literals
/// that contain only ASCII characters.
///
/// **Why is this bad?** Byte string literals (e.g. `b"foo"`) can be used
/// instead. They are shorter but less discoverable than `as_bytes()`.
///
/// **Known Problems:** None.
///
/// **Example:**
/// ```rust
/// let bs = "a byte string".as_bytes();
/// ```
declare_clippy_lint! {
    pub STRING_LIT_AS_BYTES,
    style,
    "calling `as_bytes` on a string literal instead of using a byte string literal"
}

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

impl LintPass for StringAdd {
    fn get_lints(&self) -> LintArray {
        lint_array!(STRING_ADD, STRING_ADD_ASSIGN)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if let ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) = e.node {
            if is_string(cx, left) {
                if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
                    let parent = get_parent_expr(cx, e);
                    if let Some(p) = parent {
                        if let ExprKind::Assign(ref target, _) = p.node {
                            // avoid duplicate matches
                            if SpanlessEq::new(cx).eq_expr(target, left) {
                                return;
                            }
                        }
                    }
                }
                span_lint(
                    cx,
                    STRING_ADD,
                    e.span,
                    "you added something to a string. Consider using `String::push_str()` instead",
                );
            }
        } else if let ExprKind::Assign(ref target, ref src) = e.node {
            if is_string(cx, target) && is_add(cx, src, target) {
                span_lint(
                    cx,
                    STRING_ADD_ASSIGN,
                    e.span,
                    "you assigned the result of adding something to this string. Consider using \
                     `String::push_str()` instead",
                );
            }
        }
    }
}

fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
    match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), &paths::STRING)
}

fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
    match src.node {
        ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
        ExprKind::Block(ref block, _) => {
            block.stmts.is_empty()
                && block
                    .expr
                    .as_ref()
                    .map_or(false, |expr| is_add(cx, expr, target))
        },
        _ => false,
    }
}

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

impl LintPass for StringLitAsBytes {
    fn get_lints(&self) -> LintArray {
        lint_array!(STRING_LIT_AS_BYTES)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        use syntax::ast::LitKind;
        use crate::utils::{in_macro, snippet};

        if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
            if path.ident.name == "as_bytes" {
                if let ExprKind::Lit(ref lit) = args[0].node {
                    if let LitKind::Str(ref lit_content, _) = lit.node {
                        if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
                            span_lint_and_sugg(
                                cx,
                                STRING_LIT_AS_BYTES,
                                e.span,
                                "calling `as_bytes()` on a string literal",
                                "consider using a byte string literal instead",
                                format!("b{}", snippet(cx, args[0].span, r#""foo""#)),
                            );
                        }
                    }
                }
            }
        }
    }
}
<commit_msg>Remove incorrect note from string_add_assign docs<commit_after>use rustc::hir::*;
use rustc::lint::*;
use rustc::{declare_lint, lint_array};
use syntax::source_map::Spanned;
use crate::utils::SpanlessEq;
use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty};

/// **What it does:** Checks for string appends of the form `x = x + y` (without
/// `let`!).
///
/// **Why is this bad?** It's not really bad, but some people think that the
/// `.push_str(_)` method is more readable.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// let mut x = "Hello".to_owned();
/// x = x + ", World";
/// ```
declare_clippy_lint! {
    pub STRING_ADD_ASSIGN,
    pedantic,
    "using `x = x + ..` where x is a `String` instead of `push_str()`"
}

/// **What it does:** Checks for all instances of `x + _` where `x` is of type
/// `String`, but only if [`string_add_assign`](#string_add_assign) does *not*
/// match.
///
/// **Why is this bad?** It's not bad in and of itself. However, this particular
/// `Add` implementation is asymmetric (the other operand need not be `String`,
/// but `x` does), while addition as mathematically defined is symmetric, also
/// the `String::push_str(_)` function is a perfectly good replacement.
/// Therefore some dislike it and wish not to have it in their code.
///
/// That said, other people think that string addition, having a long tradition
/// in other languages is actually fine, which is why we decided to make this
/// particular lint `allow` by default.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// let x = "Hello".to_owned();
/// x + ", World"
/// ```
declare_clippy_lint! {
    pub STRING_ADD,
    restriction,
    "using `x + ..` where x is a `String` instead of `push_str()`"
}

/// **What it does:** Checks for the `as_bytes` method called on string literals
/// that contain only ASCII characters.
///
/// **Why is this bad?** Byte string literals (e.g. `b"foo"`) can be used
/// instead. They are shorter but less discoverable than `as_bytes()`.
///
/// **Known Problems:** None.
///
/// **Example:**
/// ```rust
/// let bs = "a byte string".as_bytes();
/// ```
declare_clippy_lint! {
    pub STRING_LIT_AS_BYTES,
    style,
    "calling `as_bytes` on a string literal instead of using a byte string literal"
}

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

impl LintPass for StringAdd {
    fn get_lints(&self) -> LintArray {
        lint_array!(STRING_ADD, STRING_ADD_ASSIGN)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if let ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) = e.node {
            if is_string(cx, left) {
                if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
                    let parent = get_parent_expr(cx, e);
                    if let Some(p) = parent {
                        if let ExprKind::Assign(ref target, _) = p.node {
                            // avoid duplicate matches
                            if SpanlessEq::new(cx).eq_expr(target, left) {
                                return;
                            }
                        }
                    }
                }
                span_lint(
                    cx,
                    STRING_ADD,
                    e.span,
                    "you added something to a string. Consider using `String::push_str()` instead",
                );
            }
        } else if let ExprKind::Assign(ref target, ref src) = e.node {
            if is_string(cx, target) && is_add(cx, src, target) {
                span_lint(
                    cx,
                    STRING_ADD_ASSIGN,
                    e.span,
                    "you assigned the result of adding something to this string. Consider using \
                     `String::push_str()` instead",
                );
            }
        }
    }
}

fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
    match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), &paths::STRING)
}

fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
    match src.node {
        ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
        ExprKind::Block(ref block, _) => {
            block.stmts.is_empty()
                && block
                    .expr
                    .as_ref()
                    .map_or(false, |expr| is_add(cx, expr, target))
        },
        _ => false,
    }
}

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

impl LintPass for StringLitAsBytes {
    fn get_lints(&self) -> LintArray {
        lint_array!(STRING_LIT_AS_BYTES)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        use syntax::ast::LitKind;
        use crate::utils::{in_macro, snippet};

        if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
            if path.ident.name == "as_bytes" {
                if let ExprKind::Lit(ref lit) = args[0].node {
                    if let LitKind::Str(ref lit_content, _) = lit.node {
                        if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
                            span_lint_and_sugg(
                                cx,
                                STRING_LIT_AS_BYTES,
                                e.span,
                                "calling `as_bytes()` on a string literal",
                                "consider using a byte string literal instead",
                                format!("b{}", snippet(cx, args[0].span, r#""foo""#)),
                            );
                        }
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// check-pass

#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]

struct S;

impl const PartialEq for S {
    fn eq(&self, _: &S) -> bool {
        true
    }
    fn ne(&self, other: &S) -> bool {
        !self.eq(other)
    }
}

// This duplicate bound should not result in ambiguities. It should be equivalent to a single ~const
// bound.
const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
    *t == *t
}

pub const EQ: bool = equals_self(&S);

fn main() {}
<commit_msg>Fix UI test<commit_after>// check-pass

#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]

struct S;

impl const PartialEq for S {
    fn eq(&self, _: &S) -> bool {
        true
    }
    fn ne(&self, other: &S) -> bool {
        !self.eq(other)
    }
}

// This duplicate bound should not result in ambiguities. It should be equivalent to a single ~const
// bound.
// const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
// FIXME(fee1-dead)^ why should the order matter here?
const fn equals_self<T: ~const PartialEq + PartialEq>(t: &T) -> bool {
    *t == *t
}

pub const EQ: bool = equals_self(&S);

fn main() {}
<|endoftext|>


<commit_before>//! The Tessellated Intelligence System is a
//!
//! > massively parallel computer architecture comprised of non-uniformly
//! > interconnected heterogeneous nodes.
//!
//! The manual can be found [online](https://www.vidarholen.net/contents/junk/files/TIS-100%20Reference%20Manual.pdf).
//! Another useful resource is the unofficial [TIS-100 Hackers Guide](https://alandesmet.github.io/TIS-100-Hackers-Guide/).
//!
//! # Examples
//! Here we take a node and execute some instructions and check if double 1 has
//! the expected result.
//!
//! ```rust
//! extern crate tis_100_superoptimizer;
//!
//! use tis_100_superoptimizer::TIS_100::{Node,Instruction,Source,Destination};
//!
//! fn main() {
//!     let node: Node = Node::new();
//!     let last: Node = node
//!         .execute(Instruction::MOV(Source::Literal(1), Destination::ACC))
//!         .execute(Instruction::ADD(Source::ACC));
//!
//!     assert_eq!(2, last.acc);
//! }
//! ```

/// A `Node` models the basic execution node in TIS-100. You change a node state
/// by executing an `Instruction` on it.
#[derive(Debug)]
pub struct Node {
    pub acc: i32,
    bac: i32
}

impl PartialEq for Node {
    /// Node are equal when they have the same internal state
    fn eq(&self, other: &Node) -> bool {
        self.acc == other.acc && self.bac == other.bac
    }
}

impl Eq for Node {}

/// `Instruction`s are executed by a `Node`.
pub enum Instruction {
    /// Does nothing
    NOP,
    /// Moves value from `Source` to `Destination`
    MOV(Source, Destination),
    /// Swaps the value of the accumulator (acc) and the backup (bac) register
    SWP,
    /// Saves the value of the accumulator (acc) to the backup register
    SAV,
    /// Add value from `Source` to accumulator (acc), storing result in acc
    ADD(Source),
    /// Subtracts value from `Source` from accumulator (acc), storing result in acc
    SUB(Source),
}

/// `Source` are either ports, registers or literals
pub enum Source {
    NIL,
    ACC,
    Literal(i32)
}

/// `Destination` are either ports or registers
pub enum Destination {
    NIL,
    ACC
}

impl Node {
    pub fn new() -> Node {
        Node { acc: 0, bac: 0 }
    }

    pub fn with(acc: i32, bac: i32) -> Node {
        Node { acc: acc, bac: bac }
    }

    pub fn execute(&self, instruction: Instruction) -> Node {
        match instruction {
            Instruction::NOP => self.nop(),
            Instruction::MOV(source, destination) => self.mov(source, destination) ,
            Instruction::SWP => self.swap(),
            Instruction::SAV => self.save(),
            Instruction::ADD(source) => self.add(source),
            Instruction::SUB(source) => self.subtract(source),
        }
    }

    fn nop(&self) -> Node {
        Node { acc: self.acc, bac: self.bac }
    }

    fn mov(&self, source: Source, destination: Destination) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.move_value(value, destination)
    }

    fn move_value(&self, value: i32, destination: Destination) -> Node {
        match destination {
            Destination::ACC => Node { acc: value, bac: self.bac },
            _ => self.nop()
        }
    }

    fn swap(&self) -> Node {
        Node { acc: self.bac, bac: self.acc }
    }

    fn save(&self) -> Node {
        Node { acc: self.acc, bac: self.acc }
    }

    fn add(&self, source: Source) -> Node{
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.add_value(value)
    }

    fn add_value(&self, value: i32) -> Node {
        Node { acc: self.acc + value, bac: self.bac }
    }

    fn subtract(&self, source: Source) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.subtract_value(value)
    }

    fn subtract_value(&self, value: i32) -> Node {
        Node { acc: self.acc - value, bac: self.bac }
    }
}

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

    #[test]
    fn node_should_start_with_accumulator_zero() {
        let node: Node = Node::new();

        assert_eq!(0, node.acc);
    }

    #[test]
    fn node_should_start_with_backup_zero() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(0, next.acc);
    }

    #[test]
    fn node_should_execute_NOP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::NOP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_NIL_to_NIL_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::MOV(Source::NIL,
                                                        Destination::NIL);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_ACC_to_ACC_correctly() {
        let node: Node = Node::with(2, 1);
        let instruction: Instruction = Instruction::MOV(Source::ACC,
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_Literal_to_ACC_correctly() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::MOV(Source::Literal(1),
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_SWP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(0, 1), next);
    }

    #[test]
    fn node_should_execute_SAV_correctly() {
        let node: Node = Node::with(1,0);
        let instruction: Instruction = Instruction::SAV;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 1), next);
    }

    #[test]
    fn node_should_execute_ADD_from_Literal_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::ADD(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 0), next);
    }

    #[test]
    fn node_should_execute_SUB_from_Literal_correctly() {
        let node: Node = Node::with(2, 0);
        let instruction: Instruction = Instruction::SUB(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }
}

<commit_msg>Document public methods on Node<commit_after>//! The Tessellated Intelligence System is a
//!
//! > massively parallel computer architecture comprised of non-uniformly
//! > interconnected heterogeneous nodes.
//!
//! The manual can be found [online](https://www.vidarholen.net/contents/junk/files/TIS-100%20Reference%20Manual.pdf).
//! Another useful resource is the unofficial [TIS-100 Hackers Guide](https://alandesmet.github.io/TIS-100-Hackers-Guide/).
//!
//! # Examples
//! Here we take a node and execute some instructions and check if double 1 has
//! the expected result.
//!
//! ```rust
//! extern crate tis_100_superoptimizer;
//!
//! use tis_100_superoptimizer::TIS_100::{Node,Instruction,Source,Destination};
//!
//! fn main() {
//!     let node: Node = Node::new();
//!     let last: Node = node
//!         .execute(Instruction::MOV(Source::Literal(1), Destination::ACC))
//!         .execute(Instruction::ADD(Source::ACC));
//!
//!     assert_eq!(2, last.acc);
//! }
//! ```

/// A `Node` models the basic execution node in TIS-100. You change a node state
/// by executing an `Instruction` on it.
#[derive(Debug)]
pub struct Node {
    /// The accumulator for the basic execution node.
    pub acc: i32,
    bac: i32
}

impl PartialEq for Node {
    /// Node are equal when they have the same internal state
    fn eq(&self, other: &Node) -> bool {
        self.acc == other.acc && self.bac == other.bac
    }
}

impl Eq for Node {}

/// `Instruction`s are executed by a `Node`.
pub enum Instruction {
    /// Does nothing
    NOP,
    /// Moves value from `Source` to `Destination`
    MOV(Source, Destination),
    /// Swaps the value of the accumulator (acc) and the backup (bac) register
    SWP,
    /// Saves the value of the accumulator (acc) to the backup register
    SAV,
    /// Add value from `Source` to accumulator (acc), storing result in acc
    ADD(Source),
    /// Subtracts value from `Source` from accumulator (acc), storing result in acc
    SUB(Source),
}

/// `Source` are either ports, registers or literals
pub enum Source {
    NIL,
    ACC,
    Literal(i32)
}

/// `Destination` are either ports or registers
pub enum Destination {
    NIL,
    ACC
}

impl Node {
    /// Create a `Node` with defaults for accumulator and backup registers
    pub fn new() -> Node {
        Node { acc: 0, bac: 0 }
    }

    /// Create a `Node` with prescribed values for accumulator and backup registers
    pub fn with(acc: i32, bac: i32) -> Node {
        Node { acc: acc, bac: bac }
    }

    /// Execute the `instruction` on this `Node`. Returns a `Node` that reflects
    /// the changes the `instruction` would have on this `Node`.
    pub fn execute(&self, instruction: Instruction) -> Node {
        match instruction {
            Instruction::NOP => self.nop(),
            Instruction::MOV(source, destination) => self.mov(source, destination) ,
            Instruction::SWP => self.swap(),
            Instruction::SAV => self.save(),
            Instruction::ADD(source) => self.add(source),
            Instruction::SUB(source) => self.subtract(source),
        }
    }

    fn nop(&self) -> Node {
        Node { acc: self.acc, bac: self.bac }
    }

    fn mov(&self, source: Source, destination: Destination) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.move_value(value, destination)
    }

    fn move_value(&self, value: i32, destination: Destination) -> Node {
        match destination {
            Destination::ACC => Node { acc: value, bac: self.bac },
            _ => self.nop()
        }
    }

    fn swap(&self) -> Node {
        Node { acc: self.bac, bac: self.acc }
    }

    fn save(&self) -> Node {
        Node { acc: self.acc, bac: self.acc }
    }

    fn add(&self, source: Source) -> Node{
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.add_value(value)
    }

    fn add_value(&self, value: i32) -> Node {
        Node { acc: self.acc + value, bac: self.bac }
    }

    fn subtract(&self, source: Source) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.subtract_value(value)
    }

    fn subtract_value(&self, value: i32) -> Node {
        Node { acc: self.acc - value, bac: self.bac }
    }
}

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

    #[test]
    fn node_should_start_with_accumulator_zero() {
        let node: Node = Node::new();

        assert_eq!(0, node.acc);
    }

    #[test]
    fn node_should_start_with_backup_zero() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(0, next.acc);
    }

    #[test]
    fn node_should_execute_NOP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::NOP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_NIL_to_NIL_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::MOV(Source::NIL,
                                                        Destination::NIL);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_ACC_to_ACC_correctly() {
        let node: Node = Node::with(2, 1);
        let instruction: Instruction = Instruction::MOV(Source::ACC,
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_Literal_to_ACC_correctly() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::MOV(Source::Literal(1),
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_SWP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(0, 1), next);
    }

    #[test]
    fn node_should_execute_SAV_correctly() {
        let node: Node = Node::with(1,0);
        let instruction: Instruction = Instruction::SAV;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 1), next);
    }

    #[test]
    fn node_should_execute_ADD_from_Literal_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::ADD(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 0), next);
    }

    #[test]
    fn node_should_execute_SUB_from_Literal_correctly() {
        let node: Node = Node::with(2, 0);
        let instruction: Instruction = Instruction::SUB(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }
}

<|endoftext|>


<commit_before>use crate::request::ToParams;
use crate::errors::*;

use std::str::FromStr;

#[derive(Debug, Clone, PartialEq)]
pub struct AppId(String);
#[derive(Debug, Clone, PartialEq)]
pub struct AppKey(String);
#[derive(Debug, Clone, PartialEq)]
pub struct UserKey(String);
#[derive(Debug, Clone, PartialEq)]
pub struct OAuthToken(String);

// These trait impls provide a way to reference our types as &str
impl AsRef<str> for AppId {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

impl AsRef<str> for AppKey {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

impl AsRef<str> for UserKey {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

impl AsRef<str> for OAuthToken {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

// These trait impls provide a way to &str#parse() our Application type
impl FromStr for AppId {
    type Err = Error;

    fn from_str(s: &str) -> Result<AppId> {
        Ok(AppId(s.into()))
    }
}

impl FromStr for AppKey {
    type Err = Error;

    fn from_str(s: &str) -> Result<AppKey> {
        Ok(AppKey(s.into()))
    }
}

impl FromStr for UserKey {
    type Err = Error;

    fn from_str(s: &str) -> Result<UserKey> {
        Ok(UserKey(s.into()))
    }
}

impl FromStr for OAuthToken {
    type Err = Error;

    fn from_str(s: &str) -> Result<OAuthToken> {
        Ok(OAuthToken(s.into()))
    }
}

// These trait impls are similar to FromStr (but are infallible)
impl<'a> From<&'a str> for AppId where Self: FromStr {
    fn from(s: &'a str) -> AppId {
        s.parse().unwrap()
    }
}

impl<'a> From<&'a str> for AppKey where Self: FromStr {
    fn from(s: &'a str) -> AppKey {
        s.parse().unwrap()
    }
}

impl<'a> From<&'a str> for UserKey where Self: FromStr {
    fn from(s: &'a str) -> UserKey {
        s.parse().unwrap()
    }
}

impl<'a> From<&'a str> for OAuthToken where Self: FromStr {
    fn from(s: &'a str) -> OAuthToken {
        s.parse().unwrap()
    }
}

// These trait impls take ownership of a given String and also provide Into<AppId> for String
impl From<String> for AppId {
    fn from(s: String) -> AppId {
        AppId(s)
    }
}

impl From<String> for AppKey {
    fn from(s: String) -> AppKey {
        AppKey(s)
    }
}

impl From<String> for UserKey {
    fn from(s: String) -> UserKey {
        UserKey(s)
    }
}

impl From<String> for OAuthToken {
    fn from(s: String) -> OAuthToken {
        OAuthToken(s)
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum Application {
    AppId(AppId, Option<AppKey>),
    UserKey(UserKey),
    OAuthToken(OAuthToken)
}

// These trait impls build an Application variant out of its required types
impl From<AppId> for Application {
    fn from(a: AppId) -> Self {
        Application::AppId(a, None)
    }
}

impl From<(AppId, AppKey)> for Application {
    fn from(a: (AppId, AppKey)) -> Self {
        Application::AppId(a.0, Some(a.1))
    }
}

impl From<UserKey> for Application {
    fn from(u: UserKey) -> Self {
        Application::UserKey(u)
    }
}

impl From<OAuthToken> for Application {
    fn from(o: OAuthToken) -> Self {
        Application::OAuthToken(o)
    }
}

impl Application {
    /// Creates a new `Application` from an `AppId`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_app_id("my_app_id");
    /// ```
    pub fn from_app_id<T: Into<AppId>>(app_id: T) -> Self {
        Application::AppId(app_id.into(), None)
    }

    /// Creates a new `Application` from an `AppId` and an `AppKey`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_app_id_and_key("my_app_id", "my_app_key");
    /// ```
    pub fn from_app_id_and_key<T: Into<AppId>, U: Into<AppKey>>(app_id: T, app_key: U) -> Self {
        Application::AppId(app_id.into(), Some(app_key.into()))
    }

    /// Creates a new `Application` from a `UserKey`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_user_key("my_user_key");
    /// ```
    pub fn from_user_key<T: Into<UserKey>>(user_key: T) -> Self {
        Application::UserKey(user_key.into())
    }

    /// Creates a new `Application` from an `OAuthToken`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_oauth_token("my_token");
    /// ```
    pub fn from_oauth_token<T: Into<OAuthToken>>(token: T) -> Self {
        Application::OAuthToken(token.into())
    }
}

impl ToParams for Application {
    fn to_params(&self) -> Vec<(&str, &str)>{
        use self::Application::*;

        let mut v = Vec::<(&str, &str)>::with_capacity(2);
        match self {
            AppId(app_id, None) => {
                v.push(("app_id", app_id.as_ref()));
            },
            AppId(app_id, Some(app_key)) => {
                v.push(("app_id", app_id.as_ref()));
                v.push(("app_key", app_key.as_ref()));
            },
            UserKey(user_key) => v.push(("user_key", user_key.as_ref())),
            OAuthToken(token) => v.push(("access_token", token.as_ref())),
        };

        v
    }
}

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

    #[test]
    fn transforms_app_id_into_params() {
        let app_id = "my_app_id";
        let app = Application::from_app_id(app_id);

        let result = app.to_params();

        let expected = vec![("app_id", app_id)];
        assert_eq!(expected, result);
    }

    #[test]
    fn transforms_app_id_and_key_into_params() {
        let app_id = "my_app_id";
        let key = "my_key";
        let app = Application::from_app_id_and_key(app_id, key);

        let result = app.to_params();

        let expected = vec![("app_id", app_id), ("app_key", key)];
        assert_eq!(expected, result);
    }

    #[test]
    fn transforms_user_key_into_params() {
        let user_key = "my_user_key";
        let app = Application::from_user_key(user_key);

        let result = app.to_params();

        let expected = vec![("user_key", user_key)];
        assert_eq!(expected, result);
    }

    #[test]
    fn transforms_oauth_token_into_params() {
        let oauth_token = "my_token";
        let app = Application::from_oauth_token(oauth_token);

        let result = app.to_params();

        let expected = vec![("access_token", oauth_token)];
        assert_eq!(expected, result);
    }
}
<commit_msg>application: add tests using the From trait for Application<commit_after>use crate::request::ToParams;
use crate::errors::*;

use std::str::FromStr;

#[derive(Debug, Clone, PartialEq)]
pub struct AppId(String);
#[derive(Debug, Clone, PartialEq)]
pub struct AppKey(String);
#[derive(Debug, Clone, PartialEq)]
pub struct UserKey(String);
#[derive(Debug, Clone, PartialEq)]
pub struct OAuthToken(String);

// These trait impls provide a way to reference our types as &str
impl AsRef<str> for AppId {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

impl AsRef<str> for AppKey {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

impl AsRef<str> for UserKey {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

impl AsRef<str> for OAuthToken {
    fn as_ref(&self) -> &str {
        self.0.as_str()
    }
}

// These trait impls provide a way to &str#parse() our Application type
impl FromStr for AppId {
    type Err = Error;

    fn from_str(s: &str) -> Result<AppId> {
        Ok(AppId(s.into()))
    }
}

impl FromStr for AppKey {
    type Err = Error;

    fn from_str(s: &str) -> Result<AppKey> {
        Ok(AppKey(s.into()))
    }
}

impl FromStr for UserKey {
    type Err = Error;

    fn from_str(s: &str) -> Result<UserKey> {
        Ok(UserKey(s.into()))
    }
}

impl FromStr for OAuthToken {
    type Err = Error;

    fn from_str(s: &str) -> Result<OAuthToken> {
        Ok(OAuthToken(s.into()))
    }
}

// These trait impls are similar to FromStr (but are infallible)
impl<'a> From<&'a str> for AppId where Self: FromStr {
    fn from(s: &'a str) -> AppId {
        s.parse().unwrap()
    }
}

impl<'a> From<&'a str> for AppKey where Self: FromStr {
    fn from(s: &'a str) -> AppKey {
        s.parse().unwrap()
    }
}

impl<'a> From<&'a str> for UserKey where Self: FromStr {
    fn from(s: &'a str) -> UserKey {
        s.parse().unwrap()
    }
}

impl<'a> From<&'a str> for OAuthToken where Self: FromStr {
    fn from(s: &'a str) -> OAuthToken {
        s.parse().unwrap()
    }
}

// These trait impls take ownership of a given String and also provide Into<AppId> for String
impl From<String> for AppId {
    fn from(s: String) -> AppId {
        AppId(s)
    }
}

impl From<String> for AppKey {
    fn from(s: String) -> AppKey {
        AppKey(s)
    }
}

impl From<String> for UserKey {
    fn from(s: String) -> UserKey {
        UserKey(s)
    }
}

impl From<String> for OAuthToken {
    fn from(s: String) -> OAuthToken {
        OAuthToken(s)
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum Application {
    AppId(AppId, Option<AppKey>),
    UserKey(UserKey),
    OAuthToken(OAuthToken)
}

// These trait impls build an Application variant out of its required types
impl From<AppId> for Application {
    fn from(a: AppId) -> Self {
        Application::AppId(a, None)
    }
}

impl From<(AppId, AppKey)> for Application {
    fn from(a: (AppId, AppKey)) -> Self {
        Application::AppId(a.0, Some(a.1))
    }
}

impl From<UserKey> for Application {
    fn from(u: UserKey) -> Self {
        Application::UserKey(u)
    }
}

impl From<OAuthToken> for Application {
    fn from(o: OAuthToken) -> Self {
        Application::OAuthToken(o)
    }
}

impl Application {
    /// Creates a new `Application` from an `AppId`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_app_id("my_app_id");
    /// ```
    pub fn from_app_id<T: Into<AppId>>(app_id: T) -> Self {
        Application::AppId(app_id.into(), None)
    }

    /// Creates a new `Application` from an `AppId` and an `AppKey`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_app_id_and_key("my_app_id", "my_app_key");
    /// ```
    pub fn from_app_id_and_key<T: Into<AppId>, U: Into<AppKey>>(app_id: T, app_key: U) -> Self {
        Application::AppId(app_id.into(), Some(app_key.into()))
    }

    /// Creates a new `Application` from a `UserKey`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_user_key("my_user_key");
    /// ```
    pub fn from_user_key<T: Into<UserKey>>(user_key: T) -> Self {
        Application::UserKey(user_key.into())
    }

    /// Creates a new `Application` from an `OAuthToken`.
    ///
    /// # Examples
    ///
    /// ```
    /// use threescalers::application::*;
    ///
    /// let app = Application::from_oauth_token("my_token");
    /// ```
    pub fn from_oauth_token<T: Into<OAuthToken>>(token: T) -> Self {
        Application::OAuthToken(token.into())
    }
}

impl ToParams for Application {
    fn to_params(&self) -> Vec<(&str, &str)>{
        use self::Application::*;

        let mut v = Vec::<(&str, &str)>::with_capacity(2);
        match self {
            AppId(app_id, None) => {
                v.push(("app_id", app_id.as_ref()));
            },
            AppId(app_id, Some(app_key)) => {
                v.push(("app_id", app_id.as_ref()));
                v.push(("app_key", app_key.as_ref()));
            },
            UserKey(user_key) => v.push(("user_key", user_key.as_ref())),
            OAuthToken(token) => v.push(("access_token", token.as_ref())),
        };

        v
    }
}

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

    #[test]
    fn convert_application_from_app_id() {
        let app_id = AppId::from("my_app_id");
        let app = Application::from(app_id.clone());

        assert_eq!(Application::AppId(app_id, None), app);
    }

    #[test]
    fn convert_application_from_app_id_app_key() {
        let app_id_key = (AppId::from("my_app_id"), AppKey::from("my_app_key"));
        let app = Application::from(app_id_key.clone());

        assert_eq!(Application::AppId(app_id_key.0, Some(app_id_key.1)), app);
    }

    #[test]
    fn convert_application_from_user_key() {
        let user_key = UserKey::from("my_user_key");
        let app = Application::from(user_key.clone());

        assert_eq!(Application::UserKey(user_key), app);
    }

    #[test]
    fn convert_application_from_oauth_token() {
        let token = OAuthToken::from("my_oauth_token");
        let app = Application::from(token.clone());

        assert_eq!(Application::OAuthToken(token), app);
    }

    #[test]
    fn transforms_app_id_into_params() {
        let app_id = "my_app_id";
        let app = Application::from_app_id(app_id);

        let result = app.to_params();

        let expected = vec![("app_id", app_id)];
        assert_eq!(expected, result);
    }

    #[test]
    fn transforms_app_id_and_key_into_params() {
        let app_id = "my_app_id";
        let key = "my_key";
        let app = Application::from_app_id_and_key(app_id, key);

        let result = app.to_params();

        let expected = vec![("app_id", app_id), ("app_key", key)];
        assert_eq!(expected, result);
    }

    #[test]
    fn transforms_user_key_into_params() {
        let user_key = "my_user_key";
        let app = Application::from_user_key(user_key);

        let result = app.to_params();

        let expected = vec![("user_key", user_key)];
        assert_eq!(expected, result);
    }

    #[test]
    fn transforms_oauth_token_into_params() {
        let oauth_token = "my_token";
        let app = Application::from_oauth_token(oauth_token);

        let result = app.to_params();

        let expected = vec![("access_token", oauth_token)];
        assert_eq!(expected, result);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2016 bluss and ndarray developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::{self, Visitor, SeqVisitor, MapVisitor};

use std::marker::PhantomData;

use imp_prelude::*;

use super::arraytraits::ARRAY_FORMAT_VERSION;
use super::Iter;
use Dim;
use dimension::DimPrivate;

/// **Requires crate feature `"serde"`**
impl<I> Serialize for Dim<I>
    where I: Serialize,
{
    fn serialize<Se>(&self, serializer: &mut Se) -> Result<(), Se::Error>
        where Se: Serializer
    {
        self.ix().serialize(serializer)
    }
}

/// **Requires crate feature `"serde"`**
impl<I> Deserialize for Dim<I>
    where I: Deserialize,
{
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        I::deserialize(deserializer).map(Dim::new)
    }
}

/// **Requires crate feature `"serde"`**
impl<A, D, S> Serialize for ArrayBase<S, D>
    where A: Serialize,
          D: Dimension + Serialize,
          S: Data<Elem = A>

{
    fn serialize<Se>(&self, serializer: &mut Se) -> Result<(), Se::Error>
        where Se: Serializer
    {
        let mut struct_state = try!(serializer.serialize_struct("Array", 3));
        try!(serializer.serialize_struct_elt(&mut struct_state, "v", ARRAY_FORMAT_VERSION));
        try!(serializer.serialize_struct_elt(&mut struct_state, "dim", self.raw_dimension()));
        try!(serializer.serialize_struct_elt(&mut struct_state, "data", Sequence(self.iter())));
        serializer.serialize_struct_end(struct_state)
    }
}

// private iterator wrapper
struct Sequence<'a, A: 'a, D>(Iter<'a, A, D>);

impl<'a, A, D> Serialize for Sequence<'a, A, D>
    where A: Serialize,
          D: Dimension + Serialize
{
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let iter = &self.0;
        let mut seq_state = try!(serializer.serialize_seq(Some(iter.len())));
        for elt in iter.clone() {
            try!(serializer.serialize_seq_elt(&mut seq_state, elt));
        }
        serializer.serialize_seq_end(seq_state)
    }
}

struct ArrayVisitor<S, Di> {
    _marker_a: PhantomData<S>,
    _marker_b: PhantomData<Di>,
}

enum ArrayField {
    Version,
    Dim,
    Data,
}

impl<S, Di> ArrayVisitor<S, Di> {
    pub fn new() -> Self {
        ArrayVisitor { _marker_a: PhantomData, _marker_b: PhantomData, }
    }
}

/// **Requires crate feature `"serde"`**
impl<A, Di, S> Deserialize for ArrayBase<S, Di>
    where A: Deserialize,
          Di: Deserialize + Dimension,
          S: DataOwned<Elem = A>
{
    fn deserialize<D>(deserializer: &mut D) -> Result<ArrayBase<S, Di>, D::Error>
        where D: Deserializer
    {
        static FIELDS: &'static [&'static str] = &["v", "dim", "data"];

        deserializer.deserialize_struct("Array", FIELDS, ArrayVisitor::new())
    }
}

impl Deserialize for ArrayField {
    fn deserialize<D>(deserializer: &mut D) -> Result<ArrayField, D::Error>
        where D: Deserializer
    {
        struct ArrayFieldVisitor;

        impl Visitor for ArrayFieldVisitor {
            type Value = ArrayField;

            fn visit_str<E>(&mut self, value: &str) -> Result<ArrayField, E>
                where E: de::Error
            {
                match value {
                    "v" => Ok(ArrayField::Version),
                    "data" => Ok(ArrayField::Data),
                    "dim" => Ok(ArrayField::Dim),
                    _ => Err(de::Error::custom("expected v, data, or dim")),
                }
            }
        }

        deserializer.deserialize(ArrayFieldVisitor)
    }
}

impl<A, Di, S> Visitor for ArrayVisitor<S,Di>
    where A: Deserialize,
          Di: Deserialize + Dimension,
          S: DataOwned<Elem = A>
{
    type Value = ArrayBase<S, Di>;

    fn visit_seq<V>(&mut self, mut visitor: V) -> Result<ArrayBase<S, Di>, V::Error>
        where V: SeqVisitor
    {
        let v: u8 = match try!(visitor.visit()) {
            Some(value) => value,
            None => {
                try!(visitor.end());
                return Err(de::Error::invalid_length(0));
            }
        };

        if v != ARRAY_FORMAT_VERSION {
            try!(Err(de::Error::custom(format!("unknown array version: {}", v))));
        }

        let dim: Di = match try!(visitor.visit()) {
            Some(value) => value,
            None => {
                try!(visitor.end());
                return Err(de::Error::invalid_length(1));
            }
        };

        let data: Vec<A> = match try!(visitor.visit()) {
            Some(value) => value,
            None => {
                try!(visitor.end());
                return Err(de::Error::invalid_length(2));
            }
        };

        try!(visitor.end());

        if let Ok(array) = ArrayBase::from_shape_vec(dim, data) {
            Ok(array)
        } else {
            Err(de::Error::custom("data and dimension must match in size"))
        }
    }

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<ArrayBase<S, Di>, V::Error>
        where V: MapVisitor,
    {
        let mut v: Option<u8> = None;
        let mut data: Option<Vec<A>> = None;
        let mut dim: Option<Di> = None;

        while let Some(key) = try!(visitor.visit_key()) {
            match key {
                ArrayField::Version => {
                    let val = try!(visitor.visit_value());
                    if val != ARRAY_FORMAT_VERSION {
                        let err_msg = format!("unknown array version: {}", val);
                        try!(Err(de::Error::custom(err_msg)));
                    }
                    v = Some(val);
                },
                ArrayField::Data => {
                    data = Some(try!(visitor.visit_value()));
                },
                ArrayField::Dim => {
                    dim = Some(try!(visitor.visit_value()));
                },
            }
        }
        try!(visitor.end());

        let _v = match v {
            Some(v) => v,
            None => try!(Err(de::Error::missing_field("v"))),
        };

        let data = match data {
            Some(data) => data,
            None => try!(Err(de::Error::missing_field("data"))),
        };

        let dim = match dim {
            Some(dim) => dim,
            None => try!(Err(de::Error::missing_field("dim"))),
        };

        if let Ok(array) = ArrayBase::from_shape_vec(dim, data) {
            Ok(array)
        } else {
            Err(de::Error::custom("data and dimension must match in size"))
        }
    }
}
<commit_msg>Verify the deserialized version in its own function<commit_after>// Copyright 2014-2016 bluss and ndarray developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::{self, Visitor, SeqVisitor, MapVisitor};

use std::marker::PhantomData;

use imp_prelude::*;

use super::arraytraits::ARRAY_FORMAT_VERSION;
use super::Iter;
use Dim;
use dimension::DimPrivate;

/// Verifies that the version of the deserialized array matches the current
/// `ARRAY_FORMAT_VERSION`.
pub fn verify_version<E>(v: u8) -> Result<(), E>
        where E: de::Error
{
    if v != ARRAY_FORMAT_VERSION {
        let err_msg = format!("unknown array version: {}", v);
        try!(Err(de::Error::custom(err_msg)));
    }

    Ok(())
}

/// **Requires crate feature `"serde"`**
impl<I> Serialize for Dim<I>
    where I: Serialize,
{
    fn serialize<Se>(&self, serializer: &mut Se) -> Result<(), Se::Error>
        where Se: Serializer
    {
        self.ix().serialize(serializer)
    }
}

/// **Requires crate feature `"serde"`**
impl<I> Deserialize for Dim<I>
    where I: Deserialize,
{
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        I::deserialize(deserializer).map(Dim::new)
    }
}

/// **Requires crate feature `"serde"`**
impl<A, D, S> Serialize for ArrayBase<S, D>
    where A: Serialize,
          D: Dimension + Serialize,
          S: Data<Elem = A>

{
    fn serialize<Se>(&self, serializer: &mut Se) -> Result<(), Se::Error>
        where Se: Serializer
    {
        let mut struct_state = try!(serializer.serialize_struct("Array", 3));
        try!(serializer.serialize_struct_elt(&mut struct_state, "v", ARRAY_FORMAT_VERSION));
        try!(serializer.serialize_struct_elt(&mut struct_state, "dim", self.raw_dimension()));
        try!(serializer.serialize_struct_elt(&mut struct_state, "data", Sequence(self.iter())));
        serializer.serialize_struct_end(struct_state)
    }
}

// private iterator wrapper
struct Sequence<'a, A: 'a, D>(Iter<'a, A, D>);

impl<'a, A, D> Serialize for Sequence<'a, A, D>
    where A: Serialize,
          D: Dimension + Serialize
{
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let iter = &self.0;
        let mut seq_state = try!(serializer.serialize_seq(Some(iter.len())));
        for elt in iter.clone() {
            try!(serializer.serialize_seq_elt(&mut seq_state, elt));
        }
        serializer.serialize_seq_end(seq_state)
    }
}

struct ArrayVisitor<S, Di> {
    _marker_a: PhantomData<S>,
    _marker_b: PhantomData<Di>,
}

enum ArrayField {
    Version,
    Dim,
    Data,
}

impl<S, Di> ArrayVisitor<S, Di> {
    pub fn new() -> Self {
        ArrayVisitor { _marker_a: PhantomData, _marker_b: PhantomData, }
    }
}

/// **Requires crate feature `"serde"`**
impl<A, Di, S> Deserialize for ArrayBase<S, Di>
    where A: Deserialize,
          Di: Deserialize + Dimension,
          S: DataOwned<Elem = A>
{
    fn deserialize<D>(deserializer: &mut D) -> Result<ArrayBase<S, Di>, D::Error>
        where D: Deserializer
    {
        static FIELDS: &'static [&'static str] = &["v", "dim", "data"];

        deserializer.deserialize_struct("Array", FIELDS, ArrayVisitor::new())
    }
}

impl Deserialize for ArrayField {
    fn deserialize<D>(deserializer: &mut D) -> Result<ArrayField, D::Error>
        where D: Deserializer
    {
        struct ArrayFieldVisitor;

        impl Visitor for ArrayFieldVisitor {
            type Value = ArrayField;

            fn visit_str<E>(&mut self, value: &str) -> Result<ArrayField, E>
                where E: de::Error
            {
                match value {
                    "v" => Ok(ArrayField::Version),
                    "data" => Ok(ArrayField::Data),
                    "dim" => Ok(ArrayField::Dim),
                    _ => Err(de::Error::custom("expected v, data, or dim")),
                }
            }
        }

        deserializer.deserialize(ArrayFieldVisitor)
    }
}

impl<A, Di, S> Visitor for ArrayVisitor<S,Di>
    where A: Deserialize,
          Di: Deserialize + Dimension,
          S: DataOwned<Elem = A>
{
    type Value = ArrayBase<S, Di>;

    fn visit_seq<V>(&mut self, mut visitor: V) -> Result<ArrayBase<S, Di>, V::Error>
        where V: SeqVisitor
    {
        let v: u8 = match try!(visitor.visit()) {
            Some(value) => value,
            None => {
                try!(visitor.end());
                return Err(de::Error::invalid_length(0));
            }
        };

        try!(verify_version(v));

        let dim: Di = match try!(visitor.visit()) {
            Some(value) => value,
            None => {
                try!(visitor.end());
                return Err(de::Error::invalid_length(1));
            }
        };

        let data: Vec<A> = match try!(visitor.visit()) {
            Some(value) => value,
            None => {
                try!(visitor.end());
                return Err(de::Error::invalid_length(2));
            }
        };

        try!(visitor.end());

        if let Ok(array) = ArrayBase::from_shape_vec(dim, data) {
            Ok(array)
        } else {
            Err(de::Error::custom("data and dimension must match in size"))
        }
    }

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<ArrayBase<S, Di>, V::Error>
        where V: MapVisitor,
    {
        let mut v: Option<u8> = None;
        let mut data: Option<Vec<A>> = None;
        let mut dim: Option<Di> = None;

        while let Some(key) = try!(visitor.visit_key()) {
            match key {
                ArrayField::Version => {
                    let val = try!(visitor.visit_value());
                    try!(verify_version(val));
                    v = Some(val);
                },
                ArrayField::Data => {
                    data = Some(try!(visitor.visit_value()));
                },
                ArrayField::Dim => {
                    dim = Some(try!(visitor.visit_value()));
                },
            }
        }
        try!(visitor.end());

        let _v = match v {
            Some(v) => v,
            None => try!(Err(de::Error::missing_field("v"))),
        };

        let data = match data {
            Some(data) => data,
            None => try!(Err(de::Error::missing_field("data"))),
        };

        let dim = match dim {
            Some(dim) => dim,
            None => try!(Err(de::Error::missing_field("dim"))),
        };

        if let Ok(array) = ArrayBase::from_shape_vec(dim, data) {
            Ok(array)
        } else {
            Err(de::Error::custom("data and dimension must match in size"))
        }
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "rustc-serialize")]
use serialize::{Encodable, Encoder, Decodable, Decoder};

use std::hash;
use std::iter::FromIterator;
use std::iter::IntoIterator;
use std::ops::{
    Index,
    IndexMut,
};

use imp_prelude::*;
use {
    Elements,
    ElementsMut,
    NdIndex,
};

use numeric_util;

#[cold]
#[inline(never)]
fn array_out_of_bounds() -> ! {
    panic!("ndarray: index out of bounds");
}

// Macro to insert more informative out of bounds message in debug builds
#[cfg(debug_assertions)]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => {
        if let None = $index.index_checked(&$self_.dim, &$self_.strides) {
            panic!("ndarray: index {:?} is out of bounds for array of shape {:?}",
                   $index, $self_.shape());
        }
    };
}

#[cfg(not(debug_assertions))]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => { };
}

#[inline(always)]
pub fn debug_bounds_check<S, D, I>(a: &ArrayBase<S, D>, index: &I)
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    debug_bounds_check!(a, *index);
}

/// Access the element at **index**.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> Index<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    type Output = S::Elem;
    #[inline]
    fn index(&self, index: I) -> &S::Elem {
        debug_bounds_check!(self, index);
        self.get(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Access the element at **index** mutably.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: DataMut,
{
    #[inline]
    fn index_mut(&mut self, index: I) -> &mut S::Elem {
        debug_bounds_check!(self, index);
        self.get_mut(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Return `true` if the array shapes and all elements of `self` and
/// `rhs` are equal. Return `false` otherwise.
impl<S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S2: Data<Elem = S::Elem>,
          S::Elem: PartialEq
{
    fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
        if self.shape() != rhs.shape() {
            return false;
        }
        if let Some(self_s) = self.as_slice() {
            if let Some(rhs_s) = rhs.as_slice() {
                return numeric_util::unrolled_eq(self_s, rhs_s);
            }
        }
        self.iter().zip(rhs.iter()).all(|(a, b)| a == b)
    }
}

impl<S, D> Eq for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: Eq,
{ }

impl<A, S> FromIterator<A> for ArrayBase<S, Ix>
    where S: DataOwned<Elem=A>
{
    fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=A>,
    {
        ArrayBase::from_iter(iterable)
    }
}

impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
    where D: Dimension,
          S: Data,
{
    type Item = &'a S::Elem;
    type IntoIter = Elements<'a, S::Elem, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
    where D: Dimension,
          S: DataMut
{
    type Item = &'a mut S::Elem;
    type IntoIter = ElementsMut<'a, S::Elem, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}

impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
    where D: Dimension
{
    type Item = &'a A;
    type IntoIter = Elements<'a, A, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.into_iter_()
    }
}

impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
    where D: Dimension
{
    type Item = &'a mut A;
    type IntoIter = ElementsMut<'a, A, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.into_iter_()
    }
}

impl<'a, S, D> hash::Hash for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: hash::Hash
{
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.shape().hash(state);
        if let Some(self_s) = self.as_slice() {
            hash::Hash::hash_slice(self_s, state);
        } else {
            for row in self.inner_iter() {
                if let Some(row_s) = row.as_slice() {
                    hash::Hash::hash_slice(row_s, state);
                } else {
                    for elt in row {
                        elt.hash(state)
                    }
                }
            }
        }
    }
}

// NOTE: ArrayBase keeps an internal raw pointer that always
// points into the storage. This is Sync & Send as long as we
// follow the usual inherited mutability rules, as we do with
// Vec, &[] and &mut []

/// `ArrayBase` is `Sync` when the storage type is.
unsafe impl<S, D> Sync for ArrayBase<S, D>
    where S: Sync + Data, D: Sync
{ }

/// `ArrayBase` is `Send` when the storage type is.
unsafe impl<S, D> Send for ArrayBase<S, D>
    where S: Send + Data, D: Send
{ }

#[cfg(feature = "rustc-serialize")]
// Use version number so we can add a packed format later.
static ARRAY_FORMAT_VERSION: u8 = 1u8;

/// **Requires crate feature `"rustc-serialize"`**
#[cfg(feature = "rustc-serialize")]
impl<A, S, D> Encodable for ArrayBase<S, D>
    where A: Encodable,
          D: Dimension + Encodable,
          S: Data<Elem = A>
{
    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
        s.emit_struct("Array", 3, |e| {
            try!(e.emit_struct_field("v", 0, |e| ARRAY_FORMAT_VERSION.encode(e)));
            // FIXME: Write self.dim as a slice (self.shape)
            // The problem is decoding it.
            try!(e.emit_struct_field("dim", 1, |e| self.dim.encode(e)));
            try!(e.emit_struct_field("data", 2, |e| {
                let sz = self.dim.size();
                e.emit_seq(sz, |e| {
                    for (i, elt) in self.iter().enumerate() {
                        try!(e.emit_seq_elt(i, |e| elt.encode(e)))
                    }
                    Ok(())
                })
            }));
            Ok(())
        })
    }
}

/// **Requires crate feature `"rustc-serialize"`**
#[cfg(feature = "rustc-serialize")]
impl<A, S, D> Decodable for ArrayBase<S, D>
    where A: Decodable,
          D: Dimension + Decodable,
          S: DataOwned<Elem = A>
{
    fn decode<E: Decoder>(d: &mut E) -> Result<ArrayBase<S, D>, E::Error> {
        d.read_struct("Array", 3, |d| {
            let version: u8 = try!(d.read_struct_field("v", 0, Decodable::decode));
            if version > ARRAY_FORMAT_VERSION {
                return Err(d.error("unknown array version"))
            }
            let dim: D = try!(d.read_struct_field("dim", 1, |d| {
                Decodable::decode(d)
            }));
            let elements = try!(
                d.read_struct_field("data", 2, |d| {
                    d.read_seq(|d, len| {
                        if len != dim.size() {
                            Err(d.error("data and dimension must match in size"))
                        } else {
                            let mut elements = Vec::with_capacity(len);
                            for i in 0..len {
                                elements.push(try!(d.read_seq_elt::<A, _>(i, Decodable::decode)))
                            }
                            Ok(elements)
                        }
                    })
            }));
            unsafe {
                Ok(ArrayBase::from_vec_dim_unchecked(dim, elements))
            }
        })
    }
}

// use "raw" form instead of type aliases here so that they show up in docs
/// Implementation of `ArrayView::from(&S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-only array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayBase<ViewRepr<&'a A>, Ix>
    where Slice: AsRef<[A]>
{
    fn from(slice: &'a Slice) -> Self {
        let xs = slice.as_ref();
        unsafe {
            Self::new_(xs.as_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayView::from(&A)` where `A` is an array.
///
/// Create a read-only array view of the array.
impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a A>, D>
    where S: Data<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a ArrayBase<S, D>) -> Self {
        array.view()
    }
}

/// Implementation of `ArrayViewMut::from(&mut S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-write array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayBase<ViewRepr<&'a mut A>, Ix>
    where Slice: AsMut<[A]>
{
    fn from(slice: &'a mut Slice) -> Self {
        let xs = slice.as_mut();
        unsafe {
            Self::new_(xs.as_mut_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayViewMut::from(&mut A)` where `A` is an array.
///
/// Create a read-write array view of the array.
impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a mut A>, D>
    where S: DataMut<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a mut ArrayBase<S, D>) -> Self {
        array.view_mut()
    }
}

/// Argument conversion into an array view
///
/// The trait is parameterized over `A`, the element type, and `D`, the
/// dimensionality of the array. `D` defaults to one-dimensional.
///
/// Use `.into()` to do the conversion.
///
/// ```
/// use ndarray::AsArray;
///
/// fn sum<'a, V: AsArray<'a, f64>>(data: V) -> f64 {
///     let array_view = data.into();
///     array_view.scalar_sum()
/// }
///
/// assert_eq!(
///     sum(&[1., 2., 3.]),
///     6.
/// );
///
/// ```
pub trait AsArray<'a, A: 'a, D = Ix> : Into<ArrayView<'a, A, D>> where D: Dimension { }
impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
    where T: Into<ArrayView<'a, A, D>>,
          D: Dimension,
{ }
<commit_msg>Fix unused variables in release mode<commit_after>#[cfg(feature = "rustc-serialize")]
use serialize::{Encodable, Encoder, Decodable, Decoder};

use std::hash;
use std::iter::FromIterator;
use std::iter::IntoIterator;
use std::ops::{
    Index,
    IndexMut,
};

use imp_prelude::*;
use {
    Elements,
    ElementsMut,
    NdIndex,
};

use numeric_util;

#[cold]
#[inline(never)]
fn array_out_of_bounds() -> ! {
    panic!("ndarray: index out of bounds");
}

// Macro to insert more informative out of bounds message in debug builds
#[cfg(debug_assertions)]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => {
        if let None = $index.index_checked(&$self_.dim, &$self_.strides) {
            panic!("ndarray: index {:?} is out of bounds for array of shape {:?}",
                   $index, $self_.shape());
        }
    };
}

#[cfg(not(debug_assertions))]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => { };
}

#[inline(always)]
pub fn debug_bounds_check<S, D, I>(_a: &ArrayBase<S, D>, _index: &I)
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    debug_bounds_check!(_a, *_index);
}

/// Access the element at **index**.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> Index<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    type Output = S::Elem;
    #[inline]
    fn index(&self, index: I) -> &S::Elem {
        debug_bounds_check!(self, index);
        self.get(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Access the element at **index** mutably.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: DataMut,
{
    #[inline]
    fn index_mut(&mut self, index: I) -> &mut S::Elem {
        debug_bounds_check!(self, index);
        self.get_mut(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Return `true` if the array shapes and all elements of `self` and
/// `rhs` are equal. Return `false` otherwise.
impl<S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S2: Data<Elem = S::Elem>,
          S::Elem: PartialEq
{
    fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
        if self.shape() != rhs.shape() {
            return false;
        }
        if let Some(self_s) = self.as_slice() {
            if let Some(rhs_s) = rhs.as_slice() {
                return numeric_util::unrolled_eq(self_s, rhs_s);
            }
        }
        self.iter().zip(rhs.iter()).all(|(a, b)| a == b)
    }
}

impl<S, D> Eq for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: Eq,
{ }

impl<A, S> FromIterator<A> for ArrayBase<S, Ix>
    where S: DataOwned<Elem=A>
{
    fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=A>,
    {
        ArrayBase::from_iter(iterable)
    }
}

impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
    where D: Dimension,
          S: Data,
{
    type Item = &'a S::Elem;
    type IntoIter = Elements<'a, S::Elem, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
    where D: Dimension,
          S: DataMut
{
    type Item = &'a mut S::Elem;
    type IntoIter = ElementsMut<'a, S::Elem, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}

impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
    where D: Dimension
{
    type Item = &'a A;
    type IntoIter = Elements<'a, A, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.into_iter_()
    }
}

impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
    where D: Dimension
{
    type Item = &'a mut A;
    type IntoIter = ElementsMut<'a, A, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.into_iter_()
    }
}

impl<'a, S, D> hash::Hash for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: hash::Hash
{
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.shape().hash(state);
        if let Some(self_s) = self.as_slice() {
            hash::Hash::hash_slice(self_s, state);
        } else {
            for row in self.inner_iter() {
                if let Some(row_s) = row.as_slice() {
                    hash::Hash::hash_slice(row_s, state);
                } else {
                    for elt in row {
                        elt.hash(state)
                    }
                }
            }
        }
    }
}

// NOTE: ArrayBase keeps an internal raw pointer that always
// points into the storage. This is Sync & Send as long as we
// follow the usual inherited mutability rules, as we do with
// Vec, &[] and &mut []

/// `ArrayBase` is `Sync` when the storage type is.
unsafe impl<S, D> Sync for ArrayBase<S, D>
    where S: Sync + Data, D: Sync
{ }

/// `ArrayBase` is `Send` when the storage type is.
unsafe impl<S, D> Send for ArrayBase<S, D>
    where S: Send + Data, D: Send
{ }

#[cfg(feature = "rustc-serialize")]
// Use version number so we can add a packed format later.
static ARRAY_FORMAT_VERSION: u8 = 1u8;

/// **Requires crate feature `"rustc-serialize"`**
#[cfg(feature = "rustc-serialize")]
impl<A, S, D> Encodable for ArrayBase<S, D>
    where A: Encodable,
          D: Dimension + Encodable,
          S: Data<Elem = A>
{
    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
        s.emit_struct("Array", 3, |e| {
            try!(e.emit_struct_field("v", 0, |e| ARRAY_FORMAT_VERSION.encode(e)));
            // FIXME: Write self.dim as a slice (self.shape)
            // The problem is decoding it.
            try!(e.emit_struct_field("dim", 1, |e| self.dim.encode(e)));
            try!(e.emit_struct_field("data", 2, |e| {
                let sz = self.dim.size();
                e.emit_seq(sz, |e| {
                    for (i, elt) in self.iter().enumerate() {
                        try!(e.emit_seq_elt(i, |e| elt.encode(e)))
                    }
                    Ok(())
                })
            }));
            Ok(())
        })
    }
}

/// **Requires crate feature `"rustc-serialize"`**
#[cfg(feature = "rustc-serialize")]
impl<A, S, D> Decodable for ArrayBase<S, D>
    where A: Decodable,
          D: Dimension + Decodable,
          S: DataOwned<Elem = A>
{
    fn decode<E: Decoder>(d: &mut E) -> Result<ArrayBase<S, D>, E::Error> {
        d.read_struct("Array", 3, |d| {
            let version: u8 = try!(d.read_struct_field("v", 0, Decodable::decode));
            if version > ARRAY_FORMAT_VERSION {
                return Err(d.error("unknown array version"))
            }
            let dim: D = try!(d.read_struct_field("dim", 1, |d| {
                Decodable::decode(d)
            }));
            let elements = try!(
                d.read_struct_field("data", 2, |d| {
                    d.read_seq(|d, len| {
                        if len != dim.size() {
                            Err(d.error("data and dimension must match in size"))
                        } else {
                            let mut elements = Vec::with_capacity(len);
                            for i in 0..len {
                                elements.push(try!(d.read_seq_elt::<A, _>(i, Decodable::decode)))
                            }
                            Ok(elements)
                        }
                    })
            }));
            unsafe {
                Ok(ArrayBase::from_vec_dim_unchecked(dim, elements))
            }
        })
    }
}

// use "raw" form instead of type aliases here so that they show up in docs
/// Implementation of `ArrayView::from(&S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-only array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayBase<ViewRepr<&'a A>, Ix>
    where Slice: AsRef<[A]>
{
    fn from(slice: &'a Slice) -> Self {
        let xs = slice.as_ref();
        unsafe {
            Self::new_(xs.as_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayView::from(&A)` where `A` is an array.
///
/// Create a read-only array view of the array.
impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a A>, D>
    where S: Data<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a ArrayBase<S, D>) -> Self {
        array.view()
    }
}

/// Implementation of `ArrayViewMut::from(&mut S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-write array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayBase<ViewRepr<&'a mut A>, Ix>
    where Slice: AsMut<[A]>
{
    fn from(slice: &'a mut Slice) -> Self {
        let xs = slice.as_mut();
        unsafe {
            Self::new_(xs.as_mut_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayViewMut::from(&mut A)` where `A` is an array.
///
/// Create a read-write array view of the array.
impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a mut A>, D>
    where S: DataMut<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a mut ArrayBase<S, D>) -> Self {
        array.view_mut()
    }
}

/// Argument conversion into an array view
///
/// The trait is parameterized over `A`, the element type, and `D`, the
/// dimensionality of the array. `D` defaults to one-dimensional.
///
/// Use `.into()` to do the conversion.
///
/// ```
/// use ndarray::AsArray;
///
/// fn sum<'a, V: AsArray<'a, f64>>(data: V) -> f64 {
///     let array_view = data.into();
///     array_view.scalar_sum()
/// }
///
/// assert_eq!(
///     sum(&[1., 2., 3.]),
///     6.
/// );
///
/// ```
pub trait AsArray<'a, A: 'a, D = Ix> : Into<ArrayView<'a, A, D>> where D: Dimension { }
impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
    where T: Into<ArrayView<'a, A, D>>,
          D: Dimension,
{ }
<|endoftext|>


<commit_before>#[macro_use(crate_version, crate_authors)]
extern crate clap;
extern crate inspirer;

#[macro_use]
extern crate slog;
extern crate slog_term;
use slog::DrainExt;

use clap::{App, Arg};

use std::fs::File;
use std::io::{Read, BufReader};
use std::io::{Write, BufWriter};

fn main() {

    // Initialize logging
    let drain = slog_term::streamer().build().fuse();
    let root_logger = slog::Logger::root(drain,
                                         o!("version" => crate_version!()));
    info!(root_logger, "Application started");

    // Define CLI
    let matches = App::new("aux2bib")
                        .version(crate_version!())
                        .author(crate_authors!(",\n"))
                        .about("gets BibTeX keys from Inspire")
                        .arg(Arg::with_name("INPUT")
                             .help("Sets the file from which to extract BibTeX keys")
                             .index(1))
                        .arg(Arg::with_name("OUTPUT")
                             .help("Sets the file to which results should be appended")
                             .index(2))
                        .get_matches();

    // Get input from specified file or stdin
    let mut input_data = String::new();

    let mut input_file: File;
    let mut stdin = std::io::stdin();

    let reader: &mut Read = match matches.value_of("INPUT") {
        Some(file_name) => {
            info!(root_logger, "Reading from file";
                  "file_name" => file_name);
            input_file = File::open(file_name).expect("File not found");
            &mut input_file
        },
        None => {
            info!(root_logger, "Reading from stdin");
            &mut stdin
        },
    };
    let mut reader = BufReader::new(reader);
    reader.read_to_string(&mut input_data).unwrap();

    // Extract BibTeX tags from document
    let keys = inspirer::aux2key(input_data);
    info!(root_logger, "Extracted BibTeX keys";
          "number_of_keys" => keys.len());

    // Retrieve BibTeX entries from inspire.net
    info!(root_logger, "Retrieving entries");
    let mut bibtex_entries: Vec<String> = Vec::new();
    for key in keys {
        debug!(root_logger, "Retrieving record from inspire";
               "bibtex_key" => key);
        if let Some(bibtex_entry) = inspirer::fetch_bibtex_with_key(key) {
            bibtex_entries.push(bibtex_entry);
        }
    }

    // Write BibTeX entries to file or stdout
    let mut stdout = std::io::stdout();
    let mut output_file: std::fs::File;

    let writer: &mut Write = match matches.value_of("OUTPUT") {
        Some(file_name) => {
            info!(root_logger, "Writing to file";
                  "file_name" => file_name);
            output_file = std::fs::OpenOptions::new()
                            .append(true)
                            .create(true)
                            .open(file_name).unwrap();
            &mut output_file
        },
        None            => {
            info!(root_logger, "Writing to stdout");
            // stdout.lock();
            &mut stdout
        },
    };

    let mut writer = BufWriter::new(writer);

    for bibtex_entry in bibtex_entries {
        writer.write_all(&bibtex_entry.as_bytes()).unwrap();
    }

    writer.flush().unwrap();

    info!(root_logger, "Done");
}
<commit_msg>aux2bib: Write logger output to stderr, not stdout<commit_after>#[macro_use(crate_version, crate_authors)]
extern crate clap;
extern crate inspirer;

#[macro_use]
extern crate slog;
extern crate slog_term;
use slog::DrainExt;

use clap::{App, Arg};

use std::fs::File;
use std::io::{Read, BufReader};
use std::io::{Write, BufWriter};

fn main() {

    // Initialize logging
    let drain = slog_term::streamer()
                            .stderr()
                            .build().fuse();
    let root_logger = slog::Logger::root(drain,
                                         o!("version" => crate_version!()));
    info!(root_logger, "Application started");

    // Define CLI
    let matches = App::new("aux2bib")
                        .version(crate_version!())
                        .author(crate_authors!(",\n"))
                        .about("gets BibTeX keys from Inspire")
                        .arg(Arg::with_name("INPUT")
                             .help("Sets the file from which to extract BibTeX keys")
                             .index(1))
                        .arg(Arg::with_name("OUTPUT")
                             .help("Sets the file to which results should be appended")
                             .index(2))
                        .get_matches();

    // Get input from specified file or stdin
    let mut input_data = String::new();

    let mut input_file: File;
    let mut stdin = std::io::stdin();

    let reader: &mut Read = match matches.value_of("INPUT") {
        Some(file_name) => {
            info!(root_logger, "Reading from file";
                  "file_name" => file_name);
            input_file = File::open(file_name).expect("File not found");
            &mut input_file
        },
        None => {
            info!(root_logger, "Reading from stdin");
            &mut stdin
        },
    };
    let mut reader = BufReader::new(reader);
    reader.read_to_string(&mut input_data).unwrap();

    // Extract BibTeX tags from document
    let keys = inspirer::aux2key(input_data);
    info!(root_logger, "Extracted BibTeX keys";
          "number_of_keys" => keys.len());

    // Retrieve BibTeX entries from inspire.net
    info!(root_logger, "Retrieving entries");
    let mut bibtex_entries: Vec<String> = Vec::new();
    for key in keys {
        debug!(root_logger, "Retrieving record from inspire";
               "bibtex_key" => key);
        if let Some(bibtex_entry) = inspirer::fetch_bibtex_with_key(key) {
            bibtex_entries.push(bibtex_entry);
        }
    }

    // Write BibTeX entries to file or stdout
    let mut stdout = std::io::stdout();
    let mut output_file: std::fs::File;

    let writer: &mut Write = match matches.value_of("OUTPUT") {
        Some(file_name) => {
            info!(root_logger, "Writing to file";
                  "file_name" => file_name);
            output_file = std::fs::OpenOptions::new()
                            .append(true)
                            .create(true)
                            .open(file_name).unwrap();
            &mut output_file
        },
        None            => {
            info!(root_logger, "Writing to stdout");
            // stdout.lock();
            &mut stdout
        },
    };

    let mut writer = BufWriter::new(writer);

    for bibtex_entry in bibtex_entries {
        writer.write_all(&bibtex_entry.as_bytes()).unwrap();
    }

    writer.flush().unwrap();

    info!(root_logger, "Done");
}
<|endoftext|>


<commit_before>#![crate_name = "bindgen"]
#![crate_type = "bin"]

extern crate bindgen;
#[macro_use]
extern crate docopt;
#[macro_use]
extern crate log;
extern crate clang_sys;
extern crate rustc_serialize;

use bindgen::{Bindings, BindgenOptions, LinkType, Logger};
use std::io;
use std::path;
use std::env;
use std::default::Default;
use std::fs;
use std::process::exit;

struct StdLogger;

impl Logger for StdLogger {
    fn error(&self, msg: &str) {
        println!("{}", msg);
    }

    fn warn(&self, msg: &str) {
        println!("{}", msg);
    }
}

const USAGE: &'static str = "
Usage:
    bindgen [options] \
        [--link=<lib>...] \
        [--static-link=<lib>...] \
        [--framework-link=<framework>...] \
        [--match=<name>...] \
        [--raw-line=<raw>...] \
        [--dtor-attr=<attr>...] \
        [--opaque-type=<type>...] \
        [--blacklist-type=<type>...] \
        <input-header> \
        [-- <clang-args>...]

    bindgen (-h | --help)

Options:
    -h, --help                    Display this help message.

    -l=<lib>, --link=<lib>        Link to a dynamic library, can be provided
                                  multiple times.

    --static-link=<lib>           Link to a static library, can be provided
                                  multiple times.

    --framework-link=<framework>  Link to a framework.

    -o=<output-rust-file>         Write bindings to <output-rust-file>
                                  (defaults to stdout)

    --match=<name>                Only output bindings for definitions from
                                  files whose name contains <name>. If multiple
                                  match options are provided, files matching any
                                  rule are bound to.

    --builtins                    Output bindings for builtin definitions (for
                                  example __builtin_va_list)

    --ignore-functions            Don't generate bindings for functions and
                                  methods. This is useful when you only care
                                  about struct layouts.

    --enable-cxx-namespaces       Enable support for C++ namespaces.

    --no-type-renaming            Don't rename types.

    --allow-unknown-types         Don't fail if we encounter types we do not
                                  support, instead treat them as void

    --emit-clang-ast              Output the ast (for debugging purposes)

    --use-msvc-mangling           Handle MSVC C++ ABI mangling; requires that
                                  target be set to (i686|x86_64)-pc-win32

    --override-enum-type=<type>   Override enum type, type name could be
                                    uchar
                                    schar
                                    ushort
                                    sshort
                                    uint
                                    sint
                                    ulong
                                    slong
                                    ulonglong
                                    slonglong

    --raw-line=<raw>              TODO
    --dtor-attr=<attr>            TODO
    --no-class-constants          TODO
    --no-unstable-rust            TODO
    --no-namespaced-constants     TODO
    --no-bitfield-methods         TODO
    --ignore-methods              TODO
    --opaque-type=<type>          TODO
    --blacklist-type=<type>       TODO

    <clang-args>                  Options other than stated above are passed
                                  directly through to clang.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_input_header: String,
    flag_link: Vec<String>,
    flag_static_link: Vec<String>,
    flag_framework_link: Vec<String>,
    flag_o: Option<String>,
    flag_match: Vec<String>,
    flag_builtins: bool,
    flag_ignore_functions: bool,
    flag_enable_cxx_namespaces: bool,
    flag_no_type_renaming: bool,
    flag_allow_unknown_types: bool,
    flag_emit_clang_ast: bool,
    flag_use_msvc_mangling: bool,
    flag_override_enum_type: String,
    flag_raw_line: Vec<String>,
    flag_dtor_attr: Vec<String>,
    flag_no_class_constants: bool,
    flag_no_unstable_rust: bool,
    flag_no_namespaced_constants: bool,
    flag_no_bitfield_methods: bool,
    flag_ignore_methods: bool,
    flag_opaque_type: Vec<String>,
    flag_blacklist_type: Vec<String>,
    arg_clang_args: Vec<String>,
}

type ParseResult<T> = Result<T, String>;

impl Into<ParseResult<(BindgenOptions, Box<io::Write>)>> for Args {
    fn into(mut self) -> Result<(BindgenOptions, Box<io::Write>), String> {
        let mut options: BindgenOptions = Default::default();

        options.clang_args.push(self.arg_input_header);

        for lib in self.flag_link.drain(..) {
            options.links.push((lib, LinkType::Default));
        }

        for lib in self.flag_static_link.drain(..) {
            options.links.push((lib, LinkType::Static));
        }

        for lib in self.flag_framework_link.drain(..) {
            options.links.push((lib, LinkType::Framework));
        }

        let out = if let Some(ref path_name) = self.flag_o {
            let path = path::Path::new(path_name);
            let file = try!(fs::File::create(path).map_err(|_| {
                format!("Opening {} failed", path_name)
            }));
            Box::new(io::BufWriter::new(file)) as Box<io::Write>
        } else {
            Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
        };

        options.match_pat.extend(self.flag_match.drain(..));
        options.builtins = self.flag_builtins;
        options.ignore_functions = self.flag_ignore_functions;
        options.enable_cxx_namespaces = self.flag_enable_cxx_namespaces;
        options.rename_types = !self.flag_no_type_renaming;
        options.fail_on_unknown_type = !self.flag_allow_unknown_types;
        options.emit_ast = self.flag_emit_clang_ast;
        options.msvc_mangling = self.flag_use_msvc_mangling;
        options.override_enum_ty = self.flag_override_enum_type;
        options.raw_lines.extend(self.flag_raw_line.drain(..));
        options.dtor_attrs.extend(self.flag_dtor_attr.drain(..));
        options.class_constants = !self.flag_no_class_constants;
        options.unstable_rust = !self.flag_no_unstable_rust;
        options.namespaced_constants = !self.flag_no_namespaced_constants;
        options.gen_bitfield_methods = !self.flag_no_bitfield_methods;
        options.ignore_methods = self.flag_ignore_methods;
        options.opaque_types.extend(self.flag_opaque_type.drain(..));
        options.blacklist_type.extend(self.flag_blacklist_type.drain(..));
        options.clang_args.extend(self.arg_clang_args.drain(..));

        Ok((options, out))
    }
}

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

    if let Some(clang) = clang_sys::support::Clang::find(None) {
        let has_clang_args = bind_args.iter().rposition(|arg| *arg == "--").is_some();
        if !has_clang_args {
            bind_args.push("--".to_owned());
        }

        // TODO: distinguish C and C++ paths? C++'s should be enough, I guess.
        for path in clang.cpp_search_paths.into_iter() {
            if let Ok(path) = path.into_os_string().into_string() {
                bind_args.push("-isystem".to_owned());
                bind_args.push(path);
            }
        }
    }

    let args: Args = docopt::Docopt::new(USAGE)
        .and_then(|d| d.argv(bind_args.iter()).decode())
        .unwrap_or_else(|e| e.exit());

    let logger = StdLogger;
    let result: ParseResult<_> = args.into();
    let (options, out) = result.unwrap_or_else(|msg| {
        logger.error(&msg);
        exit(-1);
    });

    match Bindings::generate(&options, Some(&logger as &Logger), None) {
        Ok(bindings) => match bindings.write(out) {
            Ok(()) => (),
            Err(e) => {
                logger.error(&format!("Unable to write bindings to file. {}", e));
                exit(-1);
            }
        },
        Err(()) => {
            logger.error("Failed to generate bindings".into());
            exit(-1);
        }
    }
}
<commit_msg>Append the input header to the end of the clang args, instead of the front<commit_after>#![crate_name = "bindgen"]
#![crate_type = "bin"]

extern crate bindgen;
#[macro_use]
extern crate docopt;
#[macro_use]
extern crate log;
extern crate clang_sys;
extern crate rustc_serialize;

use bindgen::{Bindings, BindgenOptions, LinkType, Logger};
use std::io;
use std::path;
use std::env;
use std::default::Default;
use std::fs;
use std::process::exit;

struct StdLogger;

impl Logger for StdLogger {
    fn error(&self, msg: &str) {
        println!("{}", msg);
    }

    fn warn(&self, msg: &str) {
        println!("{}", msg);
    }
}

const USAGE: &'static str = "
Usage:
    bindgen [options] \
        [--link=<lib>...] \
        [--static-link=<lib>...] \
        [--framework-link=<framework>...] \
        [--match=<name>...] \
        [--raw-line=<raw>...] \
        [--dtor-attr=<attr>...] \
        [--opaque-type=<type>...] \
        [--blacklist-type=<type>...] \
        <input-header> \
        [-- <clang-args>...]

    bindgen (-h | --help)

Options:
    -h, --help                    Display this help message.

    -l=<lib>, --link=<lib>        Link to a dynamic library, can be provided
                                  multiple times.

    --static-link=<lib>           Link to a static library, can be provided
                                  multiple times.

    --framework-link=<framework>  Link to a framework.

    -o=<output-rust-file>         Write bindings to <output-rust-file>
                                  (defaults to stdout)

    --match=<name>                Only output bindings for definitions from
                                  files whose name contains <name>. If multiple
                                  match options are provided, files matching any
                                  rule are bound to.

    --builtins                    Output bindings for builtin definitions (for
                                  example __builtin_va_list)

    --ignore-functions            Don't generate bindings for functions and
                                  methods. This is useful when you only care
                                  about struct layouts.

    --enable-cxx-namespaces       Enable support for C++ namespaces.

    --no-type-renaming            Don't rename types.

    --allow-unknown-types         Don't fail if we encounter types we do not
                                  support, instead treat them as void

    --emit-clang-ast              Output the ast (for debugging purposes)

    --use-msvc-mangling           Handle MSVC C++ ABI mangling; requires that
                                  target be set to (i686|x86_64)-pc-win32

    --override-enum-type=<type>   Override enum type, type name could be
                                    uchar
                                    schar
                                    ushort
                                    sshort
                                    uint
                                    sint
                                    ulong
                                    slong
                                    ulonglong
                                    slonglong

    --raw-line=<raw>              TODO
    --dtor-attr=<attr>            TODO
    --no-class-constants          TODO
    --no-unstable-rust            TODO
    --no-namespaced-constants     TODO
    --no-bitfield-methods         TODO
    --ignore-methods              TODO
    --opaque-type=<type>          TODO
    --blacklist-type=<type>       TODO

    <clang-args>                  Options other than stated above are passed
                                  directly through to clang.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_input_header: String,
    flag_link: Vec<String>,
    flag_static_link: Vec<String>,
    flag_framework_link: Vec<String>,
    flag_o: Option<String>,
    flag_match: Vec<String>,
    flag_builtins: bool,
    flag_ignore_functions: bool,
    flag_enable_cxx_namespaces: bool,
    flag_no_type_renaming: bool,
    flag_allow_unknown_types: bool,
    flag_emit_clang_ast: bool,
    flag_use_msvc_mangling: bool,
    flag_override_enum_type: String,
    flag_raw_line: Vec<String>,
    flag_dtor_attr: Vec<String>,
    flag_no_class_constants: bool,
    flag_no_unstable_rust: bool,
    flag_no_namespaced_constants: bool,
    flag_no_bitfield_methods: bool,
    flag_ignore_methods: bool,
    flag_opaque_type: Vec<String>,
    flag_blacklist_type: Vec<String>,
    arg_clang_args: Vec<String>,
}

type ParseResult<T> = Result<T, String>;

impl Into<ParseResult<(BindgenOptions, Box<io::Write>)>> for Args {
    fn into(mut self) -> Result<(BindgenOptions, Box<io::Write>), String> {
        let mut options: BindgenOptions = Default::default();

        for lib in self.flag_link.drain(..) {
            options.links.push((lib, LinkType::Default));
        }

        for lib in self.flag_static_link.drain(..) {
            options.links.push((lib, LinkType::Static));
        }

        for lib in self.flag_framework_link.drain(..) {
            options.links.push((lib, LinkType::Framework));
        }

        let out = if let Some(ref path_name) = self.flag_o {
            let path = path::Path::new(path_name);
            let file = try!(fs::File::create(path).map_err(|_| {
                format!("Opening {} failed", path_name)
            }));
            Box::new(io::BufWriter::new(file)) as Box<io::Write>
        } else {
            Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
        };

        options.match_pat.extend(self.flag_match.drain(..));
        options.builtins = self.flag_builtins;
        options.ignore_functions = self.flag_ignore_functions;
        options.enable_cxx_namespaces = self.flag_enable_cxx_namespaces;
        options.rename_types = !self.flag_no_type_renaming;
        options.fail_on_unknown_type = !self.flag_allow_unknown_types;
        options.emit_ast = self.flag_emit_clang_ast;
        options.msvc_mangling = self.flag_use_msvc_mangling;
        options.override_enum_ty = self.flag_override_enum_type;
        options.raw_lines.extend(self.flag_raw_line.drain(..));
        options.dtor_attrs.extend(self.flag_dtor_attr.drain(..));
        options.class_constants = !self.flag_no_class_constants;
        options.unstable_rust = !self.flag_no_unstable_rust;
        options.namespaced_constants = !self.flag_no_namespaced_constants;
        options.gen_bitfield_methods = !self.flag_no_bitfield_methods;
        options.ignore_methods = self.flag_ignore_methods;
        options.opaque_types.extend(self.flag_opaque_type.drain(..));
        options.blacklist_type.extend(self.flag_blacklist_type.drain(..));
        options.clang_args.extend(self.arg_clang_args.drain(..));
        options.clang_args.push(self.arg_input_header);

        Ok((options, out))
    }
}

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

    if let Some(clang) = clang_sys::support::Clang::find(None) {
        let has_clang_args = bind_args.iter().rposition(|arg| *arg == "--").is_some();
        if !has_clang_args {
            bind_args.push("--".to_owned());
        }

        // TODO: distinguish C and C++ paths? C++'s should be enough, I guess.
        for path in clang.cpp_search_paths.into_iter() {
            if let Ok(path) = path.into_os_string().into_string() {
                bind_args.push("-isystem".to_owned());
                bind_args.push(path);
            }
        }
    }

    let args: Args = docopt::Docopt::new(USAGE)
        .and_then(|d| d.argv(bind_args.iter()).decode())
        .unwrap_or_else(|e| e.exit());

    let logger = StdLogger;
    let result: ParseResult<_> = args.into();
    let (options, out) = result.unwrap_or_else(|msg| {
        logger.error(&msg);
        exit(-1);
    });

    match Bindings::generate(&options, Some(&logger as &Logger), None) {
        Ok(bindings) => match bindings.write(out) {
            Ok(()) => (),
            Err(e) => {
                logger.error(&format!("Unable to write bindings to file. {}", e));
                exit(-1);
            }
        },
        Err(()) => {
            logger.error("Failed to generate bindings".into());
            exit(-1);
        }
    }
}
<|endoftext|>