<commit_before>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// 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.
/*===============================================================================================*/

/*===============================================================================================*/
/*------UTIL STRUCT------------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The Math utility struct
///
/// It contains various utility functions such as: Clamp, Lerp, Min, Max, etc.
#[derive (Copy, Clone)]
pub struct Util;

/*===============================================================================================*/
/*------UTIL PUBLIC STATIC METHODS---------------------------------------------------------------*/
/*===============================================================================================*/

impl Util {

    /// Clamps a value between two numbers.
    ///
    /// # Arguments
    /// * `value` - The value to clamp
    /// * `min` - The minimum the value is allowed to be
    /// * `max` - The maximum the value is allowed to be
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let val = 23.0;
    /// let min = 5.0;
    /// let max = 19.0;
    ///
    /// println! ("Clamp = {}", Util::clamp (val, min, max));
    /// ```
    /// ```c
    /// Output : Clamp = 19.0
    pub fn clamp (value: f32, min: f32, max: f32) -> f32 {

        if value < min {
            return min;
        }

        else if value > max {
            return max;
        }

        value
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Calculates the cotangent of a value.
    pub fn cot (value: f32) -> f32 {
        1.0 / value.tan ()
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Converts a number from degrees to radians.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let deg = 95.0;
    /// println! ("Value as radians = {}", Util::deg2rad (deg));
    /// ```
    /// ```c
    /// Output : Value as radians = 1.658035
    pub fn deg2rad (value: f32) -> f32 {

        value * 0.017453
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Linearly interpolates between two numbers.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let start = 9.0;
    /// let end = 22.0;
    /// let percent = 0.5;
    ///
    /// println! ("{}", Util::lerp (start, end, percent));
    /// ```
    /// ```c
    /// Output : 15.5
    pub fn lerp (start: f32, end: f32, percentage: f32) -> f32 {

        start + (end - start) * Util::clamp (percentage, 0.0, 1.0)
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Linearly interpolates between two numbers without clamping.
    pub fn lerp_unclamped (start: f32, end: f32, percentage: f32) -> f32 {

        start + (end - start) * percentage
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns the largest of two numbers
    ///
    /// # Arguments
    /// * `lhs` - The first value to compare, or left hand side value
    /// * `rhs` - The second value to compare, or right hand side value
    pub fn max (lhs: f32, rhs: f32) -> f32 {

        if lhs > rhs {
            return lhs
        }

        rhs
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns the smallest of two numbers
    ///
    /// # Arguments
    /// * `lhs` - The first value to compare, or left hand side value
    /// * `rhs` - The second value to compare, or right hand side value
    pub fn min (lhs: f32, rhs: f32) -> f32 {

        if lhs < rhs {
            return lhs;
        }

        rhs
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Converts a number from radians to degrees
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let rad = 2.5;
    /// println! ("Value as degrees = {}", Util::rad2deg (rad));
    /// ```
    /// ```c
    /// Output : Value as degrees = 143.2394475
    pub fn rad2deg (value: f32) -> f32 {

        value * 57.295779
    }
}
<commit_msg>Added some documentation to "cot" method<commit_after>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// 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.
/*===============================================================================================*/

/*===============================================================================================*/
/*------UTIL STRUCT------------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The Math utility struct
///
/// It contains various utility functions such as: Clamp, Lerp, Min, Max, etc.
#[derive (Copy, Clone)]
pub struct Util;

/*===============================================================================================*/
/*------UTIL PUBLIC STATIC METHODS---------------------------------------------------------------*/
/*===============================================================================================*/

impl Util {

    /// Clamps a value between two numbers.
    ///
    /// # Arguments
    /// * `value` - The value to clamp
    /// * `min` - The minimum the value is allowed to be
    /// * `max` - The maximum the value is allowed to be
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let val = 23.0;
    /// let min = 5.0;
    /// let max = 19.0;
    ///
    /// println! ("Clamp = {}", Util::clamp (val, min, max));
    /// ```
    /// ```c
    /// Output : Clamp = 19.0
    pub fn clamp (value: f32, min: f32, max: f32) -> f32 {

        if value < min {
            return min;
        }

        else if value > max {
            return max;
        }

        value
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Calculates the cotangent of a value.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// println! ("{}", Util::cot (45.0));
    /// ```
    pub fn cot (value: f32) -> f32 {
        1.0 / value.tan ()
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Converts a number from degrees to radians.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let deg = 95.0;
    /// println! ("Value as radians = {}", Util::deg2rad (deg));
    /// ```
    /// ```c
    /// Output : Value as radians = 1.658035
    pub fn deg2rad (value: f32) -> f32 {

        value * 0.017453
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Linearly interpolates between two numbers.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let start = 9.0;
    /// let end = 22.0;
    /// let percent = 0.5;
    ///
    /// println! ("{}", Util::lerp (start, end, percent));
    /// ```
    /// ```c
    /// Output : 15.5
    pub fn lerp (start: f32, end: f32, percentage: f32) -> f32 {

        start + (end - start) * Util::clamp (percentage, 0.0, 1.0)
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Linearly interpolates between two numbers without clamping.
    pub fn lerp_unclamped (start: f32, end: f32, percentage: f32) -> f32 {

        start + (end - start) * percentage
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns the largest of two numbers
    ///
    /// # Arguments
    /// * `lhs` - The first value to compare, or left hand side value
    /// * `rhs` - The second value to compare, or right hand side value
    pub fn max (lhs: f32, rhs: f32) -> f32 {

        if lhs > rhs {
            return lhs
        }

        rhs
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns the smallest of two numbers
    ///
    /// # Arguments
    /// * `lhs` - The first value to compare, or left hand side value
    /// * `rhs` - The second value to compare, or right hand side value
    pub fn min (lhs: f32, rhs: f32) -> f32 {

        if lhs < rhs {
            return lhs;
        }

        rhs
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Converts a number from radians to degrees
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::math::Util;
    /// #
    /// let rad = 2.5;
    /// println! ("Value as degrees = {}", Util::rad2deg (rad));
    /// ```
    /// ```c
    /// Output : Value as degrees = 143.2394475
    pub fn rad2deg (value: f32) -> f32 {

        value * 57.295779
    }
}
<|endoftext|>


<commit_before>// This is a part of lithos_ps not lithos library
use std::io::Error as IoError;
use std::io::Write;
use std::cmp::max;
use std::fmt::Display;
use self::Column::*;

pub struct Printer {
    color: bool,
    buf: Vec<u8>,
}

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

pub struct TreeNode {
    pub head: String,
    pub children: Vec<TreeNode>,
}

pub enum Column {
    Text(Vec<String>),
    Bytes(Vec<usize>),
    Ordinal(Vec<usize>),
    Percent(Vec<f64>),
}

impl PrinterFactory {
    pub fn new(&self) -> Printer {
        let PrinterFactory(color) = *self;
        return Printer {
            color: color,
            buf: Vec::with_capacity(100),
        };
    }
}

impl Printer {
    pub fn color_factory() -> PrinterFactory {
        return PrinterFactory(true);
    }
    pub fn plain_factory() -> PrinterFactory {
        return PrinterFactory(false);
    }
    pub fn norm<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        write!(&mut self.buf, "{}", val).unwrap();
        return self;
    }
    pub fn red<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        if self.color {
            write!(&mut self.buf, "\x1b[31m\x1b[1m{}\x1b[0m\x1b[22m",
                val).unwrap();
        } else {
            write!(&mut self.buf, "{}", val).unwrap();
        }
        return self;
    }
    pub fn blue<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        if self.color {
            write!(&mut self.buf, "\x1b[34m\x1b[1m{}\x1b[0m\x1b[22m",
                val).unwrap();
        } else {
            write!(&mut self.buf, "{}", val).unwrap();
        }
        return self;
    }
    pub fn green<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        if self.color {
            write!(&mut self.buf, "\x1b[32m\x1b[1m{}\x1b[0m\x1b[22m",
                val).unwrap();
        } else {
            write!(&mut self.buf, "{}", val).unwrap();
        }
        return self;
    }
    pub fn map<F>(self, fun: F) -> Printer
        where F: Fn(Printer) -> Printer
    {
        fun(self)
    }
    pub fn unwrap(self) -> String {
        return String::from_utf8(self.buf).unwrap();
    }
}

impl TreeNode {
    pub fn print<T:Write>(&self, writer: &mut T) -> Result<(), IoError> {
        try!(write!(writer, "{}\n", self.head));
        self._print_children(writer, "  ")
    }
    pub fn _print_children<T:Write>(&self, writer: &mut T, indent: &str)
        -> Result<(), IoError>
    {
        if self.children.len() >= 2 {
            let childindent = indent.to_string() + "│   ";
            for child in self.children[..self.children.len()-1].iter() {
                try!(write!(writer, "{}├─{}\n", indent, child.head));
                try!(child._print_children(writer, &childindent[..]));
            }
        }
        if let Some(child) = self.children.last() {
            let childindent = indent.to_string() + "    ";
            try!(write!(writer, "{}└─{}\n", indent, child.head));
            try!(child._print_children(writer, &childindent[..]));
        }
        return Ok(());
    }

}

pub fn render_table(columns: &[(&'static str, Column)]) {
    let mut out_cols = Vec::new();
    for &(ref title, ref col) in columns.iter() {
        match *col {
            Bytes(ref items) => {
                let max = items.iter().max().map(|&x| x).unwrap_or(1);
                let (k, unit) = match max {
                    1 ... 10240 => (1f64, "B"),
                    10241 ... 10485760 => (1024f64, "kiB"),
                    10485761 ... 10737418240 => (1048576f64, "MiB"),
                    _ => (1073741824f64, "GiB"),
                };
                let mut values = vec!(format!("{1:>0$}", 7+unit.len(), title));
                values.extend(items.iter().map(
                    |x| format!("{:7.1}{}", (*x as f64) / k, unit)));
                values.reverse();
                out_cols.push(values);
            }
            Text(ref items) => {
                let maxlen = max(3,
                    items.iter().map(|x| x.len()).max().unwrap_or(3));
                let mut values = vec!(format!("{1:<0$}", maxlen, title));
                values.extend(items.iter().map(
                    |x| format!("{1:<0$}", maxlen, *x)));
                values.reverse();
                out_cols.push(values);
            }
            Ordinal(ref items) => {
                let maxlen = max(3, items.iter().map(
                    |x| format!("{}", x).len()).max().unwrap_or(3));
                let mut values = vec!(format!("{1:>0$}", maxlen, title));
                values.extend(items.iter().map(
                    |x| format!("{1:0$}", maxlen, *x)));
                values.reverse();
                out_cols.push(values);
            }
            Percent(ref items) => {
                let mut values = vec!(format!("{:>5}", title));
                values.extend(items.iter().map(
                    |x| format!("{:>5.1}", *x)));
                values.reverse();
                out_cols.push(values);
            }
        }
    }
    loop {
        for ref mut lst in out_cols.iter_mut() {
            if lst.len() == 0 {
                return;
            }
            print!("{} ", lst.pop().unwrap());
        }
        println!("");
    }
}

#[cfg(test)]
mod test {
    use super::TreeNode;
    use std::io::MemWriter;

    fn write_tree(node: &TreeNode) -> String {
        let mut buf = MemWriter::new();
        node.print(&mut buf).unwrap();
        return String::from_utf8(buf.into_inner()).unwrap();
    }

    #[test]
    fn test_one_node() {
        assert_eq!(write_tree(&TreeNode {
            head: "parent".to_string(),
            children: vec!()
        }).as_slice(), "\
parent\n\
        ");
    }

    #[test]
    fn test_many_nodes() {
        assert_eq!(write_tree(&TreeNode {
            head: "parent".to_string(),
            children: vec!(TreeNode {
                head: "child1".to_string(),
                children: vec!(TreeNode {
                    head: "subchild".to_string(),
                    children: vec!(),
                }),
            }, TreeNode {
                head: "child2".to_string(),
                children: vec!(TreeNode {
                    head: "subchild".to_string(),
                    children: vec!(),
                }),
            })
        }).as_slice(), "\
parent
  ├─child1
  │   └─subchild
  └─child2
      └─subchild\n\
        ");
    }
}
<commit_msg>Fixes cargo tests<commit_after>// This is a part of lithos_ps not lithos library
use std::io::Error as IoError;
use std::io::Write;
use std::cmp::max;
use std::fmt::Display;
use self::Column::*;

pub struct Printer {
    color: bool,
    buf: Vec<u8>,
}

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

pub struct TreeNode {
    pub head: String,
    pub children: Vec<TreeNode>,
}

pub enum Column {
    Text(Vec<String>),
    Bytes(Vec<usize>),
    Ordinal(Vec<usize>),
    Percent(Vec<f64>),
}

impl PrinterFactory {
    pub fn new(&self) -> Printer {
        let PrinterFactory(color) = *self;
        return Printer {
            color: color,
            buf: Vec::with_capacity(100),
        };
    }
}

impl Printer {
    pub fn color_factory() -> PrinterFactory {
        return PrinterFactory(true);
    }
    pub fn plain_factory() -> PrinterFactory {
        return PrinterFactory(false);
    }
    pub fn norm<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        write!(&mut self.buf, "{}", val).unwrap();
        return self;
    }
    pub fn red<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        if self.color {
            write!(&mut self.buf, "\x1b[31m\x1b[1m{}\x1b[0m\x1b[22m",
                val).unwrap();
        } else {
            write!(&mut self.buf, "{}", val).unwrap();
        }
        return self;
    }
    pub fn blue<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        if self.color {
            write!(&mut self.buf, "\x1b[34m\x1b[1m{}\x1b[0m\x1b[22m",
                val).unwrap();
        } else {
            write!(&mut self.buf, "{}", val).unwrap();
        }
        return self;
    }
    pub fn green<T:Display>(mut self, val: T) -> Printer {
        if self.buf.len() > 0 {
            self.buf.push(b' ');
        }
        if self.color {
            write!(&mut self.buf, "\x1b[32m\x1b[1m{}\x1b[0m\x1b[22m",
                val).unwrap();
        } else {
            write!(&mut self.buf, "{}", val).unwrap();
        }
        return self;
    }
    pub fn map<F>(self, fun: F) -> Printer
        where F: Fn(Printer) -> Printer
    {
        fun(self)
    }
    pub fn unwrap(self) -> String {
        return String::from_utf8(self.buf).unwrap();
    }
}

impl TreeNode {
    pub fn print<T:Write>(&self, writer: &mut T) -> Result<(), IoError> {
        try!(write!(writer, "{}\n", self.head));
        self._print_children(writer, "  ")
    }
    pub fn _print_children<T:Write>(&self, writer: &mut T, indent: &str)
        -> Result<(), IoError>
    {
        if self.children.len() >= 2 {
            let childindent = indent.to_string() + "│   ";
            for child in self.children[..self.children.len()-1].iter() {
                try!(write!(writer, "{}├─{}\n", indent, child.head));
                try!(child._print_children(writer, &childindent[..]));
            }
        }
        if let Some(child) = self.children.last() {
            let childindent = indent.to_string() + "    ";
            try!(write!(writer, "{}└─{}\n", indent, child.head));
            try!(child._print_children(writer, &childindent[..]));
        }
        return Ok(());
    }

}

pub fn render_table(columns: &[(&'static str, Column)]) {
    let mut out_cols = Vec::new();
    for &(ref title, ref col) in columns.iter() {
        match *col {
            Bytes(ref items) => {
                let max = items.iter().max().map(|&x| x).unwrap_or(1);
                let (k, unit) = match max {
                    1 ... 10240 => (1f64, "B"),
                    10241 ... 10485760 => (1024f64, "kiB"),
                    10485761 ... 10737418240 => (1048576f64, "MiB"),
                    _ => (1073741824f64, "GiB"),
                };
                let mut values = vec!(format!("{1:>0$}", 7+unit.len(), title));
                values.extend(items.iter().map(
                    |x| format!("{:7.1}{}", (*x as f64) / k, unit)));
                values.reverse();
                out_cols.push(values);
            }
            Text(ref items) => {
                let maxlen = max(3,
                    items.iter().map(|x| x.len()).max().unwrap_or(3));
                let mut values = vec!(format!("{1:<0$}", maxlen, title));
                values.extend(items.iter().map(
                    |x| format!("{1:<0$}", maxlen, *x)));
                values.reverse();
                out_cols.push(values);
            }
            Ordinal(ref items) => {
                let maxlen = max(3, items.iter().map(
                    |x| format!("{}", x).len()).max().unwrap_or(3));
                let mut values = vec!(format!("{1:>0$}", maxlen, title));
                values.extend(items.iter().map(
                    |x| format!("{1:0$}", maxlen, *x)));
                values.reverse();
                out_cols.push(values);
            }
            Percent(ref items) => {
                let mut values = vec!(format!("{:>5}", title));
                values.extend(items.iter().map(
                    |x| format!("{:>5.1}", *x)));
                values.reverse();
                out_cols.push(values);
            }
        }
    }
    loop {
        for ref mut lst in out_cols.iter_mut() {
            if lst.len() == 0 {
                return;
            }
            print!("{} ", lst.pop().unwrap());
        }
        println!("");
    }
}

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

    fn write_tree(node: &TreeNode) -> String {
        let mut buf = Vec::with_capacity(100);
        node.print(&mut buf).unwrap();
        return String::from_utf8(buf).unwrap();
    }

    #[test]
    fn test_one_node() {
        assert_eq!(write_tree(&TreeNode {
            head: "parent".to_string(),
            children: vec!()
        }), String::from("\
parent\n\
        "));
    }

    #[test]
    fn test_many_nodes() {
        assert_eq!(write_tree(&TreeNode {
            head: "parent".to_string(),
            children: vec!(TreeNode {
                head: "child1".to_string(),
                children: vec!(TreeNode {
                    head: "subchild".to_string(),
                    children: vec!(),
                }),
            }, TreeNode {
                head: "child2".to_string(),
                children: vec!(TreeNode {
                    head: "subchild".to_string(),
                    children: vec!(),
                }),
            })
        }), String::from("\
parent
  ├─child1
  │   └─subchild
  └─child2
      └─subchild\n\
        "));
    }
}
<|endoftext|>


<commit_before>extern crate test;
use self::test::Bencher;

use super::Rope;
use std::iter;

#[bench]
fn rope_add_1000(b: &mut Bencher) {
    let mut rope = Rope::from(iter::repeat('a')
                                    .take(100_000)
                                    .collect::<String>());
    // rope.rebalance();
    b.iter(|| {
        let n = test::black_box(1000);
        let mut r = rope.clone();
        for i in 0..n {
            r = r + i.to_string();
        }
    })

}

#[bench]
fn string_add_1000(b: &mut Bencher) {
    let mut string = iter::repeat('a').take(100_000).collect::<String>();
    b.iter(move || {
        let n = test::black_box(1000);
        let mut s = string.clone();
        for i in 0..n {
            s = s + &i.to_string();
        }
    })

}

#[bench]
fn rope_insert_1000(b: &mut Bencher) {
    let mut rope = Rope::from(iter::repeat('a')
                                    .take(100_000)
                                    .collect::<String>());
    // rope.rebalance();
    b.iter(move || {
        // let n = test::black_box(1000);
        // let mut rope = Rope::from("aaaa");
        for i in 0..1000 {
            rope.insert_str(2, &i.to_string());
        }
    })

}

#[bench]
fn string_insert_1000(b: &mut Bencher) {
    let mut string = iter::repeat('a').take(100_000).collect::<String>();
    b.iter(|| {
        // let n = test::black_box(1000);
        // let mut string = String::from("aaaa");
        for i in 0..1000 {
            string.insert_str(2, &i.to_string());
        }
    })

}

macro_rules! insert_benches {
    ( long: $lenl:expr, short: $lens:expr, $($name:ident: $frac:expr),* ) => {
        mod insert {
        mod rope {
            $(

                mod $name {
                    use ::Rope;
                    use ::bench::test::Bencher;
                    use std::iter::repeat;
                    macro_rules! mk_bench {
                        ( $n:ident: $fun:ident, $l:expr, $ins:expr) => {
                            #[bench] fn $n(b: &mut Bencher) {
                                let mut rope = Rope::from(repeat('a').take($l)
                                                        .collect::<String>());
                                b.iter(|| { rope.$fun(
                                    ($l as f64 * $frac as f64) as usize, $ins)
                                })
                            }
                        }
                    }
                    mk_bench! { long: insert_str, $lenl, "bbbbbbb" }
                    mk_bench! { short: insert_str, $lens, "bb" }
                    mk_bench! { char_long: insert, $lenl, 'c' }
                    mk_bench! { char_short: insert, $lens, 'c' }
                    mk_bench! { rope_long: insert_rope, $lenl,
                        &Rope::from(repeat('a').take($lenl)
                                    .collect::<String>()) }
                    mk_bench! { rope_short: insert_rope, $lens,
                        &Rope::from(repeat('a').take($lens)
                                    .collect::<String>()) }
                }
            )*
        }
        mod string {
            $(
                mod $name {
                    use ::bench::test::Bencher;
                    use std::iter::repeat;
                    macro_rules! mk_bench {
                        ( $n:ident: $fun:ident, $l:expr, $ins:expr) => {
                            #[bench] fn $n(b: &mut Bencher) {
                                let mut string = repeat('a').take($l)
                                                .collect::<String>();
                                b.iter(|| { string.$fun(
                                    ($l as f64 * $frac as f64) as usize, $ins)
                                })
                            }
                        }
                    }
                    mk_bench! { long: insert_str, $lenl, "bbbbbbb" }
                    mk_bench! { short: insert_str, $lens, "bb" }
                    mk_bench! { char_long: insert, $lenl, 'c' }
                    mk_bench! { char_short: insert, $lens, 'c'  }
                }
            )*
        }
    }}
}

macro_rules! split_benches {
    ( long: $lenl:expr, short: $lens:expr, $($name:ident: $frac:expr),* ) => {
        mod split {
            $(
                mod $name {
                    use ::Rope;
                    use ::bench::test::Bencher;
                    use std::iter::repeat;
                    #[bench]
                    fn long(b: &mut Bencher) {
                        let rope = Rope::from(repeat('a').take($lenl)
                                                         .collect::<String>());
                        let split = || {
                            rope.split(($lenl as f64 * $frac as f64) as usize) };
                        b.iter(split)
                    }
                    #[bench]
                    fn short(b: &mut Bencher) {
                        let rope = Rope::from(repeat('a').take($lens)
                                                         .collect::<String>());
                        let split = || {
                            rope.split(($lens as f64 * $frac as f64) as usize) };
                        b.iter(split)
                    }
                }
            )*
        }
    }
}
#[cfg(all( test, feature = "unstable") )]
split_benches! {
    long: 100_000, short: 100,
        at_start: 0,
        at_quarter: 0.25,
        at_half: 0.5,
        at_3quarter: 0.75,
        at_end: 1
}
#[cfg(all( test, feature = "unstable") )]
insert_benches! {
    long: 100_000, short: 100,
        at_start: 0,
        at_quarter: 0.25,
        at_half: 0.5,
        at_3quarter: 0.75,
        at_end: 1
}
<commit_msg>test(rope benchmarks): make insert_rope benchmarks fairer<commit_after>extern crate test;
use self::test::Bencher;

use super::Rope;
use std::iter;

#[bench]
fn rope_add_1000(b: &mut Bencher) {
    let mut rope = Rope::from(iter::repeat('a')
                                    .take(100_000)
                                    .collect::<String>());
    // rope.rebalance();
    b.iter(|| {
        let n = test::black_box(1000);
        let mut r = rope.clone();
        for i in 0..n {
            r = r + i.to_string();
        }
    })

}

#[bench]
fn string_add_1000(b: &mut Bencher) {
    let mut string = iter::repeat('a').take(100_000).collect::<String>();
    b.iter(move || {
        let n = test::black_box(1000);
        let mut s = string.clone();
        for i in 0..n {
            s = s + &i.to_string();
        }
    })

}

#[bench]
fn rope_insert_1000(b: &mut Bencher) {
    let mut rope = Rope::from(iter::repeat('a')
                                    .take(100_000)
                                    .collect::<String>());
    // rope.rebalance();
    b.iter(move || {
        // let n = test::black_box(1000);
        // let mut rope = Rope::from("aaaa");
        for i in 0..1000 {
            rope.insert_str(2, &i.to_string());
        }
    })

}

#[bench]
fn string_insert_1000(b: &mut Bencher) {
    let mut string = iter::repeat('a').take(100_000).collect::<String>();
    b.iter(|| {
        // let n = test::black_box(1000);
        // let mut string = String::from("aaaa");
        for i in 0..1000 {
            string.insert_str(2, &i.to_string());
        }
    })

}

macro_rules! insert_benches {
    ( long: $lenl:expr, short: $lens:expr, $($name:ident: $frac:expr),* ) => {
        mod insert {
        mod rope {
            $(

                mod $name {
                    use ::Rope;
                    use ::bench::test::Bencher;
                    use std::iter::repeat;

                    macro_rules! mk_bench {
                        ( $n:ident: $fun:ident, $l:expr, $ins:expr) => {
                            #[bench] fn $n(b: &mut Bencher) {
                                let rope = Rope::from(repeat('a').take($l)
                                                        .collect::<String>());
                                b.iter(|| { rope.$fun(
                                    ($l as f64 * $frac as f64) as usize, $ins)
                                })
                            }
                        }
                    }

                    mk_bench! { long: insert_str, $lenl, "bbbbbbb" }
                    mk_bench! { short: insert_str, $lens, "bb" }
                    mk_bench! { char_long: insert, $lenl, 'c' }
                    mk_bench! { char_short: insert, $lens, 'c' }
                    // mk_bench! { rope_long: insert_rope, $lenl, &rope }
                    // mk_bench! { rope_short: insert_rope, $lens, &rope }

                    #[bench] fn rope_long(b: &mut Bencher) {
                        let rope = Rope::from(repeat('a').take($lenl)
                                                .collect::<String>());
                        b.iter(|| { rope.insert_rope(
                            ($lenl as f64 * $frac as f64) as usize, &rope)
                        })
                    }
                    #[bench] fn rope_short(b: &mut Bencher) {
                        let rope = Rope::from(repeat('a').take($lens)
                                                .collect::<String>());
                        b.iter(|| { rope.insert_rope(
                            ($lens as f64 * $frac as f64) as usize, &rope)
                        })
                    }
                }
            )*
        }
        mod string {
            $(
                mod $name {
                    use ::bench::test::Bencher;
                    use std::iter::repeat;
                    macro_rules! mk_bench {
                        ( $n:ident: $fun:ident, $l:expr, $ins:expr) => {
                            #[bench] fn $n(b: &mut Bencher) {
                                let mut string = repeat('a').take($l)
                                                .collect::<String>();
                                b.iter(|| { string.$fun(
                                    ($l as f64 * $frac as f64) as usize, $ins)
                                })
                            }
                        }
                    }
                    mk_bench! { long: insert_str, $lenl, "bbbbbbb" }
                    mk_bench! { short: insert_str, $lens, "bb" }
                    mk_bench! { char_long: insert, $lenl, 'c' }
                    mk_bench! { char_short: insert, $lens, 'c'  }
                }
            )*
        }
    }}
}

macro_rules! split_benches {
    ( long: $lenl:expr, short: $lens:expr, $($name:ident: $frac:expr),* ) => {
        mod split {
            $(
                mod $name {
                    use ::Rope;
                    use ::bench::test::Bencher;
                    use std::iter::repeat;
                    #[bench]
                    fn long(b: &mut Bencher) {
                        let rope = Rope::from(repeat('a').take($lenl)
                                                         .collect::<String>());
                        let split = || {
                            rope.split(($lenl as f64 * $frac as f64) as usize) };
                        b.iter(split)
                    }
                    #[bench]
                    fn short(b: &mut Bencher) {
                        let rope = Rope::from(repeat('a').take($lens)
                                                         .collect::<String>());
                        let split = || {
                            rope.split(($lens as f64 * $frac as f64) as usize) };
                        b.iter(split)
                    }
                }
            )*
        }
    }
}
#[cfg(all( test, feature = "unstable") )]
split_benches! {
    long: 100_000, short: 100,
        at_start: 0,
        at_quarter: 0.25,
        at_half: 0.5,
        at_3quarter: 0.75,
        at_end: 1
}
#[cfg(all( test, feature = "unstable") )]
insert_benches! {
    long: 100_000, short: 100,
        at_start: 0,
        at_quarter: 0.25,
        at_half: 0.5,
        at_3quarter: 0.75,
        at_end: 1
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 6.0

#![crate_type = "lib"]
#![feature(custom_attribute)]

pub struct S {
  _field: [i32; 8],
}

pub struct UnsafeInner {
  _field: std::cell::UnsafeCell<i16>,
}

// CHECK: zeroext i1 @boolean(i1 zeroext %x)
#[no_mangle]
pub fn boolean(x: bool) -> bool {
  x
}

// CHECK: @readonly_borrow(i32* noalias readonly dereferenceable(4) %arg0)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn readonly_borrow(_: &i32) {
}

// CHECK: @static_borrow(i32* noalias readonly dereferenceable(4) %arg0)
// static borrow may be captured
#[no_mangle]
pub fn static_borrow(_: &'static i32) {
}

// CHECK: @named_borrow(i32* noalias readonly dereferenceable(4) %arg0)
// borrow with named lifetime may be captured
#[no_mangle]
pub fn named_borrow<'r>(_: &'r i32) {
}

// CHECK: @unsafe_borrow(i16* dereferenceable(2) %arg0)
// unsafe interior means this isn't actually readonly and there may be aliases ...
#[no_mangle]
pub fn unsafe_borrow(_: &UnsafeInner) {
}

// CHECK: @mutable_unsafe_borrow(i16* noalias dereferenceable(2) %arg0)
// ... unless this is a mutable borrow, those never alias
#[no_mangle]
pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
}

// CHECK: @mutable_borrow(i32* noalias dereferenceable(4) %arg0)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn mutable_borrow(_: &mut i32) {
}

// CHECK: @indirect_struct(%S* noalias nocapture dereferenceable(32) %arg0)
#[no_mangle]
pub fn indirect_struct(_: S) {
}

// CHECK: @borrowed_struct(%S* noalias readonly dereferenceable(32) %arg0)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn borrowed_struct(_: &S) {
}

// CHECK: noalias align 4 dereferenceable(4) i32* @_box(i32* noalias dereferenceable(4) %x)
#[no_mangle]
pub fn _box(x: Box<i32>) -> Box<i32> {
  x
}

// CHECK: @struct_return(%S* noalias nocapture sret dereferenceable(32))
#[no_mangle]
pub fn struct_return() -> S {
  S {
    _field: [0, 0, 0, 0, 0, 0, 0, 0]
  }
}

// Hack to get the correct size for the length part in slices
// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
#[no_mangle]
pub fn helper(_: usize) {
}

// CHECK: @slice([0 x i8]* noalias nonnull readonly %arg0.0, [[USIZE]] %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn slice(_: &[u8]) {
}

// CHECK: @mutable_slice([0 x i8]* noalias nonnull %arg0.0, [[USIZE]] %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn mutable_slice(_: &mut [u8]) {
}

// CHECK: @unsafe_slice([0 x i16]* nonnull %arg0.0, [[USIZE]] %arg0.1)
// unsafe interior means this isn't actually readonly and there may be aliases ...
#[no_mangle]
pub fn unsafe_slice(_: &[UnsafeInner]) {
}

// CHECK: @str([0 x i8]* noalias nonnull readonly %arg0.0, [[USIZE]] %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn str(_: &[u8]) {
}

// CHECK: @trait_borrow({}* nonnull %arg0.0, [4 x [[USIZE]]]* noalias readonly dereferenceable({{32|16}}) %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn trait_borrow(_: &Drop) {
}

// CHECK: @trait_box({}* noalias nonnull, [4 x [[USIZE]]]* noalias readonly dereferenceable({{32|16}}))
#[no_mangle]
pub fn trait_box(_: Box<Drop>) {
}

// CHECK: { i8*, i8* } @trait_option(i8* noalias %x.0, i8* %x.1)
#[no_mangle]
pub fn trait_option(x: Option<Box<Drop>>) -> Option<Box<Drop>> {
  x
}

// CHECK: { [0 x i16]*, [[USIZE]] } @return_slice([0 x i16]* noalias nonnull readonly %x.0, [[USIZE]] %x.1)
#[no_mangle]
pub fn return_slice(x: &[u16]) -> &[u16] {
  x
}

// CHECK: { i16, i16 } @enum_id_1(i16 %x.0, i16 %x.1)
#[no_mangle]
pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
  x
}

// CHECK: { i8, i8 } @enum_id_2(i1 zeroext %x.0, i8 %x.1)
#[no_mangle]
pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
  x
}

// CHECK: noalias i8* @allocator()
#[no_mangle]
#[allocator]
pub fn allocator() -> *const i8 {
  std::ptr::null()
}
<commit_msg>dont hardcode vtable size in codegen test<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 6.0

#![crate_type = "lib"]
#![feature(custom_attribute)]

pub struct S {
  _field: [i32; 8],
}

pub struct UnsafeInner {
  _field: std::cell::UnsafeCell<i16>,
}

// CHECK: zeroext i1 @boolean(i1 zeroext %x)
#[no_mangle]
pub fn boolean(x: bool) -> bool {
  x
}

// CHECK: @readonly_borrow(i32* noalias readonly dereferenceable(4) %arg0)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn readonly_borrow(_: &i32) {
}

// CHECK: @static_borrow(i32* noalias readonly dereferenceable(4) %arg0)
// static borrow may be captured
#[no_mangle]
pub fn static_borrow(_: &'static i32) {
}

// CHECK: @named_borrow(i32* noalias readonly dereferenceable(4) %arg0)
// borrow with named lifetime may be captured
#[no_mangle]
pub fn named_borrow<'r>(_: &'r i32) {
}

// CHECK: @unsafe_borrow(i16* dereferenceable(2) %arg0)
// unsafe interior means this isn't actually readonly and there may be aliases ...
#[no_mangle]
pub fn unsafe_borrow(_: &UnsafeInner) {
}

// CHECK: @mutable_unsafe_borrow(i16* noalias dereferenceable(2) %arg0)
// ... unless this is a mutable borrow, those never alias
#[no_mangle]
pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
}

// CHECK: @mutable_borrow(i32* noalias dereferenceable(4) %arg0)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn mutable_borrow(_: &mut i32) {
}

// CHECK: @indirect_struct(%S* noalias nocapture dereferenceable(32) %arg0)
#[no_mangle]
pub fn indirect_struct(_: S) {
}

// CHECK: @borrowed_struct(%S* noalias readonly dereferenceable(32) %arg0)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn borrowed_struct(_: &S) {
}

// CHECK: noalias align 4 dereferenceable(4) i32* @_box(i32* noalias dereferenceable(4) %x)
#[no_mangle]
pub fn _box(x: Box<i32>) -> Box<i32> {
  x
}

// CHECK: @struct_return(%S* noalias nocapture sret dereferenceable(32))
#[no_mangle]
pub fn struct_return() -> S {
  S {
    _field: [0, 0, 0, 0, 0, 0, 0, 0]
  }
}

// Hack to get the correct size for the length part in slices
// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
#[no_mangle]
pub fn helper(_: usize) {
}

// CHECK: @slice([0 x i8]* noalias nonnull readonly %arg0.0, [[USIZE]] %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn slice(_: &[u8]) {
}

// CHECK: @mutable_slice([0 x i8]* noalias nonnull %arg0.0, [[USIZE]] %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn mutable_slice(_: &mut [u8]) {
}

// CHECK: @unsafe_slice([0 x i16]* nonnull %arg0.0, [[USIZE]] %arg0.1)
// unsafe interior means this isn't actually readonly and there may be aliases ...
#[no_mangle]
pub fn unsafe_slice(_: &[UnsafeInner]) {
}

// CHECK: @str([0 x i8]* noalias nonnull readonly %arg0.0, [[USIZE]] %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn str(_: &[u8]) {
}

// CHECK: @trait_borrow({}* nonnull %arg0.0, [4 x [[USIZE]]]* noalias readonly dereferenceable({{.*}}) %arg0.1)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
pub fn trait_borrow(_: &Drop) {
}

// CHECK: @trait_box({}* noalias nonnull, [4 x [[USIZE]]]* noalias readonly dereferenceable({{.*}}))
#[no_mangle]
pub fn trait_box(_: Box<Drop>) {
}

// CHECK: { i8*, i8* } @trait_option(i8* noalias %x.0, i8* %x.1)
#[no_mangle]
pub fn trait_option(x: Option<Box<Drop>>) -> Option<Box<Drop>> {
  x
}

// CHECK: { [0 x i16]*, [[USIZE]] } @return_slice([0 x i16]* noalias nonnull readonly %x.0, [[USIZE]] %x.1)
#[no_mangle]
pub fn return_slice(x: &[u16]) -> &[u16] {
  x
}

// CHECK: { i16, i16 } @enum_id_1(i16 %x.0, i16 %x.1)
#[no_mangle]
pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
  x
}

// CHECK: { i8, i8 } @enum_id_2(i1 zeroext %x.0, i8 %x.1)
#[no_mangle]
pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
  x
}

// CHECK: noalias i8* @allocator()
#[no_mangle]
#[allocator]
pub fn allocator() -> *const i8 {
  std::ptr::null()
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers.
// Copyright 2015 Guillaume Gomez
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Library to interface with chunks of memory allocated in C.
//!
//! It is often desirable to safely interface with memory allocated from C,
//! encapsulating the unsafety into allocation and destruction time.  Indeed,
//! allocating memory externally is currently the only way to give Rust shared
//! mut state with C programs that keep their own references; vectors are
//! unsuitable because they could be reallocated or moved at any time, and
//! importing C memory into a vector takes a one-time snapshot of the memory.
//!
//! This module simplifies the usage of such external blocks of memory.  Memory
//! is encapsulated into an opaque object after creation; the lifecycle of the
//! memory can be optionally managed by Rust, if an appropriate destructor
//! closure is provided.  Safety is ensured by bounds-checking accesses, which
//! are marshalled through get and set functions.
//!
//! There are three unsafe functions: the two constructors, and the
//! unwrapping method. The constructors are unsafe for the
//! obvious reason (they act on a pointer that cannot be checked inside the
//! method), but `into_inner()` is somewhat more subtle in its unsafety.
//! It returns the contained pointer, but at the same time destroys the CVec
//! without running its destructor. This can be used to pass memory back to
//! C, but care must be taken that the ownership of underlying resources are
//! handled correctly, i.e. that allocated memory is eventually freed
//! if necessary.

#![feature(unsafe_destructor, core, std_misc, unique)]

use std::mem;
use std::ptr;
use std::raw;
use std::ptr::Unique;
use std::thunk::Invoke;
use std::ops::{Index, IndexMut};

/// The type representing a foreign chunk of memory
pub struct CVec<T> {
    base: Unique<T>,
    len: usize,
    dtor: Option<Box<Invoke<*mut T> + 'static>>
}

#[unsafe_destructor]
impl<T> Drop for CVec<T> {
    fn drop(&mut self) {
        match self.dtor.take() {
            None => (),
            Some(f) => f.invoke(*self.base),
        }
    }
}

impl<T> CVec<T> {
    /// Create a `CVec` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: Unique<T>, len: usize) -> CVec<T> {
        assert!(*base != ptr::null_mut());
        CVec {
            base: base,
            len: len,
            dtor: None,
        }
    }

    /// Create a `CVec` from a foreign buffer, with a given length,
    /// and a function to run upon destruction.
    ///
    /// Panics if the given pointer is null.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    /// * dtor - A fn to run when the value is destructed, useful
    ///          for freeing the buffer, etc. `base` will be passed
    ///          to it as an argument.
    pub unsafe fn new_with_dtor<F>(base: Unique<T>,
                                   len: usize,
                                   dtor: F)
                                   -> CVec<T>
        where F : FnOnce(*mut T) + 'static
    {
        assert!(*base != ptr::null_mut());
        let dtor = Box::new(dtor);
        CVec {
            base: base,
            len: len,
            dtor: Some(dtor)
        }
    }

    /// View the stored data as a mutable slice.
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        unsafe {
            mem::transmute(raw::Slice { data: *self.base as *const T, len: self.len })
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Unwrap the pointer without running the destructor
    ///
    /// This method retrieves the underlying pointer, and in the process
    /// destroys the CVec but without running the destructor. A use case
    /// would be transferring ownership of the buffer to a C function, as
    /// in this case you would not want to run the destructor.
    ///
    /// Note that if you want to access the underlying pointer without
    /// cancelling the destructor, you can simply call `transmute` on the return
    /// value of `get(0)`.
    pub unsafe fn into_inner(mut self) -> *mut T {
        self.dtor = None;
        *self.base
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }

    /// Convert to CSlice
    pub fn as_cslice(&self) -> CSlice<T> {
        CSlice {
            base: *self.base,
            len: self.len
        }
    }
}

impl<T> AsSlice<T> for CVec<T> {
    /// View the stored data as a slice.
    fn as_slice<'a>(&'a self) -> &'a [T] {
        unsafe {
            mem::transmute(raw::Slice { data: *self.base as *const T, len: self.len })
        }
    }
}

/// The type representing an 'unsafe' foreign chunk of memory
pub struct CSlice<T> {
    base: *mut T,
    len: usize
}

impl<T> CSlice<T> {
    /// Create a `CSlice` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A raw pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: *mut T, len: usize) -> CSlice<T> {
        assert!(base != ptr::null_mut());
        CSlice {
            base: base,
            len: len
        }
    }

    /// View the stored data as a mutable slice.
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        unsafe {
            mem::transmute(raw::Slice { data: self.base as *const T, len: self.len })
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> AsSlice<T> for CSlice<T> {
    /// View the stored data as a slice.
    fn as_slice<'a>(&'a self) -> &'a [T] {
        unsafe {
            mem::transmute(raw::Slice { data: self.base as *const T, len: self.len })
        }
    }
}

impl<T> Index<usize> for CSlice<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: usize) -> &'a T {
        assert!(_index < self.len);
        unsafe { &*self.base.offset(_index as isize) }
    }
}

impl<T> IndexMut<usize> for CSlice<T> {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut T {
        assert!(_index < self.len);
        unsafe { &mut *self.base.offset(_index as isize) }
    }
}

#[cfg(test)]
mod tests {
    extern crate alloc;
    extern crate libc;

    use super::{CVec, CSlice};
    use std::ptr::{self, Unique};

    // allocation of CVec
    fn v_malloc(n: usize) -> CVec<u8> {
        unsafe {
            let mem: Unique<u8> = Unique::new(
                libc::malloc(n as libc::size_t) as *mut _);
            if (*mem).is_null() { alloc::oom() }

            CVec::new_with_dtor(mem, n,
                                |mem| { libc::free((mem) as *mut _); })
        }
    }

    // allocation of CSlice
    fn s_malloc(n: usize) -> CSlice<u8> {
        unsafe {
            let mem: *mut u8 = libc::malloc(n as libc::size_t) as *mut _;
            if mem.is_null() { alloc::oom() }

            CSlice::new(mem, n)
        }
    }

    #[test]
    fn vec_test_basic() {
        let mut cv = v_malloc(16);

        *cv.get_mut(3).unwrap() = 8;
        *cv.get_mut(4).unwrap() = 9;
        assert_eq!(*cv.get(3).unwrap(), 8);
        assert_eq!(*cv.get(4).unwrap(), 9);
        assert_eq!(cv.len(), 16);
    }

    #[test]
    fn slice_test_basic() {
        let mut cs = s_malloc(16);

        cs[3] = 8;
        cs[4] = 9;
        assert_eq!(cs[3], 8);
        assert_eq!(cs[4], 9);
        assert_eq!(cs.len(), 16);
    }

    #[test]
    #[should_fail]
    fn vec_test_panic_at_null() {
        unsafe {
            CVec::new(Unique::new(ptr::null_mut::<u8>()), 9);
        }
    }

    #[test]
    #[should_fail]
    fn slice_test_panic_at_null() {
        unsafe {
            CSlice::new(ptr::null_mut::<u8>(), 9);
        }
    }

    #[test]
    fn vec_test_overrun_get() {
        let cv = v_malloc(16);

        assert!(cv.get(17).is_none());
    }

    #[test]
    #[should_fail]
    fn slice_test_overrun_get() {
        let cs = s_malloc(16);

        assert!(cs[17] == 18);
    }

    #[test]
    fn vec_test_overrun_set() {
        let mut cv = v_malloc(16);

        assert!(cv.get_mut(17).is_none());
    }

    #[test]
    fn vec_test_unwrap() {
        unsafe {
            let cv = CVec::new_with_dtor(Unique::new(1 as *mut isize),
                                         0,
                                         |_| panic!("Don't run this destructor!"));
            let p = cv.into_inner();
            assert_eq!(p, 1 as *mut isize);
        }
    }

    #[test]
    fn vec_to_slice_test() {
        unsafe {
            let mut cv = v_malloc(2);

            *cv.get_mut(0).unwrap() = 10;
            *cv.get_mut(1).unwrap() = 12;
            let cs = cv.as_cslice();

            assert_eq!(cs[0], 10);
            assert_eq!(cs[1], 12);
        }
    }

    #[test]
    fn slice_to_vec_test() {
        let cv = v_malloc(2);
        let mut cs = cv.as_cslice();

        cs[0] = 13;
        cs[1] = 26;
        assert_eq!(*cv.get(0).unwrap(), 13);
        assert_eq!(*cv.get(1).unwrap(), 26);
    }
}
<commit_msg>Use AsRef and AsMut traits instead of deprecated AsSlice<commit_after>// Copyright 2012 The Rust Project Developers.
// Copyright 2015 Guillaume Gomez
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Library to interface with chunks of memory allocated in C.
//!
//! It is often desirable to safely interface with memory allocated from C,
//! encapsulating the unsafety into allocation and destruction time.  Indeed,
//! allocating memory externally is currently the only way to give Rust shared
//! mut state with C programs that keep their own references; vectors are
//! unsuitable because they could be reallocated or moved at any time, and
//! importing C memory into a vector takes a one-time snapshot of the memory.
//!
//! This module simplifies the usage of such external blocks of memory.  Memory
//! is encapsulated into an opaque object after creation; the lifecycle of the
//! memory can be optionally managed by Rust, if an appropriate destructor
//! closure is provided.  Safety is ensured by bounds-checking accesses, which
//! are marshalled through get and set functions.
//!
//! There are three unsafe functions: the two constructors, and the
//! unwrapping method. The constructors are unsafe for the
//! obvious reason (they act on a pointer that cannot be checked inside the
//! method), but `into_inner()` is somewhat more subtle in its unsafety.
//! It returns the contained pointer, but at the same time destroys the CVec
//! without running its destructor. This can be used to pass memory back to
//! C, but care must be taken that the ownership of underlying resources are
//! handled correctly, i.e. that allocated memory is eventually freed
//! if necessary.

#![feature(unsafe_destructor, std_misc, unique, convert)]

use std::ptr;
use std::slice;
use std::ptr::Unique;
use std::thunk::Invoke;
use std::ops::{Index, IndexMut};

/// The type representing a foreign chunk of memory
pub struct CVec<T> {
    base: Unique<T>,
    len: usize,
    dtor: Option<Box<Invoke<*mut T> + 'static>>
}

#[unsafe_destructor]
impl<T> Drop for CVec<T> {
    fn drop(&mut self) {
        match self.dtor.take() {
            None => (),
            Some(f) => f.invoke(*self.base),
        }
    }
}

impl<T> CVec<T> {
    /// Create a `CVec` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: Unique<T>, len: usize) -> CVec<T> {
        assert!(*base != ptr::null_mut());
        CVec {
            base: base,
            len: len,
            dtor: None,
        }
    }

    /// Create a `CVec` from a foreign buffer, with a given length,
    /// and a function to run upon destruction.
    ///
    /// Panics if the given pointer is null.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    /// * dtor - A fn to run when the value is destructed, useful
    ///          for freeing the buffer, etc. `base` will be passed
    ///          to it as an argument.
    pub unsafe fn new_with_dtor<F>(base: Unique<T>,
                                   len: usize,
                                   dtor: F)
                                   -> CVec<T>
        where F : FnOnce(*mut T) + 'static
    {
        assert!(*base != ptr::null_mut());
        let dtor = Box::new(dtor);
        CVec {
            base: base,
            len: len,
            dtor: Some(dtor)
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Unwrap the pointer without running the destructor
    ///
    /// This method retrieves the underlying pointer, and in the process
    /// destroys the CVec but without running the destructor. A use case
    /// would be transferring ownership of the buffer to a C function, as
    /// in this case you would not want to run the destructor.
    ///
    /// Note that if you want to access the underlying pointer without
    /// cancelling the destructor, you can simply call `transmute` on the return
    /// value of `get(0)`.
    pub unsafe fn into_inner(mut self) -> *mut T {
        self.dtor = None;
        *self.base
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }

    /// Convert to CSlice
    pub fn as_cslice(&self) -> CSlice<T> {
        CSlice {
            base: *self.base,
            len: self.len
        }
    }
}

impl<T> AsRef<[T]> for CVec<T> {
    /// View the stored data as a slice.
    fn as_ref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(*self.base as *const T, self.len)
        }
    }
}

impl<T> AsMut<[T]> for CVec<T> {
    /// View the stored data as a slice.
    fn as_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(*self.base, self.len)
        }
    }
}

/// The type representing an 'unsafe' foreign chunk of memory
pub struct CSlice<T> {
    base: *mut T,
    len: usize
}

impl<T> CSlice<T> {
    /// Create a `CSlice` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A raw pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: *mut T, len: usize) -> CSlice<T> {
        assert!(base != ptr::null_mut());
        CSlice {
            base: base,
            len: len
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> AsRef<[T]> for CSlice<T> {
    /// View the stored data as a slice.
    fn as_ref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self.base as *const T, self.len)
        }
    }
}

impl<T> AsMut<[T]> for CSlice<T> {
    /// View the stored data as a slice.
    fn as_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self.base, self.len)
        }
    }
}

impl<T> Index<usize> for CSlice<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: usize) -> &'a T {
        assert!(_index < self.len);
        unsafe { &*self.base.offset(_index as isize) }
    }
}

impl<T> IndexMut<usize> for CSlice<T> {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut T {
        assert!(_index < self.len);
        unsafe { &mut *self.base.offset(_index as isize) }
    }
}

#[cfg(test)]
mod tests {
    extern crate alloc;
    extern crate libc;

    use super::{CVec, CSlice};
    use std::ptr::{self, Unique};

    // allocation of CVec
    fn v_malloc(n: usize) -> CVec<u8> {
        unsafe {
            let mem: Unique<u8> = Unique::new(
                libc::malloc(n as libc::size_t) as *mut _);
            if (*mem).is_null() { alloc::oom() }

            CVec::new_with_dtor(mem, n,
                                |mem| { libc::free((mem) as *mut _); })
        }
    }

    // allocation of CSlice
    fn s_malloc(n: usize) -> CSlice<u8> {
        unsafe {
            let mem: *mut u8 = libc::malloc(n as libc::size_t) as *mut _;
            if mem.is_null() { alloc::oom() }

            CSlice::new(mem, n)
        }
    }

    #[test]
    fn vec_test_basic() {
        let mut cv = v_malloc(16);

        *cv.get_mut(3).unwrap() = 8;
        *cv.get_mut(4).unwrap() = 9;
        assert_eq!(*cv.get(3).unwrap(), 8);
        assert_eq!(*cv.get(4).unwrap(), 9);
        assert_eq!(cv.len(), 16);
    }

    #[test]
    fn slice_test_basic() {
        let mut cs = s_malloc(16);

        cs[3] = 8;
        cs[4] = 9;
        assert_eq!(cs[3], 8);
        assert_eq!(cs[4], 9);
        assert_eq!(cs.len(), 16);
    }

    #[test]
    #[should_fail]
    fn vec_test_panic_at_null() {
        unsafe {
            CVec::new(Unique::new(ptr::null_mut::<u8>()), 9);
        }
    }

    #[test]
    #[should_fail]
    fn slice_test_panic_at_null() {
        unsafe {
            CSlice::new(ptr::null_mut::<u8>(), 9);
        }
    }

    #[test]
    fn vec_test_overrun_get() {
        let cv = v_malloc(16);

        assert!(cv.get(17).is_none());
    }

    #[test]
    #[should_fail]
    fn slice_test_overrun_get() {
        let cs = s_malloc(16);

        assert!(cs[17] == 18);
    }

    #[test]
    fn vec_test_overrun_set() {
        let mut cv = v_malloc(16);

        assert!(cv.get_mut(17).is_none());
    }

    #[test]
    fn vec_test_unwrap() {
        unsafe {
            let cv = CVec::new_with_dtor(Unique::new(1 as *mut isize),
                                         0,
                                         |_| panic!("Don't run this destructor!"));
            let p = cv.into_inner();
            assert_eq!(p, 1 as *mut isize);
        }
    }

    #[test]
    fn vec_to_slice_test() {
        unsafe {
            let mut cv = v_malloc(2);

            *cv.get_mut(0).unwrap() = 10;
            *cv.get_mut(1).unwrap() = 12;
            let cs = cv.as_cslice();

            assert_eq!(cs[0], 10);
            assert_eq!(cs[1], 12);
        }
    }

    #[test]
    fn slice_to_vec_test() {
        let cv = v_malloc(2);
        let mut cs = cv.as_cslice();

        cs[0] = 13;
        cs[1] = 26;
        assert_eq!(*cv.get(0).unwrap(), 13);
        assert_eq!(*cv.get(1).unwrap(), 26);
    }
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-2018 Alex Maslakov, <gildedhonour.com>, <alexmaslakov.me>
 *
 * 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.
 *
 * For questions and comments about this product, please see the project page at:
 *
 * https://github.com/GildedHonour/frank_jwt
 *
 */

use std::io::Error as IoError;
use serde_json::Error as SJError;
use openssl::error::ErrorStack;
use base64::DecodeError as B64Error;
use std::error;
use std::fmt;

macro_rules! impl_error {
    ($from:ty, $to:path) => {
        impl From<$from> for Error {
            fn from(e: $from) -> Self {
                $to(format!("{:?}", e))
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error {
    SignatureExpired,
    SignatureInvalid,
    JWTInvalid,
    IssuerInvalid,
    ExpirationInvalid,
    AudienceInvalid,
    FormatInvalid(String),
    IoError(String),
    OpenSslError(String),
    ProtocolError(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::SignatureExpired => write!(f, "Signature expired."),
            Error::SignatureInvalid => write!(f, "Signature invalid."),
            Error::JWTInvalid => write!(f, "JWT invalid."),
            Error::IssuerInvalid => write!(f, "Issuer invalid."),
            Error::ExpirationInvalid => write!(f, "Expiration invalid."),
            Error::AudienceInvalid => write!(f, "Audience invalid."),
            Error::FormatInvalid(msg) => write!(f, "Format invalid: {}.", msg),
            Error::IoError(msg) => write!(f, "Format invalid: {}.", msg),
            Error::OpenSslError(msg) => write!(f, "Format invalid: {}.", msg),
            Error::ProtocolError(msg) => write!(f, "Format invalid: {}.", msg),
        }
    }
}

impl error::Error for Error {}

impl_error!{IoError, Error::IoError}
impl_error!{SJError, Error::FormatInvalid}
impl_error!{ErrorStack, Error::OpenSslError}
impl_error!{B64Error, Error::ProtocolError}
<commit_msg>Fix, bad error descriptions<commit_after>/**
 * Copyright (c) 2015-2018 Alex Maslakov, <gildedhonour.com>, <alexmaslakov.me>
 *
 * 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.
 *
 * For questions and comments about this product, please see the project page at:
 *
 * https://github.com/GildedHonour/frank_jwt
 *
 */

use std::io::Error as IoError;
use serde_json::Error as SJError;
use openssl::error::ErrorStack;
use base64::DecodeError as B64Error;
use std::error;
use std::fmt;

macro_rules! impl_error {
    ($from:ty, $to:path) => {
        impl From<$from> for Error {
            fn from(e: $from) -> Self {
                $to(format!("{:?}", e))
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error {
    SignatureExpired,
    SignatureInvalid,
    JWTInvalid,
    IssuerInvalid,
    ExpirationInvalid,
    AudienceInvalid,
    FormatInvalid(String),
    IoError(String),
    OpenSslError(String),
    ProtocolError(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::SignatureExpired => write!(f, "Signature expired."),
            Error::SignatureInvalid => write!(f, "Signature invalid."),
            Error::JWTInvalid => write!(f, "JWT invalid."),
            Error::IssuerInvalid => write!(f, "Issuer invalid."),
            Error::ExpirationInvalid => write!(f, "Expiration invalid."),
            Error::AudienceInvalid => write!(f, "Audience invalid."),
            Error::FormatInvalid(msg) => write!(f, "Format invalid: {}.", msg),
            Error::IoError(msg) => write!(f, "IO error: {}.", msg),
            Error::OpenSslError(msg) => write!(f, "Open SSL error: {}.", msg),
            Error::ProtocolError(msg) => write!(f, "Protocol error: {}.", msg),
        }
    }
}

impl error::Error for Error {}

impl_error!{IoError, Error::IoError}
impl_error!{SJError, Error::FormatInvalid}
impl_error!{ErrorStack, Error::OpenSslError}
impl_error!{B64Error, Error::ProtocolError}
<|endoftext|>


<commit_before>#![doc="Defines errors related to SciRust library
"]

// std imports

// local imports

/// Enum for errors related to SciRust library
#[deriving(Show)]
pub enum SRError{

    /******************************************************
     *
     *   General matrix operation errors
     *
     *******************************************************/

    /// The matrix is empty
    EmptyMatrix,
    /// The dimensions of two matrices mismatch
    DimensionsMismatch,
    /// Number of rows don't match
    RowsMismatch,
    /// Number of columns don't match
    ColsMismatch,
    /// The matrix is not a square matrix
    IsNotSquareMatrix,
    /// The matrix is not a vector
    IsNotAVector,
    // The matrix is not a column vector
    IsNotAColVector,
    // The matrix is not a row vector
    IsNotARowVector,
    /// Indicates that a matrix is not full rank
    IsNotFullRankMatrix,
    /// Indicates that the matrix is full rank
    IsFullRankMatrix,
    /// The matrix is singular
    IsSingular,
    /// The matrix is invertible (non-singular)
    IsNonSingular,
    /// The matrix is positive definite
    IsPositiveDefinite,
    /// The matrix is positive semi definite
    IsPositiveSemiDefinite,
    /// The matrix is negative definite
    IsNegativeDefinite,
    /// The matrix is negative semi definite
    IsNegativeSemiDefinite,
    /// The matrix is non-definite
    IsNonDefinite,

    /******************************************************
     *
     *   Errors related to solving a system of linear equations
     *
     *******************************************************/

    /// The dimensions of left and right hand side don't match
    LRDimensionMismatch,
    /// There is no solution to the system of equations
    NoSolution,
    /// There are infinite solutions to the system of equations.
    InfiniteSolutions,

    /******************************************************
     *
     *   Discrete numbers related stuff
     *
     *******************************************************/

    /// The number is not a power of two
    IsNotPowerOfTwo,

}

///A convenient typedef of the return value of SciRust API
/// whenever applicable.
pub type SRResult<T> = Result<T, SRError>;

impl SRError{

    /// Converts enum values to string representation
    pub fn to_string(&self) -> String {
        match *self{
            //  Matrices
            SRError::EmptyMatrix => format!("Matrix is empty"),
            SRError::DimensionsMismatch => format!("Dimensions don't match"),
            SRError::RowsMismatch => format!("Number of rows don't match"),
            SRError::ColsMismatch => format!("Number of columns don't match"),
            SRError::IsNotSquareMatrix => format!("Matrix is not square"),
            SRError::IsNotAVector => format!("Matrix is not a vector"),
            SRError::IsNotAColVector => format!("Matrix is not a column vector"),
            SRError::IsNotARowVector => format!("Matrix is not a row vector"),
            SRError::IsNotFullRankMatrix => format!("Matrix is not full rank"),
            SRError::IsFullRankMatrix => format!("Matrix is full rank"),
            SRError::IsSingular => format!("Matrix is singular"),
            SRError::IsNonSingular => format!("Matrix is not singular"),
            SRError::IsPositiveDefinite => format!("Matrix is positive definite"),
            SRError::IsPositiveSemiDefinite => format!("Matrix is positive semi-definite"),
            SRError::IsNegativeDefinite => format!("Matrix is negative definite"),
            SRError::IsNegativeSemiDefinite => format!("Matrix is negative semi-definite"),
            SRError::IsNonDefinite => format!("Matrix is non-definite"),
            // Linear systems
            SRError::LRDimensionMismatch => format!("The dimensions of LHS and RHS don't match"),
            SRError::NoSolution => format!("No solution"),
            SRError::InfiniteSolutions => format!("Infinite solutions"),
            // Discrete numbers
            SRError::IsNotPowerOfTwo => format!("Number is not power of two"),

        }
    }
}

<commit_msg>divide by zero.<commit_after>#![doc="Defines errors related to SciRust library
"]

// std imports

// local imports

/// Enum for errors related to SciRust library
#[deriving(Show)]
pub enum SRError{

    /******************************************************
     *
     *   General matrix operation errors
     *
     *******************************************************/

    /// The matrix is empty
    EmptyMatrix,
    /// The dimensions of two matrices mismatch
    DimensionsMismatch,
    /// Number of rows don't match
    RowsMismatch,
    /// Number of columns don't match
    ColsMismatch,
    /// The matrix is not a square matrix
    IsNotSquareMatrix,
    /// The matrix is not a vector
    IsNotAVector,
    // The matrix is not a column vector
    IsNotAColVector,
    // The matrix is not a row vector
    IsNotARowVector,
    /// Indicates that a matrix is not full rank
    IsNotFullRankMatrix,
    /// Indicates that the matrix is full rank
    IsFullRankMatrix,
    /// The matrix is singular
    IsSingular,
    /// The matrix is invertible (non-singular)
    IsNonSingular,
    /// The matrix is positive definite
    IsPositiveDefinite,
    /// The matrix is positive semi definite
    IsPositiveSemiDefinite,
    /// The matrix is negative definite
    IsNegativeDefinite,
    /// The matrix is negative semi definite
    IsNegativeSemiDefinite,
    /// The matrix is non-definite
    IsNonDefinite,

    /******************************************************
     *
     *   Errors related to solving a system of linear equations
     *
     *******************************************************/

    /// The dimensions of left and right hand side don't match
    LRDimensionMismatch,
    /// There is no solution to the system of equations
    NoSolution,
    /// There are infinite solutions to the system of equations.
    InfiniteSolutions,

    /******************************************************
     *
     *   Arithmetic related stuff
     *
     *******************************************************/
    //  Divide by zero
    DivideByZero,

    /******************************************************
     *
     *   Discrete numbers related stuff
     *
     *******************************************************/

    /// The number is not a power of two
    IsNotPowerOfTwo,

}

///A convenient typedef of the return value of SciRust API
/// whenever applicable.
pub type SRResult<T> = Result<T, SRError>;

impl SRError{

    /// Converts enum values to string representation
    pub fn to_string(&self) -> String {
        match *self{
            //  Matrices
            SRError::EmptyMatrix => format!("Matrix is empty"),
            SRError::DimensionsMismatch => format!("Dimensions don't match"),
            SRError::RowsMismatch => format!("Number of rows don't match"),
            SRError::ColsMismatch => format!("Number of columns don't match"),
            SRError::IsNotSquareMatrix => format!("Matrix is not square"),
            SRError::IsNotAVector => format!("Matrix is not a vector"),
            SRError::IsNotAColVector => format!("Matrix is not a column vector"),
            SRError::IsNotARowVector => format!("Matrix is not a row vector"),
            SRError::IsNotFullRankMatrix => format!("Matrix is not full rank"),
            SRError::IsFullRankMatrix => format!("Matrix is full rank"),
            SRError::IsSingular => format!("Matrix is singular"),
            SRError::IsNonSingular => format!("Matrix is not singular"),
            SRError::IsPositiveDefinite => format!("Matrix is positive definite"),
            SRError::IsPositiveSemiDefinite => format!("Matrix is positive semi-definite"),
            SRError::IsNegativeDefinite => format!("Matrix is negative definite"),
            SRError::IsNegativeSemiDefinite => format!("Matrix is negative semi-definite"),
            SRError::IsNonDefinite => format!("Matrix is non-definite"),
            // Linear systems
            SRError::LRDimensionMismatch => format!("The dimensions of LHS and RHS don't match"),
            SRError::NoSolution => format!("No solution"),
            SRError::InfiniteSolutions => format!("Infinite solutions"),
            // Arithmetic
            SRError::DivideByZero => format!("Attempt to divide by zero"),
            // Discrete numbers
            SRError::IsNotPowerOfTwo => format!("Number is not power of two"),

        }
    }
}

<|endoftext|>


<commit_before>use hyper::status::StatusCode;
use rustc_serialize::base64::FromBase64Error;
use rustc_serialize::json::{Json, ToJson, ParserError, DecoderError};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::convert::From;
use std::error::Error;
use std::fmt;
use std::io::Error as IoError;

#[derive(PartialEq, Debug)]
pub enum ErrorStatus {
    ElementNotSelectable,
    ElementNotVisible,
    InvalidArgument,
    InvalidCookieDomain,
    InvalidElementCoordinates,
    InvalidElementState,
    InvalidSelector,
    InvalidSessionId,
    JavascriptError,
    MoveTargetOutOfBounds,
    NoSuchAlert,
    NoSuchElement,
    NoSuchFrame,
    NoSuchWindow,
    ScriptTimeout,
    SessionNotCreated,
    StaleElementReference,
    Timeout,
    UnableToSetCookie,
    UnexpectedAlertOpen,
    UnknownError,
    UnknownPath,
    UnknownMethod,
    UnsupportedOperation
}

impl ErrorStatus {
    pub fn status_code(&self) -> &'static str {
        match self {
            &ErrorStatus::ElementNotSelectable => "element not selectable",
            &ErrorStatus::ElementNotVisible => "element not visible",
            &ErrorStatus::InvalidArgument => "invalid argument",
            &ErrorStatus::InvalidCookieDomain => "invalid cookie domain",
            &ErrorStatus::InvalidElementCoordinates => "invalid element coordinates",
            &ErrorStatus::InvalidElementState => "invalid element state",
            &ErrorStatus::InvalidSelector => "invalid selector",
            &ErrorStatus::InvalidSessionId => "invalid session id",
            &ErrorStatus::JavascriptError => "javascript error",
            &ErrorStatus::MoveTargetOutOfBounds => "move target out of bounds",
            &ErrorStatus::NoSuchAlert => "no such alert",
            &ErrorStatus::NoSuchElement => "no such element",
            &ErrorStatus::NoSuchFrame => "no such frame",
            &ErrorStatus::NoSuchWindow => "no such window",
            &ErrorStatus::ScriptTimeout => "script timeout",
            &ErrorStatus::SessionNotCreated => "session not created",
            &ErrorStatus::StaleElementReference => "stale element reference",
            &ErrorStatus::Timeout => "timeout",
            &ErrorStatus::UnableToSetCookie => "unable to set cookie",
            &ErrorStatus::UnexpectedAlertOpen => "unexpected alert open",
            &ErrorStatus::UnknownError => "unknown error",
            &ErrorStatus::UnknownPath => "unknown command",
            &ErrorStatus::UnknownMethod => "unknown command",
            &ErrorStatus::UnsupportedOperation => "unsupported operation"
        }
    }

    pub fn http_status(&self) -> StatusCode {
        match self {
            &ErrorStatus::ElementNotSelectable => StatusCode::BadRequest,
            &ErrorStatus::ElementNotVisible => StatusCode::BadRequest,
            &ErrorStatus::InvalidArgument => StatusCode::BadRequest,
            &ErrorStatus::InvalidCookieDomain => StatusCode::BadRequest,
            &ErrorStatus::InvalidElementCoordinates => StatusCode::BadRequest,
            &ErrorStatus::InvalidElementState => StatusCode::BadRequest,
            &ErrorStatus::InvalidSelector => StatusCode::BadRequest,
            &ErrorStatus::InvalidSessionId => StatusCode::NotFound,
            &ErrorStatus::JavascriptError => StatusCode::InternalServerError,
            &ErrorStatus::MoveTargetOutOfBounds => StatusCode::InternalServerError,
            &ErrorStatus::NoSuchAlert => StatusCode::BadRequest,
            &ErrorStatus::NoSuchElement => StatusCode::NotFound,
            &ErrorStatus::NoSuchFrame => StatusCode::BadRequest,
            &ErrorStatus::NoSuchWindow => StatusCode::BadRequest,
            &ErrorStatus::ScriptTimeout => StatusCode::RequestTimeout,
            &ErrorStatus::SessionNotCreated => StatusCode::InternalServerError,
            &ErrorStatus::StaleElementReference => StatusCode::BadRequest,
            &ErrorStatus::Timeout => StatusCode::RequestTimeout,
            &ErrorStatus::UnableToSetCookie => StatusCode::InternalServerError,
            &ErrorStatus::UnexpectedAlertOpen => StatusCode::InternalServerError,
            &ErrorStatus::UnknownError => StatusCode::InternalServerError,
            &ErrorStatus::UnknownPath => StatusCode::NotFound,
            &ErrorStatus::UnknownMethod => StatusCode::MethodNotAllowed,
            &ErrorStatus::UnsupportedOperation => StatusCode::InternalServerError
        }
    }
}

pub type WebDriverResult<T> = Result<T, WebDriverError>;

#[derive(Debug)]
pub struct WebDriverError {
    pub error: ErrorStatus,
    pub message: Cow<'static, str>,
    delete_session: bool
}

impl fmt::Display for WebDriverError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.message.fmt(f)
    }
}

impl WebDriverError {
    pub fn new<S>(error: ErrorStatus, message: S) -> WebDriverError
        where S: Into<Cow<'static, str>>
    {
        WebDriverError {
            error: error,
            message: message.into(),
            delete_session: false
        }
    }

    pub fn status_code(&self) -> &'static str {
        self.error.status_code()
    }

    pub fn http_status(&self) -> StatusCode {
        self.error.http_status()
    }

    pub fn to_json_string(&self) -> String {
        self.to_json().to_string()
    }

    pub fn set_delete_session(&mut self) {
        self.delete_session = true
    }

    pub fn delete_session(&self) -> bool {
        self.delete_session
    }
}

impl ToJson for WebDriverError {
    fn to_json(&self) -> Json {
        let mut data = BTreeMap::new();
        data.insert("error".to_string(), self.status_code().to_json());
        data.insert("message".to_string(), self.message.to_json());
        Json::Object(data)
    }
}

impl Error for WebDriverError {
    fn description(&self) -> &str {
        self.status_code()
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl From<ParserError> for WebDriverError {
    fn from(err: ParserError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
            err.description().to_string())
    }
}

impl From<IoError> for WebDriverError {
    fn from(err: IoError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
            err.description().to_string())
    }
}

impl From<DecoderError> for WebDriverError {
    fn from(err: DecoderError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
                            err.description().to_string())
    }
}

impl From<FromBase64Error> for WebDriverError {
    fn from(err: FromBase64Error) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
                            err.description().to_string())
    }
}

impl From<Box<Error>> for WebDriverError {
    fn from(err: Box<Error>) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
                            err.description().to_string())
    }
}
<commit_msg>error: add ErrorStatus::InsecureCertificate<commit_after>use hyper::status::StatusCode;
use rustc_serialize::base64::FromBase64Error;
use rustc_serialize::json::{Json, ToJson, ParserError, DecoderError};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::convert::From;
use std::error::Error;
use std::fmt;
use std::io::Error as IoError;

#[derive(PartialEq, Debug)]
pub enum ErrorStatus {
    ElementNotSelectable,
    ElementNotVisible,
    InsecureCertificate,
    InvalidArgument,
    InvalidCookieDomain,
    InvalidElementCoordinates,
    InvalidElementState,
    InvalidSelector,
    InvalidSessionId,
    JavascriptError,
    MoveTargetOutOfBounds,
    NoSuchAlert,
    NoSuchElement,
    NoSuchFrame,
    NoSuchWindow,
    ScriptTimeout,
    SessionNotCreated,
    StaleElementReference,
    Timeout,
    UnableToSetCookie,
    UnexpectedAlertOpen,
    UnknownError,
    UnknownMethod,
    UnknownPath,
    UnsupportedOperation,
}

impl ErrorStatus {
    pub fn status_code(&self) -> &'static str {
        match self {
            &ErrorStatus::ElementNotSelectable => "element not selectable",
            &ErrorStatus::ElementNotVisible => "element not visible",
            &ErrorStatus::InsecureCertificate => "insecure certificate",
            &ErrorStatus::InvalidArgument => "invalid argument",
            &ErrorStatus::InvalidCookieDomain => "invalid cookie domain",
            &ErrorStatus::InvalidElementCoordinates => "invalid element coordinates",
            &ErrorStatus::InvalidElementState => "invalid element state",
            &ErrorStatus::InvalidSelector => "invalid selector",
            &ErrorStatus::InvalidSessionId => "invalid session id",
            &ErrorStatus::JavascriptError => "javascript error",
            &ErrorStatus::MoveTargetOutOfBounds => "move target out of bounds",
            &ErrorStatus::NoSuchAlert => "no such alert",
            &ErrorStatus::NoSuchElement => "no such element",
            &ErrorStatus::NoSuchFrame => "no such frame",
            &ErrorStatus::NoSuchWindow => "no such window",
            &ErrorStatus::ScriptTimeout => "script timeout",
            &ErrorStatus::SessionNotCreated => "session not created",
            &ErrorStatus::StaleElementReference => "stale element reference",
            &ErrorStatus::Timeout => "timeout",
            &ErrorStatus::UnableToSetCookie => "unable to set cookie",
            &ErrorStatus::UnexpectedAlertOpen => "unexpected alert open",
            &ErrorStatus::UnknownError => "unknown error",
            &ErrorStatus::UnknownMethod => "unknown command",
            &ErrorStatus::UnknownPath => "unknown command",
            &ErrorStatus::UnsupportedOperation => "unsupported operation",
        }
    }

    pub fn http_status(&self) -> StatusCode {
        match self {
            &ErrorStatus::ElementNotSelectable => StatusCode::BadRequest,
            &ErrorStatus::ElementNotVisible => StatusCode::BadRequest,
            &ErrorStatus::InsecureCertificate => StatusCode::BadRequest,
            &ErrorStatus::InvalidArgument => StatusCode::BadRequest,
            &ErrorStatus::InvalidCookieDomain => StatusCode::BadRequest,
            &ErrorStatus::InvalidElementCoordinates => StatusCode::BadRequest,
            &ErrorStatus::InvalidElementState => StatusCode::BadRequest,
            &ErrorStatus::InvalidSelector => StatusCode::BadRequest,
            &ErrorStatus::InvalidSessionId => StatusCode::NotFound,
            &ErrorStatus::JavascriptError => StatusCode::InternalServerError,
            &ErrorStatus::MoveTargetOutOfBounds => StatusCode::InternalServerError,
            &ErrorStatus::NoSuchAlert => StatusCode::BadRequest,
            &ErrorStatus::NoSuchElement => StatusCode::NotFound,
            &ErrorStatus::NoSuchFrame => StatusCode::BadRequest,
            &ErrorStatus::NoSuchWindow => StatusCode::BadRequest,
            &ErrorStatus::ScriptTimeout => StatusCode::RequestTimeout,
            &ErrorStatus::SessionNotCreated => StatusCode::InternalServerError,
            &ErrorStatus::StaleElementReference => StatusCode::BadRequest,
            &ErrorStatus::Timeout => StatusCode::RequestTimeout,
            &ErrorStatus::UnableToSetCookie => StatusCode::InternalServerError,
            &ErrorStatus::UnexpectedAlertOpen => StatusCode::InternalServerError,
            &ErrorStatus::UnknownError => StatusCode::InternalServerError,
            &ErrorStatus::UnknownMethod => StatusCode::MethodNotAllowed,
            &ErrorStatus::UnknownPath => StatusCode::NotFound,
            &ErrorStatus::UnsupportedOperation => StatusCode::InternalServerError,
        }
    }
}

pub type WebDriverResult<T> = Result<T, WebDriverError>;

#[derive(Debug)]
pub struct WebDriverError {
    pub error: ErrorStatus,
    pub message: Cow<'static, str>,
    delete_session: bool
}

impl fmt::Display for WebDriverError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.message.fmt(f)
    }
}

impl WebDriverError {
    pub fn new<S>(error: ErrorStatus, message: S) -> WebDriverError
        where S: Into<Cow<'static, str>>
    {
        WebDriverError {
            error: error,
            message: message.into(),
            delete_session: false
        }
    }

    pub fn status_code(&self) -> &'static str {
        self.error.status_code()
    }

    pub fn http_status(&self) -> StatusCode {
        self.error.http_status()
    }

    pub fn to_json_string(&self) -> String {
        self.to_json().to_string()
    }

    pub fn set_delete_session(&mut self) {
        self.delete_session = true
    }

    pub fn delete_session(&self) -> bool {
        self.delete_session
    }
}

impl ToJson for WebDriverError {
    fn to_json(&self) -> Json {
        let mut data = BTreeMap::new();
        data.insert("error".to_string(), self.status_code().to_json());
        data.insert("message".to_string(), self.message.to_json());
        Json::Object(data)
    }
}

impl Error for WebDriverError {
    fn description(&self) -> &str {
        self.status_code()
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl From<ParserError> for WebDriverError {
    fn from(err: ParserError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
            err.description().to_string())
    }
}

impl From<IoError> for WebDriverError {
    fn from(err: IoError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
            err.description().to_string())
    }
}

impl From<DecoderError> for WebDriverError {
    fn from(err: DecoderError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
                            err.description().to_string())
    }
}

impl From<FromBase64Error> for WebDriverError {
    fn from(err: FromBase64Error) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
                            err.description().to_string())
    }
}

impl From<Box<Error>> for WebDriverError {
    fn from(err: Box<Error>) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError,
                            err.description().to_string())
    }
}
<|endoftext|>