<commit_before>// Copyright 2014 Tyler Neely
//
// 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.
//

extern crate libc;
extern crate rocksdb_sys as ffi;

pub mod comparator;
pub mod merge_operator;
mod rocksdb;
mod rocksdb_options;

pub use rocksdb::{DB, DBCompressionType, DBCompactionStyle, DBRecoveryMode, DBIterator, DBVector, Direction, IteratorMode, Writable, WriteBatch, Error, new_bloom_filter};
pub use merge_operator::MergeOperands;

pub struct BlockBasedOptions {
    inner: *mut ffi::rocksdb_block_based_table_options_t,
}

pub struct Options {
    inner: *mut ffi::rocksdb_options_t,
}

pub struct WriteOptions {
    inner: *mut ffi::rocksdb_writeoptions_t,
}
<commit_msg>Now exports `Snapshot` at root-level.<commit_after>// Copyright 2014 Tyler Neely
//
// 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.
//

extern crate libc;
extern crate rocksdb_sys as ffi;

pub mod comparator;
pub mod merge_operator;
mod rocksdb;
mod rocksdb_options;

pub use rocksdb::{DB, DBCompressionType, DBCompactionStyle, DBRecoveryMode, DBIterator, DBVector, Direction, Error, IteratorMode, Writable, WriteBatch, Snapshot, new_bloom_filter};
pub use merge_operator::MergeOperands;

pub struct BlockBasedOptions {
    inner: *mut ffi::rocksdb_block_based_table_options_t,
}

pub struct Options {
    inner: *mut ffi::rocksdb_options_t,
}

pub struct WriteOptions {
    inner: *mut ffi::rocksdb_writeoptions_t,
}
<|endoftext|>


<commit_before>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/session")]

//! Session-storage middleware for the [Iron](https://ironframework.io/) web framework.
//!
//! The `sessions` module is used to create new sessioning middleware.
//!
//! `sessionstore` provides a default implementation of a session store.

extern crate core;
extern crate iron;

pub use sessions::Sessions;
pub use sessionstore::SessionStore;
pub use sessionstore::session::Session;
pub use sessionstore::hashsession::HashSessionStore;

pub mod sessions;
pub mod sessionstore;
<commit_msg>(docs) Name and href.<commit_after>#![crate_name = "session"]
#![crate_type="lib"]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128")]
#![doc(html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256")]

//! Session-storage middleware for the [Iron](https://ironframework.io/) web framework.
//!
//! The `sessions` module is used to create new sessioning middleware.
//!
//! `sessionstore` provides a default implementation of a session store.

extern crate core;
extern crate iron;

pub use sessions::Sessions;
pub use sessionstore::SessionStore;
pub use sessionstore::session::Session;
pub use sessionstore::hashsession::HashSessionStore;

pub mod sessions;
pub mod sessionstore;
<|endoftext|>


<commit_before>#![allow(dead_code)]

use libc::{c_void, c_char, c_uint, c_int};

pub type DBusConnection = c_void;
pub type DBusMessage = c_void;
pub type DBusCallback = extern "C" fn(*mut c_void, *mut c_void, *mut c_void) -> DBusHandlerResult;

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusBusType {
    Session = 0,
    System = 1,
    Starter = 2,
}

pub const DBUS_TYPE_ARRAY: c_int = 'a' as c_int;
pub const DBUS_TYPE_VARIANT: c_int = 'v' as c_int;
pub const DBUS_TYPE_BOOLEAN: c_int = 'b' as c_int;
pub const DBUS_TYPE_INVALID: c_int = 0;
pub const DBUS_TYPE_STRING: c_int = 's' as c_int;
pub const DBUS_TYPE_DICT_ENTRY: c_int = 'e' as c_int;
pub const DBUS_TYPE_BYTE: c_int = 'y' as c_int;
pub const DBUS_TYPE_INT16: c_int = 'n' as c_int;
pub const DBUS_TYPE_UINT16: c_int = 'q' as c_int;
pub const DBUS_TYPE_INT32: c_int = 'i' as c_int;
pub const DBUS_TYPE_UINT32: c_int = 'u' as c_int;
pub const DBUS_TYPE_INT64: c_int = 'x' as c_int;
pub const DBUS_TYPE_UINT64: c_int = 't' as c_int;
pub const DBUS_TYPE_DOUBLE: c_int = 'd' as c_int;
pub const DBUS_TYPE_UNIX_FD: c_int = 'h' as c_int;
pub const DBUS_TYPE_STRUCT: c_int = 'r' as c_int;
pub const DBUS_TYPE_OBJECT_PATH: c_int = 'o' as c_int;

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusNameFlag {
    AllowReplacement = 1,
    ReplaceExisting = 2,
    DoNotQueue = 4,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusRequestNameReply {
    PrimaryOwner = 1,
    InQueue = 2,
    Exists = 3,
    AlreadyOwner = 4,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusReleaseNameReply {
    Released = 1,
    NonExistent = 2,
    NotOwner = 3,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusHandlerResult {
    Handled = 0,
    NotYetHandled = 1,
    NeedMemory = 2,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusMessageType {
    Invalid = 0,
    MethodCall = 1,
    MethodReturn = 2,
    Error = 3,
    Signal = 4,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusDispatchStatus {
    DataRemains = 0,
    Complete = 1,
    NeedMemory = 2,
}

#[repr(C)]
pub struct DBusError {
    pub name: *const c_char,
    pub message: *const c_char,
    pub dummy: c_uint,
    pub padding1: *const c_void
}

#[repr(C)]
pub struct DBusMessageIter {
    pub dummy1: *mut (),
    pub dummy2: *mut (),
    pub dummy3: u32,
    pub dummy4: c_int,
    pub dummy5: c_int,
    pub dummy6: c_int,
    pub dummy7: c_int,
    pub dummy8: c_int,
    pub dummy9: c_int,
    pub dummy10: c_int,
    pub dummy11: c_int,
    pub pad1: c_int,
    pub pad2: c_int,
    pub pad3: *mut (),
}

pub type DBusHandleMessageFunction = Option<
        extern fn(conn: *mut DBusConnection, msg: *mut DBusMessage, user_data: *mut c_void) -> DBusHandlerResult>;

#[repr(C)]
pub struct DBusObjectPathVTable {
    pub unregister_function: Option<extern fn(conn: *mut DBusConnection, user_data: *mut c_void)>,
    pub message_function: DBusHandleMessageFunction,
    pub dbus_internal_pad1: Option<extern fn()>,
    pub dbus_internal_pad2: Option<extern fn()>,
    pub dbus_internal_pad3: Option<extern fn()>,
    pub dbus_internal_pad4: Option<extern fn()>,
}

#[link(name = "dbus-1")]
extern "C" {
    pub fn dbus_bus_get_private(t: DBusBusType, error: *mut DBusError) -> *mut DBusConnection;
    pub fn dbus_bus_get_unique_name(conn: *mut DBusConnection) -> *const c_char;
    pub fn dbus_bus_request_name(conn: *mut DBusConnection, name: *const c_char,
        flags: c_uint, error: *mut DBusError) -> c_int;
    pub fn dbus_bus_release_name(conn: *mut DBusConnection, name: *const c_char,
        error: *mut DBusError) -> c_int;
    pub fn dbus_bus_add_match(conn: *mut DBusConnection, rule: *const c_char,
        error: *mut DBusError);
    pub fn dbus_bus_remove_match(conn: *mut DBusConnection, rule: *const c_char,
        error: *mut DBusError);

    pub fn dbus_connection_close(conn: *mut DBusConnection);
    pub fn dbus_connection_dispatch(conn: *mut DBusConnection) -> DBusDispatchStatus;
    pub fn dbus_connection_flush(conn: *mut DBusConnection);
    pub fn dbus_connection_unref(conn: *mut DBusConnection);
    pub fn dbus_connection_set_exit_on_disconnect(conn: *mut DBusConnection, enable: u32);
    pub fn dbus_connection_send_with_reply_and_block(conn: *mut DBusConnection,
        message: *mut DBusMessage, timeout_milliseconds: c_int, error: *mut DBusError) -> *mut DBusMessage;
    pub fn dbus_connection_send(conn: *mut DBusConnection,
        message: *mut DBusMessage, serial: *mut u32) -> u32;
    pub fn dbus_connection_read_write_dispatch(conn: *mut DBusConnection,
        timeout_milliseconds: c_int) -> u32;
    pub fn dbus_connection_try_register_object_path(conn: *mut DBusConnection,
        path: *const c_char, vtable: *const DBusObjectPathVTable, user_data: *mut c_void,
        error: *mut DBusError) -> u32;
    pub fn dbus_connection_unregister_object_path(conn: *mut DBusConnection,
        path: *const c_char) -> u32;
    pub fn dbus_connection_list_registered(conn: *mut DBusConnection,
        parent_path: *const c_char, child_entries: *mut *mut *mut c_char) -> u32;
    pub fn dbus_connection_add_filter(conn: *mut DBusConnection, function: DBusHandleMessageFunction,
        user_data: *mut c_void, free_data_function: Option<extern fn(memory: *mut c_void)>) -> u32;
    pub fn dbus_connection_remove_filter(conn: *mut DBusConnection, function: DBusHandleMessageFunction,
        user_data: *mut c_void) -> u32;

    pub fn dbus_error_init(error: *mut DBusError);
    pub fn dbus_error_free(error: *mut DBusError);
    pub fn dbus_set_error(error: *mut DBusError, name: *const c_char, message: *const c_char, ...);
    pub fn dbus_set_error_from_message(error: *mut DBusError, message: *mut DBusMessage) -> u32;

    pub fn dbus_message_new_method_call(destination: *const c_char, path: *const c_char,
        iface: *const c_char, method: *const c_char) -> *mut DBusMessage;
    pub fn dbus_message_new_method_return(message: *mut DBusMessage) -> *mut DBusMessage;
    pub fn dbus_message_new_error(message: *mut DBusMessage,
        error_name: *const c_char, error_message: *const c_char) -> *mut DBusMessage;
    pub fn dbus_message_new_signal(path: *const c_char,
        iface: *const c_char, name: *const c_char) -> *mut DBusMessage;
    pub fn dbus_message_ref(message: *mut DBusMessage) -> *mut DBusMessage;
    pub fn dbus_message_unref(message: *mut DBusMessage);
    pub fn dbus_message_get_type(message: *mut DBusMessage) -> c_int;
    pub fn dbus_message_is_method_call(message: *mut DBusMessage, iface: *const c_char, method: *const c_char) -> u32;
    pub fn dbus_message_is_signal(message: *mut DBusMessage, iface: *const c_char, signal_name: *const c_char) -> u32;
    pub fn dbus_message_get_serial(message: *mut DBusMessage) -> u32;
    pub fn dbus_message_get_path(message: *mut DBusMessage) -> *const c_char;
    pub fn dbus_message_get_interface(message: *mut DBusMessage) -> *const c_char;
    pub fn dbus_message_get_member(message: *mut DBusMessage) -> *const c_char;
    pub fn dbus_message_get_sender(message: *mut DBusMessage) -> *const c_char;

    pub fn dbus_message_iter_append_basic(iter: *mut DBusMessageIter, t: c_int, value: *const c_void) -> u32;
    pub fn dbus_message_iter_init(message: *mut DBusMessage, iter: *mut DBusMessageIter) -> u32;
    pub fn dbus_message_iter_init_append(message: *mut DBusMessage, iter: *mut DBusMessageIter);
    pub fn dbus_message_iter_get_arg_type(iter: *mut DBusMessageIter) -> c_int;
    pub fn dbus_message_iter_get_basic(iter: *mut DBusMessageIter, value: *mut c_void);
    pub fn dbus_message_iter_get_signature(iter: *mut DBusMessageIter) -> *mut c_char;
    pub fn dbus_message_iter_next(iter: *mut DBusMessageIter) -> u32;
    pub fn dbus_message_iter_recurse(iter: *mut DBusMessageIter, subiter: *mut DBusMessageIter);
    pub fn dbus_message_iter_open_container(iter: *mut DBusMessageIter, _type: c_int,
        contained_signature: *const c_char, sub: *mut DBusMessageIter) -> u32;
    pub fn dbus_message_iter_close_container(iter: *mut DBusMessageIter, sub: *mut DBusMessageIter) -> u32;

    pub fn dbus_free(memory: *mut c_void);
    pub fn dbus_free_string_array(str_array: *mut *mut c_char) -> c_void;

    pub fn dbus_threads_init_default() -> c_int;
}
<commit_msg>Fix compiler warning<commit_after>#![allow(dead_code)]

use libc::{c_void, c_char, c_uint, c_int};

pub type DBusConnection = c_void;
pub type DBusMessage = c_void;
pub type DBusCallback = extern "C" fn(*mut c_void, *mut c_void, *mut c_void) -> DBusHandlerResult;

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusBusType {
    Session = 0,
    System = 1,
    Starter = 2,
}

pub const DBUS_TYPE_ARRAY: c_int = 'a' as c_int;
pub const DBUS_TYPE_VARIANT: c_int = 'v' as c_int;
pub const DBUS_TYPE_BOOLEAN: c_int = 'b' as c_int;
pub const DBUS_TYPE_INVALID: c_int = 0;
pub const DBUS_TYPE_STRING: c_int = 's' as c_int;
pub const DBUS_TYPE_DICT_ENTRY: c_int = 'e' as c_int;
pub const DBUS_TYPE_BYTE: c_int = 'y' as c_int;
pub const DBUS_TYPE_INT16: c_int = 'n' as c_int;
pub const DBUS_TYPE_UINT16: c_int = 'q' as c_int;
pub const DBUS_TYPE_INT32: c_int = 'i' as c_int;
pub const DBUS_TYPE_UINT32: c_int = 'u' as c_int;
pub const DBUS_TYPE_INT64: c_int = 'x' as c_int;
pub const DBUS_TYPE_UINT64: c_int = 't' as c_int;
pub const DBUS_TYPE_DOUBLE: c_int = 'd' as c_int;
pub const DBUS_TYPE_UNIX_FD: c_int = 'h' as c_int;
pub const DBUS_TYPE_STRUCT: c_int = 'r' as c_int;
pub const DBUS_TYPE_OBJECT_PATH: c_int = 'o' as c_int;

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusNameFlag {
    AllowReplacement = 1,
    ReplaceExisting = 2,
    DoNotQueue = 4,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusRequestNameReply {
    PrimaryOwner = 1,
    InQueue = 2,
    Exists = 3,
    AlreadyOwner = 4,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusReleaseNameReply {
    Released = 1,
    NonExistent = 2,
    NotOwner = 3,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusHandlerResult {
    Handled = 0,
    NotYetHandled = 1,
    NeedMemory = 2,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusMessageType {
    Invalid = 0,
    MethodCall = 1,
    MethodReturn = 2,
    Error = 3,
    Signal = 4,
}

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DBusDispatchStatus {
    DataRemains = 0,
    Complete = 1,
    NeedMemory = 2,
}

#[repr(C)]
pub struct DBusError {
    pub name: *const c_char,
    pub message: *const c_char,
    pub dummy: c_uint,
    pub padding1: *const c_void
}

#[repr(C)]
pub struct DBusMessageIter {
    pub dummy1: *mut c_void,
    pub dummy2: *mut c_void,
    pub dummy3: u32,
    pub dummy4: c_int,
    pub dummy5: c_int,
    pub dummy6: c_int,
    pub dummy7: c_int,
    pub dummy8: c_int,
    pub dummy9: c_int,
    pub dummy10: c_int,
    pub dummy11: c_int,
    pub pad1: c_int,
    pub pad2: c_int,
    pub pad3: *mut c_void,
}

pub type DBusHandleMessageFunction = Option<
        extern fn(conn: *mut DBusConnection, msg: *mut DBusMessage, user_data: *mut c_void) -> DBusHandlerResult>;

#[repr(C)]
pub struct DBusObjectPathVTable {
    pub unregister_function: Option<extern fn(conn: *mut DBusConnection, user_data: *mut c_void)>,
    pub message_function: DBusHandleMessageFunction,
    pub dbus_internal_pad1: Option<extern fn()>,
    pub dbus_internal_pad2: Option<extern fn()>,
    pub dbus_internal_pad3: Option<extern fn()>,
    pub dbus_internal_pad4: Option<extern fn()>,
}

#[link(name = "dbus-1")]
extern "C" {
    pub fn dbus_bus_get_private(t: DBusBusType, error: *mut DBusError) -> *mut DBusConnection;
    pub fn dbus_bus_get_unique_name(conn: *mut DBusConnection) -> *const c_char;
    pub fn dbus_bus_request_name(conn: *mut DBusConnection, name: *const c_char,
        flags: c_uint, error: *mut DBusError) -> c_int;
    pub fn dbus_bus_release_name(conn: *mut DBusConnection, name: *const c_char,
        error: *mut DBusError) -> c_int;
    pub fn dbus_bus_add_match(conn: *mut DBusConnection, rule: *const c_char,
        error: *mut DBusError);
    pub fn dbus_bus_remove_match(conn: *mut DBusConnection, rule: *const c_char,
        error: *mut DBusError);

    pub fn dbus_connection_close(conn: *mut DBusConnection);
    pub fn dbus_connection_dispatch(conn: *mut DBusConnection) -> DBusDispatchStatus;
    pub fn dbus_connection_flush(conn: *mut DBusConnection);
    pub fn dbus_connection_unref(conn: *mut DBusConnection);
    pub fn dbus_connection_set_exit_on_disconnect(conn: *mut DBusConnection, enable: u32);
    pub fn dbus_connection_send_with_reply_and_block(conn: *mut DBusConnection,
        message: *mut DBusMessage, timeout_milliseconds: c_int, error: *mut DBusError) -> *mut DBusMessage;
    pub fn dbus_connection_send(conn: *mut DBusConnection,
        message: *mut DBusMessage, serial: *mut u32) -> u32;
    pub fn dbus_connection_read_write_dispatch(conn: *mut DBusConnection,
        timeout_milliseconds: c_int) -> u32;
    pub fn dbus_connection_try_register_object_path(conn: *mut DBusConnection,
        path: *const c_char, vtable: *const DBusObjectPathVTable, user_data: *mut c_void,
        error: *mut DBusError) -> u32;
    pub fn dbus_connection_unregister_object_path(conn: *mut DBusConnection,
        path: *const c_char) -> u32;
    pub fn dbus_connection_list_registered(conn: *mut DBusConnection,
        parent_path: *const c_char, child_entries: *mut *mut *mut c_char) -> u32;
    pub fn dbus_connection_add_filter(conn: *mut DBusConnection, function: DBusHandleMessageFunction,
        user_data: *mut c_void, free_data_function: Option<extern fn(memory: *mut c_void)>) -> u32;
    pub fn dbus_connection_remove_filter(conn: *mut DBusConnection, function: DBusHandleMessageFunction,
        user_data: *mut c_void) -> u32;

    pub fn dbus_error_init(error: *mut DBusError);
    pub fn dbus_error_free(error: *mut DBusError);
    pub fn dbus_set_error(error: *mut DBusError, name: *const c_char, message: *const c_char, ...);
    pub fn dbus_set_error_from_message(error: *mut DBusError, message: *mut DBusMessage) -> u32;

    pub fn dbus_message_new_method_call(destination: *const c_char, path: *const c_char,
        iface: *const c_char, method: *const c_char) -> *mut DBusMessage;
    pub fn dbus_message_new_method_return(message: *mut DBusMessage) -> *mut DBusMessage;
    pub fn dbus_message_new_error(message: *mut DBusMessage,
        error_name: *const c_char, error_message: *const c_char) -> *mut DBusMessage;
    pub fn dbus_message_new_signal(path: *const c_char,
        iface: *const c_char, name: *const c_char) -> *mut DBusMessage;
    pub fn dbus_message_ref(message: *mut DBusMessage) -> *mut DBusMessage;
    pub fn dbus_message_unref(message: *mut DBusMessage);
    pub fn dbus_message_get_type(message: *mut DBusMessage) -> c_int;
    pub fn dbus_message_is_method_call(message: *mut DBusMessage, iface: *const c_char, method: *const c_char) -> u32;
    pub fn dbus_message_is_signal(message: *mut DBusMessage, iface: *const c_char, signal_name: *const c_char) -> u32;
    pub fn dbus_message_get_serial(message: *mut DBusMessage) -> u32;
    pub fn dbus_message_get_path(message: *mut DBusMessage) -> *const c_char;
    pub fn dbus_message_get_interface(message: *mut DBusMessage) -> *const c_char;
    pub fn dbus_message_get_member(message: *mut DBusMessage) -> *const c_char;
    pub fn dbus_message_get_sender(message: *mut DBusMessage) -> *const c_char;

    pub fn dbus_message_iter_append_basic(iter: *mut DBusMessageIter, t: c_int, value: *const c_void) -> u32;
    pub fn dbus_message_iter_init(message: *mut DBusMessage, iter: *mut DBusMessageIter) -> u32;
    pub fn dbus_message_iter_init_append(message: *mut DBusMessage, iter: *mut DBusMessageIter);
    pub fn dbus_message_iter_get_arg_type(iter: *mut DBusMessageIter) -> c_int;
    pub fn dbus_message_iter_get_basic(iter: *mut DBusMessageIter, value: *mut c_void);
    pub fn dbus_message_iter_get_signature(iter: *mut DBusMessageIter) -> *mut c_char;
    pub fn dbus_message_iter_next(iter: *mut DBusMessageIter) -> u32;
    pub fn dbus_message_iter_recurse(iter: *mut DBusMessageIter, subiter: *mut DBusMessageIter);
    pub fn dbus_message_iter_open_container(iter: *mut DBusMessageIter, _type: c_int,
        contained_signature: *const c_char, sub: *mut DBusMessageIter) -> u32;
    pub fn dbus_message_iter_close_container(iter: *mut DBusMessageIter, sub: *mut DBusMessageIter) -> u32;

    pub fn dbus_free(memory: *mut c_void);
    pub fn dbus_free_string_array(str_array: *mut *mut c_char) -> c_void;

    pub fn dbus_threads_init_default() -> c_int;
}
<|endoftext|>


<commit_before>extern crate fixedbitset;
extern crate rand;

pub mod dna_base;
pub mod base4;
pub mod graph;

use std::str::FromStr;
use std::ops::Deref;
use std::fmt::{self, Debug};
use fixedbitset::FixedBitSet;
use rand::{Rng, Rand};

/// Represents the bases used in the genome string.
/// For example the bases of the DNA are adenine (A),
/// thymine (T), guanine (G) and cytosine (C).
pub trait Base: Sized + PartialEq + Eq + Copy + Clone + Debug + Rand {
    /// Returns the "successor" base, wrapping around. Used
    /// to produce the gene product.
    fn succ(self) -> Self;

    fn from_char(c: char) -> Option<Self>;
}

// Locate ```substr``` in ```s```.
fn locate_substr<T: Eq>(s: &[T], substr: &[T]) -> Option<usize> {
    assert!(substr.len() > 0);

    if s.len() < substr.len() {
        return None;
    }

    for (i, window) in s.windows(substr.len()).enumerate() {
        if window == substr {
            return Some(i);
        }
    }

    return None;
}

// Count occurrence of ```substr``` in ```s```.
fn count_substr<T: Eq>(s: &[T], substr: &[T]) -> usize {
    assert!(substr.len() > 0);

    let mut cnt = 0;
    for window in s.windows(substr.len()) {
        if window == substr {
            cnt += 1;
        }
    }

    return cnt;
}

#[derive(Debug)]
pub struct Gene<'a, B: Base + 'a> {
    pub regulatory_region: &'a [B],
    pub gene: &'a [B],
}

impl<'a, B: Base + 'a> Gene<'a, B> {
    /// The gene product
    pub fn product(&self) -> BaseString<B> {
        BaseString { v: self.gene.iter().map(|b| b.succ()).collect() }
    }

    pub fn find_product_in_regulatory_region(&self, product: &[B]) -> bool {
        locate_substr(self.regulatory_region, product).is_some()
    }
    pub fn count_product_in_regulatory_region(&self, product: &[B]) -> usize {
        count_substr(self.regulatory_region, product)
    }
}

pub struct GeneIterator<'a, 'b, B: Base + 'a + 'b> {
    // Genes have fixed length
    length_of_gene: usize,
    sequence: &'a [B],
    promoter: &'b [B],
}

impl<'a, 'b, B: Base + 'a + 'b> Iterator for GeneIterator<'a, 'b, B> {
    type Item = Gene<'a, B>;

    fn next(&mut self) -> Option<Self::Item> {
        match locate_substr(self.sequence, self.promoter) {
            Some(pos) => {
                let gene_start = pos + self.promoter.len();
                let gene_end = gene_start + self.length_of_gene;

                // gene is not complete
                if gene_end > self.sequence.len() {
                    return None;
                }

                let gene = Gene {
                    regulatory_region: &self.sequence[..pos],
                    gene: &self.sequence[gene_start..gene_end],
                };
                self.sequence = &self.sequence[gene_end..];
                return Some(gene);
            }
            None => {
                return None;
            }
        }
    }
}

// A positive value enhances, a negative inhibits the expression of a gene.
#[derive(Debug)]
pub struct ProteinRegulator(i32);

impl ProteinRegulator {
    pub fn enhance() -> ProteinRegulator {
        ProteinRegulator(1)
    }

    pub fn inhibit() -> ProteinRegulator {
        ProteinRegulator(-1)
    }
}

#[derive(Clone)]
pub struct BaseString<B: Base> {
    v: Vec<B>,
}

impl<B: Base> FromStr for BaseString<B> {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(BaseString { v: s.chars().filter_map(|c| B::from_char(c)).collect() })
    }
}

impl<B: Base> Deref for BaseString<B> {
    type Target = [B];

    fn deref(&self) -> &Self::Target {
        &self.v
    }
}

impl<B: Base> Debug for BaseString<B> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "["));
        for base in &self.v {
            try!(write!(f, "{:?}", base));
        }
        write!(f, "]")
    }
}

impl<B: Base> BaseString<B> {
    pub fn random<R: Rng>(rng: &mut R, n: usize) -> BaseString<B> {
        assert!(n > 0);
        BaseString { v: (0..n).map(|_| rng.gen()).collect() }
    }
}

/// A Genome is a string of Base
#[derive(Clone)]
pub struct Genome<B: Base> {
    genome: BaseString<B>,
}

impl<B: Base> Genome<B> {
    pub fn from_vec(v: Vec<B>) -> Genome<B> {
        Genome { genome: BaseString { v: v } }
    }

    pub fn random<R: Rng>(rng: &mut R, n: usize) -> Genome<B> {
        Genome { genome: BaseString::random(rng, n) }
    }
}

impl<B: Base> Deref for Genome<B> {
    type Target = [B];

    fn deref(&self) -> &Self::Target {
        &self.genome
    }
}

#[derive(Debug)]
struct Edge {
    src: usize,
    weight: ProteinRegulator,
}

#[derive(Debug)]
pub struct Node {
    incoming_edges: Vec<Edge>,
}

impl Node {
    fn new() -> Node {
        Node { incoming_edges: Vec::new() }
    }

    pub fn sum_edges(&self, network_state: &GeneNetworkState) -> i32 {
        let mut sum = 0;
        for edge in self.incoming_edges.iter() {
            let factor = if network_state.state.contains(edge.src) {
                1
            } else {
                0
            };
            sum += factor * edge.weight.0;
        }

        return sum;
    }
}

#[derive(Debug)]
pub struct GeneNetwork {
    nodes: Vec<Node>,
}

#[derive(Debug, Clone)]
pub struct GeneNetworkState {
    pub state: FixedBitSet,
}

impl GeneNetwork {
    fn new(num_nodes: usize) -> GeneNetwork {
        assert!(num_nodes > 0);
        GeneNetwork { nodes: (0..num_nodes).map(|_| Node::new()).collect() }
    }

    pub fn nodes(&self) -> &[Node] {
        &self.nodes
    }

    fn add_edge(&mut self, src: usize, dst: usize, weight: ProteinRegulator) {
        assert!(src < self.nodes.len());
        assert!(dst < self.nodes.len());
        self.nodes[dst].incoming_edges.push(Edge {
            src: src,
            weight: weight,
        });
    }

    pub fn new_state(&self) -> GeneNetworkState {
        GeneNetworkState { state: FixedBitSet::with_capacity(self.nodes.len()) }
    }
}

// Convert genome into sections, i.e. Split at the promoter.
impl<B: Base> Genome<B> {
    pub fn iter_genes<'a, 'b>(&'a self,
                              promoter: &'b [B],
                              length_of_gene: usize)
                              -> GeneIterator<'a, 'b, B> {
        GeneIterator {
            length_of_gene: length_of_gene,
            sequence: &self.genome,
            promoter: promoter,
        }
    }

    // Construct a dependency network between the genes
    pub fn construct_network<F>(&self,
                                promoter: &[B],
                                length_of_gene: usize,
                                protein_regulation: &F)
                                -> Option<GeneNetwork>
        where F: Fn(&[B]) -> ProteinRegulator
    {
        let genes: Vec<_> = self.iter_genes(promoter, length_of_gene).collect();
        let num_genes = genes.len();

        if num_genes == 0 {
            return None;
        }

        // each gene is a node in the boolean network
        let mut network = GeneNetwork::new(num_genes);

        for (src, gene) in genes.iter().enumerate() {
            let product = gene.product();
            // A gene product either enhances (> 0) or inyhibits (< 0) the expression of
            // another gene.
            let regulator = protein_regulation(&product);

            // determine which other genes ```gene``` regulates
            for (dst, gene2) in genes.iter().enumerate() {
                // XXX: Can a gene regulate itself?
                // if src != dst {
                let factor = gene2.count_product_in_regulatory_region(&product);
                if factor > 0 {
                    network.add_edge(src, dst, ProteinRegulator(regulator.0 * factor as i32));
                }
                // }
            }
        }

        return Some(network);
    }
}

impl<B: Base> FromStr for Genome<B> {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        FromStr::from_str(s).map(|bs| Genome { genome: bs })
    }
}
<commit_msg>Derive Debug for Genome<commit_after>extern crate fixedbitset;
extern crate rand;

pub mod dna_base;
pub mod base4;
pub mod graph;

use std::str::FromStr;
use std::ops::Deref;
use std::fmt::{self, Debug};
use fixedbitset::FixedBitSet;
use rand::{Rng, Rand};

/// Represents the bases used in the genome string.
/// For example the bases of the DNA are adenine (A),
/// thymine (T), guanine (G) and cytosine (C).
pub trait Base: Sized + PartialEq + Eq + Copy + Clone + Debug + Rand {
    /// Returns the "successor" base, wrapping around. Used
    /// to produce the gene product.
    fn succ(self) -> Self;

    fn from_char(c: char) -> Option<Self>;
}

// Locate ```substr``` in ```s```.
fn locate_substr<T: Eq>(s: &[T], substr: &[T]) -> Option<usize> {
    assert!(substr.len() > 0);

    if s.len() < substr.len() {
        return None;
    }

    for (i, window) in s.windows(substr.len()).enumerate() {
        if window == substr {
            return Some(i);
        }
    }

    return None;
}

// Count occurrence of ```substr``` in ```s```.
fn count_substr<T: Eq>(s: &[T], substr: &[T]) -> usize {
    assert!(substr.len() > 0);

    let mut cnt = 0;
    for window in s.windows(substr.len()) {
        if window == substr {
            cnt += 1;
        }
    }

    return cnt;
}

#[derive(Debug)]
pub struct Gene<'a, B: Base + 'a> {
    pub regulatory_region: &'a [B],
    pub gene: &'a [B],
}

impl<'a, B: Base + 'a> Gene<'a, B> {
    /// The gene product
    pub fn product(&self) -> BaseString<B> {
        BaseString { v: self.gene.iter().map(|b| b.succ()).collect() }
    }

    pub fn find_product_in_regulatory_region(&self, product: &[B]) -> bool {
        locate_substr(self.regulatory_region, product).is_some()
    }
    pub fn count_product_in_regulatory_region(&self, product: &[B]) -> usize {
        count_substr(self.regulatory_region, product)
    }
}

pub struct GeneIterator<'a, 'b, B: Base + 'a + 'b> {
    // Genes have fixed length
    length_of_gene: usize,
    sequence: &'a [B],
    promoter: &'b [B],
}

impl<'a, 'b, B: Base + 'a + 'b> Iterator for GeneIterator<'a, 'b, B> {
    type Item = Gene<'a, B>;

    fn next(&mut self) -> Option<Self::Item> {
        match locate_substr(self.sequence, self.promoter) {
            Some(pos) => {
                let gene_start = pos + self.promoter.len();
                let gene_end = gene_start + self.length_of_gene;

                // gene is not complete
                if gene_end > self.sequence.len() {
                    return None;
                }

                let gene = Gene {
                    regulatory_region: &self.sequence[..pos],
                    gene: &self.sequence[gene_start..gene_end],
                };
                self.sequence = &self.sequence[gene_end..];
                return Some(gene);
            }
            None => {
                return None;
            }
        }
    }
}

// A positive value enhances, a negative inhibits the expression of a gene.
#[derive(Debug)]
pub struct ProteinRegulator(i32);

impl ProteinRegulator {
    pub fn enhance() -> ProteinRegulator {
        ProteinRegulator(1)
    }

    pub fn inhibit() -> ProteinRegulator {
        ProteinRegulator(-1)
    }
}

#[derive(Clone)]
pub struct BaseString<B: Base> {
    v: Vec<B>,
}

impl<B: Base> FromStr for BaseString<B> {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(BaseString { v: s.chars().filter_map(|c| B::from_char(c)).collect() })
    }
}

impl<B: Base> Deref for BaseString<B> {
    type Target = [B];

    fn deref(&self) -> &Self::Target {
        &self.v
    }
}

impl<B: Base> Debug for BaseString<B> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "["));
        for base in &self.v {
            try!(write!(f, "{:?}", base));
        }
        write!(f, "]")
    }
}

impl<B: Base> BaseString<B> {
    pub fn random<R: Rng>(rng: &mut R, n: usize) -> BaseString<B> {
        assert!(n > 0);
        BaseString { v: (0..n).map(|_| rng.gen()).collect() }
    }
}

/// A Genome is a string of Base
#[derive(Debug, Clone)]
pub struct Genome<B: Base> {
    genome: BaseString<B>,
}

impl<B: Base> Genome<B> {
    pub fn from_vec(v: Vec<B>) -> Genome<B> {
        Genome { genome: BaseString { v: v } }
    }

    pub fn random<R: Rng>(rng: &mut R, n: usize) -> Genome<B> {
        Genome { genome: BaseString::random(rng, n) }
    }
}

impl<B: Base> Deref for Genome<B> {
    type Target = [B];

    fn deref(&self) -> &Self::Target {
        &self.genome
    }
}

#[derive(Debug)]
struct Edge {
    src: usize,
    weight: ProteinRegulator,
}

#[derive(Debug)]
pub struct Node {
    incoming_edges: Vec<Edge>,
}

impl Node {
    fn new() -> Node {
        Node { incoming_edges: Vec::new() }
    }

    pub fn sum_edges(&self, network_state: &GeneNetworkState) -> i32 {
        let mut sum = 0;
        for edge in self.incoming_edges.iter() {
            let factor = if network_state.state.contains(edge.src) {
                1
            } else {
                0
            };
            sum += factor * edge.weight.0;
        }

        return sum;
    }
}

#[derive(Debug)]
pub struct GeneNetwork {
    nodes: Vec<Node>,
}

#[derive(Debug, Clone)]
pub struct GeneNetworkState {
    pub state: FixedBitSet,
}

impl GeneNetwork {
    fn new(num_nodes: usize) -> GeneNetwork {
        assert!(num_nodes > 0);
        GeneNetwork { nodes: (0..num_nodes).map(|_| Node::new()).collect() }
    }

    pub fn nodes(&self) -> &[Node] {
        &self.nodes
    }

    fn add_edge(&mut self, src: usize, dst: usize, weight: ProteinRegulator) {
        assert!(src < self.nodes.len());
        assert!(dst < self.nodes.len());
        self.nodes[dst].incoming_edges.push(Edge {
            src: src,
            weight: weight,
        });
    }

    pub fn new_state(&self) -> GeneNetworkState {
        GeneNetworkState { state: FixedBitSet::with_capacity(self.nodes.len()) }
    }
}

// Convert genome into sections, i.e. Split at the promoter.
impl<B: Base> Genome<B> {
    pub fn iter_genes<'a, 'b>(&'a self,
                              promoter: &'b [B],
                              length_of_gene: usize)
                              -> GeneIterator<'a, 'b, B> {
        GeneIterator {
            length_of_gene: length_of_gene,
            sequence: &self.genome,
            promoter: promoter,
        }
    }

    // Construct a dependency network between the genes
    pub fn construct_network<F>(&self,
                                promoter: &[B],
                                length_of_gene: usize,
                                protein_regulation: &F)
                                -> Option<GeneNetwork>
        where F: Fn(&[B]) -> ProteinRegulator
    {
        let genes: Vec<_> = self.iter_genes(promoter, length_of_gene).collect();
        let num_genes = genes.len();

        if num_genes == 0 {
            return None;
        }

        // each gene is a node in the boolean network
        let mut network = GeneNetwork::new(num_genes);

        for (src, gene) in genes.iter().enumerate() {
            let product = gene.product();
            // A gene product either enhances (> 0) or inyhibits (< 0) the expression of
            // another gene.
            let regulator = protein_regulation(&product);

            // determine which other genes ```gene``` regulates
            for (dst, gene2) in genes.iter().enumerate() {
                // XXX: Can a gene regulate itself?
                // if src != dst {
                let factor = gene2.count_product_in_regulatory_region(&product);
                if factor > 0 {
                    network.add_edge(src, dst, ProteinRegulator(regulator.0 * factor as i32));
                }
                // }
            }
        }

        return Some(network);
    }
}

impl<B: Base> FromStr for Genome<B> {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        FromStr::from_str(s).map(|bs| Genome { genome: bs })
    }
}
<|endoftext|>


<commit_before>use libc::{uint16_t, int16_t, uint8_t};

use encparams::EncParams;
use types::{IntPoly, ProdPoly, TernPoly, KeyPair, PrivPoly, PublicKey, PrivateKey};
use rand::{RandContext, RandGen};

extern "C" {
    // ntru.h
    pub fn ntru_gen_key_pair(params: *const EncParams,
                             kp: *mut KeyPair,
                             rand_ctx: *const RandContext)
                             -> uint8_t;
    pub fn ntru_gen_key_pair_multi(params: *const EncParams,
                                   private: *mut PrivateKey,
                                   public: *mut PublicKey,
                                   rand_ctx: *const RandContext,
                                   num_pub: u32)
                                   -> uint8_t;
    pub fn ntru_gen_pub(params: *const EncParams,
                        private: *const PrivateKey,
                        public: *mut PublicKey,
                        rand_ctx: *const RandContext)
                        -> uint8_t;
    pub fn ntru_encrypt(msg: *const uint8_t,
                        msg_len: uint16_t,
                        public: *const PublicKey,
                        params: *const EncParams,
                        rand_ctx: *const RandContext,
                        enc: *mut uint8_t)
                        -> uint8_t;
    pub fn ntru_decrypt(enc: *const uint8_t,
                        kp: *const KeyPair,
                        params: *const EncParams,
                        dec: *mut uint8_t,
                        dec_len: *mut uint16_t)
                        -> uint8_t;

    // hash.h
    pub fn ntru_sha1(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha1_4way(input: *const *const uint8_t,
                          input_len: uint16_t,
                          digest: *mut *mut uint8_t);
    pub fn ntru_sha1_8way(input: *const *const uint8_t,
                          input_len: uint16_t,
                          digest: *mut *mut uint8_t);
    pub fn ntru_sha256(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha256_4way(input: *const *const uint8_t,
                            input_len: uint16_t,
                            digest: *mut *mut uint8_t);
    pub fn ntru_sha256_8way(input: *const *const uint8_t,
                            input_len: uint16_t,
                            digest: *mut *mut uint8_t);

    // rand.h
    pub fn ntru_rand_init(rand_ctx: *mut RandContext, rand_gen: *const RandGen) -> uint8_t;
    pub fn ntru_rand_init_det(rand_ctx: *mut RandContext,
                              rand_gen: *const RandGen,
                              seed: *const uint8_t,
                              seed_len: uint16_t)
                              -> uint8_t;
    pub fn ntru_rand_generate(rand_data: *mut uint8_t,
                              len: uint16_t,
                              rand_ctx: *const RandContext)
                              -> uint8_t;
    pub fn ntru_rand_release(rand_ctx: *mut RandContext) -> uint8_t;

    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_init(rand_ctx: *mut NtruRandContext,
                                   rand_gen: *const RandGen)
                                   -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_generate(rand_data: *mut uint8_t,
                                       len: uint16_t,
                                       rand_ctx: *const NtruRandContext)
                                       -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_release(rand_ctx: *mut NtruRandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_init(rand_ctx: *mut RandContext,
                                    rand_gen: *const RandGen)
                                    -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_generate(rand_data: *mut uint8_t,
                                        len: uint16_t,
                                        rand_ctx: *const RandContext)
                                        -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_release(rand_ctx: *mut RandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_init(rand_ctx: *mut RandContext,
                                     rand_gen: *const RandGen)
                                     -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_generate(rand_data: *mut uint8_t,
                                         len: uint16_t,
                                         rand_ctx: *const RandContext)
                                         -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_release(rand_ctx: *mut RandContext) -> uint8_t;

    pub fn ntru_rand_default_init(rand_ctx: *mut RandContext, rand_gen: *const RandGen) -> uint8_t;
    pub fn ntru_rand_default_generate(rand_data: *mut uint8_t,
                                      len: uint16_t,
                                      rand_ctx: *const RandContext)
                                      -> uint8_t;
    pub fn ntru_rand_default_release(rand_ctx: *mut RandContext) -> uint8_t;

    pub fn ntru_rand_ctr_drbg_init(rand_ctx: *mut RandContext,
                                   rand_gen: *const RandGen)
                                   -> uint8_t;
    pub fn ntru_rand_ctr_drbg_generate(rand_data: *mut uint8_t,
                                       len: uint16_t,
                                       rand_ctx: *const RandContext)
                                       -> uint8_t;
    pub fn ntru_rand_ctr_drbg_release(rand_ctx: *mut RandContext) -> uint8_t;

    // poly.h
    pub fn ntru_rand_tern(n: uint16_t,
                          num_ones: uint16_t,
                          num_neg_ones: uint16_t,
                          poly: *mut TernPoly,
                          rand_ctx: *const RandContext)
                          -> uint8_t;
    pub fn ntru_mult_tern(a: *const IntPoly,
                          b: *const TernPoly,
                          c: *mut IntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_prod(a: *const IntPoly,
                          b: *const ProdPoly,
                          c: *mut IntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_priv(a: *const PrivPoly,
                          b: *const IntPoly,
                          c: *mut IntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_int(a: *const IntPoly,
                         b: *const IntPoly,
                         c: *mut IntPoly,
                         mod_mask: uint16_t)
                         -> uint8_t;
    pub fn ntru_add(a: *mut IntPoly, b: *const IntPoly);
    pub fn ntru_sub(a: *mut IntPoly, b: *const IntPoly);
    pub fn ntru_mod_mask(p: *mut IntPoly, mod_mask: uint16_t);
    pub fn ntru_mult_fac(a: *mut IntPoly, factor: int16_t);
    pub fn ntru_mod_center(p: *mut IntPoly, modulus: uint16_t);
    pub fn ntru_mod3(p: *mut IntPoly);
    pub fn ntru_to_arr(p: *const IntPoly, q: uint16_t, a: *mut uint8_t);
    pub fn ntru_from_arr(arr: *const uint8_t, n: uint16_t, q: uint16_t, p: *mut IntPoly);
    pub fn ntru_invert(a: *const PrivPoly, mod_mask: uint16_t, fq: *mut IntPoly) -> uint8_t;

    // key.h
    pub fn ntru_export_pub(key: *const PublicKey, arr: *mut uint8_t);
    pub fn ntru_import_pub(arr: *const uint8_t, key: *mut PublicKey) -> uint16_t;

    pub fn ntru_export_priv(key: *const PrivateKey, arr: *mut uint8_t) -> uint16_t;
    pub fn ntru_import_priv(arr: *const uint8_t, key: *mut PrivateKey);

    pub fn ntru_params_from_priv_key(key: *const PrivateKey, params: *mut EncParams) -> uint8_t;
}
<commit_msg>Now fixed<commit_after>use libc::{uint16_t, int16_t, uint8_t};

use encparams::EncParams;
use types::{IntPoly, ProdPoly, TernPoly, KeyPair, PrivPoly, PublicKey, PrivateKey};
use rand::{RandContext, RandGen};

extern "C" {
    // ntru.h
    pub fn ntru_gen_key_pair(params: *const EncParams,
                             kp: *mut KeyPair,
                             rand_ctx: *const RandContext)
                             -> uint8_t;
    pub fn ntru_gen_key_pair_multi(params: *const EncParams,
                                   private: *mut PrivateKey,
                                   public: *mut PublicKey,
                                   rand_ctx: *const RandContext,
                                   num_pub: u32)
                                   -> uint8_t;
    pub fn ntru_gen_pub(params: *const EncParams,
                        private: *const PrivateKey,
                        public: *mut PublicKey,
                        rand_ctx: *const RandContext)
                        -> uint8_t;
    pub fn ntru_encrypt(msg: *const uint8_t,
                        msg_len: uint16_t,
                        public: *const PublicKey,
                        params: *const EncParams,
                        rand_ctx: *const RandContext,
                        enc: *mut uint8_t)
                        -> uint8_t;
    pub fn ntru_decrypt(enc: *const uint8_t,
                        kp: *const KeyPair,
                        params: *const EncParams,
                        dec: *mut uint8_t,
                        dec_len: *mut uint16_t)
                        -> uint8_t;

    // hash.h
    pub fn ntru_sha1(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha1_4way(input: *const *const uint8_t,
                          input_len: uint16_t,
                          digest: *mut *mut uint8_t);
    pub fn ntru_sha1_8way(input: *const *const uint8_t,
                          input_len: uint16_t,
                          digest: *mut *mut uint8_t);
    pub fn ntru_sha256(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha256_4way(input: *const *const uint8_t,
                            input_len: uint16_t,
                            digest: *mut *mut uint8_t);
    pub fn ntru_sha256_8way(input: *const *const uint8_t,
                            input_len: uint16_t,
                            digest: *mut *mut uint8_t);

    // rand.h
    pub fn ntru_rand_init(rand_ctx: *mut RandContext, rand_gen: *const RandGen) -> uint8_t;
    pub fn ntru_rand_init_det(rand_ctx: *mut RandContext,
                              rand_gen: *const RandGen,
                              seed: *const uint8_t,
                              seed_len: uint16_t)
                              -> uint8_t;
    pub fn ntru_rand_generate(rand_data: *mut uint8_t,
                              len: uint16_t,
                              rand_ctx: *const RandContext)
                              -> uint8_t;
    pub fn ntru_rand_release(rand_ctx: *mut RandContext) -> uint8_t;

    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_init(rand_ctx: *mut RandContext,
                                   rand_gen: *const RandGen)
                                   -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_generate(rand_data: *mut uint8_t,
                                       len: uint16_t,
                                       rand_ctx: *const RandContext)
                                       -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_release(rand_ctx: *mut RandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_init(rand_ctx: *mut RandContext,
                                    rand_gen: *const RandGen)
                                    -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_generate(rand_data: *mut uint8_t,
                                        len: uint16_t,
                                        rand_ctx: *const RandContext)
                                        -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_release(rand_ctx: *mut RandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_init(rand_ctx: *mut RandContext,
                                     rand_gen: *const RandGen)
                                     -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_generate(rand_data: *mut uint8_t,
                                         len: uint16_t,
                                         rand_ctx: *const RandContext)
                                         -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_release(rand_ctx: *mut RandContext) -> uint8_t;

    pub fn ntru_rand_default_init(rand_ctx: *mut RandContext, rand_gen: *const RandGen) -> uint8_t;
    pub fn ntru_rand_default_generate(rand_data: *mut uint8_t,
                                      len: uint16_t,
                                      rand_ctx: *const RandContext)
                                      -> uint8_t;
    pub fn ntru_rand_default_release(rand_ctx: *mut RandContext) -> uint8_t;

    pub fn ntru_rand_ctr_drbg_init(rand_ctx: *mut RandContext,
                                   rand_gen: *const RandGen)
                                   -> uint8_t;
    pub fn ntru_rand_ctr_drbg_generate(rand_data: *mut uint8_t,
                                       len: uint16_t,
                                       rand_ctx: *const RandContext)
                                       -> uint8_t;
    pub fn ntru_rand_ctr_drbg_release(rand_ctx: *mut RandContext) -> uint8_t;

    // poly.h
    pub fn ntru_rand_tern(n: uint16_t,
                          num_ones: uint16_t,
                          num_neg_ones: uint16_t,
                          poly: *mut TernPoly,
                          rand_ctx: *const RandContext)
                          -> uint8_t;
    pub fn ntru_mult_tern(a: *const IntPoly,
                          b: *const TernPoly,
                          c: *mut IntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_prod(a: *const IntPoly,
                          b: *const ProdPoly,
                          c: *mut IntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_priv(a: *const PrivPoly,
                          b: *const IntPoly,
                          c: *mut IntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_int(a: *const IntPoly,
                         b: *const IntPoly,
                         c: *mut IntPoly,
                         mod_mask: uint16_t)
                         -> uint8_t;
    pub fn ntru_add(a: *mut IntPoly, b: *const IntPoly);
    pub fn ntru_sub(a: *mut IntPoly, b: *const IntPoly);
    pub fn ntru_mod_mask(p: *mut IntPoly, mod_mask: uint16_t);
    pub fn ntru_mult_fac(a: *mut IntPoly, factor: int16_t);
    pub fn ntru_mod_center(p: *mut IntPoly, modulus: uint16_t);
    pub fn ntru_mod3(p: *mut IntPoly);
    pub fn ntru_to_arr(p: *const IntPoly, q: uint16_t, a: *mut uint8_t);
    pub fn ntru_from_arr(arr: *const uint8_t, n: uint16_t, q: uint16_t, p: *mut IntPoly);
    pub fn ntru_invert(a: *const PrivPoly, mod_mask: uint16_t, fq: *mut IntPoly) -> uint8_t;

    // key.h
    pub fn ntru_export_pub(key: *const PublicKey, arr: *mut uint8_t);
    pub fn ntru_import_pub(arr: *const uint8_t, key: *mut PublicKey) -> uint16_t;

    pub fn ntru_export_priv(key: *const PrivateKey, arr: *mut uint8_t) -> uint16_t;
    pub fn ntru_import_priv(arr: *const uint8_t, key: *mut PrivateKey);

    pub fn ntru_params_from_priv_key(key: *const PrivateKey, params: *mut EncParams) -> uint8_t;
}
<|endoftext|>


<commit_before>#![allow(non_camel_case_types)]

use std::io::{self, Read, Seek, SeekFrom};
use std::mem::transmute;

use static_assertions::assert_eq_size;

// TODO static assertion

// Minimal ELF support, sufficient for a very simple 64-bit static Linux
// executable.

// Sources:
// * /usr/include/elf.h
// * https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
// * https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html

type Elf64_Half = u16;
type Elf64_Word = u32;
type Elf64_Xword = u64;
type Elf64_Addr = u64;
type Elf64_Off = u64;

const ELFOSABI_LINUX: u8 = 3;
const ET_EXEC: u16 = 2;
const EM_X86_64: u16 = 62;
const PT_LOAD: u32 = 1;

const PF_X: u32 = 1 << 0;
const PF_W: u32 = 1 << 1;
const PF_R: u32 = 1 << 2;

const SHT_STRTAB: u32 = 3;

const EHDR_SIZE: usize = 64;
const PHDR_SIZE: usize = 56;
const SHDR_SIZE: usize = 64;

assert_eq_size!(ehdr_size_assert; Elf64_Ehdr, [u8; EHDR_SIZE]);
assert_eq_size!(phdr_size_assert; Elf64_Phdr, [u8; PHDR_SIZE]);
assert_eq_size!(shdr_size_assert; Elf64_Shdr, [u8; SHDR_SIZE]);

// ELF header
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Elf64_Ehdr {
    pub e_ident: [u8; 16],
    pub e_type: Elf64_Half,
    pub e_machine: Elf64_Half,
    pub e_version: Elf64_Word,
    pub e_entry: Elf64_Addr,
    pub e_phoff: Elf64_Off,
    pub e_shoff: Elf64_Off,
    pub e_flags: Elf64_Word,
    pub e_ehsize: Elf64_Half,
    pub e_phentsize: Elf64_Half,
    pub e_phnum: Elf64_Half,
    pub e_shentsize: Elf64_Half,
    pub e_shnum: Elf64_Half,
    pub e_shstrndx: Elf64_Half,
}

// Program header
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Elf64_Phdr {
    pub p_type: Elf64_Word,
    pub p_flags: Elf64_Word,
    pub p_offset: Elf64_Off,
    pub p_vaddr: Elf64_Addr,
    pub p_paddr: Elf64_Addr,
    pub p_filesz: Elf64_Xword,
    pub p_memsz: Elf64_Xword,
    pub p_align: Elf64_Xword,
}

// Symbol header
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Elf64_Shdr {
    pub sh_name: Elf64_Word,
    pub sh_type: Elf64_Word,
    pub sh_flags: Elf64_Xword,
    pub sh_addr: Elf64_Addr,
    pub sh_offset: Elf64_Off,
    pub sh_size: Elf64_Xword,
    pub sh_link: Elf64_Word,
    pub sh_info: Elf64_Word,
    pub sh_addralign: Elf64_Xword,
    pub sh_entsize: Elf64_Xword,
}

pub fn create_elf64_hdr(size: u64, bss_size: u64) -> Vec<u8> {
    let ehdr = Elf64_Ehdr {
        e_ident: [0x7f, b'E', b'L', b'F', 2, 1, 1, ELFOSABI_LINUX, 0, 0, 0, 0, 0, 0, 0, 0 ],
        e_type: ET_EXEC,
        e_machine: EM_X86_64,
        e_version: 1,
        e_entry: 0x401000,
        // Put program header immediately after ELF header
        e_phoff: EHDR_SIZE as u64,
        // Don't include a section header table
        e_shoff: 0,
        e_flags: 0,
        e_ehsize: EHDR_SIZE as u16,
        e_phentsize: PHDR_SIZE as u16,
        e_phnum: 2,
        e_shentsize: 0,
        e_shnum: 0,
        e_shstrndx: 0,
    };

    let phdr_text = Elf64_Phdr {
        p_type: PT_LOAD,
        p_flags: PF_R | PF_X,
        p_offset: 0,
        p_vaddr: 0x401000,
        p_paddr: 0x401000,
        p_filesz: size,
        p_memsz: size,
        p_align: 0x1000,
    };

    let bss_offset = (size + 0x1000 - 1) & !(0x1000 - 1);

    let phdr_bss = Elf64_Phdr {
        p_type: PT_LOAD,
        p_flags: PF_R | PF_W,
        p_offset: bss_offset,
        p_vaddr: 0x401000 + bss_offset,
        p_paddr: 0x401000 + bss_offset,
        p_filesz: 0,
        p_memsz: bss_size,
        p_align: 0x1000,
    };

    let mut vec = Vec::new();
    unsafe {
        vec.extend_from_slice(&transmute::<_, [u8; EHDR_SIZE]>(ehdr));
        vec.extend_from_slice(&transmute::<_, [u8; PHDR_SIZE]>(phdr_text));
        vec.extend_from_slice(&transmute::<_, [u8; PHDR_SIZE]>(phdr_bss));
    }
    vec
}

pub fn elf64_get_section(f: &mut (impl Read + Seek), name: &[u8]) -> io::Result<Option<Elf64_Shdr>> {
    f.seek(SeekFrom::Start(0))?;

    let mut ehdr_buf = [0; EHDR_SIZE];
    f.read(&mut ehdr_buf)?;
    let ehdr: Elf64_Ehdr = unsafe { transmute(ehdr_buf) };

    let mut strtab = Vec::new();

    f.seek(SeekFrom::Start(ehdr.e_shoff))?;
    for _ in 0..ehdr.e_shnum {
        let mut shdr_buf = [0; SHDR_SIZE];
        f.read(&mut shdr_buf)?;
        let shdr: Elf64_Shdr = unsafe { transmute(shdr_buf) };

        if shdr.sh_type == SHT_STRTAB {
            let current = f.seek(SeekFrom::Current(0))?;
            f.seek(SeekFrom::Start(shdr.sh_offset))?;
            strtab.resize(shdr.sh_size as usize, 0);
            f.read(&mut strtab)?;
            f.seek(SeekFrom::Start(current))?;
        }
    }

    f.seek(SeekFrom::Start(ehdr.e_shoff))?;
    for _ in 0..ehdr.e_shnum {
        let mut shdr_buf = [0; SHDR_SIZE];
        f.read(&mut shdr_buf)?;
        let shdr: Elf64_Shdr = unsafe { transmute(shdr_buf) };

        let mut cur_name = &strtab[shdr.sh_name as usize..];
        if let Some(idx) = cur_name.iter().position(|c| *c == b'\0') {
            cur_name = &cur_name[..idx];
        }
        if cur_name == name {
            return Ok(Some(shdr));
        }
    }

    Ok(None)
}
<commit_msg>A couple improvements to elf.rs<commit_after>#![allow(non_camel_case_types)]

use std::io::{self, Read, Seek, SeekFrom};
use std::mem::transmute;

use static_assertions::assert_eq_size;

// TODO static assertion

// Minimal ELF support, sufficient for a very simple 64-bit static Linux
// executable.

// Sources:
// * /usr/include/elf.h
// * https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
// * https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html

type Elf64_Half = u16;
type Elf64_Word = u32;
type Elf64_Xword = u64;
type Elf64_Addr = u64;
type Elf64_Off = u64;

const ELFOSABI_LINUX: u8 = 3;
const ET_EXEC: u16 = 2;
const EM_X86_64: u16 = 62;
const PT_LOAD: u32 = 1;

const PF_X: u32 = 1 << 0;
const PF_W: u32 = 1 << 1;
const PF_R: u32 = 1 << 2;

const EHDR_SIZE: usize = 64;
const PHDR_SIZE: usize = 56;
const SHDR_SIZE: usize = 64;

assert_eq_size!(ehdr_size_assert; Elf64_Ehdr, [u8; EHDR_SIZE]);
assert_eq_size!(phdr_size_assert; Elf64_Phdr, [u8; PHDR_SIZE]);
assert_eq_size!(shdr_size_assert; Elf64_Shdr, [u8; SHDR_SIZE]);

// ELF header
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Elf64_Ehdr {
    pub e_ident: [u8; 16],
    pub e_type: Elf64_Half,
    pub e_machine: Elf64_Half,
    pub e_version: Elf64_Word,
    pub e_entry: Elf64_Addr,
    pub e_phoff: Elf64_Off,
    pub e_shoff: Elf64_Off,
    pub e_flags: Elf64_Word,
    pub e_ehsize: Elf64_Half,
    pub e_phentsize: Elf64_Half,
    pub e_phnum: Elf64_Half,
    pub e_shentsize: Elf64_Half,
    pub e_shnum: Elf64_Half,
    pub e_shstrndx: Elf64_Half,
}

// Program header
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct Elf64_Phdr {
    pub p_type: Elf64_Word,
    pub p_flags: Elf64_Word,
    pub p_offset: Elf64_Off,
    pub p_vaddr: Elf64_Addr,
    pub p_paddr: Elf64_Addr,
    pub p_filesz: Elf64_Xword,
    pub p_memsz: Elf64_Xword,
    pub p_align: Elf64_Xword,
}

// Symbol header
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Elf64_Shdr {
    pub sh_name: Elf64_Word,
    pub sh_type: Elf64_Word,
    pub sh_flags: Elf64_Xword,
    pub sh_addr: Elf64_Addr,
    pub sh_offset: Elf64_Off,
    pub sh_size: Elf64_Xword,
    pub sh_link: Elf64_Word,
    pub sh_info: Elf64_Word,
    pub sh_addralign: Elf64_Xword,
    pub sh_entsize: Elf64_Xword,
}

pub fn create_elf64_hdr(size: u64, bss_size: u64) -> Vec<u8> {
    let ehdr = Elf64_Ehdr {
        e_ident: [0x7f, b'E', b'L', b'F', 2, 1, 1, ELFOSABI_LINUX, 0, 0, 0, 0, 0, 0, 0, 0 ],
        e_type: ET_EXEC,
        e_machine: EM_X86_64,
        e_version: 1,
        e_entry: 0x401000,
        // Put program header immediately after ELF header
        e_phoff: EHDR_SIZE as u64,
        // Don't include a section header table
        e_shoff: 0,
        e_flags: 0,
        e_ehsize: EHDR_SIZE as u16,
        e_phentsize: PHDR_SIZE as u16,
        e_phnum: 2,
        e_shentsize: SHDR_SIZE as u16,
        e_shnum: 0,
        e_shstrndx: 0,
    };

    let phdr_text = Elf64_Phdr {
        p_type: PT_LOAD,
        p_flags: PF_R | PF_X,
        p_offset: 0,
        p_vaddr: 0x401000,
        p_paddr: 0x401000,
        p_filesz: size,
        p_memsz: size,
        p_align: 0x1000,
    };

    let bss_offset = (size + 0x1000 - 1) & !(0x1000 - 1);

    println!("{:x} - {:x}", bss_offset, bss_size);

    let phdr_bss = Elf64_Phdr {
        p_type: PT_LOAD,
        p_flags: PF_R | PF_W,
        p_offset: bss_offset,
        p_vaddr: 0x401000 + bss_offset,
        p_paddr: 0x401000 + bss_offset,
        p_filesz: 0,
        p_memsz: bss_size,
        p_align: 0x1000,
    };

    let mut vec = Vec::new();
    unsafe {
        vec.extend_from_slice(&transmute::<_, [u8; EHDR_SIZE]>(ehdr));
        vec.extend_from_slice(&transmute::<_, [u8; PHDR_SIZE]>(phdr_text));
        vec.extend_from_slice(&transmute::<_, [u8; PHDR_SIZE]>(phdr_bss));
    }
    vec
}

fn elf64_read_strtab(f: &mut (impl Read + Seek), ehdr: &Elf64_Ehdr) -> io::Result<Vec<u8>> {
    // Read section header for the string table
    let mut shdr_buf = [0; SHDR_SIZE];
    f.seek(SeekFrom::Start(ehdr.e_shoff + ehdr.e_shstrndx as u64 * SHDR_SIZE as u64))?;
    f.read(&mut shdr_buf)?;
    let shdr: Elf64_Shdr = unsafe { transmute(shdr_buf) };

    // Read string table section
    let mut strtab = Vec::with_capacity(shdr.sh_size as usize);
    strtab.resize(shdr.sh_size as usize, 0);
    f.seek(SeekFrom::Start(shdr.sh_offset))?;
    f.read(&mut strtab)?;

    Ok(strtab)
}

pub fn elf64_get_section(f: &mut (impl Read + Seek), name: &[u8]) -> io::Result<Option<Elf64_Shdr>> {
    let mut ehdr_buf = [0; EHDR_SIZE];
    f.seek(SeekFrom::Start(0))?;
    f.read(&mut ehdr_buf)?;
    let ehdr: Elf64_Ehdr = unsafe { transmute(ehdr_buf) };

    let strtab = elf64_read_strtab(f, &ehdr)?;

    f.seek(SeekFrom::Start(ehdr.e_shoff))?;
    for _ in 0..ehdr.e_shnum {
        let mut shdr_buf = [0; SHDR_SIZE];
        f.read(&mut shdr_buf)?;
        let shdr: Elf64_Shdr = unsafe { transmute(shdr_buf) };

        let mut cur_name = &strtab[shdr.sh_name as usize..];
        if let Some(idx) = cur_name.iter().position(|c| *c == b'\0') {
            cur_name = &cur_name[..idx];
        }
        if cur_name == name {
            return Ok(Some(shdr));
        }
    }

    Ok(None)
}
<|endoftext|>


<commit_before>#![feature(globs)]

extern crate serialize;

extern crate conduit;
extern crate middleware = "conduit-middleware";
extern crate utils = "conduit-utils";

use std::fmt;
use std::fmt::{Show, Formatter};
use std::any::{Any, AnyRefExt};
use serialize::{Decodable, json};

use conduit::Request;
use utils::RequestDelegator;
use middleware::Middleware;

pub struct BodyReader<T>;

trait JsonDecodable : Decodable<json::Decoder, json::DecoderError> {}
impl<T: Decodable<json::Decoder, json::DecoderError>> JsonDecodable for T {}

impl<T: JsonDecodable + 'static> Middleware for BodyReader<T> {
    fn before<'a>(&self, req: &'a mut Request) -> Result<(), Box<Show>> {
        let json: T = try!(decode::<T>(req.body()).map_err(|err| {
            box format!("Couldn't parse JSON: {}", show(err)) as Box<Show>
        }));

        req.mut_extensions().insert("body-params.json", box json as Box<Any>);
        Ok(())
    }
}

// Hack around the lack of impl Show for Box<Show>
struct Shower<'a> {
    inner: &'a Show
}

impl<'a> Show for Shower<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        self.inner.fmt(f)
    }
}

fn show<'a>(s: &'a Show) -> Shower<'a> {
    Shower { inner: s }
}

fn decode<T: JsonDecodable + 'static>(reader: &mut Reader) -> Result<T, Box<Show>> {
    let j = try!(json::from_reader(reader).map_err(|e| box e as Box<Show>));
    let mut decoder = json::Decoder::new(j);
    Decodable::decode(&mut decoder).map_err(|e| box e as Box<Show>)
}

pub fn json_params<'a, T: JsonDecodable + 'static>(req: &'a mut Request) -> Option<&'a T> {
    req.extensions().find(&"body-params.json")
        .and_then(|s| s.as_ref::<T>())
}

#[cfg(test)]
mod tests {
    extern crate conduit_test = "conduit-test";
    use super::*;
    use std::collections::HashMap;
    use std::io::MemReader;
    use serialize::json;

    use conduit;
    use conduit::{Request, Response, Handler};
    use middleware::MiddlewareBuilder;

    #[deriving(PartialEq, Decodable, Encodable, Show)]
    struct Person {
        name: String,
        location: String
    }

    fn handler(req: &mut Request) -> Result<Response, ()> {
        let person = json_params::<Person>(req);
        let out = person.map(|p| json::Encoder::str_encode(p)).expect("No JSON");

        Ok(Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: box MemReader::new(out.into_bytes()) as Box<Reader + Send>
        })
    }

    #[test]
    fn test_body_params() {
        let mut req = conduit_test::MockRequest::new(conduit::Get, "/");
        req.with_body(r#"{ "name": "Alex Crichton", "location": "San Francisco" }"#);

        let mut middleware = MiddlewareBuilder::new(handler);
        middleware.add(BodyReader::<Person>);

        let mut res = middleware.call(&mut req).ok().expect("No response");
        let person = super::decode::<Person>(res.body).ok().expect("No JSON response");
        assert_eq!(person, Person {
            name: "Alex Crichton".to_str(),
            location: "San Francisco".to_str()
        });
    }
}
<commit_msg>Update to master<commit_after>#![feature(globs)]

extern crate serialize;

extern crate conduit;
extern crate middleware = "conduit-middleware";
extern crate utils = "conduit-utils";

use std::fmt;
use std::fmt::{Show, Formatter};
use std::any::{Any, AnyRefExt};
use serialize::{Decodable, json};

use conduit::Request;
use utils::RequestDelegator;
use middleware::Middleware;

pub struct BodyReader<T>;

trait JsonDecodable : Decodable<json::Decoder, json::DecoderError> {}
impl<T: Decodable<json::Decoder, json::DecoderError>> JsonDecodable for T {}

impl<T: JsonDecodable + 'static> Middleware for BodyReader<T> {
    fn before<'a>(&self, req: &'a mut Request) -> Result<(), Box<Show>> {
        let json: T = try!(decode::<T>(req.body()).map_err(|err| {
            box format!("Couldn't parse JSON: {}", show(err)) as Box<Show>
        }));

        req.mut_extensions().insert("body-params.json", box json as Box<Any>);
        Ok(())
    }
}

// Hack around the lack of impl Show for Box<Show>
struct Shower<'a> {
    inner: &'a Show
}

impl<'a> Show for Shower<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        self.inner.fmt(f)
    }
}

fn show<'a>(s: &'a Show) -> Shower<'a> {
    Shower { inner: s }
}

fn decode<T: JsonDecodable + 'static>(reader: &mut Reader) -> Result<T, Box<Show>> {
    let j = try!(json::from_reader(reader).map_err(|e| box e as Box<Show>));
    let mut decoder = json::Decoder::new(j);
    Decodable::decode(&mut decoder).map_err(|e| box e as Box<Show>)
}

pub fn json_params<'a, T: JsonDecodable + 'static>(req: &'a Request) -> Option<&'a T> {
    req.extensions().find(&"body-params.json")
        .and_then(|s| s.as_ref::<T>())
}

#[cfg(test)]
mod tests {
    extern crate conduit_test = "conduit-test";
    use super::*;
    use std::collections::HashMap;
    use std::io::MemReader;
    use serialize::json;

    use conduit;
    use conduit::{Request, Response, Handler};
    use middleware::MiddlewareBuilder;

    #[deriving(PartialEq, Decodable, Encodable, Show)]
    struct Person {
        name: String,
        location: String
    }

    fn handler(req: &mut Request) -> Result<Response, ()> {
        let person = json_params::<Person>(req);
        let out = person.map(|p| json::encode(p)).expect("No JSON");

        Ok(Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: box MemReader::new(out.into_bytes()) as Box<Reader + Send>
        })
    }

    #[test]
    fn test_body_params() {
        let mut req = conduit_test::MockRequest::new(conduit::Get, "/");
        req.with_body(r#"{ "name": "Alex Crichton", "location": "San Francisco" }"#);

        let mut middleware = MiddlewareBuilder::new(handler);
        middleware.add(BodyReader::<Person>);

        let mut res = middleware.call(&mut req).ok().expect("No response");
        let person = super::decode::<Person>(res.body).ok().expect("No JSON response");
        assert_eq!(person, Person {
            name: "Alex Crichton".to_string(),
            location: "San Francisco".to_string()
        });
    }
}
<|endoftext|>


<commit_before>#![feature(box_syntax)]
#![feature(fnbox)]
#![feature(drain)]
#![feature(catch_panic)]

#![warn(missing_docs, dead_code)]

//! Ferrous Threads Crate
//!
//! This crate contains a number of different structs and functions that are of use
//! when attempting to do concurrent/parallel programming.
//!
//! This includes a thread pool, a multi-producer/multi-consumer queue, a task runner, and
//! a publish/subscribe queue.

extern crate canal;

pub mod task_runner;
pub mod thread_pool;
<commit_msg>[deny(missing_docs, dead_code)]<commit_after>#![feature(box_syntax)]
#![feature(fnbox)]
#![feature(drain)]
#![feature(catch_panic)]

#![deny(missing_docs, dead_code)]

//! Ferrous Threads Crate
//!
//! This crate contains a number of different structs and functions that are of use
//! when attempting to do concurrent/parallel programming.
//!
//! This includes a thread pool, a multi-producer/multi-consumer queue, a task runner, and
//! a publish/subscribe queue.

extern crate canal;

pub mod task_runner;
pub mod thread_pool;
<|endoftext|>


<commit_before>extern crate byteorder;

use std::io::{Result, Write, ErrorKind, Error};
use byteorder::{ReadBytesExt, LittleEndian, WriteBytesExt};

pub struct Triangle {
    normal: [f32; 3],
    v1: [f32; 3],
    v2: [f32; 3],
    v3: [f32; 3],
    attr_byte_count: u16
}

fn point_eq(lhs: [f32; 3], rhs: [f32; 3]) -> bool {
    lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2]
}

impl PartialEq for Triangle {
    fn eq(&self, rhs: &Triangle) -> bool {
        point_eq(self.normal, rhs.normal)
            && point_eq(self.v1, rhs.v1)
            && point_eq(self.v2, rhs.v2)
            && point_eq(self.v3, rhs.v3)
            && self.attr_byte_count == rhs.attr_byte_count
    }
}

impl Eq for Triangle {}

pub struct BinaryStlHeader {
    pub header: [u8; 80],
    pub num_triangles: u32
}

pub struct BinaryStlFile {
    pub header: BinaryStlHeader,
    pub triangles: Vec<Triangle>
}

fn read_point<T: ReadBytesExt>(input: &mut T) -> Result<[f32; 3]> {
    let x1 = try!(input.read_f32::<LittleEndian>());
    let x2 = try!(input.read_f32::<LittleEndian>());
    let x3 = try!(input.read_f32::<LittleEndian>());

    Ok([x1, x2, x3])
}

fn read_triangle<T: ReadBytesExt>(input: &mut T) -> Result<Triangle> {
    let normal = try!(read_point(input));
    let v1 = try!(read_point(input));
    let v2 = try!(read_point(input));
    let v3 = try!(read_point(input));
    let attr_count = try!(input.read_u16::<LittleEndian>());

    Ok(Triangle { normal: normal,
                  v1: v1, v2: v2, v3: v3,
                  attr_byte_count: attr_count })
}

fn read_header<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlHeader> {
    let mut header = [0u8; 80];

    match input.read(&mut header) {
        Ok(n) => if n == header.len() {
            ()
        }
        else {
            return Err(Error::new(ErrorKind::Other,
                                  "Couldn't read STL header"));
        },
        Err(e) => return Err(e)
    };

    let num_triangles = try!(input.read_u32::<LittleEndian>());

    Ok(BinaryStlHeader{ header: header, num_triangles: num_triangles })
}

pub fn read_stl<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlFile> {

    // read the header
    let header = try!(read_header(input));

    let mut triangles = Vec::new();
    for _ in 0 .. header.num_triangles {
        triangles.push(try!(read_triangle(input)));
    }

    Ok(BinaryStlFile {
        header: header,
        triangles: triangles
    })
}

fn write_point<T: WriteBytesExt>(out: &mut T, p: [f32; 3]) -> Result<()> {
    for x in &p {
        try!(out.write_f32::<LittleEndian>(*x));
    }
    Ok(())
}

pub fn write_stl<T: WriteBytesExt>(out: &mut T,
                                   stl: &BinaryStlFile) -> Result<()> {
    assert_eq!(stl.header.num_triangles as usize, stl.triangles.len());

    //write the header.
    try!(out.write_all(&stl.header.header));
    try!(out.write_u32::<LittleEndian>(stl.header.num_triangles));

    // write all the triangles
    for t in &stl.triangles {
        try!(write_point(out, t.normal));
        try!(write_point(out, t.v1));
        try!(write_point(out, t.v2));
        try!(write_point(out, t.v3));
        try!(out.write_u16::<LittleEndian>(t.attr_byte_count));
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use super::{BinaryStlFile, BinaryStlHeader, write_stl, read_stl, Triangle};
    use std::io::Cursor;
    #[test]
    fn write_read() {
        // Make sure we can write and read a simple file.
        let file = BinaryStlFile {
            header: BinaryStlHeader { header: [0u8; 80],
                                      num_triangles: 1 },
            triangles: vec![Triangle { normal: [0f32, 1f32, 0f32],
                                       v1: [0f32, 0f32, 0f32],
                                       v2: [0f32, 0f32, 1f32],
                                       v3: [1f32, 0f32, 1f32],
                                       attr_byte_count: 0 }]
        };

        let mut buffer = Vec::new();

        match write_stl(&mut buffer, &file) {
            Ok(_) => (),
            Err(_) => panic!()
        }

        match read_stl(&mut Cursor::new(buffer)) {
            Ok(stl) => {
                assert!(stl.header.num_triangles == file.header.num_triangles);
                assert!(stl.triangles.len() == 1);
                assert!(stl.triangles[0] == file.triangles[0])
            },
            Err(_) => panic!()
        }
    }
}
<commit_msg>run rustfmt on code<commit_after>extern crate byteorder;

use std::io::{Result, Write, ErrorKind, Error};
use byteorder::{ReadBytesExt, LittleEndian, WriteBytesExt};

pub struct Triangle {
    normal: [f32; 3],
    v1: [f32; 3],
    v2: [f32; 3],
    v3: [f32; 3],
    attr_byte_count: u16,
}

fn point_eq(lhs: [f32; 3], rhs: [f32; 3]) -> bool {
    lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2]
}

impl PartialEq for Triangle {
    fn eq(&self, rhs: &Triangle) -> bool {
        point_eq(self.normal, rhs.normal) && point_eq(self.v1, rhs.v1) &&
        point_eq(self.v2, rhs.v2) && point_eq(self.v3, rhs.v3) &&
        self.attr_byte_count == rhs.attr_byte_count
    }
}

impl Eq for Triangle {}

pub struct BinaryStlHeader {
    pub header: [u8; 80],
    pub num_triangles: u32,
}

pub struct BinaryStlFile {
    pub header: BinaryStlHeader,
    pub triangles: Vec<Triangle>,
}

fn read_point<T: ReadBytesExt>(input: &mut T) -> Result<[f32; 3]> {
    let x1 = try!(input.read_f32::<LittleEndian>());
    let x2 = try!(input.read_f32::<LittleEndian>());
    let x3 = try!(input.read_f32::<LittleEndian>());

    Ok([x1, x2, x3])
}

fn read_triangle<T: ReadBytesExt>(input: &mut T) -> Result<Triangle> {
    let normal = try!(read_point(input));
    let v1 = try!(read_point(input));
    let v2 = try!(read_point(input));
    let v3 = try!(read_point(input));
    let attr_count = try!(input.read_u16::<LittleEndian>());

    Ok(Triangle {
           normal: normal,
           v1: v1,
           v2: v2,
           v3: v3,
           attr_byte_count: attr_count,
       })
}

fn read_header<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlHeader> {
    let mut header = [0u8; 80];

    match input.read(&mut header) {
        Ok(n) => {
            if n == header.len() {
                ()
            } else {
                return Err(Error::new(ErrorKind::Other, "Couldn't read STL header"));
            }
        }
        Err(e) => return Err(e),
    };

    let num_triangles = try!(input.read_u32::<LittleEndian>());

    Ok(BinaryStlHeader {
           header: header,
           num_triangles: num_triangles,
       })
}

pub fn read_stl<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlFile> {

    // read the header
    let header = try!(read_header(input));

    let mut triangles = Vec::new();
    for _ in 0..header.num_triangles {
        triangles.push(try!(read_triangle(input)));
    }

    Ok(BinaryStlFile {
           header: header,
           triangles: triangles,
       })
}

fn write_point<T: WriteBytesExt>(out: &mut T, p: [f32; 3]) -> Result<()> {
    for x in &p {
        try!(out.write_f32::<LittleEndian>(*x));
    }
    Ok(())
}

pub fn write_stl<T: WriteBytesExt>(out: &mut T, stl: &BinaryStlFile) -> Result<()> {
    assert_eq!(stl.header.num_triangles as usize, stl.triangles.len());

    //write the header.
    try!(out.write_all(&stl.header.header));
    try!(out.write_u32::<LittleEndian>(stl.header.num_triangles));

    // write all the triangles
    for t in &stl.triangles {
        try!(write_point(out, t.normal));
        try!(write_point(out, t.v1));
        try!(write_point(out, t.v2));
        try!(write_point(out, t.v3));
        try!(out.write_u16::<LittleEndian>(t.attr_byte_count));
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use super::{BinaryStlFile, BinaryStlHeader, write_stl, read_stl, Triangle};
    use std::io::Cursor;
    #[test]
    fn write_read() {
        // Make sure we can write and read a simple file.
        let file = BinaryStlFile {
            header: BinaryStlHeader {
                header: [0u8; 80],
                num_triangles: 1,
            },
            triangles: vec![Triangle {
                                normal: [0f32, 1f32, 0f32],
                                v1: [0f32, 0f32, 0f32],
                                v2: [0f32, 0f32, 1f32],
                                v3: [1f32, 0f32, 1f32],
                                attr_byte_count: 0,
                            }],
        };

        let mut buffer = Vec::new();

        match write_stl(&mut buffer, &file) {
            Ok(_) => (),
            Err(_) => panic!(),
        }

        match read_stl(&mut Cursor::new(buffer)) {
            Ok(stl) => {
                assert!(stl.header.num_triangles == file.header.num_triangles);
                assert!(stl.triangles.len() == 1);
                assert!(stl.triangles[0] == file.triangles[0])
            }
            Err(_) => panic!(),
        }
    }
}
<|endoftext|>


<commit_before>//! Learn what's changed in the crates index.
//!
//! Have a look at the real-world usage to learn more about it:
//! [crates-io-cli](https://github.com/Byron/crates-io-cli-rs/blob/b7a39ad8ef68adb81b2d8a7e552cb0a2a73f7d5b/src/main.rs#L62)
#![deny(missing_docs, rust_2018_idioms)]

///
pub mod index;
mod types;

pub use git2;
pub use types::{Change, CrateVersion, Dependency, Index};
<commit_msg>feat: re-export `git-repository` as `git`<commit_after>//! Learn what's changed in the crates index.
//!
//! Have a look at the real-world usage to learn more about it:
//! [crates-io-cli](https://github.com/Byron/crates-io-cli-rs/blob/b7a39ad8ef68adb81b2d8a7e552cb0a2a73f7d5b/src/main.rs#L62)
#![deny(missing_docs, rust_2018_idioms)]

///
pub mod index;
mod types;

pub use git2;
pub use git_repository as git;
pub use types::{Change, CrateVersion, Dependency, Index};
<|endoftext|>


<commit_before>extern crate byteorder;

use std::io::{Result, Write, ErrorKind, Error};
use byteorder::{ReadBytesExt, LittleEndian, WriteBytesExt};

pub struct Triangle {
    normal: [f32; 3],
    v1: [f32; 3],
    v2: [f32; 3],
    v3: [f32; 3],
    attr_byte_count: u16
}

fn point_eq(lhs: [f32; 3], rhs: [f32; 3]) -> bool {
    lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2]
}

impl PartialEq for Triangle {
    fn eq(&self, rhs: &Triangle) -> bool {
        point_eq(self.normal, rhs.normal)
            && point_eq(self.v1, rhs.v1)
            && point_eq(self.v2, rhs.v2)
            && point_eq(self.v3, rhs.v3)
            && self.attr_byte_count == rhs.attr_byte_count
    }
}

impl Eq for Triangle {}

pub struct BinaryStlHeader {
    pub header: [u8; 80],
    pub num_triangles: u32
}

pub struct BinaryStlFile {
    pub header: BinaryStlHeader,
    pub triangles: Vec<Triangle>
}

fn read_point<T: ReadBytesExt>(input: &mut T) -> Result<[f32; 3]> {
    let x1 = try!(input.read_f32::<LittleEndian>());
    let x2 = try!(input.read_f32::<LittleEndian>());
    let x3 = try!(input.read_f32::<LittleEndian>());

    Ok([x1, x2, x3])
}

fn read_triangle<T: ReadBytesExt>(input: &mut T) -> Result<Triangle> {
    let normal = try!(read_point(input));
    let v1 = try!(read_point(input));
    let v2 = try!(read_point(input));
    let v3 = try!(read_point(input));
    let attr_count = try!(input.read_u16::<LittleEndian>());

    Ok(Triangle { normal: normal,
                  v1: v1, v2: v2, v3: v3,
                  attr_byte_count: attr_count })
}

fn read_header<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlHeader> {
    let mut header = [0u8; 80];

    match input.read(&mut header) {
        Ok(n) => if n == header.len() {
            ()
        }
        else {
            return Err(Error::new(ErrorKind::Other,
                                  "Couldn't read STL header"));
        },
        Err(e) => return Err(e)
    };

    let num_triangles = try!(input.read_u32::<LittleEndian>());

    Ok(BinaryStlHeader{ header: header, num_triangles: num_triangles })
}

pub fn read_stl<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlFile> {

    // read the header
    let header = try!(read_header(input));

    let mut triangles = Vec::new();
    for _ in 0 .. header.num_triangles {
        triangles.push(try!(read_triangle(input)));
    }

    Ok(BinaryStlFile {
        header: header,
        triangles: triangles
    })
}

fn write_point<T: WriteBytesExt>(out: &mut T, p: [f32; 3]) -> Result<()> {
    for x in p.iter() {
        try!(out.write_f32::<LittleEndian>(*x));
    }
    Ok(())
}

pub fn write_stl<T: WriteBytesExt>(out: &mut T,
                                   stl: &BinaryStlFile) -> Result<()> {
    assert!(stl.header.num_triangles as usize == stl.triangles.len());

    //write the header.
    try!(out.write(&stl.header.header));
    try!(out.write_u32::<LittleEndian>(stl.header.num_triangles));

    // write all the triangles
    for t in stl.triangles.iter() {
        try!(write_point(out, t.normal));
        try!(write_point(out, t.v1));
        try!(write_point(out, t.v2));
        try!(write_point(out, t.v3));
        try!(out.write_u16::<LittleEndian>(t.attr_byte_count));
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use super::{BinaryStlFile, BinaryStlHeader, write_stl, read_stl, Triangle};
    use std::io::Cursor;
    #[test]
    fn write_read() {
        // Make sure we can write and read a simple file.
        let file = BinaryStlFile {
            header: BinaryStlHeader { header: [0u8; 80],
                                      num_triangles: 1 },
            triangles: vec![Triangle { normal: [0f32, 1f32, 0f32],
                                       v1: [0f32, 0f32, 0f32],
                                       v2: [0f32, 0f32, 1f32],
                                       v3: [1f32, 0f32, 1f32],
                                       attr_byte_count: 0 }]
        };

        let mut buffer = Vec::new();

        match write_stl(&mut buffer, &file) {
            Ok(_) => (),
            Err(_) => panic!()
        }

        match read_stl(&mut Cursor::new(buffer)) {
            Ok(stl) => {
                assert!(stl.header.num_triangles == file.header.num_triangles);
                assert!(stl.triangles.len() == 1);
                assert!(stl.triangles[0] == file.triangles[0])
            },
            Err(_) => panic!()
        }
    }
}
<commit_msg>fix clippy lints<commit_after>extern crate byteorder;

use std::io::{Result, Write, ErrorKind, Error};
use byteorder::{ReadBytesExt, LittleEndian, WriteBytesExt};

pub struct Triangle {
    normal: [f32; 3],
    v1: [f32; 3],
    v2: [f32; 3],
    v3: [f32; 3],
    attr_byte_count: u16
}

fn point_eq(lhs: [f32; 3], rhs: [f32; 3]) -> bool {
    lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2]
}

impl PartialEq for Triangle {
    fn eq(&self, rhs: &Triangle) -> bool {
        point_eq(self.normal, rhs.normal)
            && point_eq(self.v1, rhs.v1)
            && point_eq(self.v2, rhs.v2)
            && point_eq(self.v3, rhs.v3)
            && self.attr_byte_count == rhs.attr_byte_count
    }
}

impl Eq for Triangle {}

pub struct BinaryStlHeader {
    pub header: [u8; 80],
    pub num_triangles: u32
}

pub struct BinaryStlFile {
    pub header: BinaryStlHeader,
    pub triangles: Vec<Triangle>
}

fn read_point<T: ReadBytesExt>(input: &mut T) -> Result<[f32; 3]> {
    let x1 = try!(input.read_f32::<LittleEndian>());
    let x2 = try!(input.read_f32::<LittleEndian>());
    let x3 = try!(input.read_f32::<LittleEndian>());

    Ok([x1, x2, x3])
}

fn read_triangle<T: ReadBytesExt>(input: &mut T) -> Result<Triangle> {
    let normal = try!(read_point(input));
    let v1 = try!(read_point(input));
    let v2 = try!(read_point(input));
    let v3 = try!(read_point(input));
    let attr_count = try!(input.read_u16::<LittleEndian>());

    Ok(Triangle { normal: normal,
                  v1: v1, v2: v2, v3: v3,
                  attr_byte_count: attr_count })
}

fn read_header<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlHeader> {
    let mut header = [0u8; 80];

    match input.read(&mut header) {
        Ok(n) => if n == header.len() {
            ()
        }
        else {
            return Err(Error::new(ErrorKind::Other,
                                  "Couldn't read STL header"));
        },
        Err(e) => return Err(e)
    };

    let num_triangles = try!(input.read_u32::<LittleEndian>());

    Ok(BinaryStlHeader{ header: header, num_triangles: num_triangles })
}

pub fn read_stl<T: ReadBytesExt>(input: &mut T) -> Result<BinaryStlFile> {

    // read the header
    let header = try!(read_header(input));

    let mut triangles = Vec::new();
    for _ in 0 .. header.num_triangles {
        triangles.push(try!(read_triangle(input)));
    }

    Ok(BinaryStlFile {
        header: header,
        triangles: triangles
    })
}

fn write_point<T: WriteBytesExt>(out: &mut T, p: [f32; 3]) -> Result<()> {
    for x in &p {
        try!(out.write_f32::<LittleEndian>(*x));
    }
    Ok(())
}

pub fn write_stl<T: WriteBytesExt>(out: &mut T,
                                   stl: &BinaryStlFile) -> Result<()> {
    assert_eq!(stl.header.num_triangles as usize, stl.triangles.len());

    //write the header.
    try!(out.write_all(&stl.header.header));
    try!(out.write_u32::<LittleEndian>(stl.header.num_triangles));

    // write all the triangles
    for t in &stl.triangles {
        try!(write_point(out, t.normal));
        try!(write_point(out, t.v1));
        try!(write_point(out, t.v2));
        try!(write_point(out, t.v3));
        try!(out.write_u16::<LittleEndian>(t.attr_byte_count));
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use super::{BinaryStlFile, BinaryStlHeader, write_stl, read_stl, Triangle};
    use std::io::Cursor;
    #[test]
    fn write_read() {
        // Make sure we can write and read a simple file.
        let file = BinaryStlFile {
            header: BinaryStlHeader { header: [0u8; 80],
                                      num_triangles: 1 },
            triangles: vec![Triangle { normal: [0f32, 1f32, 0f32],
                                       v1: [0f32, 0f32, 0f32],
                                       v2: [0f32, 0f32, 1f32],
                                       v3: [1f32, 0f32, 1f32],
                                       attr_byte_count: 0 }]
        };

        let mut buffer = Vec::new();

        match write_stl(&mut buffer, &file) {
            Ok(_) => (),
            Err(_) => panic!()
        }

        match read_stl(&mut Cursor::new(buffer)) {
            Ok(stl) => {
                assert!(stl.header.num_triangles == file.header.num_triangles);
                assert!(stl.triangles.len() == 1);
                assert!(stl.triangles[0] == file.triangles[0])
            },
            Err(_) => panic!()
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// 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.

use std::collections::HashMap;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

#[derive(RustcDecodable)]
pub struct CrateInfo {
    pub name: String,
    pub vers: String,
    pub deps: Vec<DepInfo>,
    pub cksum: String,
    pub features: HashMap<String, Vec<String>>,
    pub yanked: bool,
}

#[derive(RustcDecodable)]
pub struct DepInfo {
    pub name: String,
    pub req: String,
    pub features: Vec<String>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<String>,
    pub kind: Option<String>
}

pub struct CratesIndex {
    path: PathBuf,
}

impl CratesIndex {
    /// Construct a new CratesIndex supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> CratesIndex {
        CratesIndex{path: path}
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Clones the index to the path specified from the constructor
    pub fn clone(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    /// Returns all the `.json` files in the index
    pub fn json_paths(&self) -> Vec<PathBuf> {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;

        let glob_pattern = format!("{}/*/*/*", self.path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", self.path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let index_paths = index_paths1.chain(index_paths2);
        index_paths.map(|glob_result| glob_result.unwrap()).collect()
    }

    /// Generates a map of dependencies where the keys are crate names and the values are vectors
    /// of crate names that are its dependencies
    pub fn dependency_map(&self) -> HashMap<String, Vec<String>> {
        let mut map = HashMap::new();
        for index_path in self.json_paths() {
            let file = fs::File::open(&index_path).unwrap();

            // Each line of the file is a different published version of the crate, and the last
            // line is the latest version
            let last_line = BufReader::new(file).lines().last().unwrap().unwrap();

            let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
            let mut deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect::<Vec<_>>();
            deps_names.sort_by(|a, b| a.cmp(b));
            deps_names.dedup();
            map.insert(crate_info.name, deps_names);
        }

        map
    }
}

#[test]
fn test_dependencies() {
    let index = CratesIndex::new("_test".into());
    if !index.exists() {
        index.clone().unwrap();
    }
}
<commit_msg>Add Crate struct representing all crate versions<commit_after>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// 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.

use std::ascii::AsciiExt;
use std::collections::HashMap;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

#[derive(RustcDecodable)]
pub struct CrateInfo {
    pub name: String,
    pub vers: String,
    pub deps: Vec<DepInfo>,
    pub cksum: String,
    pub features: HashMap<String, Vec<String>>,
    pub yanked: bool,
}

#[derive(RustcDecodable)]
pub struct DepInfo {
    pub name: String,
    pub req: String,
    pub features: Vec<String>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<String>,
    pub kind: Option<String>
}

pub struct CratesIndex {
    path: PathBuf,
}

impl CratesIndex {
    /// Construct a new CratesIndex supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> CratesIndex {
        CratesIndex{path: path}
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Clones the index to the path specified from the constructor
    pub fn clone(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    pub fn crate_(&self, crate_name: &str) -> Option<Crate> {
        self.json_paths()
            .iter()
            .find(|path| path.file_name().unwrap().to_str().unwrap().eq_ignore_ascii_case(crate_name))
            .map(Crate::from_index_path)
    }

    /// Returns all the `.json` files in the index
    pub fn json_paths(&self) -> Vec<PathBuf> {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;

        let glob_pattern = format!("{}/*/*/*", self.path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", self.path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let index_paths = index_paths1.chain(index_paths2);
        index_paths.map(|glob_result| glob_result.unwrap()).collect()
    }

    /// Generates a map of dependencies where the keys are crate names and the values are vectors
    /// of crate names that are its dependencies
    pub fn dependency_map(&self) -> HashMap<String, Vec<String>> {
        let mut map = HashMap::new();
        for index_path in self.json_paths() {
            let file = fs::File::open(&index_path).unwrap();

            // Each line of the file is a different published version of the crate, and the last
            // line is the latest version
            let last_line = BufReader::new(file).lines().last().unwrap().unwrap();

            let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
            let mut deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect::<Vec<_>>();
            deps_names.sort_by(|a, b| a.cmp(b));
            deps_names.dedup();
            map.insert(crate_info.name, deps_names);
        }

        map
    }
}

pub struct Crate {
    infos: Vec<CrateInfo>,
}

impl Crate {
    pub fn from_index_path(index_path: &PathBuf) -> Crate {
        let mut infos = vec![];
        let file = fs::File::open(&index_path).unwrap();
        for line in BufReader::new(file).lines() {
            let info: CrateInfo = rustc_serialize::json::decode(&line.unwrap()).unwrap();
            infos.push(info);
        }
        Crate {infos: infos}
    }
}

#[test]
fn test_dependencies() {
    let index = CratesIndex::new("_test".into());
    if !index.exists() {
        index.clone().unwrap();
    }
}
<|endoftext|>