<commit_before>//! # cabot
//!
//! cabot is a command line tool and a rust library for sending HTTP query.
//! It is a simple implementation of HTTP based on the rust standard library
//! to perform TCP and DNS query, and use rustls for handling HTTPS connection.
//! No tiers library are used for HTTP protocol.
//!
//! cabot is inspired by the cURL command line tool, but focus on the
//! http protocol which is the referent in HTTP client library.
//!
//! # Examples:
//!
//! ## Command Line:
//!
//! ```bash
//! $ cabot https://www.rust-lang.org/en-US/ | head -n 10 | grep "description"
//! <meta name="description" content="A systems programming language that runs
//! blazingly fast, prevents segfaults, and guarantees thread safety.">
//! ```
//!
//! ## Library:
//!
//! ```
//! use cabot::{RequestBuilder, Client};
//!
//! let request = RequestBuilder::new("https://www.rust-lang.org/en-US/")
//!     .build()
//!     .unwrap();
//! let client = Client::new();
//! let response = client.execute(&request).unwrap();
//! assert!(response.body_as_string().unwrap().contains("runs blazingly fast"));
//!
//! ```
//!
//! # Why cabot ?
//!
//! To get a simple rust native https client. No binding to OpenSSL.
//!
//! # License
//!
//! BSD 3-Clause License
//!

#[macro_use]
extern crate log;

#[macro_use]
extern crate lazy_static;
extern crate regex;
extern crate rustls;
extern crate url;
extern crate webpki;
extern crate webpki_roots;

mod dns;

pub mod client;
pub mod constants;
pub mod errors;
pub mod http;
pub mod request;
pub mod response;
pub mod results;

// Rexport
pub use client::Client;
pub use request::RequestBuilder;
<commit_msg>Fix tests from new rust website<commit_after>//! # cabot
//!
//! cabot is a command line tool and a rust library for sending HTTP query.
//! It is a simple implementation of HTTP based on the rust standard library
//! to perform TCP and DNS query, and use rustls for handling HTTPS connection.
//! No tiers library are used for HTTP protocol.
//!
//! cabot is inspired by the cURL command line tool, but focus on the
//! http protocol which is the referent in HTTP client library.
//!
//! # Examples:
//!
//! ## Command Line:
//!
//! ```bash
//! $ cargo run https://www.rust-lang.org/ | head -n 20 | grep 'name="description"'
//!     <meta name="description" content="A language empowering everyone to build reliable and efficient software.">
//! ```
//! ## Library:
//!
//! ```
//! use cabot::{RequestBuilder, Client};
//!
//! let request = RequestBuilder::new("https://www.rust-lang.org/")
//!     .build()
//!     .unwrap();
//! let client = Client::new();
//! let response = client.execute(&request).unwrap();
//! assert!(response.body_as_string().unwrap().contains("A language empowering everyone to build reliable and efficient software."));
//!
//! ```
//!
//! # Why cabot ?
//!
//! To get a simple rust native https client. No binding to OpenSSL.
//!
//! # License
//!
//! BSD 3-Clause License
//!

#[macro_use]
extern crate log;

#[macro_use]
extern crate lazy_static;
extern crate regex;
extern crate rustls;
extern crate url;
extern crate webpki;
extern crate webpki_roots;

mod dns;

pub mod client;
pub mod constants;
pub mod errors;
pub mod http;
pub mod request;
pub mod response;
pub mod results;

// Rexport
pub use client::Client;
pub use request::RequestBuilder;
<|endoftext|>


<commit_before>#![allow(raw_pointer_derive)]

pub mod graph;
pub mod vertex;

mod tests {
    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_deref() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        let vertex = &*v1;
        assert!(vertex.id == 1);
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();

        assert_eq!(v1.id, 1);

        unsafe {
            let vertex = &*v1;
            assert_eq!((*v1).id, 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        let e1 = v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);

        assert_eq!(v1.out_edges.len(), v2.in_edges.len());

        // ensure the vertex and edge pointers are correct

        assert_eq!(v1.v, e1.from_vertex);
        assert_eq!(e1.to_vertex, v2.v);

        //assert_eq!(v1.v, *(e1.edge).from_vertex);
    }
}
<commit_msg>fixed missing imports so tests work<commit_after>#![allow(raw_pointer_derive)]

pub mod graph;
pub mod vertex;

mod tests {
    use vertex::Vertex;
    use graph::Graph;
    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_deref() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        let vertex = &*v1;
        assert!(vertex.id == 1);
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();

        assert_eq!(v1.id, 1);

        unsafe {
            let vertex = &*v1;
            assert_eq!((*v1).id, 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        let e1 = v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);

        assert_eq!(v1.out_edges.len(), v2.in_edges.len());

        // ensure the vertex and edge pointers are correct

        assert_eq!(v1.v, e1.from_vertex);
        assert_eq!(e1.to_vertex, v2.v);

        //assert_eq!(v1.v, *(e1.edge).from_vertex);
    }
}
<|endoftext|>


<commit_before>//! `textwrap` provides functions for word wrapping and filling text.

extern crate unicode_width;

use std::iter;
use unicode_width::UnicodeWidthStr;

/// A Wrapper holds settings for wrapping text.
pub struct Wrapper {
    width: usize,
}

impl Wrapper {
    /// Create a new Wrapper for wrapping at the specified width.
    pub fn new(width: usize) -> Wrapper {
        Wrapper { width: width }
    }

    /// Fill a line of text at `self.width` bytes.
    ///
    /// The result is a string with newlines between each line. Use
    /// the `wrap` method if you need access to the individual lines.
    ///
    /// ```
    /// use textwrap::Wrapper;
    ///
    /// let wrapper = Wrapper::new(15);
    /// assert_eq!(wrapper.fill("Memory safety without garbage collection."),
    ///            "Memory safety\nwithout garbage\ncollection.");
    /// ```
    pub fn fill(&self, s: &str) -> String {
        self.wrap(&s).join("\n")
    }

    /// Wrap a line of text at `self.width` bytes and return a vector
    /// of lines.
    ///
    /// ```
    /// use textwrap::Wrapper;
    ///
    /// let wrap15 = Wrapper::new(15);
    /// assert_eq!(wrap15.wrap("Concurrency without data races."),
    ///            vec!["Concurrency",
    ///                 "without data",
    ///                 "races."]);
    ///
    /// let wrap20 = Wrapper::new(20);
    /// assert_eq!(wrap20.wrap("Concurrency without data races."),
    ///            vec!["Concurrency without",
    ///                 "data races."]);
    /// ```
    pub fn wrap(&self, s: &str) -> Vec<String> {
        let mut result = Vec::new();
        let mut line = Vec::new();
        let mut line_width = 0;

        for mut word in s.split_whitespace() {
            while !word.is_empty() {
                let splits = split_word(&word);
                let (smallest, longest) = splits[0];
                let min_width = smallest.width();

                // Add a new line if even the smallest split doesn't
                // fit.
                if !line.is_empty() && line_width + line.len() + min_width > self.width {
                    result.push(line.join(" "));
                    line = Vec::new();
                    line_width = 0;
                }

                // Find a split that fits on the current line.
                for &(head, tail) in splits.iter().rev() {
                    if line_width + line.len() + head.width() <= self.width {
                        line.push(head);
                        line_width += head.width();
                        word = tail;
                        break;
                    }
                }

                // If nothing got added, we forcibly add the smallest
                // split and continue with the longest tail.
                if line_width == 0 {
                    result.push(String::from(smallest));
                    line_width = 0;
                    word = longest;
                }
            }
        }
        if !line.is_empty() {
            result.push(line.join(" "));
        }
        return result;
    }
}

/// Fill a line of text at `width` bytes.
///
/// The result is a string with newlines between each line. Use `wrap`
/// if you need access to the individual lines.
///
/// ```
/// use textwrap::fill;
///
/// assert_eq!(fill("Memory safety without garbage collection.", 15),
///            "Memory safety\nwithout garbage\ncollection.");
/// ```
///
/// This function creates a Wrapper on the fly. If you need to wrap
/// many strings, it can be more efficient to create a single Wrapper
/// and call its [`fill` method](struct.Wrapper.html#method.fill).
pub fn fill(s: &str, width: usize) -> String {
    wrap(s, width).join("\n")
}

/// Wrap a line of text at `width` bytes and return a vector of lines.
///
/// ```
/// use textwrap::wrap;
///
/// assert_eq!(wrap("Concurrency without data races.", 15),
///            vec!["Concurrency",
///                 "without data",
///                 "races."]);
///
/// assert_eq!(wrap("Concurrency without data races.", 20),
///            vec!["Concurrency without",
///                 "data races."]);
/// ```
///
/// This function creates a Wrapper on the fly. If you need to wrap
/// many strings, it can be more efficient to create a single Wrapper
/// and call its [`wrap` method](struct.Wrapper.html#method.wrap).
pub fn wrap(s: &str, width: usize) -> Vec<String> {
    Wrapper::new(width).wrap(s)
}

/// Split word into all possible parts (head, tail). Word must be
/// non-empty. The returned vector will always be non-empty.
fn split_word(word: &str) -> Vec<(&str, &str)> {
    let hyphens = word.match_indices('-');
    let word_end = iter::once((word.len() - 1, ""));
    return hyphens.chain(word_end)
        .map(|(n, _)| word.split_at(n + 1))
        .collect();
}

/// Add prefix to each non-empty line.
///
/// ```
/// use textwrap::indent;
///
/// assert_eq!(indent("Foo\nBar\n", "  "), "  Foo\n  Bar\n");
/// ```
///
/// Empty lines (lines consisting only of whitespace) are not indented
/// and the whitespace is replaced by a single newline (`\n`):
///
/// ```
/// use textwrap::indent;
///
/// assert_eq!(indent("Foo\n\nBar\n  \t  \nBaz\n", "  "),
///            "  Foo\n\n  Bar\n\n  Baz\n");
/// ```
///
/// Leading and trailing whitespace on non-empty lines is kept
/// unchanged:
///
/// ```
/// use textwrap::indent;
///
/// assert_eq!(indent(" \t  Foo   ", "  "), "   \t  Foo   \n");
/// ```
pub fn indent(s: &str, prefix: &str) -> String {
    let mut result = String::new();
    for line in s.lines() {
        if line.chars().any(|c| !c.is_whitespace()) {
            result.push_str(prefix);
            result.push_str(line);
        }
        result.push('\n');
    }
    return result;
}

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

    /// Add newlines. Ensures that the final line in the vector also
    /// has a newline.
    fn add_nl(lines: &Vec<&str>) -> String {
        lines.join("\n") + "\n"
    }

    #[test]
    fn no_wrap() {
        assert_eq!(wrap("foo", 10), vec!["foo"]);
    }

    #[test]
    fn simple() {
        assert_eq!(wrap("foo bar baz", 5), vec!["foo", "bar", "baz"]);
    }

    #[test]
    fn multi_word_on_line() {
        assert_eq!(wrap("foo bar baz", 10), vec!["foo bar", "baz"]);
    }

    #[test]
    fn long_word() {
        assert_eq!(wrap("foo", 0), vec!["foo"]);
    }

    #[test]
    fn long_words() {
        assert_eq!(wrap("foo bar", 0), vec!["foo", "bar"]);
    }

    #[test]
    fn whitespace_is_squeezed() {
        assert_eq!(wrap(" foo \t  bar  ", 10), vec!["foo bar"]);
    }

    #[test]
    fn wide_character_handling() {
        assert_eq!(wrap("Hello, World!", 15), vec!["Hello, World!"]);
        assert_eq!(wrap("Ｈｅｌｌｏ, Ｗｏｒｌｄ!", 15),
                   vec!["Ｈｅｌｌｏ,", "Ｗｏｒｌｄ!"]);
    }

    #[test]
    fn hyphens() {
        assert_eq!(wrap("foo-bar", 5), vec!["foo-", "bar"]);
    }

    #[test]
    fn trailing_hyphen() {
        assert_eq!(wrap("foobar-", 5), vec!["foobar-"]);
    }

    #[test]
    fn multiple_hyphens() {
        assert_eq!(wrap("foo-bar-baz", 5), vec!["foo-", "bar-", "baz"]);
    }

    #[test]
    fn multiple_splits() {
        assert_eq!(wrap("foo-bar-baz", 9), vec!["foo-bar-", "baz"]);
    }

    #[test]
    fn forced_split() {
        assert_eq!(wrap("foobar-baz", 5), vec!["foobar-", "baz"]);
    }

    #[test]
    fn test_fill() {
        assert_eq!(fill("foo bar baz", 10), "foo bar\nbaz");
    }

    #[test]
    fn test_indent_empty() {
        assert_eq!(indent("\n", "  "), "\n");
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_indent_nonempty() {
        let x = vec!["  foo",
                     "bar",
                     "  baz"];
        let y = vec!["//  foo",
                     "//bar",
                     "//  baz"];
        assert_eq!(indent(&add_nl(&x), "//"), add_nl(&y));
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_indent_empty_line() {
        let x = vec!["  foo",
                     "bar",
                     "",
                     "  baz"];
        let y = vec!["//  foo",
                     "//bar",
                     "",
                     "//  baz"];
        assert_eq!(indent(&add_nl(&x), "//"), add_nl(&y));
    }
}
<commit_msg>textwrap: add simple dedent or un-indent function<commit_after>//! `textwrap` provides functions for word wrapping and filling text.

extern crate unicode_width;

use std::iter;
use unicode_width::UnicodeWidthStr;

/// A Wrapper holds settings for wrapping text.
pub struct Wrapper {
    width: usize,
}

impl Wrapper {
    /// Create a new Wrapper for wrapping at the specified width.
    pub fn new(width: usize) -> Wrapper {
        Wrapper { width: width }
    }

    /// Fill a line of text at `self.width` bytes.
    ///
    /// The result is a string with newlines between each line. Use
    /// the `wrap` method if you need access to the individual lines.
    ///
    /// ```
    /// use textwrap::Wrapper;
    ///
    /// let wrapper = Wrapper::new(15);
    /// assert_eq!(wrapper.fill("Memory safety without garbage collection."),
    ///            "Memory safety\nwithout garbage\ncollection.");
    /// ```
    pub fn fill(&self, s: &str) -> String {
        self.wrap(&s).join("\n")
    }

    /// Wrap a line of text at `self.width` bytes and return a vector
    /// of lines.
    ///
    /// ```
    /// use textwrap::Wrapper;
    ///
    /// let wrap15 = Wrapper::new(15);
    /// assert_eq!(wrap15.wrap("Concurrency without data races."),
    ///            vec!["Concurrency",
    ///                 "without data",
    ///                 "races."]);
    ///
    /// let wrap20 = Wrapper::new(20);
    /// assert_eq!(wrap20.wrap("Concurrency without data races."),
    ///            vec!["Concurrency without",
    ///                 "data races."]);
    /// ```
    pub fn wrap(&self, s: &str) -> Vec<String> {
        let mut result = Vec::new();
        let mut line = Vec::new();
        let mut line_width = 0;

        for mut word in s.split_whitespace() {
            while !word.is_empty() {
                let splits = split_word(&word);
                let (smallest, longest) = splits[0];
                let min_width = smallest.width();

                // Add a new line if even the smallest split doesn't
                // fit.
                if !line.is_empty() && line_width + line.len() + min_width > self.width {
                    result.push(line.join(" "));
                    line = Vec::new();
                    line_width = 0;
                }

                // Find a split that fits on the current line.
                for &(head, tail) in splits.iter().rev() {
                    if line_width + line.len() + head.width() <= self.width {
                        line.push(head);
                        line_width += head.width();
                        word = tail;
                        break;
                    }
                }

                // If nothing got added, we forcibly add the smallest
                // split and continue with the longest tail.
                if line_width == 0 {
                    result.push(String::from(smallest));
                    line_width = 0;
                    word = longest;
                }
            }
        }
        if !line.is_empty() {
            result.push(line.join(" "));
        }
        return result;
    }
}

/// Fill a line of text at `width` bytes.
///
/// The result is a string with newlines between each line. Use `wrap`
/// if you need access to the individual lines.
///
/// ```
/// use textwrap::fill;
///
/// assert_eq!(fill("Memory safety without garbage collection.", 15),
///            "Memory safety\nwithout garbage\ncollection.");
/// ```
///
/// This function creates a Wrapper on the fly. If you need to wrap
/// many strings, it can be more efficient to create a single Wrapper
/// and call its [`fill` method](struct.Wrapper.html#method.fill).
pub fn fill(s: &str, width: usize) -> String {
    wrap(s, width).join("\n")
}

/// Wrap a line of text at `width` bytes and return a vector of lines.
///
/// ```
/// use textwrap::wrap;
///
/// assert_eq!(wrap("Concurrency without data races.", 15),
///            vec!["Concurrency",
///                 "without data",
///                 "races."]);
///
/// assert_eq!(wrap("Concurrency without data races.", 20),
///            vec!["Concurrency without",
///                 "data races."]);
/// ```
///
/// This function creates a Wrapper on the fly. If you need to wrap
/// many strings, it can be more efficient to create a single Wrapper
/// and call its [`wrap` method](struct.Wrapper.html#method.wrap).
pub fn wrap(s: &str, width: usize) -> Vec<String> {
    Wrapper::new(width).wrap(s)
}

/// Split word into all possible parts (head, tail). Word must be
/// non-empty. The returned vector will always be non-empty.
fn split_word(word: &str) -> Vec<(&str, &str)> {
    let hyphens = word.match_indices('-');
    let word_end = iter::once((word.len() - 1, ""));
    return hyphens.chain(word_end)
        .map(|(n, _)| word.split_at(n + 1))
        .collect();
}

/// Add prefix to each non-empty line.
///
/// ```
/// use textwrap::indent;
///
/// assert_eq!(indent("Foo\nBar\n", "  "), "  Foo\n  Bar\n");
/// ```
///
/// Empty lines (lines consisting only of whitespace) are not indented
/// and the whitespace is replaced by a single newline (`\n`):
///
/// ```
/// use textwrap::indent;
///
/// assert_eq!(indent("Foo\n\nBar\n  \t  \nBaz\n", "  "),
///            "  Foo\n\n  Bar\n\n  Baz\n");
/// ```
///
/// Leading and trailing whitespace on non-empty lines is kept
/// unchanged:
///
/// ```
/// use textwrap::indent;
///
/// assert_eq!(indent(" \t  Foo   ", "  "), "   \t  Foo   \n");
/// ```
pub fn indent(s: &str, prefix: &str) -> String {
    let mut result = String::new();
    for line in s.lines() {
        if line.chars().any(|c| !c.is_whitespace()) {
            result.push_str(prefix);
            result.push_str(line);
        }
        result.push('\n');
    }
    return result;
}

/// Removes common leading whitespace from each line.
///
/// This will look at each non-empty line and determine the maximum
/// amount of whitespace that can be removed from the line.
///
/// ```
/// use textwrap::dedent;
///
/// assert_eq!(dedent("  1st line\n  2nd line\n"),
///            "1st line\n2nd line\n");
/// ```
pub fn dedent(s: &str) -> String {
    let mut prefix = String::new();
    let mut lines = s.lines();

    // We first search for a non-empty line to find a prefix.
    for line in &mut lines {
        let whitespace = line.chars()
            .take_while(|c| c.is_whitespace())
            .collect::<String>();
        // Check if the line had anything but whitespace
        if whitespace.len() < line.len() {
            prefix = whitespace;
            break;
        }
    }

    // We then continue looking through the remaining lines to
    // possibly shorten the prefix.
    for line in &mut lines {
        let whitespace = line.chars()
            .zip(prefix.chars())
            .take_while(|&(a, b)| a == b)
            .map(|(_, b)| b)
            .collect::<String>();
        // Check if we have found a shorter prefix
        if whitespace.len() < prefix.len() {
            prefix = whitespace;
        }
    }

    // We now go over the lines a second time to build the result.
    let mut result = String::new();
    for line in s.lines() {
        if line.starts_with(&prefix) && line.chars().any(|c| !c.is_whitespace()) {
            let (_, tail) = line.split_at(prefix.len());
            result.push_str(tail);
        }
        result.push('\n');
    }
    return result;
}

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

    /// Add newlines. Ensures that the final line in the vector also
    /// has a newline.
    fn add_nl(lines: &Vec<&str>) -> String {
        lines.join("\n") + "\n"
    }

    #[test]
    fn no_wrap() {
        assert_eq!(wrap("foo", 10), vec!["foo"]);
    }

    #[test]
    fn simple() {
        assert_eq!(wrap("foo bar baz", 5), vec!["foo", "bar", "baz"]);
    }

    #[test]
    fn multi_word_on_line() {
        assert_eq!(wrap("foo bar baz", 10), vec!["foo bar", "baz"]);
    }

    #[test]
    fn long_word() {
        assert_eq!(wrap("foo", 0), vec!["foo"]);
    }

    #[test]
    fn long_words() {
        assert_eq!(wrap("foo bar", 0), vec!["foo", "bar"]);
    }

    #[test]
    fn whitespace_is_squeezed() {
        assert_eq!(wrap(" foo \t  bar  ", 10), vec!["foo bar"]);
    }

    #[test]
    fn wide_character_handling() {
        assert_eq!(wrap("Hello, World!", 15), vec!["Hello, World!"]);
        assert_eq!(wrap("Ｈｅｌｌｏ, Ｗｏｒｌｄ!", 15),
                   vec!["Ｈｅｌｌｏ,", "Ｗｏｒｌｄ!"]);
    }

    #[test]
    fn hyphens() {
        assert_eq!(wrap("foo-bar", 5), vec!["foo-", "bar"]);
    }

    #[test]
    fn trailing_hyphen() {
        assert_eq!(wrap("foobar-", 5), vec!["foobar-"]);
    }

    #[test]
    fn multiple_hyphens() {
        assert_eq!(wrap("foo-bar-baz", 5), vec!["foo-", "bar-", "baz"]);
    }

    #[test]
    fn multiple_splits() {
        assert_eq!(wrap("foo-bar-baz", 9), vec!["foo-bar-", "baz"]);
    }

    #[test]
    fn forced_split() {
        assert_eq!(wrap("foobar-baz", 5), vec!["foobar-", "baz"]);
    }

    #[test]
    fn test_fill() {
        assert_eq!(fill("foo bar baz", 10), "foo bar\nbaz");
    }

    #[test]
    fn test_indent_empty() {
        assert_eq!(indent("\n", "  "), "\n");
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_indent_nonempty() {
        let x = vec!["  foo",
                     "bar",
                     "  baz"];
        let y = vec!["//  foo",
                     "//bar",
                     "//  baz"];
        assert_eq!(indent(&add_nl(&x), "//"), add_nl(&y));
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_indent_empty_line() {
        let x = vec!["  foo",
                     "bar",
                     "",
                     "  baz"];
        let y = vec!["//  foo",
                     "//bar",
                     "",
                     "//  baz"];
        assert_eq!(indent(&add_nl(&x), "//"), add_nl(&y));
    }

    #[test]
    fn test_dedent_empty() {
        assert_eq!(dedent(""), "");
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_dedent_multi_line() {
        let x = vec!["    foo",
                     "  bar",
                     "    baz"];
        let y = vec!["  foo",
                     "bar",
                     "  baz"];
        assert_eq!(dedent(&add_nl(&x)), add_nl(&y));
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_dedent_empty_line() {
        let x = vec!["    foo",
                     "  bar",
                     "   ",
                     "    baz"];
        let y = vec!["  foo",
                     "bar",
                     "",
                     "  baz"];
        assert_eq!(dedent(&add_nl(&x)), add_nl(&y));
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_dedent_mixed_whitespace() {
        let x = vec!["\tfoo",
                     "  bar"];
        let y = vec!["\tfoo",
                     "  bar"];
        assert_eq!(dedent(&add_nl(&x)), add_nl(&y));
    }
}
<|endoftext|>


<commit_before>//! # `derive_more`
//! Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
//! [`Not`] or [`From`].
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as when using the
//! commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//!
//! ```rust
//! # #[macro_use] extern crate derive_more;
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! enum MyEnum {
//!     Int(i32),
//!     UnsignedInt(u32),
//!     Nothing,
//! }
//!
//! fn main() {
//!     let my_11 = MyInt(5) + 6.into();
//!     assert_eq!(MyInt(11), MyInt(5) + 6.into());
//!     assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
//!     assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
//!     assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
//!     assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
//! }
//! ```
//!
//! ## The derivable traits
//!
//! Below are all the traits that you can derive using this library.
//! Some trait derivations are so similar that the furter documentation will only show a single one
//! of them.
//! You can recognize these by the "-like" suffix in their name.
//! The trait name before that will be the only one that is used throughout the further
//! documentation.
//!
//! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
//! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
//!
//! ### Conversion traits
//! These are traits that are used to convert automatically between types.
//!
//! 1. [`From`]
//! 2. [`Into`]
//! 3. [`FromStr`]
//!
//! ### Formatting traits
//! These traits are used for converting a struct to a string in different ways.
//!
//! 1. `Display`-like, contains [`Display`], [`Binary`], [`Octal`], [`LowerHex`], [`UpperHex`],
//!    [`LowerExp`], [`UpperExp`], [`Pointer`]
//!
//! ### Operators
//! These are traits that can be used for operator overloading.
//!
//! 1. [`Index`]
//! 2. `Not`-like, contains [`Not`] and [`Neg`]
//! 3. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`]
//!    and [`BitXorAssign`]
//! 4. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`]
//! 5. [`IndexMut`]
//! 6. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
//! 7. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and
//!    [`ShlAssign`]
//!
//! ### Static methods
//! These don't derive traits, but derive static methods instead.
//!
//! 1. `Constructor`, this derives a `new` method that can be used as a constructor. This is very
//!    basic if you need more customization for your constructor, check out the [`derive-new`] crate.
//!
//!
//! ## Generated code
//!
//! It is important to understand what code gets generated when using one of the derives from this
//! crate.
//! That is why the links below explain what code gets generated for a trait for each group from
//! before.
//!
//! 1. [`#[derive(From)]`](from.html)
//! 2. [`#[derive(Into)]`](into.html)
//! 3. [`#[derive(FromStr)]`](from_str.html)
//! 4. [`#[derive(Display)]`](display.html)
//! 7. [`#[derive(Index)]`](index_op.html)
//! 5. [`#[derive(Not)]`](not.html)
//! 6. [`#[derive(Add)]`](add.html)
//! 7. [`#[derive(Mul)]`](mul.html)
//! 7. [`#[derive(IndexMut)]`](index_mut.html)
//! 8. [`#[derive(AddAssign)]`](add_assign.html)
//! 9. [`#[derive(MulAssign)]`](mul_assign.html)
//! 10. [`#[derive(Constructor)]`](constructor.html)
//!
//! If you want to be sure what code is generated for your specific type I recommend using the
//! [`cargo-expand`] utility.
//! This will show you your code with all macros and derives expanded.
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.6.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! #[macro_use]
//! extern crate derive_more;
//! # fn main () {}
//! ```
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`derive-new`]: https://github.com/nrc/derive-new
//! [`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
//! [`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
//! [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
//! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
//! [`Binary`]: https://doc.rust-lang.org/std/fmt/trait.Binary.html
//! [`Octal`]: https://doc.rust-lang.org/std/fmt/trait.Octal.html
//! [`LowerHex`]: https://doc.rust-lang.org/std/fmt/trait.LowerHex.html
//! [`UpperHex`]: https://doc.rust-lang.org/std/fmt/trait.UpperHex.html
//! [`LowerExp`]: https://doc.rust-lang.org/std/fmt/trait.LowerExp.html
//! [`UpperExp`]: https://doc.rust-lang.org/std/fmt/trait.UpperExp.html
//! [`Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html
//! [`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html
//! [`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
//! [`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
//! [`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
//! [`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
//! [`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
//! [`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
//! [`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
//! [`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
//! [`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
//! [`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
//! [`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
//! [`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
//! [`IndexMut`]: https://doc.rust-lang.org/std/ops/trait.IndexMut.html
//! [`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
//! [`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
//! [`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
//! [`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
//! [`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
//! [`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
//! [`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
//! [`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
//! [`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
//! [`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html

extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;

mod utils;

mod from;
mod into;
mod constructor;
mod not_like;
mod add_like;
mod add_assign_like;
mod mul_like;
mod mul_assign_like;
mod from_str;
mod display;
mod index;
mod index_mut;

macro_rules! create_derive(
    ($mod_:ident, $trait_:ident, $fn_name: ident) => {
        #[proc_macro_derive($trait_)]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let ast = syn::parse(input).unwrap();
            $mod_::expand(&ast, stringify!($trait_)).into()
        }
    }
);

create_derive!(from, From, from_derive);

create_derive!(into, Into, into_derive);

create_derive!(constructor, Constructor, constructor_derive);

create_derive!(not_like, Not, not_derive);
create_derive!(not_like, Neg, neg_derive);

create_derive!(add_like, Add, add_derive);
create_derive!(add_like, Sub, sub_derive);
create_derive!(add_like, BitAnd, bit_and_derive);
create_derive!(add_like, BitOr, bit_or_derive);
create_derive!(add_like, BitXor, bit_xor_derive);

create_derive!(mul_like, Mul, mul_derive);
create_derive!(mul_like, Div, div_derive);
create_derive!(mul_like, Rem, rem_derive);
create_derive!(mul_like, Shr, shr_derive);
create_derive!(mul_like, Shl, shl_derive);

create_derive!(add_assign_like, AddAssign, add_assign_derive);
create_derive!(add_assign_like, SubAssign, sub_assign_derive);
create_derive!(add_assign_like, BitAndAssign, bit_and_assign_derive);
create_derive!(add_assign_like, BitOrAssign, bit_or_assign_derive);
create_derive!(add_assign_like, BitXorAssign, bit_xor_assign_derive);

create_derive!(mul_assign_like, MulAssign, mul_assign_derive);
create_derive!(mul_assign_like, DivAssign, div_assign_derive);
create_derive!(mul_assign_like, RemAssign, rem_assign_derive);
create_derive!(mul_assign_like, ShrAssign, shr_assign_derive);
create_derive!(mul_assign_like, ShlAssign, shl_assign_derive);

create_derive!(from_str, FromStr, from_str_derive);

create_derive!(display, Display, display_derive);
create_derive!(display, Binary, binary_derive);
create_derive!(display, Octal, octal_derive);
create_derive!(display, LowerHex, lower_hex_derive);
create_derive!(display, UpperHex, upper_hex_derive);
create_derive!(display, LowerExp, lower_exp_derive);
create_derive!(display, UpperExp, upper_exp_derive);
create_derive!(display, Pointer, pointer_derive);

create_derive!(index, Index, index_derive);
create_derive!(index_mut, IndexMut, index_mut_derive);
<commit_msg>Docs: Fix numbering<commit_after>//! # `derive_more`
//! Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
//! [`Not`] or [`From`].
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as when using the
//! commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//!
//! ```rust
//! # #[macro_use] extern crate derive_more;
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! enum MyEnum {
//!     Int(i32),
//!     UnsignedInt(u32),
//!     Nothing,
//! }
//!
//! fn main() {
//!     let my_11 = MyInt(5) + 6.into();
//!     assert_eq!(MyInt(11), MyInt(5) + 6.into());
//!     assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
//!     assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
//!     assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
//!     assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
//! }
//! ```
//!
//! ## The derivable traits
//!
//! Below are all the traits that you can derive using this library.
//! Some trait derivations are so similar that the furter documentation will only show a single one
//! of them.
//! You can recognize these by the "-like" suffix in their name.
//! The trait name before that will be the only one that is used throughout the further
//! documentation.
//!
//! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
//! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
//!
//! ### Conversion traits
//! These are traits that are used to convert automatically between types.
//!
//! 1. [`From`]
//! 2. [`Into`]
//! 3. [`FromStr`]
//!
//! ### Formatting traits
//! These traits are used for converting a struct to a string in different ways.
//!
//! 1. `Display`-like, contains [`Display`], [`Binary`], [`Octal`], [`LowerHex`], [`UpperHex`],
//!    [`LowerExp`], [`UpperExp`], [`Pointer`]
//!
//! ### Operators
//! These are traits that can be used for operator overloading.
//!
//! 1. [`Index`]
//! 2. `Not`-like, contains [`Not`] and [`Neg`]
//! 3. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`]
//!    and [`BitXorAssign`]
//! 4. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`]
//! 5. [`IndexMut`]
//! 6. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
//! 7. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and
//!    [`ShlAssign`]
//!
//! ### Static methods
//! These don't derive traits, but derive static methods instead.
//!
//! 1. `Constructor`, this derives a `new` method that can be used as a constructor. This is very
//!    basic if you need more customization for your constructor, check out the [`derive-new`] crate.
//!
//!
//! ## Generated code
//!
//! It is important to understand what code gets generated when using one of the derives from this
//! crate.
//! That is why the links below explain what code gets generated for a trait for each group from
//! before.
//!
//! 1. [`#[derive(From)]`](from.html)
//! 2. [`#[derive(Into)]`](into.html)
//! 3. [`#[derive(FromStr)]`](from_str.html)
//! 4. [`#[derive(Display)]`](display.html)
//! 5. [`#[derive(Index)]`](index_op.html)
//! 6. [`#[derive(Not)]`](not.html)
//! 7. [`#[derive(Add)]`](add.html)
//! 8. [`#[derive(Mul)]`](mul.html)
//! 9. [`#[derive(IndexMut)]`](index_mut.html)
//! 10. [`#[derive(AddAssign)]`](add_assign.html)
//! 11. [`#[derive(MulAssign)]`](mul_assign.html)
//! 12. [`#[derive(Constructor)]`](constructor.html)
//!
//! If you want to be sure what code is generated for your specific type I recommend using the
//! [`cargo-expand`] utility.
//! This will show you your code with all macros and derives expanded.
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.6.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! #[macro_use]
//! extern crate derive_more;
//! # fn main () {}
//! ```
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`derive-new`]: https://github.com/nrc/derive-new
//! [`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
//! [`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
//! [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
//! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
//! [`Binary`]: https://doc.rust-lang.org/std/fmt/trait.Binary.html
//! [`Octal`]: https://doc.rust-lang.org/std/fmt/trait.Octal.html
//! [`LowerHex`]: https://doc.rust-lang.org/std/fmt/trait.LowerHex.html
//! [`UpperHex`]: https://doc.rust-lang.org/std/fmt/trait.UpperHex.html
//! [`LowerExp`]: https://doc.rust-lang.org/std/fmt/trait.LowerExp.html
//! [`UpperExp`]: https://doc.rust-lang.org/std/fmt/trait.UpperExp.html
//! [`Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html
//! [`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html
//! [`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
//! [`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
//! [`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
//! [`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
//! [`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
//! [`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
//! [`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
//! [`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
//! [`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
//! [`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
//! [`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
//! [`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
//! [`IndexMut`]: https://doc.rust-lang.org/std/ops/trait.IndexMut.html
//! [`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
//! [`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
//! [`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
//! [`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
//! [`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
//! [`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
//! [`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
//! [`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
//! [`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
//! [`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html

extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;

mod utils;

mod from;
mod into;
mod constructor;
mod not_like;
mod add_like;
mod add_assign_like;
mod mul_like;
mod mul_assign_like;
mod from_str;
mod display;
mod index;
mod index_mut;

macro_rules! create_derive(
    ($mod_:ident, $trait_:ident, $fn_name: ident) => {
        #[proc_macro_derive($trait_)]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let ast = syn::parse(input).unwrap();
            $mod_::expand(&ast, stringify!($trait_)).into()
        }
    }
);

create_derive!(from, From, from_derive);

create_derive!(into, Into, into_derive);

create_derive!(constructor, Constructor, constructor_derive);

create_derive!(not_like, Not, not_derive);
create_derive!(not_like, Neg, neg_derive);

create_derive!(add_like, Add, add_derive);
create_derive!(add_like, Sub, sub_derive);
create_derive!(add_like, BitAnd, bit_and_derive);
create_derive!(add_like, BitOr, bit_or_derive);
create_derive!(add_like, BitXor, bit_xor_derive);

create_derive!(mul_like, Mul, mul_derive);
create_derive!(mul_like, Div, div_derive);
create_derive!(mul_like, Rem, rem_derive);
create_derive!(mul_like, Shr, shr_derive);
create_derive!(mul_like, Shl, shl_derive);

create_derive!(add_assign_like, AddAssign, add_assign_derive);
create_derive!(add_assign_like, SubAssign, sub_assign_derive);
create_derive!(add_assign_like, BitAndAssign, bit_and_assign_derive);
create_derive!(add_assign_like, BitOrAssign, bit_or_assign_derive);
create_derive!(add_assign_like, BitXorAssign, bit_xor_assign_derive);

create_derive!(mul_assign_like, MulAssign, mul_assign_derive);
create_derive!(mul_assign_like, DivAssign, div_assign_derive);
create_derive!(mul_assign_like, RemAssign, rem_assign_derive);
create_derive!(mul_assign_like, ShrAssign, shr_assign_derive);
create_derive!(mul_assign_like, ShlAssign, shl_assign_derive);

create_derive!(from_str, FromStr, from_str_derive);

create_derive!(display, Display, display_derive);
create_derive!(display, Binary, binary_derive);
create_derive!(display, Octal, octal_derive);
create_derive!(display, LowerHex, lower_hex_derive);
create_derive!(display, UpperHex, upper_hex_derive);
create_derive!(display, LowerExp, lower_exp_derive);
create_derive!(display, UpperExp, upper_exp_derive);
create_derive!(display, Pointer, pointer_derive);

create_derive!(index, Index, index_derive);
create_derive!(index_mut, IndexMut, index_mut_derive);
<|endoftext|>


<commit_before>//! Toy Math Library

use std::ops::{Add, Mul};

/// Calculate sine function with Taylor series as approximation approach
///
///
/// ```raw
///              x^3   x^5   x^7   x^9   x^11   x^13
/// sin(x) = x - --- + --- - --- + --- - ---- + ---- - ...
///               3!    5!    7!    9!    11!    13!
/// ```
///
/// Error Function :
///
/// ```raw
/// Error(x) = | sin(x) - taylor_sin(x) |
/// ```
///
/// * the error getting smaller when x getting close to 0
/// * the error getting greater when x getting far from 0
///
/// limit the x will make precision greater
///
/// trigonometric identities we can use :
///
/// * sin(2π+β) = sin(β)
/// * sin(π+β) = -sin(β)
/// * sin(-π/2+β) = -cos(β)
///
/// `sin(x) = sin(απ+β) = (-1)^α sin(β), ∀ α ∈ ℤ, β ∈ ℝ, 0 ≦ β < π`
///
pub fn taylor_sin<T>(x: T) -> T
    where T: Mul<T, Output=T> + Mul<f64, Output=T> +
             Add<T, Output=T> + Add<f64, Output=T> +
             Copy
{

    const A0: f64 =  1.0;                                   //  1/1!
    const A1: f64 = -1.666666666666666666666666666666E-1;   // -1/3!
    const A2: f64 =  8.333333333333333333333333333333E-3;   //  1/5!
    const A3: f64 = -1.984126984126984126984126984126E-4;   // -1/7!
    const A4: f64 =  2.755731922398589065255731922398E-6;   //  1/9!
    const A5: f64 = -2.505210838544171877505210838544E-8;   // -1/11!
    const A6: f64 =  1.605904383682161459939237717015E-10;  //  1/13!

    let x2 = x * x;

    ((((((
        x2 * A6
           + A5) * x2
           + A4) * x2
           + A3) * x2
           + A2) * x2
           + A1) * x2
           + A0) * x

}

/// Calculate cosine function with Taylor series as approximation approach
///
///
/// ```raw
///              x^2   x^4   x^6   x^8   x^10   x^12
/// sin(x) = 1 - --- + --- - --- + --- - ---- + ---- - ...
///               2!    4!    6!    8!    10!    12!
/// ```
///
/// Error Function :
///
/// ```raw
/// Error(x) = | cos(x) - taylor_cos(x) |
/// ```
///
/// * the error getting smaller when x getting close to 0
/// * the error getting greater when x getting far from 0
///
/// limit the x will make precision greater
///
/// trigonometric identities we can use :
///
/// * cos(2π+β) = cos(β)
/// * cos(π+β) = -cos(β)
/// * cos(-π/2+β) = sin(β)
///
/// `sin(x) = sin(απ+β) = (-1)^α sin(β), ∀ α ∈ ℤ, β ∈ ℝ, 0 ≦ β < π`
///
pub fn taylor_cos<T>(x: T) -> T
    where T: Mul<T, Output=T> + Mul<f64, Output=T> +
             Add<T, Output=T> + Add<f64, Output=T> +
             Copy
{

    const A0: f64 =  1.0;                                   //  1/0!
    const A1: f64 = -0.5;                                   // -1/2!
    const A2: f64 =  4.166666666666666666666666666666E-2;   //  1/4!
    const A3: f64 = -1.388888888888888888888888888888E-3;   // -1/6!
    const A4: f64 =  2.480158730158730158730158730158E-5;   //  1/8!
    const A5: f64 = -2.755731922398589065255731922398E-7;   // -1/10!
    const A6: f64 =  2.087675698786809897921009032120E-9;   //  1/12!

    let x2 = x * x;

    ((((((
        x2 * A6
           + A5) * x2
           + A4) * x2
           + A3) * x2
           + A2) * x2
           + A1) * x2
           + A0)

}

/// sine function for f64
///
/// Currently, we call [taylor_sin] and [taylor_cos] as implementation.
///
/// [taylor_sin]: fn.taylor_sin.html
/// [taylor_cos]: fn.taylor_cos.html
///
pub fn sin(data: f64) -> f64 {
    use std::f64::consts::{PI, FRAC_PI_2, FRAC_PI_4};

    let (data, neg_flag) = (data % PI, ((data / PI) as u8) % 2 != 0);
    let (data, neg_flag) = (data.abs(), neg_flag ^ (data < 0.));

    let ret = match data {
        data if ((0. <= data) && (data < FRAC_PI_4)) => {
            taylor_sin(data)
        },
        data if ((FRAC_PI_4 <= data) && (data < (PI - FRAC_PI_4))) => {
            taylor_cos(data - FRAC_PI_2)
        },
        data if (((PI - FRAC_PI_4) <= data) && (data < PI)) => {
            taylor_sin(PI - data)
        },
        _ => { panic!("why are you here ?") }
    };

    if neg_flag {
        return -ret;
    }

    ret
}

/// sine function for f32
///
/// Currently, we call [sin] as implementation.
///
/// [sin]: fn.sin.html
pub fn sinf(data: f32) -> f32 {
    return sin(data as f64) as f32;
}

/// cosine function for f64
///
/// Currently, we call [sin] as implementation.
///
/// [sin]: fn.sin.html
pub fn cos(data: f64) -> f64 {
    use std::f64::consts::FRAC_PI_2;

    sin(FRAC_PI_2 - data)
}

/// cosine function for f32
///
/// Currently, we call [cos] as implementation.
///
/// [cos]: fn.cos.html
pub fn cosf(data: f32) -> f32 {
    return cos(data as f64) as f32;
}
<commit_msg>add comments and little clean up<commit_after>//! Toy Math Library

use std::ops::{Add, Mul};

/// Calculate sine function with Taylor series as approximation approach
///
///
/// ```raw
///              x^3   x^5   x^7   x^9   x^11   x^13
/// sin(x) = x - --- + --- - --- + --- - ---- + ---- - ...
///               3!    5!    7!    9!    11!    13!
/// ```
///
/// Error Function :
///
/// ```raw
/// Error(x) = | sin(x) - taylor_sin(x) |
/// ```
///
/// * the error getting smaller when x getting close to 0
/// * the error getting greater when x getting far from 0
///
/// limit the x will make precision greater
///
/// trigonometric identities we can use :
///
/// * sin(2π+β) = sin(β)
/// * sin(π+β) = -sin(β)
/// * sin(-π/2+β) = -cos(β)
///
/// `sin(x) = sin(απ+β) = (-1)^α sin(β), ∀ α ∈ ℤ, β ∈ ℝ, 0 ≦ β < π`
///
pub fn taylor_sin<T>(x: T) -> T
    where T: Mul<T, Output=T> + Mul<f64, Output=T> +
             Add<T, Output=T> + Add<f64, Output=T> +
             Copy
{

    const A0: f64 =  1.0;                                   //  1/1!
    const A1: f64 = -1.666666666666666666666666666666E-1;   // -1/3!
    const A2: f64 =  8.333333333333333333333333333333E-3;   //  1/5!
    const A3: f64 = -1.984126984126984126984126984126E-4;   // -1/7!
    const A4: f64 =  2.755731922398589065255731922398E-6;   //  1/9!
    const A5: f64 = -2.505210838544171877505210838544E-8;   // -1/11!
    const A6: f64 =  1.605904383682161459939237717015E-10;  //  1/13!

    let x2 = x * x;

    ((((((
        x2 * A6
           + A5) * x2
           + A4) * x2
           + A3) * x2
           + A2) * x2
           + A1) * x2
           + A0) * x

}

/// Calculate cosine function with Taylor series as approximation approach
///
///
/// ```raw
///              x^2   x^4   x^6   x^8   x^10   x^12
/// sin(x) = 1 - --- + --- - --- + --- - ---- + ---- - ...
///               2!    4!    6!    8!    10!    12!
/// ```
///
/// Error Function :
///
/// ```raw
/// Error(x) = | cos(x) - taylor_cos(x) |
/// ```
///
/// * the error getting smaller when x getting close to 0
/// * the error getting greater when x getting far from 0
///
/// limit the x will make precision greater
///
/// trigonometric identities we can use :
///
/// * cos(2π+β) = cos(β)
/// * cos(π+β) = -cos(β)
/// * cos(-π/2+β) = sin(β)
///
/// `sin(x) = sin(απ+β) = (-1)^α sin(β), ∀ α ∈ ℤ, β ∈ ℝ, 0 ≦ β < π`
///
pub fn taylor_cos<T>(x: T) -> T
    where T: Mul<T, Output=T> + Mul<f64, Output=T> +
             Add<T, Output=T> + Add<f64, Output=T> +
             Copy
{

    const A0: f64 =  1.0;                                   //  1/0!
    const A1: f64 = -0.5;                                   // -1/2!
    const A2: f64 =  4.166666666666666666666666666666E-2;   //  1/4!
    const A3: f64 = -1.388888888888888888888888888888E-3;   // -1/6!
    const A4: f64 =  2.480158730158730158730158730158E-5;   //  1/8!
    const A5: f64 = -2.755731922398589065255731922398E-7;   // -1/10!
    const A6: f64 =  2.087675698786809897921009032120E-9;   //  1/12!

    let x2 = x * x;

    ((((((
        x2 * A6
           + A5) * x2
           + A4) * x2
           + A3) * x2
           + A2) * x2
           + A1) * x2
           + A0)

}

/// sine function for f64
///
/// Currently, we call [taylor_sin] and [taylor_cos] as implementation.
///
/// [taylor_sin]: fn.taylor_sin.html
/// [taylor_cos]: fn.taylor_cos.html
///
pub fn sin(data: f64) -> f64 {
    use std::f64::consts::{PI, FRAC_PI_2, FRAC_PI_4};

    // [-∞, ∞] => (-π, π)
    // sin(θ) = -sin(θ-π)
    let (data, neg_flag) = (data % PI, ((data / PI) as u8) % 2 != 0);
    // (-π, π) => (0, π)
    // sin(θ) = -sin(-θ)
    let (data, neg_flag) = (data.abs(), neg_flag ^ (data < 0.));

    let ret = match data {
        data if ((0. <= data) && (data < FRAC_PI_4)) => {
            // sin(θ)
            taylor_sin(data)
        },
        data if ((FRAC_PI_4 <= data) && (data < (PI - FRAC_PI_4))) => {
            // sin(θ) = cos(θ-π/2)
            taylor_cos(data - FRAC_PI_2)
        },
        data if (((PI - FRAC_PI_4) <= data) && (data < PI)) => {
            // sin(θ) = sin(π-θ)
            taylor_sin(PI - data)
        },
        _ => { panic!("why are you here ?") }
    };

    if neg_flag {
        return -ret;
    }

    ret
}

/// sine function for f32
///
/// Currently, we call [sin] as implementation.
///
/// [sin]: fn.sin.html
pub fn sinf(data: f32) -> f32 {
    sin(data as f64) as f32
}

/// cosine function for f64
///
/// Currently, we call [sin] as implementation.
///
/// [sin]: fn.sin.html
pub fn cos(data: f64) -> f64 {
    use std::f64::consts::FRAC_PI_2;

    sin(FRAC_PI_2 - data)
}

/// cosine function for f32
///
/// Currently, we call [cos] as implementation.
///
/// [cos]: fn.cos.html
pub fn cosf(data: f32) -> f32 {
    cos(data as f64) as f32
}
<|endoftext|>


<commit_before>//! # Half-precision conversion for Rust
//! This crate uses the fast table-based f32 <-> f16 conversions given in
//! "Fast Half Float Conversions" by Jeroen van der Zijp; see
//! `ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf`.

use std::mem::transmute;

#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
pub struct f16 {
    pub bytes: u16,
}

impl PartialEq for f16 {
    fn eq(self: &f16, other: &f16) -> bool {
        return self.bytes == other.bytes;
    }
}

impl From<f32> for f16 {
    fn from(f: f32) -> f16 {
        unsafe {
            let base_table: *const u16 = transmute(include_bytes!("base_table.bin"));
            let shift_table: *const u8 = transmute(include_bytes!("shift_table.bin"));

            let ff: u32 = transmute(f);

            let bytes =
                *base_table.offset(((ff >> 23) & 0x1FF) as isize) +
                ((ff & 0x007FFFFF) >> *shift_table.offset(((ff >> 23) & 0x1FF) as isize)) as u16;
            f16 { bytes: bytes }
        }
    }
}

impl Into<f32> for f16 {
    fn into(self: f16) -> f32 {
        unsafe {
            let mantissa_table: *const u32 = transmute(include_bytes!("mantissa_table.bin"));
            let offset_table: *const u32 = transmute(include_bytes!("offset_table.bin"));
            let exponent_table: *const u32 = transmute(include_bytes!("exponent_table.bin"));

            let h0 = (self.bytes >> 10) as isize;
            let h1 = (self.bytes & 0x3FF) as u16 as isize;

            let mt_offset = *offset_table.offset(h0) as isize + h1;
            transmute(*mantissa_table.offset(mt_offset) + *exponent_table.offset(h0))
        }
    }
}

pub fn vec_to_f16(v: &Vec<f32>) -> Vec<f16> {
    let mut tr = Vec::with_capacity(v.len());
    for it in v.iter() {
        tr.push(f16::from(*it));
    }
    tr
}

pub fn vec_from_f16(v: &Vec<f16>) -> Vec<f32> {
    let mut tr = Vec::with_capacity(v.len());
    for it in v.iter() {
        tr.push((*it).into());
    }
    tr
}

#[test]
fn test() {
    for bytes in 0..(1 << 15) as u16 {
        let h0 = f16 { bytes: bytes };

        let f: f32 = h0.into();
        let h1 = f16::from(f);
        let f1: f32 = h1.into();
        assert_eq!(f, f1);
    }
}
<commit_msg>changed vec_* to slice_*<commit_after>//! # Half-precision conversion for Rust
//! This crate uses the fast table-based f32 <-> f16 conversions given in
//! "Fast Half Float Conversions" by Jeroen van der Zijp; see
//! `ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf`.

use std::mem::transmute;

#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
pub struct f16 {
    pub bytes: u16,
}

impl PartialEq for f16 {
    fn eq(self: &f16, other: &f16) -> bool {
        return self.bytes == other.bytes;
    }
}

impl From<f32> for f16 {
    fn from(f: f32) -> f16 {
        unsafe {
            let base_table: *const u16 = transmute(include_bytes!("base_table.bin"));
            let shift_table: *const u8 = transmute(include_bytes!("shift_table.bin"));

            let ff: u32 = transmute(f);

            let bytes =
                *base_table.offset(((ff >> 23) & 0x1FF) as isize) +
                ((ff & 0x007FFFFF) >> *shift_table.offset(((ff >> 23) & 0x1FF) as isize)) as u16;
            f16 { bytes: bytes }
        }
    }
}

impl Into<f32> for f16 {
    fn into(self: f16) -> f32 {
        unsafe {
            let mantissa_table: *const u32 = transmute(include_bytes!("mantissa_table.bin"));
            let offset_table: *const u32 = transmute(include_bytes!("offset_table.bin"));
            let exponent_table: *const u32 = transmute(include_bytes!("exponent_table.bin"));

            let h0 = (self.bytes >> 10) as isize;
            let h1 = (self.bytes & 0x3FF) as u16 as isize;

            let mt_offset = *offset_table.offset(h0) as isize + h1;
            transmute(*mantissa_table.offset(mt_offset) + *exponent_table.offset(h0))
        }
    }
}

pub fn slice_to_f16(v: &[f32]) -> Vec<f16> {
    let mut tr = Vec::with_capacity(v.len());
    for it in v.iter() {
        tr.push(f16::from(*it));
    }
    tr
}

pub fn slice_to_f32(v: &[f16]) -> Vec<f32> {
    let mut tr = Vec::with_capacity(v.len());
    for it in v.iter() {
        tr.push((*it).into());
    }
    tr
}

#[test]
fn test() {
    for bytes in 0..(1 << 15) as u16 {
        let h0 = f16 { bytes: bytes };

        let f: f32 = h0.into();
        let h1 = f16::from(f);
        let f1: f32 = h1.into();
        assert_eq!(f, f1);
    }
}
<|endoftext|>


<commit_before>use std::iter::repeat;

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

    #[test]
    fn zeros_creates_zero_filled_vector_of_correct_size_and_length() {
        let a1 = zeros(vec![0]);
        assert_eq!(a1.dimensions, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = zeros(vec![1]);
        assert_eq!(a2.dimensions, vec![1]);
        assert_eq!(a2.data, vec![0]);

        let a3 = zeros(vec![10]);
        assert_eq!(a3.dimensions, vec![10]);
        assert_eq!(a3.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

        let a4 = zeros(vec![1, 2, 3]);
        assert_eq!(a4.dimensions, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn index_test_1() {
        let array = QArray {
            dimensions: vec![1, 1, 1],
            data: vec![1],
        };

        assert_eq!(array.index(vec![0, 0, 0].as_slice()), Some(1));
    }

    #[test]
    fn index_test_2() {
        let array = QArray {
            dimensions: vec![2, 2, 1],
            data: vec![1, 2, 3, 4],
        };

        assert_eq!(array.index(vec![1, 0, 0].as_slice()), Some(2));
        assert_eq!(array.index(vec![0, 1, 0].as_slice()), Some(3));
    }

    #[test]
    fn index_test_3() {
        let array = QArray {
            dimensions: vec![2, 4, 3],
            data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                       22, 23, 24],
        };

        assert_eq!(array.index(vec![1, 2, 1].as_slice()), Some(14));
        assert_eq!(array.index(vec![0, 2, 2].as_slice()), Some(21));
    }

    #[test]
    fn test_1d_vec_to_qarray() {
        let v = vec![1, 2, 3];
        let array = v.to_qarray();

        assert_eq!(array.dimensions, vec![3]);
        assert_eq!(array.data, vec![1, 2, 3]);
    }

    #[test]
    fn test_2d_vec_to_qarray() {
        let v1 = vec![vec![1, 2], vec![3, 4]];
        let array1 = v1.to_qarray();

        assert_eq!(array1.dimensions, vec![2, 2]);
        assert_eq!(array1.data, vec![1, 2, 3, 4]);

        let v2 = vec![vec![1, 2, 3], vec![4, 5, 6]];
        let array2 = v2.to_qarray();

        assert_eq!(array2.dimensions, vec![2, 3]);
        assert_eq!(array2.data, vec![1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn test_3d_vec_to_qarray() {
        let v = vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]];
        let array = v.to_qarray();

        assert_eq!(array.dimensions, vec![2, 2, 2]);
        assert_eq!(array.data, vec![1, 2, 3, 4, 5, 6, 7, 8]);
    }
}

/// Return a new QArray of the given dimensions, filled with zeroes.
///
/// ```
/// use quota::zeros;
/// let qarray = zeros(vec![1, 2, 3]);
/// assert_eq!(qarray.dimensions, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![0, 0, 0, 0, 0, 0])
/// ```
pub fn zeros(dimensions: Vec<usize>) -> QArray {
    let data = repeat(0).take(dimensions.iter().sum()).collect::<Vec<isize>>();
    QArray { dimensions, data }
}

#[derive(Debug)]
pub struct QArray {
    pub dimensions: Vec<usize>,
    pub data: Vec<isize>,
}

impl QArray {
    /// Return the element at the given coordinates.
    /// If the coordinates don't specify a single element (e.g. 2D coordinates
    /// are given for a 3D array), or the coordinates are invalid,
    /// this function will return None.
    ///
    /// ```
    /// use quota::*;
    ///
    /// let qarray = zeros(vec![2, 2]);
    /// assert_eq!(qarray.index(vec![0, 0].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![1, 1].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![3, 3].as_slice()), None);
    /// assert_eq!(qarray.index(vec![1].as_slice()), None);
    /// ```
    pub fn index(&self, coordinates: &[usize]) -> Option<isize> {
        // Check that the coordinates are valid
        // The number of coordinates should match the dimensions of the array.
        // Each coordinate should be less than the length of the array
        // in that dimension.
        if coordinates.len() != self.dimensions.len() { return None }
        for (coord, dim) in coordinates.iter().zip(self.dimensions.as_slice()) {
            if *coord >= *dim { return None }
        }

        return Some(self.data[offset(self, coordinates)])
    }
}

fn offset(array: &QArray, coordinates: &[usize]) -> usize {
    coordinates
        .into_iter()
        .enumerate()
        .map(|(idx, coord)| {
                 array
                     .dimensions
                     .iter()
                     .take(idx)
                     .fold(*coord, |acc, x| acc * x)
             })
        .fold(0, |acc, x| acc + x)
}

trait ToQArray {
    fn to_qarray(&self) -> QArray;
}

impl ToQArray for Vec<isize> {
    fn to_qarray(&self) -> QArray {
        QArray {
            dimensions: vec![self.len()],
            data: self.clone(),
        }
    }
}

impl ToQArray for Vec<Vec<isize>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let l2 = match self.first() {
            Some(fst) => fst.len(),
            None => 0,
        };
        let dimensions = vec![l1, l2];

        let mut data = Vec::new();

        for row in self {
            for e in row {
                data.push(*e);
            }
        }

        QArray { dimensions, data }
    }
}

impl ToQArray for Vec<Vec<Vec<isize>>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let (l2, l3) = match self.first() {
            Some(fst) => match fst.first() {
                Some(ffst) => (fst.len(), ffst.len()),
                None => (fst.len(), 0)
            },
            None => (0, 0)
        };
        let dimensions = vec![l1, l2, l3];

        let mut data = Vec::new();

        for row in self {
            for col in row {
                for e in col {
                    data.push(*e)
                }
            }
        };

        QArray { dimensions, data }
    }
}
<commit_msg>Rename dimension to shape<commit_after>use std::iter::repeat;

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

    #[test]
    fn zeros_creates_zero_filled_vector_of_correct_size_and_length() {
        let a1 = zeros(vec![0]);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = zeros(vec![1]);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![0]);

        let a3 = zeros(vec![10]);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

        let a4 = zeros(vec![1, 2, 3]);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn index_test_1() {
        let array = QArray {
            shape: vec![1, 1, 1],
            data: vec![1],
        };

        assert_eq!(array.index(vec![0, 0, 0].as_slice()), Some(1));
    }

    #[test]
    fn index_test_2() {
        let array = QArray {
            shape: vec![2, 2, 1],
            data: vec![1, 2, 3, 4],
        };

        assert_eq!(array.index(vec![1, 0, 0].as_slice()), Some(2));
        assert_eq!(array.index(vec![0, 1, 0].as_slice()), Some(3));
    }

    #[test]
    fn index_test_3() {
        let array = QArray {
            shape: vec![2, 4, 3],
            data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                       22, 23, 24],
        };

        assert_eq!(array.index(vec![1, 2, 1].as_slice()), Some(14));
        assert_eq!(array.index(vec![0, 2, 2].as_slice()), Some(21));
    }

    #[test]
    fn test_1d_vec_to_qarray() {
        let v = vec![1, 2, 3];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![3]);
        assert_eq!(array.data, vec![1, 2, 3]);
    }

    #[test]
    fn test_2d_vec_to_qarray() {
        let v1 = vec![vec![1, 2], vec![3, 4]];
        let array1 = v1.to_qarray();

        assert_eq!(array1.shape, vec![2, 2]);
        assert_eq!(array1.data, vec![1, 2, 3, 4]);

        let v2 = vec![vec![1, 2, 3], vec![4, 5, 6]];
        let array2 = v2.to_qarray();

        assert_eq!(array2.shape, vec![2, 3]);
        assert_eq!(array2.data, vec![1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn test_3d_vec_to_qarray() {
        let v = vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![2, 2, 2]);
        assert_eq!(array.data, vec![1, 2, 3, 4, 5, 6, 7, 8]);
    }
}

/// Return a new QArray of the given shape, filled with zeroes.
///
/// ```
/// use quota::zeros;
/// let qarray = zeros(vec![1, 2, 3]);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![0, 0, 0, 0, 0, 0])
/// ```
pub fn zeros(shape: Vec<usize>) -> QArray {
    let data = repeat(0).take(shape.iter().sum()).collect::<Vec<isize>>();
    QArray { shape, data }
}

#[derive(Debug)]
pub struct QArray {
    pub shape: Vec<usize>,
    pub data: Vec<isize>,
}

impl QArray {
    /// Return the element at the given coordinates.
    /// If the coordinates don't specify a single element (e.g. 2D coordinates
    /// are given for a 3D array), or the coordinates are invalid,
    /// this function will return None.
    ///
    /// ```
    /// use quota::*;
    ///
    /// let qarray = zeros(vec![2, 2]);
    /// assert_eq!(qarray.index(vec![0, 0].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![1, 1].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![3, 3].as_slice()), None);
    /// assert_eq!(qarray.index(vec![1].as_slice()), None);
    /// ```
    pub fn index(&self, coordinates: &[usize]) -> Option<isize> {
        // Check that the coordinates are valid
        // The number of coordinates should match the shape of the array.
        // Each coordinate should be less than the length of the array
        // in that dimension.
        if coordinates.len() != self.shape.len() { return None }
        for (coord, dim) in coordinates.iter().zip(self.shape.as_slice()) {
            if *coord >= *dim { return None }
        }

        return Some(self.data[offset(self, coordinates)])
    }
}

fn offset(array: &QArray, coordinates: &[usize]) -> usize {
    coordinates
        .into_iter()
        .enumerate()
        .map(|(idx, coord)| {
                 array
                     .shape
                     .iter()
                     .take(idx)
                     .fold(*coord, |acc, x| acc * x)
             })
        .fold(0, |acc, x| acc + x)
}

trait ToQArray {
    fn to_qarray(&self) -> QArray;
}

impl ToQArray for Vec<isize> {
    fn to_qarray(&self) -> QArray {
        QArray {
            shape: vec![self.len()],
            data: self.clone(),
        }
    }
}

impl ToQArray for Vec<Vec<isize>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let l2 = match self.first() {
            Some(fst) => fst.len(),
            None => 0,
        };
        let shape = vec![l1, l2];

        let mut data = Vec::new();

        for row in self {
            for e in row {
                data.push(*e);
            }
        }

        QArray { shape, data }
    }
}

impl ToQArray for Vec<Vec<Vec<isize>>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let (l2, l3) = match self.first() {
            Some(fst) => match fst.first() {
                Some(ffst) => (fst.len(), ffst.len()),
                None => (fst.len(), 0)
            },
            None => (0, 0)
        };
        let shape = vec![l1, l2, l3];

        let mut data = Vec::new();

        for row in self {
            for col in row {
                for e in col {
                    data.push(*e)
                }
            }
        };

        QArray { shape, data }
    }
}
<|endoftext|>


<commit_before>
/// Actions are just boxed immutable functions that take an argument of the event that triggered them
pub type Action<S, E> = Box<Fn(&S,&E)>;

/// Predicates are used to filter down whether a transition can occur
pub type Predicate<S, E> = Box<Fn(&S,&E) -> bool>;

/// Trait that should be trivially implementable for any C-Like Enum type
pub trait EnumTag: Copy {
	/// returns the discriminator tag for the enum (some_value as usize)
	fn tag_number(&self) -> usize;
	/// returns the highest discriminator tag for this enum
	fn max_tag_number() -> usize;
}

/// The Transition records, for a given current state, what event type triggers it to move to
/// what state, performing a specific action on the transition, filterable by a predicate function
struct Transition<S: EnumTag, E: EnumTag> {
	predicate: Option<Predicate<S, E>>,
	next_state: S,
	action: Action<S, E>,
}

/// The EdgeTransitions record all the Transitions for a given event type
struct EventTransitions<S: EnumTag, E: EnumTag> {
	transitions: Vec<Transition<S, E>>,
}

/// The StateTransition records all Transitions for a given state
struct StateTransitions<S: EnumTag, E: EnumTag> {
	edges: Vec<EventTransitions<S, E>>,
}

/// The Machine is the Finite State Machine, which has a current state and set of all valid
/// transitions
pub struct Machine<S: EnumTag, E: EnumTag> {
	state: S,
	transitions: Vec<StateTransitions<S, E>>,
}

impl<S: EnumTag, E: EnumTag> Machine<S, E> {
	/// Constructs a new FSM with a given initial state
	pub fn new(initial_state: S) -> Machine<S, E> {
		let mut transitions = Vec::with_capacity(S::max_tag_number());

		for _ in 0..S::max_tag_number() + 1 {
			let mut edges = Vec::with_capacity(E::max_tag_number());

			for _ in 0..E::max_tag_number() + 1 {
				edges.push(EventTransitions {
					transitions: Vec::new(),
				});
			}

			transitions.push(StateTransitions {
				edges: edges,
			});
		}

		Machine {
			state: initial_state,
			transitions: transitions,
		}
	}

	/// Registers a new valid transition with the FSM
	pub fn add_transition(&mut self, in_state: S, on_event: E, next_state: S, action: Action<S, E>) {
		let transition = &mut self.transitions[in_state.tag_number()];

		let edge = &mut transition.edges[on_event.tag_number()];

		edge.transitions.push(Transition {
			predicate: None,
			action: action,
			next_state: next_state,
		});
	}

	/// Retrieves a reference to the current state
	pub fn current_state(&self) -> S {
		self.state
	}

	/// Tick the State Machine with an Event
	pub fn on_event(&mut self, event_type: E) {
		let transition = &self.transitions[self.state.tag_number()];
		let edge = &transition.edges[event_type.tag_number()];

		for transition in edge.transitions.iter() {
			let valid = match &transition.predicate {
				&Some(ref p) => (*p)(&self.current_state(), &event_type),
				&None => true,
			};

			if valid {
				(*transition.action)(&self.state, &event_type);
				self.state = transition.next_state;
				break;
			}
		}
	}
}

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

	#[derive(Copy, Clone, Debug, Eq, PartialEq)]
	enum TurnStyleState {
		Locked,
		Unlocked,
	}

	#[derive(Copy, Clone, Debug, Eq, PartialEq)]
	enum TurnStyleEvent {
		Push,
		InsertCoin,
	}

	impl EnumTag for TurnStyleState {
		fn tag_number(&self) -> usize {
			*self as usize
		}
		fn max_tag_number() -> usize {
			TurnStyleState::Unlocked as usize
		}
	}

	impl EnumTag for TurnStyleEvent {
		fn tag_number(&self) -> usize {
			*self as usize
		}
		fn max_tag_number() -> usize {
			TurnStyleEvent::InsertCoin as usize
		}
	}

	#[test]
	fn test_machine() {
		let mut machine = Machine::new(TurnStyleState::Locked);
		machine.add_transition(
			TurnStyleState::Locked, TurnStyleEvent::InsertCoin,
			TurnStyleState::Unlocked, Box::new(|_,_| println!("unlocked"))
		);
		machine.add_transition(
			TurnStyleState::Unlocked, TurnStyleEvent::Push,
			TurnStyleState::Locked, Box::new(|_,_| println!("locked"))
		);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
	}
}
<commit_msg>I added lifetime annotations and internalised the boxing of the closures, so it's tidier, yay<commit_after>
/// Actions are just boxed immutable functions that take an argument of the event that triggered them
pub type Action<'a, S, E> = Box<Fn(&S,&E) + 'a>;

/// Predicates are used to filter down whether a transition can occur
pub type Predicate<'a, S, E> = Box<Fn(&S,&E) -> bool + 'a>;

/// Trait that should be trivially implementable for any C-Like Enum type
pub trait EnumTag: Copy {
	/// returns the discriminator tag for the enum (some_value as usize)
	fn tag_number(&self) -> usize;
	/// returns the highest discriminator tag for this enum
	fn max_tag_number() -> usize;
}

/// The Transition records, for a given current state, what event type triggers it to move to
/// what state, performing a specific action on the transition, filterable by a predicate function
struct Transition<'a, S: EnumTag, E: EnumTag> {
	predicate: Option<Predicate<'a, S, E>>,
	next_state: S,
	action: Action<'a, S, E>,
}

/// The EdgeTransitions record all the Transitions for a given event type
struct EventTransitions<'a, S: EnumTag, E: EnumTag> {
	transitions: Vec<Transition<'a, S, E>>,
}

/// The StateTransition records all Transitions for a given state
struct StateTransitions<'a, S: EnumTag, E: EnumTag> {
	edges: Vec<EventTransitions<'a, S, E>>,
}

/// The Machine is the Finite State Machine, which has a current state and set of all valid
/// transitions
pub struct Machine<'a, S: EnumTag, E: EnumTag> {
	state: S,
	transitions: Vec<StateTransitions<'a, S, E>>,
}

impl<'a, S: EnumTag, E: EnumTag> Machine<'a, S, E> {
	/// Constructs a new FSM with a given initial state
	pub fn new(initial_state: S) -> Machine<'a, S, E> {
		let mut transitions = Vec::with_capacity(S::max_tag_number());

		for _ in 0..S::max_tag_number() + 1 {
			let mut edges = Vec::with_capacity(E::max_tag_number());

			for _ in 0..E::max_tag_number() + 1 {
				edges.push(EventTransitions {
					transitions: Vec::new(),
				});
			}

			transitions.push(StateTransitions {
				edges: edges,
			});
		}

		Machine {
			state: initial_state,
			transitions: transitions,
		}
	}

	/// Registers a new valid transition with the FSM
	pub fn add_transition<F: Fn(&S, &E) + 'a>(&mut self, in_state: S, on_event: E, next_state: S, action: F) {
		let transition = &mut self.transitions[in_state.tag_number()];

		let edge = &mut transition.edges[on_event.tag_number()];

		edge.transitions.push(Transition {
			predicate: None,
			action: Box::new(action),
			next_state: next_state,
		});
	}

	/// Retrieves a reference to the current state
	pub fn current_state(&self) -> S {
		self.state
	}

	/// Tick the State Machine with an Event
	pub fn on_event(&mut self, event_type: E) {
		let transition = &self.transitions[self.state.tag_number()];
		let edge = &transition.edges[event_type.tag_number()];

		for transition in edge.transitions.iter() {
			let valid = match &transition.predicate {
				&Some(ref p) => (*p)(&self.current_state(), &event_type),
				&None => true,
			};

			if valid {
				(*transition.action)(&self.state, &event_type);
				self.state = transition.next_state;
				break;
			}
		}
	}
}

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

	#[derive(Copy, Clone, Debug, Eq, PartialEq)]
	enum TurnStyleState {
		Locked,
		Unlocked,
	}

	#[derive(Copy, Clone, Debug, Eq, PartialEq)]
	enum TurnStyleEvent {
		Push,
		InsertCoin,
	}

	impl EnumTag for TurnStyleState {
		fn tag_number(&self) -> usize {
			*self as usize
		}
		fn max_tag_number() -> usize {
			TurnStyleState::Unlocked as usize
		}
	}

	impl EnumTag for TurnStyleEvent {
		fn tag_number(&self) -> usize {
			*self as usize
		}
		fn max_tag_number() -> usize {
			TurnStyleEvent::InsertCoin as usize
		}
	}

	#[test]
	fn test_machine() {
		let mut machine = Machine::new(TurnStyleState::Locked);
		machine.add_transition(
			TurnStyleState::Locked, TurnStyleEvent::InsertCoin,
			TurnStyleState::Unlocked, |_,_| println!("unlocked")
		);
		machine.add_transition(
			TurnStyleState::Unlocked, TurnStyleEvent::Push,
			TurnStyleState::Locked, |_,_| println!("locked")
		);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::InsertCoin);
		assert!(machine.current_state() == TurnStyleState::Unlocked);
		machine.on_event(TurnStyleEvent::Push);
		assert!(machine.current_state() == TurnStyleState::Locked);
	}
}
<|endoftext|>


<commit_before>#![feature(inclusive_range_syntax)]

extern crate arrayvec;
extern crate collect_slice;
extern crate crossbeam;
extern crate map_in_place;
extern crate num;
extern crate quad_osc;
extern crate rand;

pub mod allocs;
pub mod coefs;
pub mod consts;
pub mod decoder;
pub mod descramble;
pub mod enhance;
pub mod frame;
pub mod gain;
pub mod params;
pub mod prev;
pub mod scan;
pub mod spectral;
pub mod unvoiced;
pub mod voiced;
pub mod window;

pub use decoder::IMBEDecoder;
pub use frame::ReceivedFrame;
<commit_msg>Add crate description<commit_after>//! Decode the Improved Multi-Band Excitation (IMBE) digital voice codec.

#![feature(inclusive_range_syntax)]

extern crate arrayvec;
extern crate collect_slice;
extern crate crossbeam;
extern crate map_in_place;
extern crate num;
extern crate quad_osc;
extern crate rand;

pub mod allocs;
pub mod coefs;
pub mod consts;
pub mod decoder;
pub mod descramble;
pub mod enhance;
pub mod frame;
pub mod gain;
pub mod params;
pub mod prev;
pub mod scan;
pub mod spectral;
pub mod unvoiced;
pub mod voiced;
pub mod window;

pub use decoder::IMBEDecoder;
pub use frame::ReceivedFrame;
<|endoftext|>


<commit_before>#![allow(unstable)]

use std::io::Command;
use std::io::fs::PathExtensions;
use std::os;
use std::str;

pub fn target_supported() -> bool {
    os::getenv("HOST") == os::getenv("TARGET") ||
        os::getenv("PKG_CONFIG_ALLOW_CROSS") == Some("1".to_string())
}

pub struct Options {
    pub statik: bool,
    pub atleast_version: Option<String>,
}

pub fn find_library(name: &str) -> Result<(), String> {
    find_library_opts(name, &default_options(name))
}

pub fn find_library_opts(name: &str, options: &Options) -> Result<(), String> {
    if os::getenv(format!("{}_NO_PKG_CONFIG", envify(name)).as_slice()).is_some() {
        return Err(format!("pkg-config requested to be aborted for {}", name))
    } else if !target_supported() {
        return Err("pkg-config doesn't handle cross compilation. Use \
                    PKG_CONFIG_ALLOW_CROSS=1 to override".to_string());
    }
    let mut cmd = Command::new("pkg-config");
    if options.statik {
        cmd.arg("--static");
    }
    cmd.arg("--libs")
       .env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1")
       .arg(name);
    match options.atleast_version {
        Some(ref v) => { cmd.arg(format!("--atleast-version={}", v)); }
        None => {}
    }
    let out = try!(cmd.output().map_err(|e| {
        format!("failed to run `{}`: {}", cmd, e)
    }));
    let stdout = str::from_utf8(out.output.as_slice()).unwrap();
    let stderr = str::from_utf8(out.error.as_slice()).unwrap();
    if !out.status.success() {
        let mut msg = format!("`{}` did not exit successfully: {}", cmd,
                              out.status);
        if stdout.len() > 0 {
            msg.push_str("\n--- stdout\n");
            msg.push_str(stdout);
        }
        if stderr.len() > 0 {
            msg.push_str("\n--- stderr\n");
            msg.push_str(stderr);
        }
        return Err(msg)
    }

    let mut dirs = Vec::new();
    let parts = stdout.split(' ').filter(|l| !l.is_empty() && l.len() > 2)
                      .map(|arg| (&arg[0..2], &arg[2..]))
                      .collect::<Vec<_>>();
    for &(flag, val) in parts.iter() {
        if flag == "-L" {
            println!("cargo:rustc-flags=-L native={}", val);
            dirs.push(Path::new(val));
        }
    }
    for &(flag, val) in parts.iter() {
        if flag == "-l" {
            if options.statik && !is_system_lib(val, &dirs[]) {
                println!("cargo:rustc-flags=-l static={}", val);
            } else {
                println!("cargo:rustc-flags=-l {}", val);
            }
        }
    }
    Ok(())
}

pub fn default_options(name: &str) -> Options {
    let name = envify(name);
    let statik = if os::getenv(format!("{}_STATIC", name).as_slice()).is_some() {
        true
    } else if os::getenv(format!("{}_DYNAMIC", name).as_slice()).is_some() {
        false
    } else if os::getenv("PKG_CONFIG_ALL_STATIC").is_some() {
        true
    } else if os::getenv("PKG_CONFIG_ALL_DYNAMIC").is_some() {
        false
    } else {
        false
    };
    Options { statik: statik, atleast_version: None }
}

fn envify(name: &str) -> String {
    name.chars().map(|c| c.to_uppercase()).map(|c| if c == '-' {'_'} else {c})
        .collect()
}

fn is_system_lib(name: &str, dirs: &[Path]) -> bool {
    let libname = format!("lib{}.a", name);
    let root = Path::new("/usr");
    !dirs.iter().any(|d| {
        !root.is_ancestor_of(d) && d.join(&libname).exists()
    })
}
<commit_msg>Change how atleast_version is passed to pkg-config<commit_after>#![allow(unstable)]

use std::io::Command;
use std::io::fs::PathExtensions;
use std::os;
use std::str;

pub fn target_supported() -> bool {
    os::getenv("HOST") == os::getenv("TARGET") ||
        os::getenv("PKG_CONFIG_ALLOW_CROSS") == Some("1".to_string())
}

pub struct Options {
    pub statik: bool,
    pub atleast_version: Option<String>,
}

pub fn find_library(name: &str) -> Result<(), String> {
    find_library_opts(name, &default_options(name))
}

pub fn find_library_opts(name: &str, options: &Options) -> Result<(), String> {
    if os::getenv(format!("{}_NO_PKG_CONFIG", envify(name)).as_slice()).is_some() {
        return Err(format!("pkg-config requested to be aborted for {}", name))
    } else if !target_supported() {
        return Err("pkg-config doesn't handle cross compilation. Use \
                    PKG_CONFIG_ALLOW_CROSS=1 to override".to_string());
    }
    let mut cmd = Command::new("pkg-config");
    if options.statik {
        cmd.arg("--static");
    }
    cmd.arg("--libs")
       .env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1");
    match options.atleast_version {
        Some(ref v) => { cmd.arg(format!("{} >= {}", name, v)); }
        None => { cmd.arg(name); }
    }
    let out = try!(cmd.output().map_err(|e| {
        format!("failed to run `{}`: {}", cmd, e)
    }));
    let stdout = str::from_utf8(out.output.as_slice()).unwrap();
    let stderr = str::from_utf8(out.error.as_slice()).unwrap();
    if !out.status.success() {
        let mut msg = format!("`{}` did not exit successfully: {}", cmd,
                              out.status);
        if stdout.len() > 0 {
            msg.push_str("\n--- stdout\n");
            msg.push_str(stdout);
        }
        if stderr.len() > 0 {
            msg.push_str("\n--- stderr\n");
            msg.push_str(stderr);
        }
        return Err(msg)
    }

    let mut dirs = Vec::new();
    let parts = stdout.split(' ').filter(|l| !l.is_empty() && l.len() > 2)
                      .map(|arg| (&arg[0..2], &arg[2..]))
                      .collect::<Vec<_>>();
    for &(flag, val) in parts.iter() {
        if flag == "-L" {
            println!("cargo:rustc-flags=-L native={}", val);
            dirs.push(Path::new(val));
        }
    }
    for &(flag, val) in parts.iter() {
        if flag == "-l" {
            if options.statik && !is_system_lib(val, &dirs[]) {
                println!("cargo:rustc-flags=-l static={}", val);
            } else {
                println!("cargo:rustc-flags=-l {}", val);
            }
        }
    }
    Ok(())
}

pub fn default_options(name: &str) -> Options {
    let name = envify(name);
    let statik = if os::getenv(format!("{}_STATIC", name).as_slice()).is_some() {
        true
    } else if os::getenv(format!("{}_DYNAMIC", name).as_slice()).is_some() {
        false
    } else if os::getenv("PKG_CONFIG_ALL_STATIC").is_some() {
        true
    } else if os::getenv("PKG_CONFIG_ALL_DYNAMIC").is_some() {
        false
    } else {
        false
    };
    Options { statik: statik, atleast_version: None }
}

fn envify(name: &str) -> String {
    name.chars().map(|c| c.to_uppercase()).map(|c| if c == '-' {'_'} else {c})
        .collect()
}

fn is_system_lib(name: &str, dirs: &[Path]) -> bool {
    let libname = format!("lib{}.a", name);
    let root = Path::new("/usr");
    !dirs.iter().any(|d| {
        !root.is_ancestor_of(d) && d.join(&libname).exists()
    })
}
<|endoftext|>