<commit_before>extern crate libc;

pub mod groonga;

use libc::funcs::c95::string;
use std::ffi::CString;
use std::fs;
use std::mem;
use std::ptr;
use std::result::Result;
use std::result::Result::{Ok, Err};

#[derive(Debug)]
pub struct Error {
    code: i32
}

impl Error {
    pub fn new(code: i32) -> Error {
        Error {code: code}
    }
}

pub struct Groonga {
    closed: bool
}

impl Groonga {
    pub fn new() -> Result<Groonga, Error> {
        unsafe {
            let rc =  groonga::grn_init();
            if rc != groonga::GRN_SUCCESS {
                return Err(Error::new(rc))
            }
            Ok(Groonga{ closed: false })
        }
    }

    pub fn close(&mut self) -> Result<(), Error> {
        if self.closed {
            return Ok(())
        }
        unsafe {
            let rc = groonga::grn_fin();
            if rc != groonga::GRN_SUCCESS {
                return Err(Error::new(rc))
            }
            self.closed = true;
            Ok(())
        }
    }
}

impl Drop for Groonga {
    fn drop(&mut self) {
        self.close().unwrap()
    }
}

pub struct Context {
    ctx: *mut groonga::grn_ctx,
    db: *mut groonga::grn_obj,
}

pub struct Obj {
    obj: *mut groonga::grn_obj,
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            if !self.db.is_null() {
                groonga::grn_obj_unlink(self.ctx, self.db);
            }

            let rc2 = groonga::grn_ctx_fin(self.ctx);
            if rc2 != groonga::GRN_SUCCESS {
                panic!("grn_ctx_fin(ctx) failed with rc2={}", rc2);
            }
        }
    }
}

impl Context {
    pub fn new() -> Result<Context, Error> {
        unsafe {
            let ctx = groonga::grn_ctx_open(0);
            if ctx.is_null() {
                return Err(Error::new(groonga::GRN_NO_MEMORY_AVAILABLE))
            }
            Ok(Context { ctx: ctx, db: mem::zeroed() })
        }
    }

    pub fn db_create(&mut self, path: &str) -> Result<(), Error> {
        let c_path = CString::new(path).unwrap();
        unsafe {
            self.db = groonga::grn_db_create(
                self.ctx, c_path.as_ptr(), mem::zeroed());
            if self.db.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(())
        }
    }

    pub fn db_open(&mut self, path: &str) -> Result<(), Error> {
        let c_path = CString::new(path).unwrap();
        unsafe {
            self.db = groonga::grn_db_open(self.ctx, c_path.as_ptr());
            if self.db.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(())
        }
    }

    pub fn db_open_or_create(&mut self, path: &str) -> Result<(), Error> {
        if file_exists(path) {
            self.db_open(path)
        } else {
            self.db_create(path)
        }
    }

    pub fn ctx_at(&mut self, id: u32) -> Result<Obj, Error> {
        unsafe {
            let obj = groonga::grn_ctx_at(self.ctx, id);
            if obj.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Obj { obj: obj })
        }
    }

    pub fn ctx_get(&mut self, name: &str) -> Result<Obj, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        unsafe {
            let obj = groonga::grn_ctx_get(
                self.ctx, c_name, string::strlen(c_name) as i32);
            if obj.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Obj { obj: obj })
        }
    }

    pub fn table_create(&mut self, name: &str, path: &str, flags: u32,
        key_type: &Obj, value_type: Option<&Obj>) -> Result<Obj, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        let c_path = if path != "" {
            CString::new(path).unwrap().as_ptr()
        } else {
            ptr::null()
        };
        unsafe {
            let c_value_type =
                match value_type {
                    Some(value_type_obj) => value_type_obj.obj,
                    None => mem::zeroed(),
                };
            let table = groonga::grn_table_create(
                self.ctx, c_name, string::strlen(c_name) as u32, c_path,
                flags as u16, key_type.obj, c_value_type);
            if table.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Obj { obj: table })
        }
    }

    pub fn table_open_or_create(&mut self, name: &str, path: &str, flags: u32,
        key_type: &Obj, value_type: Option<&Obj>) -> Result<Obj, Error> {
        if let Ok(table) = self.ctx_get(name) {
            Ok(table)
        } else {
            self.table_create(name, path, flags,
                key_type, value_type)
        }
    }

    pub fn obj_column(&mut self, table: &Obj, name: &str)
        -> Result<Obj, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        unsafe {
            let obj = groonga::grn_obj_column(
                self.ctx, table.obj, c_name, string::strlen(c_name) as u32);
            if obj.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Obj { obj: obj })
        }
    }

    pub fn column_create(&mut self, table: &Obj, name: &str, path: &str,
        flags: u32, _type: &Obj) -> Result<Obj, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        let c_path = if path != "" {
            CString::new(path).unwrap().as_ptr()
        } else {
            ptr::null()
        };
        unsafe {
            let column = groonga::grn_column_create(
                self.ctx, table.obj, c_name, string::strlen(c_name) as u32,
                c_path, flags as u16, _type.obj);
            if column.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Obj { obj: column })
        }
    }

    pub fn column_open_or_create(&mut self, table: &Obj, name: &str,
        path: &str, flags: u32, _type: &Obj) -> Result<Obj, Error> {
        if let Ok(column) = self.obj_column(&table, name) {
            Ok(column)
        } else {
            self.column_create(&table, name, path, flags, _type)
        }
    }
}

fn file_exists(path: &str) -> bool {
    match fs::File::open(path) {
        Ok(_) => true,
        Err(_) => false,
    }
}
<commit_msg>Rename Obj to Object<commit_after>extern crate libc;

pub mod groonga;

use libc::funcs::c95::string;
use std::ffi::CString;
use std::fs;
use std::mem;
use std::ptr;
use std::result::Result;
use std::result::Result::{Ok, Err};

#[derive(Debug)]
pub struct Error {
    code: i32
}

impl Error {
    pub fn new(code: i32) -> Error {
        Error {code: code}
    }
}

pub struct Groonga {
    closed: bool
}

impl Groonga {
    pub fn new() -> Result<Groonga, Error> {
        unsafe {
            let rc =  groonga::grn_init();
            if rc != groonga::GRN_SUCCESS {
                return Err(Error::new(rc))
            }
            Ok(Groonga{ closed: false })
        }
    }

    pub fn close(&mut self) -> Result<(), Error> {
        if self.closed {
            return Ok(())
        }
        unsafe {
            let rc = groonga::grn_fin();
            if rc != groonga::GRN_SUCCESS {
                return Err(Error::new(rc))
            }
            self.closed = true;
            Ok(())
        }
    }
}

impl Drop for Groonga {
    fn drop(&mut self) {
        self.close().unwrap()
    }
}

pub struct Context {
    ctx: *mut groonga::grn_ctx,
    db: *mut groonga::grn_obj,
}

pub struct Object {
    obj: *mut groonga::grn_obj,
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            if !self.db.is_null() {
                groonga::grn_obj_unlink(self.ctx, self.db);
            }

            let rc2 = groonga::grn_ctx_fin(self.ctx);
            if rc2 != groonga::GRN_SUCCESS {
                panic!("grn_ctx_fin(ctx) failed with rc2={}", rc2);
            }
        }
    }
}

impl Context {
    pub fn new() -> Result<Context, Error> {
        unsafe {
            let ctx = groonga::grn_ctx_open(0);
            if ctx.is_null() {
                return Err(Error::new(groonga::GRN_NO_MEMORY_AVAILABLE))
            }
            Ok(Context { ctx: ctx, db: mem::zeroed() })
        }
    }

    pub fn db_create(&mut self, path: &str) -> Result<(), Error> {
        let c_path = CString::new(path).unwrap();
        unsafe {
            self.db = groonga::grn_db_create(
                self.ctx, c_path.as_ptr(), mem::zeroed());
            if self.db.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(())
        }
    }

    pub fn db_open(&mut self, path: &str) -> Result<(), Error> {
        let c_path = CString::new(path).unwrap();
        unsafe {
            self.db = groonga::grn_db_open(self.ctx, c_path.as_ptr());
            if self.db.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(())
        }
    }

    pub fn db_open_or_create(&mut self, path: &str) -> Result<(), Error> {
        if file_exists(path) {
            self.db_open(path)
        } else {
            self.db_create(path)
        }
    }

    pub fn ctx_at(&mut self, id: u32) -> Result<Object, Error> {
        unsafe {
            let obj = groonga::grn_ctx_at(self.ctx, id);
            if obj.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Object { obj: obj })
        }
    }

    pub fn ctx_get(&mut self, name: &str) -> Result<Object, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        unsafe {
            let obj = groonga::grn_ctx_get(
                self.ctx, c_name, string::strlen(c_name) as i32);
            if obj.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Object { obj: obj })
        }
    }

    pub fn table_create(&mut self, name: &str, path: &str, flags: u32,
        key_type: &Object, value_type: Option<&Object>) -> Result<Object, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        let c_path = if path != "" {
            CString::new(path).unwrap().as_ptr()
        } else {
            ptr::null()
        };
        unsafe {
            let c_value_type =
                match value_type {
                    Some(value_type_obj) => value_type_obj.obj,
                    None => mem::zeroed(),
                };
            let table = groonga::grn_table_create(
                self.ctx, c_name, string::strlen(c_name) as u32, c_path,
                flags as u16, key_type.obj, c_value_type);
            if table.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Object { obj: table })
        }
    }

    pub fn table_open_or_create(&mut self, name: &str, path: &str, flags: u32,
        key_type: &Object, value_type: Option<&Object>) -> Result<Object, Error> {
        if let Ok(table) = self.ctx_get(name) {
            Ok(table)
        } else {
            self.table_create(name, path, flags,
                key_type, value_type)
        }
    }

    pub fn obj_column(&mut self, table: &Object, name: &str)
        -> Result<Object, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        unsafe {
            let obj = groonga::grn_obj_column(
                self.ctx, table.obj, c_name, string::strlen(c_name) as u32);
            if obj.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Object { obj: obj })
        }
    }

    pub fn column_create(&mut self, table: &Object, name: &str, path: &str,
        flags: u32, _type: &Object) -> Result<Object, Error> {
        let c_name = CString::new(name).unwrap().as_ptr();
        let c_path = if path != "" {
            CString::new(path).unwrap().as_ptr()
        } else {
            ptr::null()
        };
        unsafe {
            let column = groonga::grn_column_create(
                self.ctx, table.obj, c_name, string::strlen(c_name) as u32,
                c_path, flags as u16, _type.obj);
            if column.is_null() {
                return Err(Error::new((*self.ctx).rc))
            }
            Ok(Object { obj: column })
        }
    }

    pub fn column_open_or_create(&mut self, table: &Object, name: &str,
        path: &str, flags: u32, _type: &Object) -> Result<Object, Error> {
        if let Ok(column) = self.obj_column(&table, name) {
            Ok(column)
        } else {
            self.column_create(&table, name, path, flags, _type)
        }
    }
}

fn file_exists(path: &str) -> bool {
    match fs::File::open(path) {
        Ok(_) => true,
        Err(_) => false,
    }
}
<|endoftext|>


<commit_before>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

use std::cmp::Ord;
use std::option::{None, Option, Some};
use std::to_string::ToString;

/// Four
struct Four<V: ToString+Ord>(V, V, V, Option<(Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>)>);

impl <V: ToString+Ord> Four<V> {

    fn from_leaf_3node_and_value(node: LeafThree<V>, value: V) -> Four<V> {
        let LeafThree(value1, value2) = node;

        if value > value2      { Four(value1, value2, value, None) }
        else if value < value1 { Four(value, value1, value2, None) }
        else                   { Four(value1, value, value2, None) }
    }

    /// Convert a Split into a TwoNode with the middle value as the value of the new parent node
    fn to_two(self) -> Two<V> {
        match self {
            Four(v1, v2, v3, None) =>
                Two(v2,
                    box LeafTwoNode(LeafTwo(v1)),
                    box LeafTwoNode(LeafTwo(v3))),
            Four(v1, v2, v3, Some((n1, n2, n3, n4))) =>
                Two(v2,
                    box TwoNode(Two(v1, n1, n2)),
                    box TwoNode(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: ToString+Ord> {
    Fit(Node<V>),  // box this node?
    Split(Four<V>),  // split should always contain a ThreeNode/LeafThreeNode. box this?
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: ToString+Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Two<V> {
    fn to_node(self) -> Node<V> { TwoNode(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }
}

/// Three
pub struct Three<V: ToString+Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Three<V> {
    fn to_node(self) -> Node<V> { ThreeNode(self) }

    fn to_four(self, other_value: V, other_node: Box<Node<V>>) -> Four<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            Four(other_value, self_value1, self_value2, Some((other_node, self_left, self_middle, self_right)))
        } else {
            Four(self_value1, self_value2, other_value, Some((self_left, self_middle, self_right, other_node)))
        }
    }
}

/// LeafTwo
pub struct LeafTwo<V: ToString+Ord>(pub V);

/// LeafThree
pub struct LeafThree<V: ToString+Ord>(pub V, pub V);

/// Node
pub enum Node<V: ToString+Ord> {
    LeafTwoNode(LeafTwo<V>),
    LeafThreeNode(LeafThree<V>),
    TwoNode(Two<V>),
    ThreeNode(Three<V>),
}

impl <V: ToString+Ord> ToString for Node<V> {
    fn to_string(&self) -> String {
        match *self {
            LeafTwoNode(LeafTwo(ref v)) => format!("LeafTwoNode({:s})", v.to_string()),
            LeafThreeNode(LeafThree(ref v1, ref v2)) => format!("LeafThreeNode({:s}, {:s})", v1.to_string(), v2.to_string()),
            TwoNode(Two(ref v, ref left, ref middle)) => format!("TwoNode({:s}, {:s}, {:s})", v.to_string(), left.to_string(), middle.to_string()),
            ThreeNode(Three(_, _, ref left, ref middle, ref right)) => format!("ThreeNode({:s}, {:s}, {:s})", left.to_string(), middle.to_string(), right.to_string()),
        }
    }
}

impl <V: ToString+Ord> Node<V> {
    // PRIVATE

    fn next_direction(&self, to_insert: &V) -> Direction {
        match self {
            &TwoNode(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            &ThreeNode(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn contains_node(&self, to_check: &V) -> bool {
        match self {
            &TwoNode(Two(ref v, _, _)) |
                &LeafTwoNode(LeafTwo(ref v)) if to_check == v => true,

            &ThreeNode(Three(ref v1, ref v2, _, _, _)) |
                &LeafThreeNode(LeafThree(ref v1, ref v2)) if to_check == v1 || to_check == v2 => true,

            _ => false
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.contains_node(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            LeafTwoNode(LeafTwo(value)) => {
                let (smaller, larger) =
                    if value < to_insert { (value, to_insert) }
                    else                 { (to_insert, value) };
                let new_node = LeafThreeNode(LeafThree(smaller, larger));
                Fit(new_node)
            },

            // Split if leaf ThreeNode
            LeafThreeNode(leaf_three) => {
                let four_node = Four::from_leaf_3node_and_value(leaf_three, to_insert);
                Split(four_node)
            },

            // Recurse down if internal Node and handle results
            TwoNode(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => fail!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left => Two(value, box returned_node, box other_node).to_node(),
                            Middle => Two(value, box other_node, box returned_node).to_node(),
                            _ => fail!(""),
                        },
                    Split(four_node) => four_node.to_two().to_three(value, box other_node).to_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            ThreeNode(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => fail!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let new_node = match next_direction {
                            Left => ThreeNode(Three(value1, value2, box returned_node, other_node1, other_node2)),
                            Middle => ThreeNode(Three(value1, value2, other_node1, box returned_node, other_node2)),
                            Right => ThreeNode(Three(value1, value2, other_node1, other_node2, box returned_node)),
                            _ => fail!(""),
                        };
                        Fit(new_node)
                    },
                    Split(four_node) => {
                        let new_node: Four<V> = match next_direction {
                            Left => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Middle => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Right => four_node.to_two().to_three(value2, other_node2).to_four(value1, other_node1),
                            _ => fail!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: ToString+Ord> {
    pub root: Option<Node<V>>,
}

impl <V: ToString+Ord> ToString for TTTree<V> {
    fn to_string(&self) -> String {
        match self.root {
            Some(ref node) => node.to_string(),
            None => "TTTree(<empty>)".to_string(),
        }
    }
}

impl <V: ToString+Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => LeafTwoNode(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(node @ Four(..)) => node.to_two().to_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}

// TODO:
// Collection trait
// convert this to Key/Value K/V
// remove ToString debugging stuffs
<commit_msg>Convert static constructor to method<commit_after>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

use std::cmp::Ord;
use std::option::{None, Option, Some};
use std::to_string::ToString;

/// Four
struct Four<V: ToString+Ord>(V, V, V, Option<(Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>)>);

impl <V: ToString+Ord> Four<V> {

    /// Convert a Split into a TwoNode with the middle value as the value of the new parent node
    fn to_two(self) -> Two<V> {
        match self {
            Four(v1, v2, v3, None) =>
                Two(v2,
                    box LeafTwoNode(LeafTwo(v1)),
                    box LeafTwoNode(LeafTwo(v3))),
            Four(v1, v2, v3, Some((n1, n2, n3, n4))) =>
                Two(v2,
                    box TwoNode(Two(v1, n1, n2)),
                    box TwoNode(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: ToString+Ord> {
    Fit(Node<V>),  // box this node?
    Split(Four<V>),  // split should always contain a ThreeNode/LeafThreeNode. box this?
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: ToString+Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Two<V> {
    fn to_node(self) -> Node<V> { TwoNode(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }
}

/// Three
pub struct Three<V: ToString+Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: ToString+Ord> Three<V> {
    fn to_node(self) -> Node<V> { ThreeNode(self) }

    fn to_four(self, other_value: V, other_node: Box<Node<V>>) -> Four<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            Four(other_value, self_value1, self_value2, Some((other_node, self_left, self_middle, self_right)))
        } else {
            Four(self_value1, self_value2, other_value, Some((self_left, self_middle, self_right, other_node)))
        }
    }
}

/// LeafTwo
pub struct LeafTwo<V: ToString+Ord>(pub V);

/// LeafThree
pub struct LeafThree<V: ToString+Ord>(pub V, pub V);

impl <V: ToString+Ord> LeafThree<V> {
    fn to_four(self, value: V) -> Four<V> {
        let LeafThree(value1, value2) = self;
        if value > value2      { Four(value1, value2, value, None) }
        else if value < value1 { Four(value, value1, value2, None) }
        else                   { Four(value1, value, value2, None) }
    }
}

/// Node
pub enum Node<V: ToString+Ord> {
    LeafTwoNode(LeafTwo<V>),
    LeafThreeNode(LeafThree<V>),
    TwoNode(Two<V>),
    ThreeNode(Three<V>),
}

impl <V: ToString+Ord> ToString for Node<V> {
    fn to_string(&self) -> String {
        match *self {
            LeafTwoNode(LeafTwo(ref v)) => format!("LeafTwoNode({:s})", v.to_string()),
            LeafThreeNode(LeafThree(ref v1, ref v2)) => format!("LeafThreeNode({:s}, {:s})", v1.to_string(), v2.to_string()),
            TwoNode(Two(ref v, ref left, ref middle)) => format!("TwoNode({:s}, {:s}, {:s})", v.to_string(), left.to_string(), middle.to_string()),
            ThreeNode(Three(_, _, ref left, ref middle, ref right)) => format!("ThreeNode({:s}, {:s}, {:s})", left.to_string(), middle.to_string(), right.to_string()),
        }
    }
}

impl <V: ToString+Ord> Node<V> {
    // PRIVATE

    fn next_direction(&self, to_insert: &V) -> Direction {
        match self {
            &TwoNode(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            &ThreeNode(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn contains_node(&self, to_check: &V) -> bool {
        match self {
            &TwoNode(Two(ref v, _, _)) |
                &LeafTwoNode(LeafTwo(ref v)) if to_check == v => true,

            &ThreeNode(Three(ref v1, ref v2, _, _, _)) |
                &LeafThreeNode(LeafThree(ref v1, ref v2)) if to_check == v1 || to_check == v2 => true,

            _ => false
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.contains_node(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            LeafTwoNode(LeafTwo(value)) => {
                let (smaller, larger) =
                    if value < to_insert { (value, to_insert) }
                    else                 { (to_insert, value) };
                let new_node = LeafThreeNode(LeafThree(smaller, larger));
                Fit(new_node)
            },

            // Split if leaf ThreeNode
            LeafThreeNode(leaf_three) => {
                let four_node = leaf_three.to_four(to_insert);
                Split(four_node)
            },

            // Recurse down if internal Node and handle results
            TwoNode(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => fail!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left => Two(value, box returned_node, box other_node).to_node(),
                            Middle => Two(value, box other_node, box returned_node).to_node(),
                            _ => fail!(""),
                        },
                    Split(four_node) => four_node.to_two().to_three(value, box other_node).to_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            ThreeNode(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => fail!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let new_node = match next_direction {
                            Left => ThreeNode(Three(value1, value2, box returned_node, other_node1, other_node2)),
                            Middle => ThreeNode(Three(value1, value2, other_node1, box returned_node, other_node2)),
                            Right => ThreeNode(Three(value1, value2, other_node1, other_node2, box returned_node)),
                            _ => fail!(""),
                        };
                        Fit(new_node)
                    },
                    Split(four_node) => {
                        let new_node: Four<V> = match next_direction {
                            Left => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Middle => four_node.to_two().to_three(value1, other_node1).to_four(value2, other_node2),
                            Right => four_node.to_two().to_three(value2, other_node2).to_four(value1, other_node1),
                            _ => fail!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: ToString+Ord> {
    pub root: Option<Node<V>>,
}

impl <V: ToString+Ord> ToString for TTTree<V> {
    fn to_string(&self) -> String {
        match self.root {
            Some(ref node) => node.to_string(),
            None => "TTTree(<empty>)".to_string(),
        }
    }
}

impl <V: ToString+Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => LeafTwoNode(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(node @ Four(..)) => node.to_two().to_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}

// TODO:
// Collection trait
// convert this to Key/Value K/V
// remove ToString debugging stuffs
<|endoftext|>


<commit_before>//! Receive, parse, store, and retrieve Iridium Short Burst Data (SBD) messages.
//!
//! Iridium is both a [satellite constellation](https://en.wikipedia.org/wiki/Iridium_satellite_constellation)
//! and a [company](https://en.wikipedia.org/wiki/Iridium_Communications) that provides satellite
//! communications. The Iridium network is used by phones, modems, and other communication devices.
//!
//! One mode of transmitting data over the Iridium network is via Short Burst Data (SBD) messages.
//! These messages carry a payload of some small number of bytes, usually less than one thousand.
//! Messages can be Mobile-Originated (MO), meaning that they are sent *from* an Iridium modem, or
//! Mobile-Terminated (MT), meaning that the are sent *to* an Iridium modem. Mobile-originated
//! messages are delivered either to an email address via MIME attachment, or directly to a given
//! IP address and port via TCP; this second method is called DirectIP.
//!
//! This is a simple library for reading SBD messages from a stream, decoding their headers and
//! data payloads, and writing them back to a stream.

pub mod information_element;
pub mod message;
pub mod mobile_originated;

extern crate byteorder;
#[macro_use]
extern crate enum_primitive;
extern crate num;

use std::result;

#[derive(Debug)]
pub enum Error {
    ByteorderError(byteorder::Error),
    IoError(std::io::Error),
    InvalidProtocolRevisionNumber(u8),
    NoMobileOriginatedHeader,
    NoMobileOriginatedPayload,
    Oversized, // Oversized doesn't demand a size since we don't want to find out how much there really is
    Undersized(usize),
}

impl From<byteorder::Error> for Error {
    fn from(err: byteorder::Error) -> Error {
        Error::ByteorderError(err)
    }
}

impl From<std::io::Error> for Error {
    fn from(err: std::io::Error) -> Error {
        Error::IoError(err)
    }
}

pub type Result<T> = result::Result<T, Error>;
<commit_msg>Reexport the three big ones<commit_after>//! Parse Iridium Short Burst Data (SBD) messages.
//!
//! Iridium is both a [satellite constellation](https://en.wikipedia.org/wiki/Iridium_satellite_constellation)
//! and a [company](https://en.wikipedia.org/wiki/Iridium_Communications) that provides satellite
//! communications. The Iridium network is used by phones, modems, and other communication devices.
//!
//! One mode of transmitting data over the Iridium network is via Short Burst Data (SBD) messages.
//! These messages carry a payload of some small number of bytes, usually less than one thousand.
//! Messages can be Mobile-Originated (MO), meaning that they are sent *from* an Iridium modem, or
//! Mobile-Terminated (MT), meaning that the are sent *to* an Iridium modem. Mobile-originated
//! messages are delivered either to an email address via MIME attachment, or directly to a given
//! IP address and port via TCP; this second method is called DirectIP.
//!
//! This is a simple library for reading SBD messages from a stream, decoding their headers and
//! data payloads, and writing them back to a stream.

pub mod information_element;
pub mod message;
pub mod mobile_originated;

pub use information_element::InformationElement;
pub use message::Message;
pub use mobile_originated::MobileOriginated;

extern crate byteorder;
#[macro_use]
extern crate enum_primitive;
extern crate num;

use std::result;

#[derive(Debug)]
pub enum Error {
    ByteorderError(byteorder::Error),
    IoError(std::io::Error),
    InvalidProtocolRevisionNumber(u8),
    NoMobileOriginatedHeader,
    NoMobileOriginatedPayload,
    Oversized, // Oversized doesn't demand a size since we don't want to find out how much there really is
    Undersized(usize),
}

impl From<byteorder::Error> for Error {
    fn from(err: byteorder::Error) -> Error {
        Error::ByteorderError(err)
    }
}

impl From<std::io::Error> for Error {
    fn from(err: std::io::Error) -> Error {
        Error::IoError(err)
    }
}

pub type Result<T> = result::Result<T, Error>;
<|endoftext|>


<commit_before>use std::ops::*;

extern crate cgmath;

use cgmath::num_traits::*;
use cgmath::*;

use std::num::FpCategory;

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct F64Err {
    val: f64,
    err: f64,
}

impl F64Err {
    pub fn new_errorless(val: f64) -> F64Err {
        F64Err {
            val: val,
            err: 0.
        }
    }

    pub fn new(val: f64) -> F64Err {
        F64Err {
            val: val,
            err: val
        }
    }

    pub fn new_exact(val: f64, err: f64) -> F64Err {
        F64Err {
            val: val,
            err: err
        }
    }

    pub fn val(&self) -> f64 {
        self.val
    }

    pub fn err(&self) -> f64 {
        self.err
    }

    pub fn err_times_eps(&self) -> f64 {
        self.err * ::std::f64::EPSILON
    }
}

impl Mul for F64Err {
    type Output = F64Err;
    fn mul(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val * rhs.val,
            err: self.val.abs() * rhs.err + rhs.val.abs() * self.err
        }
    }
}

impl MulAssign for F64Err {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs
    }
}

impl Div for F64Err {
    type Output = F64Err;
    fn div(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val / rhs.val,
            err: self.err / rhs.val.abs() + rhs.err * self.val / (rhs.val * rhs.val)
        }
    }
}

impl DivAssign for F64Err {
    fn div_assign(&mut self, rhs: Self) {
        *self = *self / rhs
    }
}

impl Add for F64Err {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val + rhs.val,
            err: self.val.abs().max(rhs.val.abs()) + self.err + rhs.err
        }
    }
}

impl AddAssign for F64Err {
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs
    }
}

impl Sub for F64Err {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val - rhs.val,
            err: self.val.abs().max(rhs.val.abs()) + self.err + rhs.err
        }
    }
}

impl SubAssign for F64Err {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs
    }
}

impl Rem for F64Err {
    type Output = Self;
    fn rem(self, rhs: Self) -> Self::Output {
        unimplemented!();
    }
}

impl RemAssign for F64Err {
    fn rem_assign(&mut self, rhs: Self) {
        *self = *self % rhs
    }
}

impl PartialOrd for F64Err {
    fn partial_min(self, other: Self) -> Self {
        if self.val < other.val {
            self
        } else {
            other
        }
    }
    fn partial_max(self, other: Self) -> Self {
        if self.val > other.val {
            self
        } else {
            other
        }
    }
}

impl ::std::cmp::PartialOrd for F64Err {
    fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> {
        self.val.partial_cmp(&other.val)
    }
}

impl Zero for F64Err {
    fn zero() -> Self {
        Self::new_errorless(0.)
    }

    fn is_zero(&self) -> bool {
        self.val.is_zero()
    }
}

impl One for F64Err {
    fn one() -> Self {
        Self::new_errorless(1.)
    }
}

impl ToPrimitive for F64Err {
    /// Converts the value of `self` to an `isize`.
    #[inline]
    fn to_isize(&self) -> Option<isize> {
        self.val.to_isize()
    }

    /// Converts the value of `self` to an `i8`.
    #[inline]
    fn to_i8(&self) -> Option<i8> {
        self.val.to_i8()
    }

    /// Converts the value of `self` to an `i16`.
    #[inline]
    fn to_i16(&self) -> Option<i16> {
        self.val.to_i16()
    }

    /// Converts the value of `self` to an `i32`.
    #[inline]
    fn to_i32(&self) -> Option<i32> {
        self.val.to_i32()
    }

    #[inline]
    fn to_i64(&self) -> Option<i64> {
        self.val.to_i64()
    }

    /// Converts the value of `self` to a `usize`.
    #[inline]
    fn to_usize(&self) -> Option<usize> {
        self.val.to_usize()
    }

    /// Converts the value of `self` to an `u8`.
    #[inline]
    fn to_u8(&self) -> Option<u8> {
        self.val.to_u8()
    }

    /// Converts the value of `self` to an `u16`.
    #[inline]
    fn to_u16(&self) -> Option<u16> {
        self.val.to_u16()
    }

    /// Converts the value of `self` to an `u32`.
    #[inline]
    fn to_u32(&self) -> Option<u32> {
        self.val.to_u32()
    }

    /// Converts the value of `self` to an `u32`.
    #[inline]
    fn to_u64(&self) -> Option<u64> {
        self.val.to_u64()
    }

    /// Converts the value of `self` to an `f32`.
    #[inline]
    fn to_f32(&self) -> Option<f32> {
        self.val.to_f32()
    }

    /// Converts the value of `self` to an `f64`.
    #[inline]
    fn to_f64(&self) -> Option<f64> {
        self.val.to_f64()
    }
}

impl NumCast for F64Err {
    fn from<T>(t: T) -> Option<Self> {
        unimplemented!();
    }
}

impl Num for F64Err {
    type FromStrRadixErr = ParseFloatError;
    fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseFloatError> {
        //todo finish me.
        Ok(Self::new(0.))
    }
}

impl BaseNum for F64Err {}

impl ApproxEq for F64Err {
    type Epsilon = Self;
    fn default_epsilon() -> Self::Epsilon {
        unimplemented!()
    }

    fn default_max_relative() -> Self::Epsilon {
        unimplemented!()
    }

    fn default_max_ulps() -> u32 {
        unimplemented!()
    }

    fn relative_eq(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool {
        unimplemented!()
    }

    fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
        unimplemented!()
    }
}

impl Neg for F64Err {
    type Output = Self;
    fn neg(self) -> Self::Output {
        unimplemented!()
    }
}

impl Float for F64Err {
    fn nan() -> Self {
        unimplemented!()
    }

    fn infinity() -> Self {
        unimplemented!()
    }

    fn neg_infinity() -> Self {
        unimplemented!()
    }

    fn neg_zero() -> Self {
        unimplemented!()
    }

    fn min_value() -> Self {
        unimplemented!()
    }

    fn min_positive_value() -> Self {
        unimplemented!()
    }

    fn max_value() -> Self {
        unimplemented!()
    }

    fn is_nan(self) -> bool {
        unimplemented!()
    }

    fn is_infinite(self) -> bool {
        unimplemented!()
    }

    fn is_finite(self) -> bool {
        unimplemented!()
    }

    fn is_normal(self) -> bool {
        unimplemented!()
    }

    fn classify(self) -> FpCategory {
        unimplemented!()
    }

    fn floor(self) -> Self {
        unimplemented!()
    }

    fn ceil(self) -> Self {
        unimplemented!()
    }

    fn round(self) -> Self {
        unimplemented!()
    }

    fn trunc(self) -> Self {
        unimplemented!()
    }

    fn fract(self) -> Self {
        unimplemented!()
    }

    fn abs(self) -> Self {
        unimplemented!()
    }

    fn signum(self) -> Self {
        unimplemented!()
    }

    fn is_sign_positive(self) -> bool {
        unimplemented!()
    }

    fn is_sign_negative(self) -> bool {
        unimplemented!()
    }

    fn mul_add(self, a: Self, b: Self) -> Self {
        unimplemented!()
    }

    fn recip(self) -> Self {
        unimplemented!()
    }

    fn powi(self, n: i32) -> Self {
        unimplemented!()
    }

    fn powf(self, n: Self) -> Self {
        unimplemented!()
    }

    fn sqrt(self) -> Self {
        unimplemented!()
    }

    fn exp(self) -> Self {
        unimplemented!()
    }

    fn exp2(self) -> Self {
        unimplemented!()
    }

    fn ln(self) -> Self {
        unimplemented!()
    }

    fn log(self, base: Self) -> Self {
        unimplemented!()
    }

    fn log2(self) -> Self {
        unimplemented!()
    }

    fn log10(self) -> Self {
        unimplemented!()
    }

    fn max(self, other: Self) -> Self {
        unimplemented!()
    }

    fn min(self, other: Self) -> Self {
        unimplemented!()
    }

    fn abs_sub(self, other: Self) -> Self {
        unimplemented!()
    }

    fn cbrt(self) -> Self {
        unimplemented!()
    }

    fn hypot(self, other: Self) -> Self {
        unimplemented!()
    }

    fn sin(self) -> Self {
        unimplemented!()
    }

    fn cos(self) -> Self {
        unimplemented!()
    }

    fn tan(self) -> Self {
        unimplemented!()
    }

    fn asin(self) -> Self {
        unimplemented!()
    }

    fn acos(self) -> Self {
        unimplemented!()
    }

    fn atan(self) -> Self {
        unimplemented!()
    }

    fn atan2(self, other: Self) -> Self {
        unimplemented!()
    }

    fn sin_cos(self) -> (Self, Self) {
        unimplemented!()
    }

    fn exp_m1(self) -> Self {
        unimplemented!()
    }

    fn ln_1p(self) -> Self {
        unimplemented!()
    }

    fn sinh(self) -> Self {
        unimplemented!()
    }

    fn cosh(self) -> Self {
        unimplemented!()
    }

    fn tanh(self) -> Self {
        unimplemented!()
    }

    fn asinh(self) -> Self {
        unimplemented!()
    }

    fn acosh(self) -> Self {
        unimplemented!()
    }

    fn atanh(self) -> Self {
        unimplemented!()
    }

    fn integer_decode(self) -> (u64, i16, i8) {
        unimplemented!()
    }
}

impl BaseFloat for F64Err {}

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

    #[test]
    fn multiplication_error() {
        let left = F64Err::new_errorless(2.);
        let right = F64Err::new_errorless(2.);

        let res = left * right;

        assert_eq!(4., res.val());
        assert_eq!(0., res.err());
    }

    #[test]
    fn addition_error() {
        let left = F64Err::new_errorless(2.);
        let right = F64Err::new_errorless(3.);

        let res = left + right;

        assert_eq!(5., res.val());
        assert_eq!(3., res.err());
    }

    #[test]
    fn addition_then_multipl() {
        let left = F64Err::new_errorless(2.);
        let right = F64Err::new_errorless(3.);

        let res_add = left + right;
        let res_mul = res_add * left;

        assert_eq!(10., res_mul.val());
        assert_eq!(3. * 2., res_mul.err());

        let res_mul = res_mul * res_mul;

        assert_eq!(100., res_mul.val());
        assert_eq!((3. * 2.) * 10. + (3. * 2.) * 10., res_mul.err());
    }

    #[test]
    fn subtract_error() {
        let left = F64Err::new_errorless(2.);
        let right = F64Err::new_errorless(3.);

        let res = left - right;

        assert_eq!(-1., res.val());
        assert_eq!(3., res.err());

        let res = res - right;

        assert_eq!(-4., res.val());
        assert_eq!(6., res.err());
    }

    #[test]
    fn can_use_cgmath_stuff() {
        type Point2 = ::cgmath::Point2<F64Err>;

        let a = Point2::new(F64Err::new(1.), F64Err::new(0.));
        let b = Point2::new(F64Err::new(1.), F64Err::new(0.));

        let det = ::cgmath::Matrix2::new(a.x, a.y,
                               b.x, b.y).determinant();
    }
}
<commit_msg>small rename<commit_after>use std::ops::*;

extern crate cgmath;

use cgmath::num_traits::*;
use cgmath::*;

use std::num::FpCategory;

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct F64Err {
    val: f64,
    err: f64,
}

impl F64Err {
    pub fn new_errorfree(val: f64) -> F64Err {
        F64Err {
            val: val,
            err: 0.
        }
    }

    pub fn new(val: f64) -> F64Err {
        F64Err {
            val: val,
            err: val
        }
    }

    pub fn new_exact(val: f64, err: f64) -> F64Err {
        F64Err {
            val: val,
            err: err
        }
    }

    pub fn val(&self) -> f64 {
        self.val
    }

    pub fn err(&self) -> f64 {
        self.err
    }

    pub fn err_times_eps(&self) -> f64 {
        self.err * ::std::f64::EPSILON
    }
}

impl Mul for F64Err {
    type Output = F64Err;
    fn mul(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val * rhs.val,
            err: self.val.abs() * rhs.err + rhs.val.abs() * self.err
        }
    }
}

impl MulAssign for F64Err {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs
    }
}

impl Div for F64Err {
    type Output = F64Err;
    fn div(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val / rhs.val,
            err: self.err / rhs.val.abs() + rhs.err * self.val / (rhs.val * rhs.val)
        }
    }
}

impl DivAssign for F64Err {
    fn div_assign(&mut self, rhs: Self) {
        *self = *self / rhs
    }
}

impl Add for F64Err {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val + rhs.val,
            err: self.val.abs().max(rhs.val.abs()) + self.err + rhs.err
        }
    }
}

impl AddAssign for F64Err {
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs
    }
}

impl Sub for F64Err {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        F64Err {
            val: self.val - rhs.val,
            err: self.val.abs().max(rhs.val.abs()) + self.err + rhs.err
        }
    }
}

impl SubAssign for F64Err {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs
    }
}

impl Rem for F64Err {
    type Output = Self;
    fn rem(self, rhs: Self) -> Self::Output {
        unimplemented!();
    }
}

impl RemAssign for F64Err {
    fn rem_assign(&mut self, rhs: Self) {
        *self = *self % rhs
    }
}

impl PartialOrd for F64Err {
    fn partial_min(self, other: Self) -> Self {
        if self.val < other.val {
            self
        } else {
            other
        }
    }
    fn partial_max(self, other: Self) -> Self {
        if self.val > other.val {
            self
        } else {
            other
        }
    }
}

impl ::std::cmp::PartialOrd for F64Err {
    fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> {
        self.val.partial_cmp(&other.val)
    }
}

impl Zero for F64Err {
    fn zero() -> Self {
        Self::new_errorfree(0.)
    }

    fn is_zero(&self) -> bool {
        self.val.is_zero()
    }
}

impl One for F64Err {
    fn one() -> Self {
        Self::new_errorfree(1.)
    }
}

impl ToPrimitive for F64Err {
    /// Converts the value of `self` to an `isize`.
    #[inline]
    fn to_isize(&self) -> Option<isize> {
        self.val.to_isize()
    }

    /// Converts the value of `self` to an `i8`.
    #[inline]
    fn to_i8(&self) -> Option<i8> {
        self.val.to_i8()
    }

    /// Converts the value of `self` to an `i16`.
    #[inline]
    fn to_i16(&self) -> Option<i16> {
        self.val.to_i16()
    }

    /// Converts the value of `self` to an `i32`.
    #[inline]
    fn to_i32(&self) -> Option<i32> {
        self.val.to_i32()
    }

    #[inline]
    fn to_i64(&self) -> Option<i64> {
        self.val.to_i64()
    }

    /// Converts the value of `self` to a `usize`.
    #[inline]
    fn to_usize(&self) -> Option<usize> {
        self.val.to_usize()
    }

    /// Converts the value of `self` to an `u8`.
    #[inline]
    fn to_u8(&self) -> Option<u8> {
        self.val.to_u8()
    }

    /// Converts the value of `self` to an `u16`.
    #[inline]
    fn to_u16(&self) -> Option<u16> {
        self.val.to_u16()
    }

    /// Converts the value of `self` to an `u32`.
    #[inline]
    fn to_u32(&self) -> Option<u32> {
        self.val.to_u32()
    }

    /// Converts the value of `self` to an `u32`.
    #[inline]
    fn to_u64(&self) -> Option<u64> {
        self.val.to_u64()
    }

    /// Converts the value of `self` to an `f32`.
    #[inline]
    fn to_f32(&self) -> Option<f32> {
        self.val.to_f32()
    }

    /// Converts the value of `self` to an `f64`.
    #[inline]
    fn to_f64(&self) -> Option<f64> {
        self.val.to_f64()
    }
}

impl NumCast for F64Err {
    fn from<T>(t: T) -> Option<Self> {
        unimplemented!();
    }
}

impl Num for F64Err {
    type FromStrRadixErr = ParseFloatError;
    fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseFloatError> {
        unimplemented!();
    }
}

impl BaseNum for F64Err {}

impl ApproxEq for F64Err {
    type Epsilon = Self;
    fn default_epsilon() -> Self::Epsilon {
        unimplemented!()
    }

    fn default_max_relative() -> Self::Epsilon {
        unimplemented!()
    }

    fn default_max_ulps() -> u32 {
        unimplemented!()
    }

    fn relative_eq(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool {
        unimplemented!()
    }

    fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
        unimplemented!()
    }
}

impl Neg for F64Err {
    type Output = Self;
    fn neg(self) -> Self::Output {
        unimplemented!()
    }
}

impl Float for F64Err {
    fn nan() -> Self {
        unimplemented!()
    }

    fn infinity() -> Self {
        unimplemented!()
    }

    fn neg_infinity() -> Self {
        unimplemented!()
    }

    fn neg_zero() -> Self {
        unimplemented!()
    }

    fn min_value() -> Self {
        unimplemented!()
    }

    fn min_positive_value() -> Self {
        unimplemented!()
    }

    fn max_value() -> Self {
        unimplemented!()
    }

    fn is_nan(self) -> bool {
        unimplemented!()
    }

    fn is_infinite(self) -> bool {
        unimplemented!()
    }

    fn is_finite(self) -> bool {
        unimplemented!()
    }

    fn is_normal(self) -> bool {
        unimplemented!()
    }

    fn classify(self) -> FpCategory {
        unimplemented!()
    }

    fn floor(self) -> Self {
        unimplemented!()
    }

    fn ceil(self) -> Self {
        unimplemented!()
    }

    fn round(self) -> Self {
        unimplemented!()
    }

    fn trunc(self) -> Self {
        unimplemented!()
    }

    fn fract(self) -> Self {
        unimplemented!()
    }

    fn abs(self) -> Self {
        unimplemented!()
    }

    fn signum(self) -> Self {
        unimplemented!()
    }

    fn is_sign_positive(self) -> bool {
        unimplemented!()
    }

    fn is_sign_negative(self) -> bool {
        unimplemented!()
    }

    fn mul_add(self, a: Self, b: Self) -> Self {
        unimplemented!()
    }

    fn recip(self) -> Self {
        unimplemented!()
    }

    fn powi(self, n: i32) -> Self {
        unimplemented!()
    }

    fn powf(self, n: Self) -> Self {
        unimplemented!()
    }

    fn sqrt(self) -> Self {
        unimplemented!()
    }

    fn exp(self) -> Self {
        unimplemented!()
    }

    fn exp2(self) -> Self {
        unimplemented!()
    }

    fn ln(self) -> Self {
        unimplemented!()
    }

    fn log(self, base: Self) -> Self {
        unimplemented!()
    }

    fn log2(self) -> Self {
        unimplemented!()
    }

    fn log10(self) -> Self {
        unimplemented!()
    }

    fn max(self, other: Self) -> Self {
        unimplemented!()
    }

    fn min(self, other: Self) -> Self {
        unimplemented!()
    }

    fn abs_sub(self, other: Self) -> Self {
        unimplemented!()
    }

    fn cbrt(self) -> Self {
        unimplemented!()
    }

    fn hypot(self, other: Self) -> Self {
        unimplemented!()
    }

    fn sin(self) -> Self {
        unimplemented!()
    }

    fn cos(self) -> Self {
        unimplemented!()
    }

    fn tan(self) -> Self {
        unimplemented!()
    }

    fn asin(self) -> Self {
        unimplemented!()
    }

    fn acos(self) -> Self {
        unimplemented!()
    }

    fn atan(self) -> Self {
        unimplemented!()
    }

    fn atan2(self, other: Self) -> Self {
        unimplemented!()
    }

    fn sin_cos(self) -> (Self, Self) {
        unimplemented!()
    }

    fn exp_m1(self) -> Self {
        unimplemented!()
    }

    fn ln_1p(self) -> Self {
        unimplemented!()
    }

    fn sinh(self) -> Self {
        unimplemented!()
    }

    fn cosh(self) -> Self {
        unimplemented!()
    }

    fn tanh(self) -> Self {
        unimplemented!()
    }

    fn asinh(self) -> Self {
        unimplemented!()
    }

    fn acosh(self) -> Self {
        unimplemented!()
    }

    fn atanh(self) -> Self {
        unimplemented!()
    }

    fn integer_decode(self) -> (u64, i16, i8) {
        unimplemented!()
    }
}

impl BaseFloat for F64Err {}

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

    #[test]
    fn multiplication_error() {
        let left = F64Err::new_errorfree(2.);
        let right = F64Err::new_errorfree(2.);

        let res = left * right;

        assert_eq!(4., res.val());
        assert_eq!(0., res.err());
    }

    #[test]
    fn addition_error() {
        let left = F64Err::new_errorfree(2.);
        let right = F64Err::new_errorfree(3.);

        let res = left + right;

        assert_eq!(5., res.val());
        assert_eq!(3., res.err());
    }

    #[test]
    fn addition_then_multipl() {
        let left = F64Err::new_errorfree(2.);
        let right = F64Err::new_errorfree(3.);

        let res_add = left + right;
        let res_mul = res_add * left;

        assert_eq!(10., res_mul.val());
        assert_eq!(3. * 2., res_mul.err());

        let res_mul = res_mul * res_mul;

        assert_eq!(100., res_mul.val());
        assert_eq!((3. * 2.) * 10. + (3. * 2.) * 10., res_mul.err());
    }

    #[test]
    fn subtract_error() {
        let left = F64Err::new_errorfree(2.);
        let right = F64Err::new_errorfree(3.);

        let res = left - right;

        assert_eq!(-1., res.val());
        assert_eq!(3., res.err());

        let res = res - right;

        assert_eq!(-4., res.val());
        assert_eq!(6., res.err());
    }

    #[test]
    fn can_use_cgmath_stuff() {
        type Point2 = ::cgmath::Point2<F64Err>;

        let a = Point2::new(F64Err::new(1.), F64Err::new(0.));
        let b = Point2::new(F64Err::new(1.), F64Err::new(0.));

        let det = ::cgmath::Matrix2::new(a.x, a.y,
                               b.x, b.y).determinant();
    }
}
<|endoftext|>


<commit_before>//! The `gettext` crate provides functionality for
//! parsing and using Gettext catalogs stored in MO files.

// https://pascalhertleif.de/artikel/good-practices-for-writing-rust-libraries/
#![deny(missing_docs, missing_debug_implementations,
        trivial_casts, trivial_numeric_casts,
        unsafe_code, unstable_features,
        unused_import_braces, unused_qualifications)]

use std::collections::HashMap;
use std::ops::Deref;

/// Catalog represents a set of translation strings
/// parsed out of one MO file.
#[derive(Debug)]
pub struct Catalog {
    strings: HashMap<String, Message>,
}

impl Catalog {
    fn new() -> Self {
        Catalog { strings: HashMap::new() }
    }

    fn insert(&mut self, msg: Message) {
        let key = match msg.context {
            Some(ref ctxt) => [ctxt.deref(), &*msg.id].join("\x04"),
            None => msg.id.clone(),
        };
        self.strings.insert(key, msg);
    }

    /// Returns the singular translation of `msg_id` from the given catalog
    /// or `msg_id` itself if a translation does not exist.
    pub fn gettext<'a>(&'a self, msg_id: &'a str) -> &'a str {
        self.strings.get(&msg_id.to_owned()).and_then(|msg| msg.get_translated(0)).unwrap_or(msg_id)
    }

    /// Returns the plural translation of `msg_id` from the given catalog
    /// with the correct plural form for the number `n` of objects.
    /// Returns msg_id if a translation does not exist and `n == 1`,
    /// msg_id_plural otherwise.
    ///
    /// Currently, the only supported plural formula is `n != 1`.
    pub fn ngettext<'a>(&'a self, msg_id: &'a str, msg_id_plural: &'a str, n: usize) -> &'a str {
        let form_no = if n != 1 {
            1
        } else {
            0
        };

        match self.strings.get(&msg_id.to_owned()) {
            Some(msg) => {
                msg.get_translated(form_no).unwrap_or_else(|| [msg_id, msg_id_plural][form_no])
            }
            None if form_no == 0 => msg_id,
            None if form_no == 1 => msg_id_plural,
            _ => unreachable!(),
        }
    }
}

#[derive(Debug)]
struct Message {
    id: String,
    context: Option<String>,
    translated: Vec<String>,
}

impl Message {
    fn new<T: Into<String>>(id: T, context: Option<T>, translated: Vec<T>) -> Self {
        Message {
            id: id.into(),
            context: context.map(Into::into),
            translated: translated.into_iter().map(Into::into).collect(),
        }
    }

    fn get_translated(&self, form_no: usize) -> Option<&str> {
        self.translated.get(form_no).map(|s| s.deref())
    }
}

#[test]
fn catalog_insert() {
    let mut cat = Catalog::new();
    cat.insert(Message::new("thisisid", None, vec![]));
    cat.insert(Message::new("anotherid", Some("context"), vec![]));
    let mut keys = cat.strings.keys().collect::<Vec<_>>();
    keys.sort();
    assert_eq!(keys, &["context\x04anotherid", "thisisid"])
}

#[test]
fn catalog_gettext() {
    let mut cat = Catalog::new();
    cat.insert(Message::new("Text", None, vec!["Tekstas"]));
    assert_eq!(cat.gettext("Text"), "Tekstas");
    assert_eq!(cat.gettext("Image"), "Image");
}

#[test]
fn catalog_ngettext() {
    let mut cat = Catalog::new();
    {
        // n == 1, no translation
        assert_eq!(cat.ngettext("Text", "Texts", 1), "Text");
        // n != 1, no translation
        assert_eq!(cat.ngettext("Text", "Texts", 0), "Texts");
        assert_eq!(cat.ngettext("Text", "Texts", 2), "Texts");
    }
    {
        cat.insert(Message::new("Text", None, vec!["Tekstas", "Tekstai"]));
        // n == 1, translation available
        assert_eq!(cat.ngettext("Text", "Texts", 1), "Tekstas");
        // n != 1, translation available
        assert_eq!(cat.ngettext("Text", "Texts", 0), "Tekstai");
        assert_eq!(cat.ngettext("Text", "Texts", 2), "Tekstai");
    }
}
<commit_msg>pgettext<commit_after>//! The `gettext` crate provides functionality for
//! parsing and using Gettext catalogs stored in MO files.

// https://pascalhertleif.de/artikel/good-practices-for-writing-rust-libraries/
#![deny(missing_docs, missing_debug_implementations,
        trivial_casts, trivial_numeric_casts,
        unsafe_code, unstable_features,
        unused_import_braces, unused_qualifications)]

use std::collections::HashMap;
use std::ops::Deref;

/// Catalog represents a set of translation strings
/// parsed out of one MO file.
#[derive(Debug)]
pub struct Catalog {
    strings: HashMap<String, Message>,
}

impl Catalog {
    fn new() -> Self {
        Catalog { strings: HashMap::new() }
    }

    fn insert(&mut self, msg: Message) {
        let key = match msg.context {
            Some(ref ctxt) => [ctxt.deref(), &*msg.id].join("\x04"),
            None => msg.id.clone(),
        };
        self.strings.insert(key, msg);
    }

    /// Returns the singular translation of `msg_id` from the given catalog
    /// or `msg_id` itself if a translation does not exist.
    pub fn gettext<'a>(&'a self, msg_id: &'a str) -> &'a str {
        self.strings.get(&msg_id.to_owned()).and_then(|msg| msg.get_translated(0)).unwrap_or(msg_id)
    }

    /// Returns the plural translation of `msg_id` from the given catalog
    /// with the correct plural form for the number `n` of objects.
    /// Returns msg_id if a translation does not exist and `n == 1`,
    /// msg_id_plural otherwise.
    ///
    /// Currently, the only supported plural formula is `n != 1`.
    pub fn ngettext<'a>(&'a self, msg_id: &'a str, msg_id_plural: &'a str, n: usize) -> &'a str {
        let form_no = if n != 1 {
            1
        } else {
            0
        };

        match self.strings.get(&msg_id.to_owned()) {
            Some(msg) => {
                msg.get_translated(form_no).unwrap_or_else(|| [msg_id, msg_id_plural][form_no])
            }
            None if form_no == 0 => msg_id,
            None if form_no == 1 => msg_id_plural,
            _ => unreachable!(),
        }
    }

    /// Returns the singular translation of `msg_id`
    /// in the context `msg_context`
    /// or `msg_id` itself if a translation does not exist.
    // TODO: DRY gettext/pgettext
    pub fn pgettext<'a>(&'a self, msg_context: &'a str, msg_id: &'a str) -> &'a str {
        let key = [msg_context, msg_id].join("\x04");
        self.strings.get(&key).and_then(|msg| msg.get_translated(0)).unwrap_or(msg_id)
    }
}

#[derive(Debug)]
struct Message {
    id: String,
    context: Option<String>,
    translated: Vec<String>,
}

impl Message {
    fn new<T: Into<String>>(id: T, context: Option<T>, translated: Vec<T>) -> Self {
        Message {
            id: id.into(),
            context: context.map(Into::into),
            translated: translated.into_iter().map(Into::into).collect(),
        }
    }

    fn get_translated(&self, form_no: usize) -> Option<&str> {
        self.translated.get(form_no).map(|s| s.deref())
    }
}

#[test]
fn catalog_insert() {
    let mut cat = Catalog::new();
    cat.insert(Message::new("thisisid", None, vec![]));
    cat.insert(Message::new("anotherid", Some("context"), vec![]));
    let mut keys = cat.strings.keys().collect::<Vec<_>>();
    keys.sort();
    assert_eq!(keys, &["context\x04anotherid", "thisisid"])
}

#[test]
fn catalog_gettext() {
    let mut cat = Catalog::new();
    cat.insert(Message::new("Text", None, vec!["Tekstas"]));
    cat.insert(Message::new("Image", Some("context"), vec!["Paveikslelis"]));
    assert_eq!(cat.gettext("Text"), "Tekstas");
    assert_eq!(cat.gettext("Image"), "Image");
}

#[test]
fn catalog_ngettext() {
    let mut cat = Catalog::new();
    {
        // n == 1, no translation
        assert_eq!(cat.ngettext("Text", "Texts", 1), "Text");
        // n != 1, no translation
        assert_eq!(cat.ngettext("Text", "Texts", 0), "Texts");
        assert_eq!(cat.ngettext("Text", "Texts", 2), "Texts");
    }
    {
        cat.insert(Message::new("Text", None, vec!["Tekstas", "Tekstai"]));
        // n == 1, translation available
        assert_eq!(cat.ngettext("Text", "Texts", 1), "Tekstas");
        // n != 1, translation available
        assert_eq!(cat.ngettext("Text", "Texts", 0), "Tekstai");
        assert_eq!(cat.ngettext("Text", "Texts", 2), "Tekstai");
    }
}

#[test]
fn catalog_pgettext() {
    let mut cat = Catalog::new();
    cat.insert(Message::new("Text", Some("unit test"), vec!["Tekstas"]));
    assert_eq!(cat.pgettext("unit test", "Text"), "Tekstas");
    assert_eq!(cat.pgettext("integration test", "Text"), "Text");
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "nightly", feature(drain))]
#![deny(missing_docs)]
#![cfg_attr(test, deny(dead_code))]
#![cfg_attr(not(test), allow(dead_code))]

//! Small wrapper for `thread::spawn` that optionally auto-joins threads

use std::thread;
#[cfg(not(feature = "nightly"))] use std::mem;

/// A wrapper for `thread::spawn` that optionally auto-joins threads.
pub struct Spawner {
    threads: Vec<thread::JoinHandle<()>>
}

impl Spawner {
    /// Create a new Spawner object
    pub fn new() -> Spawner { Spawner { threads: Vec::new() } }

    /// Spawn a thread that will be auto-joined when the Spawner is dropped
    ///
    /// The thread function should be a move closure returning ()
    pub fn spawn_collected<F>(&mut self, f: F)
    where F: FnOnce(), F: Send + 'static
    {
        self.threads.push(thread::spawn(f));
    }

    /// Spawn a thread that won't be auto-joine
    ///
    /// The thread function should be a move closure
    pub fn spawn<F, T>(&mut self, f: F) -> thread::JoinHandle<T>
    where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    {
        thread::spawn(f)
    }
}

impl Drop for Spawner {
    #[cfg(feature = "nightly")]
    fn drop(&mut self) {
        self.threads.drain(..)
            .map(thread::JoinHandle::join)
            .collect::<Result<Vec<_>,_>>()
            .unwrap();
    }

    #[cfg(not(feature = "nightly"))]
    fn drop(&mut self) {
        mem::replace(&mut self.threads, Vec::new())
            .into_iter()
            .map(thread::JoinHandle::join)
            .collect::<Result<Vec<_>,_>>()
            .unwrap();
    }
}

#[test]
fn spawn_some_threads() {
    let mut spawner = Spawner::new();
    spawner.spawn(move || println!("0")).join().unwrap();
    for i in 1..10 {
        spawner.spawn_collected(move || println!("{}", i));
    }
}

<commit_msg>add a real test<commit_after>#![cfg_attr(feature = "nightly", feature(drain))]
#![deny(missing_docs)]
#![cfg_attr(test, deny(dead_code))]
#![cfg_attr(not(test), allow(dead_code))]

//! Small wrapper for `thread::spawn` that optionally auto-joins threads

use std::thread;
#[cfg(not(feature = "nightly"))] use std::mem;

/// A wrapper for `thread::spawn` that optionally auto-joins threads.
pub struct Spawner {
    threads: Vec<thread::JoinHandle<()>>
}

impl Spawner {
    /// Create a new Spawner object
    pub fn new() -> Spawner { Spawner { threads: Vec::new() } }

    /// Spawn a thread that will be auto-joined when the Spawner is dropped
    ///
    /// The thread function should be a move closure returning ()
    pub fn spawn_collected<F>(&mut self, f: F)
    where F: FnOnce(), F: Send + 'static
    {
        self.threads.push(thread::spawn(f));
    }

    /// Spawn a thread that won't be auto-joine
    ///
    /// The thread function should be a move closure
    pub fn spawn<F, T>(&mut self, f: F) -> thread::JoinHandle<T>
    where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    {
        thread::spawn(f)
    }
}

impl Drop for Spawner {
    #[cfg(feature = "nightly")]
    fn drop(&mut self) {
        self.threads.drain(..)
            .map(thread::JoinHandle::join)
            .collect::<Result<Vec<_>,_>>()
            .unwrap();
    }

    #[cfg(not(feature = "nightly"))]
    fn drop(&mut self) {
        mem::replace(&mut self.threads, Vec::new())
            .into_iter()
            .map(thread::JoinHandle::join)
            .collect::<Result<Vec<_>,_>>()
            .unwrap();
    }
}

#[cfg(test)]
#[test]
fn spawn_some_threads() {
    use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
    use std::thread::sleep;
    use std::time::Duration;

    static ACTIVE: AtomicUsize = ATOMIC_USIZE_INIT;

    {
        let mut spawner = Spawner::new();

        assert!(
            spawner.spawn(move || {
                            ACTIVE.fetch_add(1, Ordering::SeqCst);
                            sleep(Duration::from_millis(100));
                            ACTIVE.fetch_sub(1, Ordering::SeqCst);
                         })
                   .join()
                   .is_ok()
        );

        assert_eq!(
            ACTIVE.load(Ordering::SeqCst),
            0
        );

        for _ in 1..10 {
            spawner.spawn_collected(move || {
                                      ACTIVE.fetch_add(1, Ordering::SeqCst);
                                      sleep(Duration::from_millis(100));
                                      ACTIVE.fetch_sub(1, Ordering::SeqCst);
                                   });
        }

        assert!(
            ACTIVE.load(Ordering::SeqCst) > 0
        );
    }

    assert_eq!(
        ACTIVE.load(Ordering::SeqCst),
        0
    );
}

<|endoftext|>


<commit_before>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is() {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt() {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// returns true if this is a tty
#[cfg(unix)]
pub fn is() -> bool {
  let r = unsafe { libc::isatty(libc::STDOUT_FILENO) };
  r != 0
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is() -> bool {
    extern crate kernel32;
    extern crate winapi;
    unsafe {
        let handle = kernel32::GetStdHandle(if fd == libc::STDOUT_FILENO {
            winapi::winbase::STD_OUTPUT_HANDLE
        } else {
            winapi::winbase::STD_ERROR_HANDLE
        });
        let mut out = 0;
        kernel32::GetConsoleMode(handle, &mut out) != 0
    }
}

/// returns true if this is _not_ a tty
pub fn isnt() -> bool {
  !is()
}

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

    #[test]
    fn is_test() {
        assert!(is())
    }
}
<commit_msg>testing windows change<commit_after>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is() {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt() {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// returns true if this is a tty
#[cfg(unix)]
pub fn is() -> bool {
  let r = unsafe { libc::isatty(libc::STDOUT_FILENO) };
  r != 0
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is() -> bool {
    extern crate kernel32;
    extern crate winapi;
    use winapi::{self, HANDLE, INVALID_HANDLE_VALUE};
    use std::ptr;
    let handle: HANDLE = unsafe {
        let name = b"CONOUT$\0";
        let handle: HANDLE = unsafe {
            kernel32::CreateFileA(
                name.as_ptr() as *const i8,
                winapi::GENERIC_READ | winapi::GENERIC_WRITE,
                winapi::FILE_SHARE_WRITE,
                ptr::null_mut(),
                winapi::OPEN_EXISTING,
                0,
                ptr::null_mut(),
            )
        };
        println!("handle {:?}", handle);
        if handle == INVALID_HANDLE_VALUE {
            println!("handle was invalid");
            return false;
        }
        let mut out = 0;
        kernel32::GetConsoleMode(handle, &mut out) != 0

    }
}

/// returns true if this is _not_ a tty
pub fn isnt() -> bool {
  !is()
}

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

    #[test]
    fn is_test() {
        assert!(is())
    }
}
<|endoftext|>


<commit_before>/// A simple dsp node for multiplying the amplitude of its inputs by some given multiplier.

extern crate dsp;
extern crate time_calc as time;

/// A simple dsp node for multiplying the amplitude of its inputs by the held multiplier.
#[derive(Copy, Clone, Debug)]
pub struct Volume {
    maybe_prev: Option<f32>,
    pub current: f32,
    pub interpolation_ms: time::calc::Ms,
}

impl Volume {

    /// Constructor for a new default volume. The default volume is 1.0, having no impact on the
    /// input signal. The default interpolation_ms is 10ms to avoid clipping.
    pub fn new() -> Volume {
        Volume {
            maybe_prev: None,
            current: 1.0,
            interpolation_ms: 10.0,
        }
    }

    /// Builder for constructing a Volume with some given volume.
    pub fn volume(mut self, volume: f32) -> Volume {
        self.current = volume;
        self
    }

    /// Builder for constructing a Volume with some given interpolation length in Ms.
    /// The interpolation length is how long it takes the volume to progress from some previous
    /// volume to a new current volume. It is mainly used to avoid clipping.
    ///
    /// The default interpolation_ms is 10ms - just enough to avoid clipping.
    pub fn interpolation_ms(mut self, ms: time::calc::Ms) -> Volume {
        self.interpolation_ms = ms;
        self
    }

    /// Set the new current volume.
    pub fn set(&mut self, volume: f32) {
        self.current = volume;
    }

}

impl<S> dsp::Node<S> for Volume
    where S: dsp::Sample + dsp::FromSample<f32>,
          f32: dsp::FromSample<S>,
{

    #[inline]
    fn audio_requested(&mut self, buffer: &mut [S], settings: dsp::Settings) {
        use dsp::Sample;
        match self.maybe_prev {

            // If the volume used for the previous buffer is different to the volume used for the
            // current buffer, we should interpolate from it to the current volume to avoid
            // clipping.
            Some(prev) if prev != self.current && self.interpolation_ms > 0.0 => {

                // Calculate the interpolation duration in frames along with the volume increment
                // to use for interpolation.
                let interpolation_frames = ::std::cmp::min(
                    settings.frames as usize,
                    time::Ms(self.interpolation_ms).samples(settings.sample_hz as f64) as usize
                );
                let volume_diff = self.current - prev;
                let volume_increment = volume_diff * (1.0 / interpolation_frames as f32);
                let mut volume = prev;

                // Interpolated frames.
                for frame in 0..interpolation_frames {
                    volume += volume_increment;
                    for channel in 0..(settings.channels as usize) {
                        let idx = frame * (settings.channels as usize) + channel;
                        let sample = &mut buffer[idx];
                        *sample = (sample.to_sample::<f32>() * volume).to_sample();
                    }
                }

                // Remaining frames.
                let start_of_remaining = interpolation_frames * settings.channels as usize;
                for idx in start_of_remaining..buffer.len() {
                    let sample = &mut buffer[idx];
                    *sample = (sample.to_sample::<f32>() * volume).to_sample();
                }
            },

            // Otherwise, simply multiply every sample by the current volume.
            _ => for sample in buffer.iter_mut() {
                *sample = (sample.to_sample::<f32>() * self.current).to_sample();
            },

        }

        // Always set the current volume as the new `maybe_prev`.
        self.maybe_prev = Some(self.current);
    }

}

<commit_msg>Use sample::Duplex<commit_after>/// A simple dsp node for multiplying the amplitude of its inputs by some given multiplier.

extern crate dsp;
extern crate time_calc as time;

/// A simple dsp node for multiplying the amplitude of its inputs by the held multiplier.
#[derive(Copy, Clone, Debug)]
pub struct Volume {
    maybe_prev: Option<f32>,
    pub current: f32,
    pub interpolation_ms: time::calc::Ms,
}

impl Volume {

    /// Constructor for a new default volume. The default volume is 1.0, having no impact on the
    /// input signal. The default interpolation_ms is 10ms to avoid clipping.
    pub fn new() -> Volume {
        Volume {
            maybe_prev: None,
            current: 1.0,
            interpolation_ms: 10.0,
        }
    }

    /// Builder for constructing a Volume with some given volume.
    pub fn volume(mut self, volume: f32) -> Volume {
        self.current = volume;
        self
    }

    /// Builder for constructing a Volume with some given interpolation length in Ms.
    /// The interpolation length is how long it takes the volume to progress from some previous
    /// volume to a new current volume. It is mainly used to avoid clipping.
    ///
    /// The default interpolation_ms is 10ms - just enough to avoid clipping.
    pub fn interpolation_ms(mut self, ms: time::calc::Ms) -> Volume {
        self.interpolation_ms = ms;
        self
    }

    /// Set the new current volume.
    pub fn set(&mut self, volume: f32) {
        self.current = volume;
    }

}

impl<S> dsp::Node<S> for Volume
    where S: dsp::Sample + dsp::sample::Duplex<f32>,
{

    #[inline]
    fn audio_requested(&mut self, buffer: &mut [S], settings: dsp::Settings) {
        use dsp::Sample;
        match self.maybe_prev {

            // If the volume used for the previous buffer is different to the volume used for the
            // current buffer, we should interpolate from it to the current volume to avoid
            // clipping.
            Some(prev) if prev != self.current && self.interpolation_ms > 0.0 => {

                // Calculate the interpolation duration in frames along with the volume increment
                // to use for interpolation.
                let interpolation_frames = ::std::cmp::min(
                    settings.frames as usize,
                    time::Ms(self.interpolation_ms).samples(settings.sample_hz as f64) as usize
                );
                let volume_diff = self.current - prev;
                let volume_increment = volume_diff * (1.0 / interpolation_frames as f32);
                let mut volume = prev;

                // Interpolated frames.
                for frame in 0..interpolation_frames {
                    volume += volume_increment;
                    for channel in 0..(settings.channels as usize) {
                        let idx = frame * (settings.channels as usize) + channel;
                        let sample = &mut buffer[idx];
                        *sample = (sample.to_sample::<f32>() * volume).to_sample();
                    }
                }

                // Remaining frames.
                let start_of_remaining = interpolation_frames * settings.channels as usize;
                for idx in start_of_remaining..buffer.len() {
                    let sample = &mut buffer[idx];
                    *sample = (sample.to_sample::<f32>() * volume).to_sample();
                }
            },

            // Otherwise, simply multiply every sample by the current volume.
            _ => for sample in buffer.iter_mut() {
                *sample = (sample.to_sample::<f32>() * self.current).to_sample();
            },

        }

        // Always set the current volume as the new `maybe_prev`.
        self.maybe_prev = Some(self.current);
    }

}

<|endoftext|>


<commit_before>// src/lib.rs
//
// Copyright 2015 David Creswick
//
// 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.

//! # Mersenne Twister
//!
//! A pure rust port of the Mersenne Twister pseudorandom number
//! generator.
//!
//! **THESE ALGORITHMS ARE NOT APPROPRIATE FOR CRYPTOGRAPHIC USE.**
//!
//!
//! ## Usage
//!
//! If your application does not require a specific Mersenne Twister
//! flavor, you can use the default one for your target platform this
//! way:
//!
//! ```
//! extern crate mersenne_twister;
//! use mersenne_twister::MersenneTwister;
//! use std::rand::{Rng, SeedableRng};
//!
//! fn main() {
//!     // Get a seed somehow.
//!     let seed: u64 = 0x123456789abcdef;
//!     // Create the default RNG.
//!     let mut rng: MersenneTwister = SeedableRng::from_seed(seed);
//!
//!     // start grabbing randomness from rng...
//! }
//! ```
//!
//! Or if you want to use the default (fixed) seeds:
//!
//! ```
//! # use mersenne_twister::MersenneTwister;
//! # use std::rand::{Rng, SeedableRng};
//! use std::default::Default;
//! let mut rng: MersenneTwister = Default::default();
//! ```
//!
//! ## Portability
//!
//! Note that `MT19937` and `MT19937_64` are **not** identical
//! algorithms, despite their similar names. They produce different
//! output streams when given the same seed. You will need to pick a
//! specific flavor of the algorithm if portable reproducibility is
//! important to you.

#![unstable]
#![allow(unstable)]
#![deny(missing_docs)]

#[cfg(test)]
extern crate test;

pub use mt19937::MT19937;
pub use mt19937_64::MT19937_64;

mod mt19937;
mod mt19937_64;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "32")]
pub type MersenneTwister = MT19937;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "64")]
pub type MersenneTwister = MT19937_64;
<commit_msg>silence warnings<commit_after>// src/lib.rs
//
// Copyright 2015 David Creswick
//
// 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.

//! # Mersenne Twister
//!
//! A pure rust port of the Mersenne Twister pseudorandom number
//! generator.
//!
//! **THESE ALGORITHMS ARE NOT APPROPRIATE FOR CRYPTOGRAPHIC USE.**
//!
//!
//! ## Usage
//!
//! If your application does not require a specific Mersenne Twister
//! flavor, you can use the default one for your target platform this
//! way:
//!
//! ```
//! extern crate mersenne_twister;
//! use mersenne_twister::MersenneTwister;
//! use std::rand::{Rng, SeedableRng};
//!
//! fn main() {
//!     // Get a seed somehow.
//!     let seed: u64 = 0x123456789abcdef;
//!     // Create the default RNG.
//!     let mut rng: MersenneTwister = SeedableRng::from_seed(seed);
//!
//!     // start grabbing randomness from rng...
//! }
//! ```
//!
//! Or if you want to use the default (fixed) seeds:
//!
//! ```
//! # use mersenne_twister::MersenneTwister;
//! # use std::rand::{Rng, SeedableRng};
//! use std::default::Default;
//! let mut rng: MersenneTwister = Default::default();
//! ```
//!
//! ## Portability
//!
//! Note that `MT19937` and `MT19937_64` are **not** identical
//! algorithms, despite their similar names. They produce different
//! output streams when given the same seed. You will need to pick a
//! specific flavor of the algorithm if portable reproducibility is
//! important to you.

#![unstable]
#![feature(core, rand)]
#![deny(missing_docs)]

#[cfg(test)]
extern crate test;

pub use mt19937::MT19937;
pub use mt19937_64::MT19937_64;

mod mt19937;
mod mt19937_64;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "32")]
pub type MersenneTwister = MT19937;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "64")]
pub type MersenneTwister = MT19937_64;
<|endoftext|>