<commit_before>//! WebAssembly function translation state.
//!
//! The `TranslationState` struct defined in this module is used to keep track of the WebAssembly
//! value and control stacks during the translation of a single function.

use cranelift_codegen::ir::{self, Ebb, Inst, Value};
use cranelift_entity::EntityRef;
use environ::{FuncEnvironment, GlobalVariable};
use std::collections::HashMap;
use std::vec::Vec;
use translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};

/// A control stack frame can be an `if`, a `block` or a `loop`, each one having the following
/// fields:
///
/// - `destination`: reference to the `Ebb` that will hold the code after the control block;
/// - `num_return_values`: number of values returned by the control block;
/// - `original_stack_size`: size of the value stack at the beginning of the control block.
///
/// Moreover, the `if` frame has the `branch_inst` field that points to the `brz` instruction
/// separating the `true` and `false` branch. The `loop` frame has a `header` field that references
/// the `Ebb` that contains the beginning of the body of the loop.
#[derive(Debug)]
pub enum ControlStackFrame {
    If {
        destination: Ebb,
        branch_inst: Inst,
        num_return_values: usize,
        original_stack_size: usize,
        exit_is_branched_to: bool,
        reachable_from_top: bool,
    },
    Block {
        destination: Ebb,
        num_return_values: usize,
        original_stack_size: usize,
        exit_is_branched_to: bool,
    },
    Loop {
        destination: Ebb,
        header: Ebb,
        num_return_values: usize,
        original_stack_size: usize,
    },
}

/// Helper methods for the control stack objects.
impl ControlStackFrame {
    pub fn num_return_values(&self) -> usize {
        match *self {
            ControlStackFrame::If {
                num_return_values, ..
            }
            | ControlStackFrame::Block {
                num_return_values, ..
            }
            | ControlStackFrame::Loop {
                num_return_values, ..
            } => num_return_values,
        }
    }
    pub fn following_code(&self) -> Ebb {
        match *self {
            ControlStackFrame::If { destination, .. }
            | ControlStackFrame::Block { destination, .. }
            | ControlStackFrame::Loop { destination, .. } => destination,
        }
    }
    pub fn br_destination(&self) -> Ebb {
        match *self {
            ControlStackFrame::If { destination, .. }
            | ControlStackFrame::Block { destination, .. } => destination,
            ControlStackFrame::Loop { header, .. } => header,
        }
    }
    pub fn original_stack_size(&self) -> usize {
        match *self {
            ControlStackFrame::If {
                original_stack_size,
                ..
            }
            | ControlStackFrame::Block {
                original_stack_size,
                ..
            }
            | ControlStackFrame::Loop {
                original_stack_size,
                ..
            } => original_stack_size,
        }
    }
    pub fn is_loop(&self) -> bool {
        match *self {
            ControlStackFrame::If { .. } | ControlStackFrame::Block { .. } => false,
            ControlStackFrame::Loop { .. } => true,
        }
    }

    pub fn exit_is_branched_to(&self) -> bool {
        match *self {
            ControlStackFrame::If {
                exit_is_branched_to,
                ..
            }
            | ControlStackFrame::Block {
                exit_is_branched_to,
                ..
            } => exit_is_branched_to,
            ControlStackFrame::Loop { .. } => false,
        }
    }

    pub fn set_branched_to_exit(&mut self) {
        match *self {
            ControlStackFrame::If {
                ref mut exit_is_branched_to,
                ..
            }
            | ControlStackFrame::Block {
                ref mut exit_is_branched_to,
                ..
            } => *exit_is_branched_to = true,
            ControlStackFrame::Loop { .. } => {}
        }
    }
}

/// Contains information passed along during the translation and that records:
///
/// - The current value and control stacks.
/// - The depth of the two unreachable control blocks stacks, that are manipulated when translating
///   unreachable code;
pub struct TranslationState {
    pub stack: Vec<Value>,
    pub control_stack: Vec<ControlStackFrame>,
    pub reachable: bool,

    // Map of global variables that have already been created by `FuncEnvironment::make_global`.
    globals: HashMap<GlobalIndex, GlobalVariable>,

    // Map of heaps that have been created by `FuncEnvironment::make_heap`.
    heaps: HashMap<MemoryIndex, ir::Heap>,

    // Map of tables that have been created by `FuncEnvironment::make_table`.
    tables: HashMap<TableIndex, ir::Table>,

    // Map of indirect call signatures that have been created by
    // `FuncEnvironment::make_indirect_sig()`.
    // Stores both the signature reference and the number of WebAssembly arguments
    signatures: HashMap<SignatureIndex, (ir::SigRef, usize)>,

    // Imported and local functions that have been created by
    // `FuncEnvironment::make_direct_func()`.
    // Stores both the function reference and the number of WebAssembly arguments
    functions: HashMap<FuncIndex, (ir::FuncRef, usize)>,
}

impl TranslationState {
    pub fn new() -> Self {
        Self {
            stack: Vec::new(),
            control_stack: Vec::new(),
            reachable: true,
            globals: HashMap::new(),
            heaps: HashMap::new(),
            tables: HashMap::new(),
            signatures: HashMap::new(),
            functions: HashMap::new(),
        }
    }

    fn clear(&mut self) {
        debug_assert!(self.stack.is_empty());
        debug_assert!(self.control_stack.is_empty());
        self.reachable = true;
        self.globals.clear();
        self.heaps.clear();
        self.signatures.clear();
        self.functions.clear();
    }

    /// Initialize the state for compiling a function with the given signature.
    ///
    /// This resets the state to containing only a single block representing the whole function.
    /// The exit block is the last block in the function which will contain the return instruction.
    pub fn initialize(&mut self, sig: &ir::Signature, exit_block: Ebb) {
        self.clear();
        self.push_block(
            exit_block,
            sig.returns
                .iter()
                .filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
                .count(),
        );
    }

    /// Push a value.
    pub fn push1(&mut self, val: Value) {
        self.stack.push(val);
    }

    /// Push multiple values.
    pub fn pushn(&mut self, vals: &[Value]) {
        self.stack.extend_from_slice(vals);
    }

    /// Pop one value.
    pub fn pop1(&mut self) -> Value {
        self.stack.pop().unwrap()
    }

    /// Peek at the top of the stack without popping it.
    pub fn peek1(&self) -> Value {
        *self.stack.last().unwrap()
    }

    /// Pop two values. Return them in the order they were pushed.
    pub fn pop2(&mut self) -> (Value, Value) {
        let v2 = self.stack.pop().unwrap();
        let v1 = self.stack.pop().unwrap();
        (v1, v2)
    }

    /// Pop three values. Return them in the order they were pushed.
    pub fn pop3(&mut self) -> (Value, Value, Value) {
        let v3 = self.stack.pop().unwrap();
        let v2 = self.stack.pop().unwrap();
        let v1 = self.stack.pop().unwrap();
        (v1, v2, v3)
    }

    /// Pop the top `n` values on the stack.
    ///
    /// The popped values are not returned. Use `peekn` to look at them before popping.
    pub fn popn(&mut self, n: usize) {
        let new_len = self.stack.len() - n;
        self.stack.truncate(new_len);
    }

    /// Peek at the top `n` values on the stack in the order they were pushed.
    pub fn peekn(&self, n: usize) -> &[Value] {
        &self.stack[self.stack.len() - n..]
    }

    // Push a block on the control stack.
    pub fn push_block(&mut self, following_code: Ebb, num_result_types: usize) {
        self.control_stack.push(ControlStackFrame::Block {
            destination: following_code,
            original_stack_size: self.stack.len(),
            num_return_values: num_result_types,
            exit_is_branched_to: false,
        });
    }

    // Push a loop on the control stack.
    pub fn push_loop(&mut self, header: Ebb, following_code: Ebb, num_result_types: usize) {
        self.control_stack.push(ControlStackFrame::Loop {
            header,
            destination: following_code,
            original_stack_size: self.stack.len(),
            num_return_values: num_result_types,
        });
    }

    // Push an if on the control stack.
    pub fn push_if(&mut self, branch_inst: Inst, following_code: Ebb, num_result_types: usize) {
        self.control_stack.push(ControlStackFrame::If {
            branch_inst,
            destination: following_code,
            original_stack_size: self.stack.len(),
            num_return_values: num_result_types,
            exit_is_branched_to: false,
            reachable_from_top: self.reachable,
        });
    }
}

/// Methods for handling entity references.
impl TranslationState {
    /// Get the `GlobalVariable` reference that should be used to access the global variable
    /// `index`. Create the reference if necessary.
    /// Also return the WebAssembly type of the global.
    pub fn get_global<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> GlobalVariable {
        let index = index as GlobalIndex;
        *self
            .globals
            .entry(index)
            .or_insert_with(|| environ.make_global(func, index))
    }

    /// Get the `Heap` reference that should be used to access linear memory `index`.
    /// Create the reference if necessary.
    pub fn get_heap<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> ir::Heap {
        let index = index as MemoryIndex;
        *self
            .heaps
            .entry(index)
            .or_insert_with(|| environ.make_heap(func, index))
    }

    /// Get the `Table` reference that should be used to access table `index`.
    /// Create the reference if necessary.
    pub fn get_table<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> ir::Table {
        let index = index as TableIndex;
        *self
            .tables
            .entry(index)
            .or_insert_with(|| environ.make_table(func, index))
    }

    /// Get the `SigRef` reference that should be used to make an indirect call with signature
    /// `index`. Also return the number of WebAssembly arguments in the signature.
    ///
    /// Create the signature if necessary.
    pub fn get_indirect_sig<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> (ir::SigRef, usize) {
        let index = index as SignatureIndex;
        *self.signatures.entry(index).or_insert_with(|| {
            let sig = environ.make_indirect_sig(func, index);
            (sig, normal_args(&func.dfg.signatures[sig]))
        })
    }

    /// Get the `FuncRef` reference that should be used to make a direct call to function
    /// `index`. Also return the number of WebAssembly arguments in the signature.
    ///
    /// Create the function reference if necessary.
    pub fn get_direct_func<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> (ir::FuncRef, usize) {
        let index = FuncIndex::new(index as usize);
        *self.functions.entry(index).or_insert_with(|| {
            let fref = environ.make_direct_func(func, index);
            let sig = func.dfg.ext_funcs[fref].signature;
            (fref, normal_args(&func.dfg.signatures[sig]))
        })
    }
}

/// Count the number of normal parameters in a signature.
/// Exclude special-purpose parameters that represent runtime stuff and not WebAssembly arguments.
fn normal_args(sig: &ir::Signature) -> usize {
    sig.params
        .iter()
        .filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
        .count()
}
<commit_msg>wasm: Clear tables too in TranslationState::clear(); (#491)<commit_after>//! WebAssembly function translation state.
//!
//! The `TranslationState` struct defined in this module is used to keep track of the WebAssembly
//! value and control stacks during the translation of a single function.

use cranelift_codegen::ir::{self, Ebb, Inst, Value};
use cranelift_entity::EntityRef;
use environ::{FuncEnvironment, GlobalVariable};
use std::collections::HashMap;
use std::vec::Vec;
use translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};

/// A control stack frame can be an `if`, a `block` or a `loop`, each one having the following
/// fields:
///
/// - `destination`: reference to the `Ebb` that will hold the code after the control block;
/// - `num_return_values`: number of values returned by the control block;
/// - `original_stack_size`: size of the value stack at the beginning of the control block.
///
/// Moreover, the `if` frame has the `branch_inst` field that points to the `brz` instruction
/// separating the `true` and `false` branch. The `loop` frame has a `header` field that references
/// the `Ebb` that contains the beginning of the body of the loop.
#[derive(Debug)]
pub enum ControlStackFrame {
    If {
        destination: Ebb,
        branch_inst: Inst,
        num_return_values: usize,
        original_stack_size: usize,
        exit_is_branched_to: bool,
        reachable_from_top: bool,
    },
    Block {
        destination: Ebb,
        num_return_values: usize,
        original_stack_size: usize,
        exit_is_branched_to: bool,
    },
    Loop {
        destination: Ebb,
        header: Ebb,
        num_return_values: usize,
        original_stack_size: usize,
    },
}

/// Helper methods for the control stack objects.
impl ControlStackFrame {
    pub fn num_return_values(&self) -> usize {
        match *self {
            ControlStackFrame::If {
                num_return_values, ..
            }
            | ControlStackFrame::Block {
                num_return_values, ..
            }
            | ControlStackFrame::Loop {
                num_return_values, ..
            } => num_return_values,
        }
    }
    pub fn following_code(&self) -> Ebb {
        match *self {
            ControlStackFrame::If { destination, .. }
            | ControlStackFrame::Block { destination, .. }
            | ControlStackFrame::Loop { destination, .. } => destination,
        }
    }
    pub fn br_destination(&self) -> Ebb {
        match *self {
            ControlStackFrame::If { destination, .. }
            | ControlStackFrame::Block { destination, .. } => destination,
            ControlStackFrame::Loop { header, .. } => header,
        }
    }
    pub fn original_stack_size(&self) -> usize {
        match *self {
            ControlStackFrame::If {
                original_stack_size,
                ..
            }
            | ControlStackFrame::Block {
                original_stack_size,
                ..
            }
            | ControlStackFrame::Loop {
                original_stack_size,
                ..
            } => original_stack_size,
        }
    }
    pub fn is_loop(&self) -> bool {
        match *self {
            ControlStackFrame::If { .. } | ControlStackFrame::Block { .. } => false,
            ControlStackFrame::Loop { .. } => true,
        }
    }

    pub fn exit_is_branched_to(&self) -> bool {
        match *self {
            ControlStackFrame::If {
                exit_is_branched_to,
                ..
            }
            | ControlStackFrame::Block {
                exit_is_branched_to,
                ..
            } => exit_is_branched_to,
            ControlStackFrame::Loop { .. } => false,
        }
    }

    pub fn set_branched_to_exit(&mut self) {
        match *self {
            ControlStackFrame::If {
                ref mut exit_is_branched_to,
                ..
            }
            | ControlStackFrame::Block {
                ref mut exit_is_branched_to,
                ..
            } => *exit_is_branched_to = true,
            ControlStackFrame::Loop { .. } => {}
        }
    }
}

/// Contains information passed along during the translation and that records:
///
/// - The current value and control stacks.
/// - The depth of the two unreachable control blocks stacks, that are manipulated when translating
///   unreachable code;
pub struct TranslationState {
    pub stack: Vec<Value>,
    pub control_stack: Vec<ControlStackFrame>,
    pub reachable: bool,

    // Map of global variables that have already been created by `FuncEnvironment::make_global`.
    globals: HashMap<GlobalIndex, GlobalVariable>,

    // Map of heaps that have been created by `FuncEnvironment::make_heap`.
    heaps: HashMap<MemoryIndex, ir::Heap>,

    // Map of tables that have been created by `FuncEnvironment::make_table`.
    tables: HashMap<TableIndex, ir::Table>,

    // Map of indirect call signatures that have been created by
    // `FuncEnvironment::make_indirect_sig()`.
    // Stores both the signature reference and the number of WebAssembly arguments
    signatures: HashMap<SignatureIndex, (ir::SigRef, usize)>,

    // Imported and local functions that have been created by
    // `FuncEnvironment::make_direct_func()`.
    // Stores both the function reference and the number of WebAssembly arguments
    functions: HashMap<FuncIndex, (ir::FuncRef, usize)>,
}

impl TranslationState {
    pub fn new() -> Self {
        Self {
            stack: Vec::new(),
            control_stack: Vec::new(),
            reachable: true,
            globals: HashMap::new(),
            heaps: HashMap::new(),
            tables: HashMap::new(),
            signatures: HashMap::new(),
            functions: HashMap::new(),
        }
    }

    fn clear(&mut self) {
        debug_assert!(self.stack.is_empty());
        debug_assert!(self.control_stack.is_empty());
        self.reachable = true;
        self.globals.clear();
        self.heaps.clear();
        self.tables.clear();
        self.signatures.clear();
        self.functions.clear();
    }

    /// Initialize the state for compiling a function with the given signature.
    ///
    /// This resets the state to containing only a single block representing the whole function.
    /// The exit block is the last block in the function which will contain the return instruction.
    pub fn initialize(&mut self, sig: &ir::Signature, exit_block: Ebb) {
        self.clear();
        self.push_block(
            exit_block,
            sig.returns
                .iter()
                .filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
                .count(),
        );
    }

    /// Push a value.
    pub fn push1(&mut self, val: Value) {
        self.stack.push(val);
    }

    /// Push multiple values.
    pub fn pushn(&mut self, vals: &[Value]) {
        self.stack.extend_from_slice(vals);
    }

    /// Pop one value.
    pub fn pop1(&mut self) -> Value {
        self.stack.pop().unwrap()
    }

    /// Peek at the top of the stack without popping it.
    pub fn peek1(&self) -> Value {
        *self.stack.last().unwrap()
    }

    /// Pop two values. Return them in the order they were pushed.
    pub fn pop2(&mut self) -> (Value, Value) {
        let v2 = self.stack.pop().unwrap();
        let v1 = self.stack.pop().unwrap();
        (v1, v2)
    }

    /// Pop three values. Return them in the order they were pushed.
    pub fn pop3(&mut self) -> (Value, Value, Value) {
        let v3 = self.stack.pop().unwrap();
        let v2 = self.stack.pop().unwrap();
        let v1 = self.stack.pop().unwrap();
        (v1, v2, v3)
    }

    /// Pop the top `n` values on the stack.
    ///
    /// The popped values are not returned. Use `peekn` to look at them before popping.
    pub fn popn(&mut self, n: usize) {
        let new_len = self.stack.len() - n;
        self.stack.truncate(new_len);
    }

    /// Peek at the top `n` values on the stack in the order they were pushed.
    pub fn peekn(&self, n: usize) -> &[Value] {
        &self.stack[self.stack.len() - n..]
    }

    // Push a block on the control stack.
    pub fn push_block(&mut self, following_code: Ebb, num_result_types: usize) {
        self.control_stack.push(ControlStackFrame::Block {
            destination: following_code,
            original_stack_size: self.stack.len(),
            num_return_values: num_result_types,
            exit_is_branched_to: false,
        });
    }

    // Push a loop on the control stack.
    pub fn push_loop(&mut self, header: Ebb, following_code: Ebb, num_result_types: usize) {
        self.control_stack.push(ControlStackFrame::Loop {
            header,
            destination: following_code,
            original_stack_size: self.stack.len(),
            num_return_values: num_result_types,
        });
    }

    // Push an if on the control stack.
    pub fn push_if(&mut self, branch_inst: Inst, following_code: Ebb, num_result_types: usize) {
        self.control_stack.push(ControlStackFrame::If {
            branch_inst,
            destination: following_code,
            original_stack_size: self.stack.len(),
            num_return_values: num_result_types,
            exit_is_branched_to: false,
            reachable_from_top: self.reachable,
        });
    }
}

/// Methods for handling entity references.
impl TranslationState {
    /// Get the `GlobalVariable` reference that should be used to access the global variable
    /// `index`. Create the reference if necessary.
    /// Also return the WebAssembly type of the global.
    pub fn get_global<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> GlobalVariable {
        let index = index as GlobalIndex;
        *self
            .globals
            .entry(index)
            .or_insert_with(|| environ.make_global(func, index))
    }

    /// Get the `Heap` reference that should be used to access linear memory `index`.
    /// Create the reference if necessary.
    pub fn get_heap<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> ir::Heap {
        let index = index as MemoryIndex;
        *self
            .heaps
            .entry(index)
            .or_insert_with(|| environ.make_heap(func, index))
    }

    /// Get the `Table` reference that should be used to access table `index`.
    /// Create the reference if necessary.
    pub fn get_table<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> ir::Table {
        let index = index as TableIndex;
        *self
            .tables
            .entry(index)
            .or_insert_with(|| environ.make_table(func, index))
    }

    /// Get the `SigRef` reference that should be used to make an indirect call with signature
    /// `index`. Also return the number of WebAssembly arguments in the signature.
    ///
    /// Create the signature if necessary.
    pub fn get_indirect_sig<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> (ir::SigRef, usize) {
        let index = index as SignatureIndex;
        *self.signatures.entry(index).or_insert_with(|| {
            let sig = environ.make_indirect_sig(func, index);
            (sig, normal_args(&func.dfg.signatures[sig]))
        })
    }

    /// Get the `FuncRef` reference that should be used to make a direct call to function
    /// `index`. Also return the number of WebAssembly arguments in the signature.
    ///
    /// Create the function reference if necessary.
    pub fn get_direct_func<FE: FuncEnvironment + ?Sized>(
        &mut self,
        func: &mut ir::Function,
        index: u32,
        environ: &mut FE,
    ) -> (ir::FuncRef, usize) {
        let index = FuncIndex::new(index as usize);
        *self.functions.entry(index).or_insert_with(|| {
            let fref = environ.make_direct_func(func, index);
            let sig = func.dfg.ext_funcs[fref].signature;
            (fref, normal_args(&func.dfg.signatures[sig]))
        })
    }
}

/// Count the number of normal parameters in a signature.
/// Exclude special-purpose parameters that represent runtime stuff and not WebAssembly arguments.
fn normal_args(sig: &ir::Signature) -> usize {
    sig.params
        .iter()
        .filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
        .count()
}
<|endoftext|>


<commit_before>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_envlogger;
extern crate slog_json;
#[macro_use]
extern crate slog_scope;
extern crate slog_stdlog;
extern crate slog_term;

extern crate chrono;
extern crate geo;
extern crate geojson;
extern crate hyper;
extern crate rs_es;

pub mod objects;
pub mod rubber;

pub use objects::*;
use std::env;

use slog::Drain;
use slog::Never;

pub fn logger_init() -> (slog_scope::GlobalLoggerGuard, ()) {
    if let Ok(s) = env::var("RUST_LOG_JSON") {
        let mut drain = slog_json::Json::new(std::io::stdout())
            .add_default_keys()
            .add_key_value(o!(
                    "module" => slog::FnValue(|rinfo : &slog::Record| {
                        rinfo.module()
                    })
        ));
        if s == "pretty" {
            drain = drain.set_pretty(true);
        }
        configure_logger(drain.build().fuse())
    } else {
        configure_logger(
            slog_term::CompactFormat::new(slog_term::TermDecorator::new().stderr().build())
                .build()
                .fuse(),
        )
    }
}

fn configure_logger<T>(drain: T) -> (slog_scope::GlobalLoggerGuard, ())
where
    T: Drain<Ok = (), Err = Never> + Send + 'static,
{
    //by default we log for info
    let builder = slog_envlogger::LogBuilder::new(drain).filter(None, slog::FilterLevel::Info);
    let builder = if let Ok(s) = env::var("RUST_LOG") {
        builder.parse(&s)
    } else {
        builder
    };
    let drain = slog_async::Async::new(builder.build())
        .chan_size(100 * 1024)
        .build();

    let log = slog::Logger::root(drain.fuse(), slog_o!());
    let _scope_guard = slog_scope::set_global_logger(log);
    let _log_guard = slog_stdlog::init().unwrap();
    (_scope_guard, _log_guard)
}
<commit_msg>change after review<commit_after>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_envlogger;
extern crate slog_json;
#[macro_use]
extern crate slog_scope;
extern crate slog_stdlog;
extern crate slog_term;

extern crate chrono;
extern crate geo;
extern crate geojson;
extern crate hyper;
extern crate rs_es;

pub mod objects;
pub mod rubber;

pub use objects::*;
use std::env;

use slog::Drain;
use slog::Never;

pub fn logger_init() -> (slog_scope::GlobalLoggerGuard, ()) {
    if let Ok(s) = env::var("RUST_LOG_JSON") {
        let mut drain = slog_json::Json::new(std::io::stderr())
            .add_default_keys()
            .add_key_value(o!(
                    "module" => slog::FnValue(|rinfo : &slog::Record| {
                        rinfo.module()
                    })
        ));
        if s == "pretty" {
            drain = drain.set_pretty(true);
        }
        configure_logger(drain.build().fuse())
    } else {
        configure_logger(
            slog_term::CompactFormat::new(slog_term::TermDecorator::new().stderr().build())
                .build()
                .fuse(),
        )
    }
}

fn configure_logger<T>(drain: T) -> (slog_scope::GlobalLoggerGuard, ())
where
    T: Drain<Ok = (), Err = Never> + Send + 'static,
{
    //by default we log for info
    let builder = slog_envlogger::LogBuilder::new(drain).filter(None, slog::FilterLevel::Info);
    let builder = if let Ok(s) = env::var("RUST_LOG") {
        builder.parse(&s)
    } else {
        builder
    };
    let drain = slog_async::Async::new(builder.build())
        .chan_size(100 * 1024)
        .build();

    let log = slog::Logger::root(drain.fuse(), slog_o!());
    let scope_guard = slog_scope::set_global_logger(log);
    let log_guard = slog_stdlog::init().unwrap();
    (scope_guard, log_guard)
}
<|endoftext|>


<commit_before>use vmx;
use collections::vec::Vec;
use core::sync::atomic::{ATOMIC_U16_INIT, AtomicU16, Ordering};

static CPU_COUNT: AtomicU16 = ATOMIC_U16_INIT;
static CPU_ASSIGNMENT: AtomicU16 = ATOMIC_U16_INIT;

pub fn init(count: u16) {
    CPU_COUNT.store(count, Ordering::Relaxed);
}

pub fn bring_core_online() {
    let cpu_num = CPU_ASSIGNMENT.fetch_add(1, Ordering::Relaxed);
    set_number(cpu_num);
}

fn set_number(num: u16) {
    vmx::write_gs(num);
}

pub fn get_number() -> u16 {
    vmx::read_gs()
}

#[derive(Default)]
pub struct PerCoreVariable<T> {
    vars: Vec<T>,
}

impl<T> PerCoreVariable<T> {
    pub fn get(&self) -> &T {
        &self.vars[get_number() as usize]
    }
}
<commit_msg>Use spin::Once to initialize CPU count<commit_after>use vmx;
use collections::vec::Vec;
use core::sync::atomic::{ATOMIC_U16_INIT, AtomicU16, Ordering};
use spin;

static CPU_COUNT: spin::Once<u16> = spin::Once::new();
static CPU_ASSIGNMENT: AtomicU16 = ATOMIC_U16_INIT;

pub fn init(count: u16) {
    CPU_COUNT.call_once(||{ count });
}

pub fn bring_core_online() {
    let cpu_num = CPU_ASSIGNMENT.fetch_add(1, Ordering::Relaxed);
    set_number(cpu_num);
}

fn set_number(num: u16) {
    vmx::write_gs(num);
}

pub fn get_number() -> u16 {
    vmx::read_gs()
}

#[derive(Default)]
pub struct PerCoreVariable<T> {
    vars: Vec<T>,
}

impl<T> PerCoreVariable<T> {
    pub fn get(&self) -> &T {
        &self.vars[get_number() as usize]
    }
}
<|endoftext|>


<commit_before>// Enlightenment Foundation Libraries Rust bindings.
// Copyright (C) 2014  Luis Araujo <araujoc.luisf@gmail.com>

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![crate_id="efl#1.10.0-0.0.1.99"]
#![crate_type="lib"]

#![feature(macro_rules)]

pub mod eo;
pub mod ecore;
pub mod evas;
pub mod eina;
pub mod eio;
pub mod eet;
pub mod edje;
pub mod eldbus;
pub mod emotion;
pub mod elementary;
pub mod eseful;
<commit_msg>Add #![feature(unsafe_destructor)] to the crate attributes<commit_after>// Enlightenment Foundation Libraries Rust bindings.
// Copyright (C) 2014  Luis Araujo <araujoc.luisf@gmail.com>

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![crate_id="efl#1.10.0-0.0.1.99"]
#![crate_type="lib"]

#![feature(macro_rules)]
#![feature(unsafe_destructor)]

pub mod eo;
pub mod ecore;
pub mod evas;
pub mod eina;
pub mod eio;
pub mod eet;
pub mod edje;
pub mod eldbus;
pub mod emotion;
pub mod elementary;
pub mod eseful;
<|endoftext|>


<commit_before>use csv;
use std::{cmp, error, fmt};
use std::error::Error;
use term_painter::{Attr, Color, ToStyle};
use term_size;
use textwrap;

pub trait Helpful {
    fn help(&self) -> String;
}

#[derive(Clone, Debug)]
pub enum Location {
    FileLineColumn(String, usize, usize),
    FileRowField(String, usize, usize),
    FileLine(String, usize),
    File(String),
    Unspecified,
}

impl fmt::Display for Location {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Location::FileLineColumn(ref file, line, col) => write!(f, "{}:{}:{}", file, line, col),
            Location::FileRowField(ref file, row, field) => {
                write!(f, "{}:{}[{}]", file, row, field)
            }
            Location::FileLine(ref file, line) => write!(f, "{}:{}]", file, line),
            Location::File(ref file) => write!(f, "{}", file),
            Location::Unspecified => Ok(()),
        }
    }
}

#[derive(Debug)]
pub struct ErrorWithLocation<E> {
    location: Location,
    error: E,
}

pub trait ErrorLoc<E>: Sized {
    #[inline]
    fn location(self, location: Location) -> ErrorWithLocation<E>;
}

impl<E: error::Error, F: Into<E>> ErrorLoc<E> for F {
    #[inline]
    fn location(self, location: Location) -> ErrorWithLocation<E> {
        ErrorWithLocation::new(location, self.into())
    }
}

pub trait ResultLoc<V, E: ErrorLoc<E>>: Sized {
    #[inline]
    fn err_location(self, location: Location) -> Result<V, ErrorWithLocation<E>>;

    #[inline]
    fn err_loc<F: FnOnce() -> Location>(self, floc: F) -> Result<V, ErrorWithLocation<E>> {
        self.err_location(floc())
    }
}

impl<V, E: error::Error, F: Into<E>> ResultLoc<V, E> for Result<V, F> {
    #[inline]
    fn err_location(self, location: Location) -> Result<V, ErrorWithLocation<E>> {
        self.map_err(|f| f.location(location))
    }
}

impl<E> ErrorWithLocation<E> {
    pub fn new<F: Into<E>>(location: Location, error: F) -> ErrorWithLocation<E> {
        ErrorWithLocation {
            location: location,
            error: error.into(),
        }
    }

    pub fn from_error<F: Into<E>>(other: F) -> ErrorWithLocation<E> {
        ErrorWithLocation::new(Location::Unspecified, other.into())
    }

    pub fn convert<F: From<E>>(self) -> ErrorWithLocation<F> {
        ErrorWithLocation {
            location: self.location,
            error: self.error.into(),
        }
    }
}

impl<E: fmt::Display + Helpful> ErrorWithLocation<E> {
    pub fn print_help(&self) {
        println!("{}{} {}",
                 Attr::Bold.paint((Color::Red.paint("error"))),
                 Attr::Bold.paint(":"),
                 Attr::Bold.paint(self.error()));
        match *self.location() {
            Location::Unspecified => (),
            _ => println!("  --> {}", Color::Yellow.paint(self.location())),
        }

        let dims = term_size::dimensions().unwrap_or((80, 25));

        let term_width = cmp::max(dims.0, 4);
        let out = textwrap::wrap(self.error.help().as_str(), term_width - 3)
            .into_iter()
            .map(|line| textwrap::indent(line.as_str(), "   "))
            .fold(String::new(), |s1, s2| s1 + s2.as_str());
        println!("{}", out);
    }
}

impl<E> ErrorWithLocation<E> {
    pub fn error(&self) -> &E {
        &self.error
    }

    pub fn into_error(self) -> E {
        self.error
    }

    pub fn location(&self) -> &Location {
        &self.location
    }
}

impl<E: fmt::Display> fmt::Display for ErrorWithLocation<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self.location() {
            Location::Unspecified => write!(f, "{}", self.error()),
            _ => write!(f, "{}: {}", self.location(), self.error()),
        }
    }
}

impl<E: error::Error> error::Error for ErrorWithLocation<E> {
    fn description(&self) -> &str {
        self.error.description()
    }

    fn cause(&self) -> Option<&error::Error> {
        Some(self.error())
    }
}

impl<E> From<E> for ErrorWithLocation<E> {
    fn from(e: E) -> ErrorWithLocation<E> {
        ErrorWithLocation::from_error(e)
    }
}

#[derive(Debug)]
pub enum CheckError {
    NotASchema,
    SchemaNotAFile,
    InvalidCsvxFilename,
    SchemaLoadError(SchemaLoadError),
    SchemaPathUtf8Error,
}

impl From<SchemaLoadError> for CheckError {
    fn from(e: SchemaLoadError) -> CheckError {
        CheckError::SchemaLoadError(e)
    }
}

impl fmt::Display for CheckError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(cause) = self.cause() {
            write!(f, "{}", cause)
        } else {
            write!(f, "{}", self.description())
        }
    }
}

impl error::Error for CheckError {
    fn description(&self) -> &str {
        match *self {
            CheckError::NotASchema => "not a schema",
            CheckError::SchemaNotAFile => "schema is not a file",
            CheckError::InvalidCsvxFilename => "filename is not a valid CSVX filename",
            CheckError::SchemaLoadError(_) => "could not load schema",
            CheckError::SchemaPathUtf8Error => "filename UTF8 decoding error",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            CheckError::SchemaLoadError(ref e) => Some(e),
            _ => None,
        }
    }
}

impl Helpful for CheckError {
    fn help(&self) -> String {
        match *self {
            CheckError::NotASchema => {
                "The file you provided is not a schema. The third field of \
                the filename must be of the form `csvx-schema-` followed by \
                the version number. As an example, when defining a schema \
                named `animals-2`, with a date of Dec 31st, 2015 and CSVX \
                version 5, the resulting filename should be: \
                `animals-2_20151231_csvx-schema-5.csv`. \n\
                Note that filenames are case sensitive!"
                        .to_owned()
            }
            CheckError::SchemaNotAFile => "The schema you supplied is not a valid file".to_owned(),
            CheckError::InvalidCsvxFilename => {
                "The filename provided is not in a valid CSVX form. CSVX \
                filenames have three components: The table name, date and \
                schema name. All components must be lowercase letters, \
                numbers or hyphens and start with a letter.\n\n\
                The table name component identifies the file or rather the \
                table it was exported from.\n\
                The date component is for the date the file was exported on.\n\
                The schema name component indicates which schema should be \
                used to validate its contents.\n\n\
                Example: With a table name of `nyc-zoo`, a date of Dec 31st, \
                2015 and using a schema named `animals-2`, the resulting \
                filename should be `nyc-zoo_20151231_animals-2.csv`."
                        .to_owned()
            }
            CheckError::SchemaPathUtf8Error => {
                "The filename you supplied contained UTF-8 errors. CSVX \
                filenames should only contain ASCII characters, please rename \
                the file and try again."
                        .to_owned()
            }
            CheckError::SchemaLoadError(ref e) => e.help(),
        }
    }
}

#[derive(Clone, Debug)]
pub enum ColumnConstraintsError {
    MalformedConstraint,
    UnknownConstraint(String),
}

#[derive(Clone, Debug)]
pub enum ColumnTypeError {
    UnknownType,
}

#[derive(Debug)]
pub enum SchemaLoadError {
    Csv(csv::Error),
    MissingHeader,
    BadHeader,
    BadIdentifier(usize, String),
    BadType(usize, ColumnTypeError),
    BadConstraints(usize, ColumnConstraintsError),
}

impl fmt::Display for SchemaLoadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(cause) = self.cause() {
            write!(f, "{}", cause)
        } else {
            write!(f, "{}", self.description())
        }
    }
}

impl error::Error for SchemaLoadError {
    fn description(&self) -> &str {
        match *self {
            _ => "TBW",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            _ => None,
        }
    }
}

impl Helpful for SchemaLoadError {
    fn help(&self) -> String {
        "FIXME".to_owned()
    }
}

impl From<csv::Error> for SchemaLoadError {
    fn from(e: csv::Error) -> SchemaLoadError {
        SchemaLoadError::Csv(e)
    }
}

#[derive(Debug)]
pub enum ValidationError {
    Csv(csv::Error),
    MissingHeaders,
    HeaderMismatch(usize, String),
    RowLengthMismatch(usize),
    ValueError(usize, usize, ValueError),
}

#[derive(Debug)]
pub enum ValueError {
    NonNullable,
    InvalidBool,
    InvalidInt,
    InvalidEnum,
    InvalidDecimal,
    InvalidDate,
    InvalidDateTime,
    InvalidTime,
}
<commit_msg>Renamed location methods to `at`, `err_at` and `error_at`.<commit_after>use csv;
use std::{cmp, error, fmt};
use std::error::Error;
use term_painter::{Attr, Color, ToStyle};
use term_size;
use textwrap;

pub trait Helpful {
    fn help(&self) -> String;
}

#[derive(Clone, Debug)]
pub enum Location {
    FileLineColumn(String, usize, usize),
    FileRowField(String, usize, usize),
    FileLine(String, usize),
    File(String),
    Unspecified,
}

impl fmt::Display for Location {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Location::FileLineColumn(ref file, line, col) => write!(f, "{}:{}:{}", file, line, col),
            Location::FileRowField(ref file, row, field) => {
                write!(f, "{}:{}[{}]", file, row, field)
            }
            Location::FileLine(ref file, line) => write!(f, "{}:{}]", file, line),
            Location::File(ref file) => write!(f, "{}", file),
            Location::Unspecified => Ok(()),
        }
    }
}

#[derive(Debug)]
pub struct ErrorWithLocation<E> {
    location: Location,
    error: E,
}

pub trait ErrorLoc<E>: Sized {
    #[inline]
    fn at(self, location: Location) -> ErrorWithLocation<E>;
}

impl<E: error::Error, F: Into<E>> ErrorLoc<E> for F {
    #[inline]
    fn at(self, location: Location) -> ErrorWithLocation<E> {
        ErrorWithLocation::new(location, self.into())
    }
}

pub trait ResultLoc<V, E: ErrorLoc<E>>: Sized {
    #[inline]
    fn error_at(self, location: Location) -> Result<V, ErrorWithLocation<E>>;

    #[inline]
    fn err_at<F: FnOnce() -> Location>(self, floc: F) -> Result<V, ErrorWithLocation<E>> {
        self.error_at(floc())
    }
}

impl<V, E: error::Error, F: Into<E>> ResultLoc<V, E> for Result<V, F> {
    #[inline]
    fn error_at(self, location: Location) -> Result<V, ErrorWithLocation<E>> {
        self.map_err(|f| f.at(location))
    }
}

impl<E> ErrorWithLocation<E> {
    pub fn new<F: Into<E>>(location: Location, error: F) -> ErrorWithLocation<E> {
        ErrorWithLocation {
            location: location,
            error: error.into(),
        }
    }

    pub fn from_error<F: Into<E>>(other: F) -> ErrorWithLocation<E> {
        ErrorWithLocation::new(Location::Unspecified, other.into())
    }

    pub fn convert<F: From<E>>(self) -> ErrorWithLocation<F> {
        ErrorWithLocation {
            location: self.location,
            error: self.error.into(),
        }
    }
}

impl<E: fmt::Display + Helpful> ErrorWithLocation<E> {
    pub fn print_help(&self) {
        println!("{}{} {}",
                 Attr::Bold.paint((Color::Red.paint("error"))),
                 Attr::Bold.paint(":"),
                 Attr::Bold.paint(self.error()));
        match *self.location() {
            Location::Unspecified => (),
            _ => println!("  --> {}", Color::Yellow.paint(self.location())),
        }

        let dims = term_size::dimensions().unwrap_or((80, 25));

        let term_width = cmp::max(dims.0, 4);
        let out = textwrap::wrap(self.error.help().as_str(), term_width - 3)
            .into_iter()
            .map(|line| textwrap::indent(line.as_str(), "   "))
            .fold(String::new(), |s1, s2| s1 + s2.as_str());
        println!("{}", out);
    }
}

impl<E> ErrorWithLocation<E> {
    pub fn error(&self) -> &E {
        &self.error
    }

    pub fn into_error(self) -> E {
        self.error
    }

    pub fn location(&self) -> &Location {
        &self.location
    }
}

impl<E: fmt::Display> fmt::Display for ErrorWithLocation<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self.location() {
            Location::Unspecified => write!(f, "{}", self.error()),
            _ => write!(f, "{}: {}", self.location(), self.error()),
        }
    }
}

impl<E: error::Error> error::Error for ErrorWithLocation<E> {
    fn description(&self) -> &str {
        self.error.description()
    }

    fn cause(&self) -> Option<&error::Error> {
        Some(self.error())
    }
}

impl<E> From<E> for ErrorWithLocation<E> {
    fn from(e: E) -> ErrorWithLocation<E> {
        ErrorWithLocation::from_error(e)
    }
}

#[derive(Debug)]
pub enum CheckError {
    NotASchema,
    SchemaNotAFile,
    InvalidCsvxFilename,
    SchemaLoadError(SchemaLoadError),
    SchemaPathUtf8Error,
}

impl From<SchemaLoadError> for CheckError {
    fn from(e: SchemaLoadError) -> CheckError {
        CheckError::SchemaLoadError(e)
    }
}

impl fmt::Display for CheckError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(cause) = self.cause() {
            write!(f, "{}", cause)
        } else {
            write!(f, "{}", self.description())
        }
    }
}

impl error::Error for CheckError {
    fn description(&self) -> &str {
        match *self {
            CheckError::NotASchema => "not a schema",
            CheckError::SchemaNotAFile => "schema is not a file",
            CheckError::InvalidCsvxFilename => "filename is not a valid CSVX filename",
            CheckError::SchemaLoadError(_) => "could not load schema",
            CheckError::SchemaPathUtf8Error => "filename UTF8 decoding error",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            CheckError::SchemaLoadError(ref e) => Some(e),
            _ => None,
        }
    }
}

impl Helpful for CheckError {
    fn help(&self) -> String {
        match *self {
            CheckError::NotASchema => {
                "The file you provided is not a schema. The third field of \
                the filename must be of the form `csvx-schema-` followed by \
                the version number. As an example, when defining a schema \
                named `animals-2`, with a date of Dec 31st, 2015 and CSVX \
                version 5, the resulting filename should be: \
                `animals-2_20151231_csvx-schema-5.csv`. \n\
                Note that filenames are case sensitive!"
                        .to_owned()
            }
            CheckError::SchemaNotAFile => "The schema you supplied is not a valid file".to_owned(),
            CheckError::InvalidCsvxFilename => {
                "The filename provided is not in a valid CSVX form. CSVX \
                filenames have three components: The table name, date and \
                schema name. All components must be lowercase letters, \
                numbers or hyphens and start with a letter.\n\n\
                The table name component identifies the file or rather the \
                table it was exported from.\n\
                The date component is for the date the file was exported on.\n\
                The schema name component indicates which schema should be \
                used to validate its contents.\n\n\
                Example: With a table name of `nyc-zoo`, a date of Dec 31st, \
                2015 and using a schema named `animals-2`, the resulting \
                filename should be `nyc-zoo_20151231_animals-2.csv`."
                        .to_owned()
            }
            CheckError::SchemaPathUtf8Error => {
                "The filename you supplied contained UTF-8 errors. CSVX \
                filenames should only contain ASCII characters, please rename \
                the file and try again."
                        .to_owned()
            }
            CheckError::SchemaLoadError(ref e) => e.help(),
        }
    }
}

#[derive(Clone, Debug)]
pub enum ColumnConstraintsError {
    MalformedConstraint,
    UnknownConstraint(String),
}

#[derive(Clone, Debug)]
pub enum ColumnTypeError {
    UnknownType,
}

#[derive(Debug)]
pub enum SchemaLoadError {
    Csv(csv::Error),
    MissingHeader,
    BadHeader,
    BadIdentifier(usize, String),
    BadType(usize, ColumnTypeError),
    BadConstraints(usize, ColumnConstraintsError),
}

impl fmt::Display for SchemaLoadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(cause) = self.cause() {
            write!(f, "{}", cause)
        } else {
            write!(f, "{}", self.description())
        }
    }
}

impl error::Error for SchemaLoadError {
    fn description(&self) -> &str {
        match *self {
            _ => "TBW",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            _ => None,
        }
    }
}

impl Helpful for SchemaLoadError {
    fn help(&self) -> String {
        "FIXME".to_owned()
    }
}

impl From<csv::Error> for SchemaLoadError {
    fn from(e: csv::Error) -> SchemaLoadError {
        SchemaLoadError::Csv(e)
    }
}

#[derive(Debug)]
pub enum ValidationError {
    Csv(csv::Error),
    MissingHeaders,
    HeaderMismatch(usize, String),
    RowLengthMismatch(usize),
    ValueError(usize, usize, ValueError),
}

#[derive(Debug)]
pub enum ValueError {
    NonNullable,
    InvalidBool,
    InvalidInt,
    InvalidEnum,
    InvalidDecimal,
    InvalidDate,
    InvalidDateTime,
    InvalidTime,
}
<|endoftext|>


<commit_before>//! Manipulations and data types that represent 2d matrix.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

#![feature(macro_rules)]

extern crate num;

use std::ops::{Add, Index, Mul, Sub};
use num::{One, Zero};

/// 2D matrix.
#[derive(PartialEq, Eq, Clone, Show)]
pub struct Matrix<T> {
    row: uint,
    column: uint,
    data: Vec<T>
}

impl<T> Matrix<T> {
    /// Creates a new `Matrix`.
    #[inline]
    pub fn from_fn<F>(row: uint, column: uint, f: F) -> Matrix<T>
        where F:Fn(uint, uint) -> T
    {
        Matrix {
            row: row,
            column: column,
            data: range(0, row * column).map(|i| f(i / column, i % column)).collect()
        }
    }

    /// Creates a new `Matrix` from vector.
    #[inline]
    pub fn from_vec(row: uint, column: uint, data: Vec<T>) -> Matrix<T> {
        assert_eq!(row * column, data.len());
        Matrix { row: row, column: column, data: data }
    }

    /// Returns the matrix's row and column.
    #[inline]
    pub fn size(&self) -> (uint, uint) { (self.row(), self.column()) }
    /// Returns the matrix's row.
    #[inline]
    pub fn row(&self) -> uint { self.row }
    /// Returns the matrix's column.
    #[inline]
    pub fn column(&self) -> uint { self.column }
}

impl<T: Zero> Matrix<T> {
    /// Creates a matrix whose elements are all zero.
    #[inline]
    pub fn zero(row: uint, column: uint) -> Matrix<T> {
        Matrix::from_fn(row, column, |_, _| Zero::zero())
    }
}

impl<T: One + Zero> Matrix<T> {
    /// Creates a identity matrix.
    #[inline]
    pub fn one(row: uint, column: uint) -> Matrix<T> {
        Matrix::from_fn(row, column, |i, j| {
            if i == j {
                One::one()
            } else {
                Zero::zero()
            }
        })
    }
}

impl<T: Clone> Matrix<T> {
    #[inline]
    /// Returns transpose of the matrix.
    pub fn trans(&self) -> Matrix<T> {
        Matrix::from_fn(self.column(), self.row(), |i, j| self[(j, i)].clone())
    }
}

impl<T> Index<(uint, uint)> for Matrix<T> {
    type Output = T;

    #[inline]
    fn index(&self, &(i, j): &(uint, uint)) -> &T {
        assert!(i < self.row() && j < self.column());
        &self.data[i * self.column() + j]
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Matrix<Rhs>> for &'a Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Add<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Add<Rhs>>::Output>;

    #[inline]
    fn add(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Add<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() + other[(i, j)].clone())
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Sub<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Sub<Rhs>>::Output>;

    #[inline]
    fn sub(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Sub<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() - other[(i, j)].clone())
    }
}

impl<Lhs, Rhs> Mul<Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        (&self).mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) ->  Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<&'a Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(other)
    }
}

impl<'a, 'b, Lhs, Rhs> Mul<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        assert_eq!(self.column(), other.row());
        Matrix::from_fn(self.row(), other.column(), |i, j| {
            let mut sum = self[(i, 0)].clone() * other[(0, j)].clone();
            for k in range(1, self.column()) {
                sum = sum + self[(i, k)].clone() * other[(k, j)].clone();
            }
            sum
        })
    }
}

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

    #[test]
    fn from_vec() {
        let mat = Matrix::from_vec(2, 3, vec![(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]);
        for i in range(0, mat.row()) {
            for j in range(0, mat.column()) {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn index() {
        let mat = Matrix::from_fn(3, 5, |i, j| (i, j));
        for i in range(0, mat.row()) {
            for j in range(0, mat.column()) {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn mul() {
        let m1 = Matrix::from_vec(1, 3, vec![1.0f64, 2.0, 3.0]);
        let m2 = Matrix::from_vec(3, 1, vec![1.0, 2.0, 3.0]);
        assert_eq!(Matrix::from_vec(1, 1, vec![14.0]), m1 * m2);
        assert_eq!(Matrix::from_vec(3, 1, vec![1.0f64, 4.0, 7.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 1, vec![1.0, 0.0, 0.0]));
        assert_eq!(Matrix::from_vec(3, 2, vec![1.0f64, 3.0, 4.0, 6.0, 7.0, 9.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 2, vec![1.0, 0.0, 0.0, 0.0, 0.0, 1.0]));
    }
}

<commit_msg>fix compiler warnings<commit_after>//! Manipulations and data types that represent 2d matrix.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

extern crate num;

use std::ops::{Add, Index, Mul, Sub};
use num::{One, Zero};

/// 2D matrix.
#[derive(PartialEq, Eq, Clone, Show)]
pub struct Matrix<T> {
    row: usize,
    column: usize,
    data: Vec<T>
}

impl<T> Matrix<T> {
    /// Creates a new `Matrix`.
    #[inline]
    pub fn from_fn<F>(row: usize, column: usize, f: F) -> Matrix<T>
        where F:Fn(usize, usize) -> T
    {
        Matrix {
            row: row,
            column: column,
            data: (0 .. row * column).map(|i| f(i / column, i % column)).collect()
        }
    }

    /// Creates a new `Matrix` from vector.
    #[inline]
    pub fn from_vec(row: usize, column: usize, data: Vec<T>) -> Matrix<T> {
        assert_eq!(row * column, data.len());
        Matrix { row: row, column: column, data: data }
    }

    /// Returns the matrix's row and column.
    #[inline]
    pub fn size(&self) -> (usize, usize) { (self.row(), self.column()) }
    /// Returns the matrix's row.
    #[inline]
    pub fn row(&self) -> usize { self.row }
    /// Returns the matrix's column.
    #[inline]
    pub fn column(&self) -> usize { self.column }
}

impl<T: Zero> Matrix<T> {
    /// Creates a matrix whose elements are all zero.
    #[inline]
    pub fn zero(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |_, _| Zero::zero())
    }
}

impl<T: One + Zero> Matrix<T> {
    /// Creates a identity matrix.
    #[inline]
    pub fn one(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |i, j| {
            if i == j {
                One::one()
            } else {
                Zero::zero()
            }
        })
    }
}

impl<T: Clone> Matrix<T> {
    #[inline]
    /// Returns transpose of the matrix.
    pub fn trans(&self) -> Matrix<T> {
        Matrix::from_fn(self.column(), self.row(), |i, j| self[(j, i)].clone())
    }
}

impl<T> Index<(usize, usize)> for Matrix<T> {
    type Output = T;

    #[inline]
    fn index(&self, &(i, j): &(usize, usize)) -> &T {
        assert!(i < self.row() && j < self.column());
        &self.data[i * self.column() + j]
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Matrix<Rhs>> for &'a Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Add<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Add<Rhs>>::Output>;

    #[inline]
    fn add(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Add<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() + other[(i, j)].clone())
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Sub<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Sub<Rhs>>::Output>;

    #[inline]
    fn sub(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Sub<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() - other[(i, j)].clone())
    }
}

impl<Lhs, Rhs> Mul<Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        (&self).mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) ->  Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<&'a Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(other)
    }
}

impl<'a, 'b, Lhs, Rhs> Mul<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        assert_eq!(self.column(), other.row());
        Matrix::from_fn(self.row(), other.column(), |i, j| {
            let mut sum = self[(i, 0)].clone() * other[(0, j)].clone();
            for k in 1 .. self.column() {
                sum = sum + self[(i, k)].clone() * other[(k, j)].clone();
            }
            sum
        })
    }
}

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

    #[test]
    fn from_vec() {
        let mat = Matrix::from_vec(2, 3, vec![(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]);
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn index() {
        let mat = Matrix::from_fn(3, 5, |i, j| (i, j));
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn mul() {
        let m1 = Matrix::from_vec(1, 3, vec![1.0f64, 2.0, 3.0]);
        let m2 = Matrix::from_vec(3, 1, vec![1.0, 2.0, 3.0]);
        assert_eq!(Matrix::from_vec(1, 1, vec![14.0]), m1 * m2);
        assert_eq!(Matrix::from_vec(3, 1, vec![1.0f64, 4.0, 7.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 1, vec![1.0, 0.0, 0.0]));
        assert_eq!(Matrix::from_vec(3, 2, vec![1.0f64, 3.0, 4.0, 6.0, 7.0, 9.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 2, vec![1.0, 0.0, 0.0, 0.0, 0.0, 1.0]));
    }
}

<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Assertor makes test assertions and failure messages more human-readable.
//!
//! Assertor is heavy affected by [Java Truth](https://github.com/google/truth) in terms of API
//! design and error messages.
//!
//! # Example
//! ```
//! use assertor::*;
//!
//! assert_that!("foobarbaz").contains("bar");
//! assert_that!("foobarbaz").ends_with("baz");
//!
//! assert_that!(0.5).with_abs_tol(0.2).is_approx_equal_to(0.6);
//!
//! assert_that!(vec!["a", "b"]).contains("a");
//! assert_that!(vec!["a", "b"]).has_length(2);
//! assert_that!(vec!["a", "b"]).contains_exactly(vec!["a", "b"]);
//!
//! assert_that!(Option::Some("Foo")).has_value("Foo");
//! ```
//! ## Failure cases
//! ```should_panic
//! use assertor::*;
//! assert_that!(vec!["a", "b", "c"]).contains_exactly(vec!["b", "c", "d"]);
//! // missing (1)   : ["d"]
//! // unexpected (1): ["a"]
//! // ---
//! // expected      : ["b", "c", "d"]
//! // actual        : ["a", "b", "c"]
//! ```
#![warn(missing_docs)]

#[cfg(feature = "float")]
extern crate num_traits;

pub use assertions::basic::{ComparableAssertion, EqualityAssertion};
#[cfg(feature = "float")]
pub use assertions::float::FloatAssertion;
pub use assertions::iterator::IteratorAssertion;
pub use assertions::map::MapAssertion;
pub use assertions::option::OptionAssertion;
pub use assertions::result::ResultAssertion;
pub use assertions::set::SetAssertion;
pub use assertions::string::StringAssertion;
pub use assertions::vec::VecAssertion;
pub use base::{AssertionResult, AssertionStrategy, Fact, Location, Subject};

mod assertions;
mod base;

// TODO: make this public once API gets stable.
#[cfg(any(test, doc, feature = "testing"))]
pub(crate) mod testing;
<commit_msg>Make testing module public<commit_after>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Assertor makes test assertions and failure messages more human-readable.
//!
//! Assertor is heavy affected by [Java Truth](https://github.com/google/truth) in terms of API
//! design and error messages.
//!
//! # Example
//! ```
//! use assertor::*;
//!
//! assert_that!("foobarbaz").contains("bar");
//! assert_that!("foobarbaz").ends_with("baz");
//!
//! assert_that!(0.5).with_abs_tol(0.2).is_approx_equal_to(0.6);
//!
//! assert_that!(vec!["a", "b"]).contains("a");
//! assert_that!(vec!["a", "b"]).has_length(2);
//! assert_that!(vec!["a", "b"]).contains_exactly(vec!["a", "b"]);
//!
//! assert_that!(Option::Some("Foo")).has_value("Foo");
//! ```
//! ## Failure cases
//! ```should_panic
//! use assertor::*;
//! assert_that!(vec!["a", "b", "c"]).contains_exactly(vec!["b", "c", "d"]);
//! // missing (1)   : ["d"]
//! // unexpected (1): ["a"]
//! // ---
//! // expected      : ["b", "c", "d"]
//! // actual        : ["a", "b", "c"]
//! ```
#![warn(missing_docs)]

#[cfg(feature = "float")]
extern crate num_traits;

pub use assertions::basic::{ComparableAssertion, EqualityAssertion};
#[cfg(feature = "float")]
pub use assertions::float::FloatAssertion;
pub use assertions::iterator::IteratorAssertion;
pub use assertions::map::MapAssertion;
pub use assertions::option::OptionAssertion;
pub use assertions::result::ResultAssertion;
pub use assertions::set::SetAssertion;
pub use assertions::string::StringAssertion;
pub use assertions::vec::VecAssertion;
pub use base::{AssertionResult, AssertionStrategy, Fact, Location, Subject};

mod assertions;
mod base;

#[cfg(any(test, doc, feature = "testing"))]
pub mod testing;
<|endoftext|>


<commit_before>extern crate rand;

use self::rand::{thread_rng, Rng};
use std::sync::{Arc, Mutex, RwLock};

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum State {
	Dead,
	Alive,
}

#[derive(Clone)]
pub struct Game {
	pub size: usize,
	current: Arc<RwLock<Vec<State>>>,
	next: Arc<Mutex<Vec<State>>>,
}

impl From<Vec<State>> for Game {
	fn from(preset_game: Vec<State>) -> Self {
		let size: usize = (preset_game.len() as f64).sqrt() as usize;
		assert!(size >= 3);

		Game {
			size: size,
			current: Arc::new(RwLock::new(preset_game.clone())),
			next: Arc::new(Mutex::new(preset_game.clone()))
		}
	}
}

impl Game {
	pub fn new(size: usize, percent_chance_for_cell_to_be_alive: f64) -> Game {
		assert!(size >= 3);
		assert!(percent_chance_for_cell_to_be_alive < 1.0);
		assert!(percent_chance_for_cell_to_be_alive >= 0.0);

		let mut board: Vec<State> = vec![State::Dead; size * size];

		for index in 0..size*size {
			board[index] = match thread_rng().next_f64() {
				i if i < percent_chance_for_cell_to_be_alive => State::Alive,
				_ => State::Dead,
			};
		}

		Game {
			size: size,
			current: Arc::new(RwLock::new(board.clone())),
			next: Arc::new(Mutex::new(board.clone())),
		}
	}

	pub fn get_current_read_lock(&self) -> std::sync::RwLockReadGuard<Vec<State>> {
		self.current.read().unwrap()
	}

	fn get_next_state_from_current_state_and_neighbors(state: State, number_of_neighbors: usize) -> State {
		match state {
			State::Dead => {
				if number_of_neighbors != 3 {
					State::Dead
				} else {
					State::Alive
				}
			},
			State::Alive => {
				if number_of_neighbors < 2 || number_of_neighbors > 3 {
					State::Dead
				} else {
					State::Alive
				}
			}
		}
	}

	pub fn advance(&self) {
		// Get read lock for 'current' and mutex lock for 'next'
		// N.B. By locking 'next' first, this ensures that if another thread tries
		// 		to call 'advance', that thread will block until this is done.
		let mut next = self.next.lock().unwrap();
		let current = self.current.read().unwrap();

		for y in 0..self.size {
			for x in 0..self.size {
				let ul = if y >= 1 && x != 0 { current[(y - 1) * self.size + x - 1]} else {State::Dead};
				let uu = if y >= 1 {current[(y - 1) * self.size + x + 0]} else {State::Dead};
				let ur = if y >= 1 && x != self.size - 1 { current[(y - 1) * self.size + x + 1]} else {State::Dead};
				let l = if x != 0 {current[y * self.size + x - 1]} else {State::Dead};
				let r = if x != self.size - 1 {current[y * self.size + x + 1]} else {State::Dead};
				let dl = if y != self.size - 1 && x != 0 {current[(y + 1) * self.size + x - 1]} else {State::Dead};
				let dd = if y != self.size - 1 {current[(y + 1) * self.size + x + 0]} else {State::Dead};
				let dr = if y != self.size - 1 && x != self.size - 1 {current[(y + 1) * self.size + x + 1]} else {State::Dead};

				let mut neighbors: usize = 0;
				if ul == State::Alive { neighbors += 1; }
				if uu == State::Alive { neighbors += 1; }
				if ur == State::Alive { neighbors += 1; }
				if l == State::Alive { neighbors += 1; }
				if r == State::Alive { neighbors += 1; }
				if dl == State::Alive { neighbors += 1; }
				if dd == State::Alive { neighbors += 1; }
				if dr == State::Alive { neighbors += 1; }

				next[y * self.size + x] = Game::get_next_state_from_current_state_and_neighbors(current[y * self.size + x], neighbors);
			}
		}

		// Exchange read lock for write lock
		drop(current);
		let mut current = self.current.write().unwrap();

		*current = next.clone();
	}

	pub fn advance_toroidally(&self) {
		// Get read lock for 'current' and mutex lock for 'next'
		// N.B. By locking 'next' first, this ensures that if another thread tries
		// 		to call 'advance', that thread will block until this is done.
		let mut next = self.next.lock().unwrap();
		let current = self.current.read().unwrap();

		for y in 0..self.size {
			for x in 0..self.size {
				let ul = if y >= 1 {
					if x != 0 { current[(y - 1) * self.size + x - 1] } // normal case
					else { current[y * self.size - 1] } // left edge
				} else {
					if x != 0 { current[(self.size - 1) * self.size + x - 1] } // top edge
					else { current[self.size * self.size - 1] } // top-left corner
				};

				let uu = if y >= 1 {
					current[(y - 1) * self.size + x + 0] // normal case
				} else {
					current[(self.size - 1) * self.size + x + 0] // top edge
				};

				let ur = if y >= 1 {
					if x != self.size - 1 { current[(y - 1) * self.size + x + 1] } // normal case
					else { current[(y - 1) * self.size + 0] } // right edge
				} else {
					if x != self.size - 1 { current[(self.size - 1) * self.size + x + 1] } // top edge
					else { current[(self.size - 1) * self.size + 0] } // top-right corner
				};

				let l = if x != 0 {
					current[y * self.size + x - 1] // normal case
				} else {
					current[(y + 1) * self.size - 1] // left edge
				};

				let r = if x != self.size - 1 {
					current[y * self.size + x + 1] // normal case
				} else {
					current[y * self.size + 0] // right edge
				};

				let dl = if y != self.size - 1 {
					if x != 0 { current[(y + 1) * self.size + x - 1] } // normal case
					else { current[(y + 2) * self.size - 1] } // left edge
				} else {
					if x != 0 { current[x - 1] } // bottom edge
					else { current[self.size - 1] } // bottom-left corner
				};

				let dd = if y != self.size - 1 {
					current[(y + 1) * self.size + x + 0] // normal case
				} else {
					current[x + 0] // bottom edge
				};

				let dr = if y != self.size - 1 {
					if x != self.size - 1 { current[(y + 1) * self.size + x + 1] } // normal case
					else { current[(y + 1) * self.size] } // right edge
				} else {
					if x != self.size - 1 { current[x + 1] } // bottom edge
					else { current[0] } // bottom-right corner
				};

				let mut neighbors: usize = 0;
				if ul == State::Alive { neighbors += 1; }
				if uu == State::Alive { neighbors += 1; }
				if ur == State::Alive { neighbors += 1; }
				if l == State::Alive { neighbors += 1; }
				if r == State::Alive { neighbors += 1; }
				if dl == State::Alive { neighbors += 1; }
				if dd == State::Alive { neighbors += 1; }
				if dr == State::Alive { neighbors += 1; }

				next[y * self.size + x] = Game::get_next_state_from_current_state_and_neighbors(current[y * self.size + x], neighbors);
			}
		}

		// Exchange read lock for write lock
		drop(current);
		let mut current = self.current.write().unwrap();

		*current = next.clone();
	}
}
<commit_msg>Make 'State' derive Eq as well as PartialEq<commit_after>extern crate rand;

use self::rand::{thread_rng, Rng};
use std::sync::{Arc, Mutex, RwLock};

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum State {
	Dead,
	Alive,
}

#[derive(Clone)]
pub struct Game {
	pub size: usize,
	current: Arc<RwLock<Vec<State>>>,
	next: Arc<Mutex<Vec<State>>>,
}

impl From<Vec<State>> for Game {
	fn from(preset_game: Vec<State>) -> Self {
		let size: usize = (preset_game.len() as f64).sqrt() as usize;
		assert!(size >= 3);

		Game {
			size: size,
			current: Arc::new(RwLock::new(preset_game.clone())),
			next: Arc::new(Mutex::new(preset_game.clone()))
		}
	}
}

impl Game {
	pub fn new(size: usize, percent_chance_for_cell_to_be_alive: f64) -> Game {
		assert!(size >= 3);
		assert!(percent_chance_for_cell_to_be_alive < 1.0);
		assert!(percent_chance_for_cell_to_be_alive >= 0.0);

		let mut board: Vec<State> = vec![State::Dead; size * size];

		for index in 0..size*size {
			board[index] = match thread_rng().next_f64() {
				i if i < percent_chance_for_cell_to_be_alive => State::Alive,
				_ => State::Dead,
			};
		}

		Game {
			size: size,
			current: Arc::new(RwLock::new(board.clone())),
			next: Arc::new(Mutex::new(board.clone())),
		}
	}

	pub fn get_current_read_lock(&self) -> std::sync::RwLockReadGuard<Vec<State>> {
		self.current.read().unwrap()
	}

	fn get_next_state_from_current_state_and_neighbors(state: State, number_of_neighbors: usize) -> State {
		match state {
			State::Dead => {
				if number_of_neighbors != 3 {
					State::Dead
				} else {
					State::Alive
				}
			},
			State::Alive => {
				if number_of_neighbors < 2 || number_of_neighbors > 3 {
					State::Dead
				} else {
					State::Alive
				}
			}
		}
	}

	pub fn advance(&self) {
		// Get read lock for 'current' and mutex lock for 'next'
		// N.B. By locking 'next' first, this ensures that if another thread tries
		// 		to call 'advance', that thread will block until this is done.
		let mut next = self.next.lock().unwrap();
		let current = self.current.read().unwrap();

		for y in 0..self.size {
			for x in 0..self.size {
				let ul = if y >= 1 && x != 0 { current[(y - 1) * self.size + x - 1]} else {State::Dead};
				let uu = if y >= 1 {current[(y - 1) * self.size + x + 0]} else {State::Dead};
				let ur = if y >= 1 && x != self.size - 1 { current[(y - 1) * self.size + x + 1]} else {State::Dead};
				let l = if x != 0 {current[y * self.size + x - 1]} else {State::Dead};
				let r = if x != self.size - 1 {current[y * self.size + x + 1]} else {State::Dead};
				let dl = if y != self.size - 1 && x != 0 {current[(y + 1) * self.size + x - 1]} else {State::Dead};
				let dd = if y != self.size - 1 {current[(y + 1) * self.size + x + 0]} else {State::Dead};
				let dr = if y != self.size - 1 && x != self.size - 1 {current[(y + 1) * self.size + x + 1]} else {State::Dead};

				let mut neighbors: usize = 0;
				if ul == State::Alive { neighbors += 1; }
				if uu == State::Alive { neighbors += 1; }
				if ur == State::Alive { neighbors += 1; }
				if l == State::Alive { neighbors += 1; }
				if r == State::Alive { neighbors += 1; }
				if dl == State::Alive { neighbors += 1; }
				if dd == State::Alive { neighbors += 1; }
				if dr == State::Alive { neighbors += 1; }

				next[y * self.size + x] = Game::get_next_state_from_current_state_and_neighbors(current[y * self.size + x], neighbors);
			}
		}

		// Exchange read lock for write lock
		drop(current);
		let mut current = self.current.write().unwrap();

		*current = next.clone();
	}

	pub fn advance_toroidally(&self) {
		// Get read lock for 'current' and mutex lock for 'next'
		// N.B. By locking 'next' first, this ensures that if another thread tries
		// 		to call 'advance', that thread will block until this is done.
		let mut next = self.next.lock().unwrap();
		let current = self.current.read().unwrap();

		for y in 0..self.size {
			for x in 0..self.size {
				let ul = if y >= 1 {
					if x != 0 { current[(y - 1) * self.size + x - 1] } // normal case
					else { current[y * self.size - 1] } // left edge
				} else {
					if x != 0 { current[(self.size - 1) * self.size + x - 1] } // top edge
					else { current[self.size * self.size - 1] } // top-left corner
				};

				let uu = if y >= 1 {
					current[(y - 1) * self.size + x + 0] // normal case
				} else {
					current[(self.size - 1) * self.size + x + 0] // top edge
				};

				let ur = if y >= 1 {
					if x != self.size - 1 { current[(y - 1) * self.size + x + 1] } // normal case
					else { current[(y - 1) * self.size + 0] } // right edge
				} else {
					if x != self.size - 1 { current[(self.size - 1) * self.size + x + 1] } // top edge
					else { current[(self.size - 1) * self.size + 0] } // top-right corner
				};

				let l = if x != 0 {
					current[y * self.size + x - 1] // normal case
				} else {
					current[(y + 1) * self.size - 1] // left edge
				};

				let r = if x != self.size - 1 {
					current[y * self.size + x + 1] // normal case
				} else {
					current[y * self.size + 0] // right edge
				};

				let dl = if y != self.size - 1 {
					if x != 0 { current[(y + 1) * self.size + x - 1] } // normal case
					else { current[(y + 2) * self.size - 1] } // left edge
				} else {
					if x != 0 { current[x - 1] } // bottom edge
					else { current[self.size - 1] } // bottom-left corner
				};

				let dd = if y != self.size - 1 {
					current[(y + 1) * self.size + x + 0] // normal case
				} else {
					current[x + 0] // bottom edge
				};

				let dr = if y != self.size - 1 {
					if x != self.size - 1 { current[(y + 1) * self.size + x + 1] } // normal case
					else { current[(y + 1) * self.size] } // right edge
				} else {
					if x != self.size - 1 { current[x + 1] } // bottom edge
					else { current[0] } // bottom-right corner
				};

				let mut neighbors: usize = 0;
				if ul == State::Alive { neighbors += 1; }
				if uu == State::Alive { neighbors += 1; }
				if ur == State::Alive { neighbors += 1; }
				if l == State::Alive { neighbors += 1; }
				if r == State::Alive { neighbors += 1; }
				if dl == State::Alive { neighbors += 1; }
				if dd == State::Alive { neighbors += 1; }
				if dr == State::Alive { neighbors += 1; }

				next[y * self.size + x] = Game::get_next_state_from_current_state_and_neighbors(current[y * self.size + x], neighbors);
			}
		}

		// Exchange read lock for write lock
		drop(current);
		let mut current = self.current.write().unwrap();

		*current = next.clone();
	}
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate exempi_sys as c;
#[macro_use]
extern crate bitflags;

mod xmp;
mod xmpstring;
mod xmpfile;
mod xmpiterator;

use std::ffi::{CString};
use std::cmp::Ordering;
use std::mem::transmute;
pub use xmp::Xmp as Xmp;
pub use xmpfile::XmpFile as XmpFile;
pub use xmpstring::XmpString as XmpString;
pub use xmpiterator::XmpIterator as XmpIterator;
pub use c::FileType as FileType;
pub use c::XmpError as Error;
// all the flags.
pub use xmpfile::flags::*;
pub use xmp::flags::*;
pub use xmpiterator::flags::*;

/// Initialize the library
pub fn init() -> bool {
    unsafe { c::xmp_init() }
}

/// Terminate the library
pub fn terminate() {
    unsafe { c::xmp_terminate() }
}

/// Get the last error code on the thread
/// Set when a function return false or None.
pub fn get_error() -> Error {
    let err = unsafe { c::xmp_get_error() };
    match err {
        -15...0 |
        -110...-101 |
        -211...-201 => unsafe { transmute(err) },
        _ => Error::TBD
    }
}

/// Register namespace with uri and suggested prefix
/// Returns the actual registered prefix.
pub fn register_namespace(uri: &str, prefix: &str) -> Option<XmpString> {
    let s_uri = CString::new(uri).unwrap();
    let s_prefix = CString::new(prefix).unwrap();
    let mut reg_prefix = XmpString::new();
    if unsafe { c::xmp_register_namespace(s_uri.as_ptr(), s_prefix.as_ptr(),
                                          reg_prefix.as_mut_ptr()) } {
        return Some(reg_prefix);
    }
    None
}

/// Return the prefix for the namespace uri.
pub fn namespace_prefix(uri: &str) -> Option<XmpString> {
    let s = CString::new(uri).unwrap();
    let mut prefix = XmpString::new();
    if unsafe { c::xmp_namespace_prefix(s.as_ptr(), prefix.as_mut_ptr()) } {
        return Some(prefix);
    }
    None
}

/// Return the namespace uri for the prefix.
pub fn prefix_namespace(prefix: &str) -> Option<XmpString> {
    let s = CString::new(prefix).unwrap();
    let mut uri = XmpString::new();
    if unsafe { c::xmp_prefix_namespace_uri(s.as_ptr(), uri.as_mut_ptr()) } {
        return Some(uri);
    }
    None
}

/// A wrapper around the C type DateTime
pub struct DateTime {
    c: c::XmpDateTime
}

impl DateTime {
    pub fn new() -> Self {
        DateTime { c: c::XmpDateTime::default() }
    }
    /// Construct from the native C type
    pub fn from(d: c::XmpDateTime) -> DateTime {
        DateTime { c: d }
    }
    /// Return the native pointer
    pub fn as_ptr(&self) -> *const c::XmpDateTime {
        &self.c as *const c::XmpDateTime
    }
    /// Return the native mutable pointer
    pub fn as_mut_ptr(&mut self) -> *mut c::XmpDateTime {
        &mut self.c as *mut c::XmpDateTime
    }
}

impl PartialEq for DateTime {
    fn eq(&self, other: &DateTime) -> bool {
        unsafe {
            c::xmp_datetime_compare(&self.c as *const c::XmpDateTime,
                                    &other.c as *const c::XmpDateTime) == 0
        }
    }
}
impl PartialOrd for DateTime {
    fn partial_cmp(&self, other: &DateTime) -> Option<Ordering> {
        match unsafe {
            c::xmp_datetime_compare(&self.c as *const c::XmpDateTime,
                                    &other.c as *const c::XmpDateTime)
        } {
            0 => Some(Ordering::Equal),
            n if n < 0 => Some(Ordering::Less),
            n if n > 0 => Some(Ordering::Greater),
            _ => None
        }
    }
}
impl Eq for DateTime {

}
impl Ord for DateTime {
    fn cmp(&self, other: &DateTime) -> Ordering {
        match unsafe {
            c::xmp_datetime_compare(&self.c as *const c::XmpDateTime,
                                    &other.c as *const c::XmpDateTime)
        } {
            n if n < 0 => Ordering::Less,
            n if n > 0 => Ordering::Greater,
            _ => Ordering::Equal
        }
    }
}

<commit_msg>style: use return value syntax<commit_after>extern crate libc;
extern crate exempi_sys as c;
#[macro_use]
extern crate bitflags;

mod xmp;
mod xmpstring;
mod xmpfile;
mod xmpiterator;

use std::ffi::{CString};
use std::cmp::Ordering;
use std::mem::transmute;
pub use xmp::Xmp as Xmp;
pub use xmpfile::XmpFile as XmpFile;
pub use xmpstring::XmpString as XmpString;
pub use xmpiterator::XmpIterator as XmpIterator;
pub use c::FileType as FileType;
pub use c::XmpError as Error;
// all the flags.
pub use xmpfile::flags::*;
pub use xmp::flags::*;
pub use xmpiterator::flags::*;

/// Initialize the library
pub fn init() -> bool {
    unsafe { c::xmp_init() }
}

/// Terminate the library
pub fn terminate() {
    unsafe { c::xmp_terminate() }
}

/// Get the last error code on the thread
/// Set when a function return false or None.
pub fn get_error() -> Error {
    let err = unsafe { c::xmp_get_error() };
    match err {
        -15...0 |
        -110...-101 |
        -211...-201 => unsafe { transmute(err) },
        _ => Error::TBD
    }
}

/// Register namespace with uri and suggested prefix
/// Returns the actual registered prefix.
pub fn register_namespace(uri: &str, prefix: &str) -> Option<XmpString> {
    let s_uri = CString::new(uri).unwrap();
    let s_prefix = CString::new(prefix).unwrap();
    let mut reg_prefix = XmpString::new();
    if unsafe { c::xmp_register_namespace(s_uri.as_ptr(), s_prefix.as_ptr(),
                                          reg_prefix.as_mut_ptr()) } {
        Some(reg_prefix)
    } else {
        None
    }
}

/// Return the prefix for the namespace uri.
pub fn namespace_prefix(uri: &str) -> Option<XmpString> {
    let s = CString::new(uri).unwrap();
    let mut prefix = XmpString::new();
    if unsafe { c::xmp_namespace_prefix(s.as_ptr(), prefix.as_mut_ptr()) } {
        Some(prefix)
    } else {
        None
    }
}

/// Return the namespace uri for the prefix.
pub fn prefix_namespace(prefix: &str) -> Option<XmpString> {
    let s = CString::new(prefix).unwrap();
    let mut uri = XmpString::new();
    if unsafe { c::xmp_prefix_namespace_uri(s.as_ptr(), uri.as_mut_ptr()) } {
        Some(uri)
    } else {
        None
    }
}

/// A wrapper around the C type DateTime
pub struct DateTime {
    c: c::XmpDateTime
}

impl DateTime {
    pub fn new() -> Self {
        DateTime { c: c::XmpDateTime::default() }
    }
    /// Construct from the native C type
    pub fn from(d: c::XmpDateTime) -> DateTime {
        DateTime { c: d }
    }
    /// Return the native pointer
    pub fn as_ptr(&self) -> *const c::XmpDateTime {
        &self.c as *const c::XmpDateTime
    }
    /// Return the native mutable pointer
    pub fn as_mut_ptr(&mut self) -> *mut c::XmpDateTime {
        &mut self.c as *mut c::XmpDateTime
    }
}

impl PartialEq for DateTime {
    fn eq(&self, other: &DateTime) -> bool {
        unsafe {
            c::xmp_datetime_compare(&self.c as *const c::XmpDateTime,
                                    &other.c as *const c::XmpDateTime) == 0
        }
    }
}
impl PartialOrd for DateTime {
    fn partial_cmp(&self, other: &DateTime) -> Option<Ordering> {
        match unsafe {
            c::xmp_datetime_compare(&self.c as *const c::XmpDateTime,
                                    &other.c as *const c::XmpDateTime)
        } {
            0 => Some(Ordering::Equal),
            n if n < 0 => Some(Ordering::Less),
            n if n > 0 => Some(Ordering::Greater),
            _ => None
        }
    }
}
impl Eq for DateTime {

}
impl Ord for DateTime {
    fn cmp(&self, other: &DateTime) -> Ordering {
        match unsafe {
            c::xmp_datetime_compare(&self.c as *const c::XmpDateTime,
                                    &other.c as *const c::XmpDateTime)
        } {
            n if n < 0 => Ordering::Less,
            n if n > 0 => Ordering::Greater,
            _ => Ordering::Equal
        }
    }
}

<|endoftext|>


<commit_before>#![warn(missing_docs)]

//! A fast and lightweight math library
//!
//! `reikna` contains implementations of various useful
//! functions, structs, and algorithms from various branches
//! of mathematics, including number theory, graph theory,
//! and calculus. The library is designed with speed and
//! ease of use in mind.

#[macro_use] pub mod func;

pub mod derivative;
pub mod factor;
pub mod figurate;
pub mod partition;
pub mod prime;
<commit_msg>update lib.rs, add examples<commit_after>#![warn(missing_docs)]

//! A fast and lightweight math library
//!
//! `reikna` contains implementations of various useful
//! functions, structs, and algorithms from various branches
//! of mathematics, including number theory, graph theory,
//! and calculus. The library is designed with speed and
//! ease of use in mind.
//!
//! # Usage
//!
//! This library is on `crates.io`, and can be added to your
//! project by placing the following into your `Cargo.toml`
//!
//! ``` text
//! [dependencies]
//! reikna = "0.6.0"
//! ```
//!
//! and then importing the crate with
//!
//! ```text
//! #[macro_use] extern crate reikna;
//! ```
//!
//! Make sure to include the #[macro_use] part!
//!
//! # Modules
//!
//! A list of the modules currently included in this crate, along
//! with a brief description of each.
//!
//! * `derivative` -- Estimate derivatives of functions, along with slope
//!                   and concavity.
//!
//! * `factor` -- Compute the GCD, LCM, and prime factorization of numbers.
//!
//! * `figurate` -- Compute the value of various kinds of figurate numbers.
//!
//! * `func` -- Utility type alias and macro, used heavily in certain
//!             other modules.
//!
//! * `partition` -- Compute the value of the number theory partition
//!                  function.
//!
//! * `prime` -- Prime sieves, basic factoring algorithms, and primality
//!              tests.
//!
//! # Examples
//!
//! ## Compute the number of primes under one million
//!
//! ```
//! # extern crate reikna;
//! # fn main() {
//! use reikna::prime::prime_sieve;
//!
//! let primes = prime_sieve(1_000_000);
//! println!("there are {} primes under one million!", primes.len());
//! # }
//! ```
//!
//! ## Factor a large integer
//!
//! ```
//! # extern crate reikna;
//! # fn main() {
//! use reikna::factor::quick_factorize;
//!
//! let my_number = 15_814_272_409_530_912_054;
//! let factors = quick_factorize(my_number);
//! println!("The prime factorization of {} is:", my_number);
//! println!("{:?}", factors);
//! }
//! ```
//!
//! Outputs:
//!
//! ```text
//! The prime factorization of 15814272409530912054 is:
//! [2, 3, 3, 23, 23, 61, 10007, 2720741641]
//! ```
//!
//! ## Relationship between the last digits of prime numbers
//!
//! Primes are considered to be pseudo-random, yet there exists
//! a relationship between the last digit of a prime number and the
//! last digit of the next prime number. For example, a prime ending
//! in `1` has only a 16% chance of being followed by another prime
//! that ends in one, at least in the range [1, 1,000,000].
//!
//!
//! ```
//! extern crate reikna;
//!
//! use reikna::prime::prime_sieve;
//!
//! pub fn main() {
//!
//!     // generate primes less than one million, removing
//!     // the single digit ones.
//!     let primes = &prime_sieve(1_000_000)[4..];
//!
//!
//!     let mut data = [[0u64; 10]; 10]; // 10x10 array to store the data
//!
//!     // loop through the primes and count digit frequency
//!     let mut old_last_digit = primes[0] % 10;
//!     for i in 1..primes.len() {
//!         let last_digit = primes[i] % 10;
//!         data[old_last_digit as usize][last_digit as usize] += 1;
//!         old_last_digit = last_digit;
//!     }
//!
//!     // store the totals into the 0's column, since it's not
//!     // being used for anything
//!     for i in 1..10 {
//!         data[0][i] = data[i].iter().fold(0, |acc, x| acc + x);
//!     }
//!
//!     // print out the data
//!     for i in vec![1, 3, 7, 9] {
//!         println!("primes ending in '{}':", i);
//!         println!(" * total -- {}", data[0][i]);
//!
//!         for k in vec![1, 3, 7, 9] {
//!             println!(" * % next prime ending in '{}' -- {}%",
//!                      k, data[i][k] as f64 / data[0][i] as f64 * 100.0);
//!         }
//!
//!         println!("");
//!     }
//! }
//! ```
//! By changing the max value, it can be observed that the bias
//! shrinks as the max grows.

#[macro_use] pub mod func;

pub mod derivative;
pub mod factor;
pub mod figurate;
pub mod partition;
pub mod prime;
<|endoftext|>