<commit_before>use token::{Lexeme, Token};
use error::{Result, SassError, ErrorKind};

use std::str::CharIndices;
use std::iter::Peekable;

pub struct Tokenizer<'a> {
    text: &'a str,
    chars: Peekable<CharIndices<'a>>,
}

impl<'a> Iterator for Tokenizer<'a> {
    type Item = Result<Lexeme>;

    fn next(&mut self) -> Option<Result<Lexeme>> {
        match self.parse() {
            Ok(Some(t)) => Some(Ok(t)),
            Ok(None) => None,
            Err(e) => Some(Err(e)),
        }
    }
}

impl<'a> Tokenizer<'a> {
    pub fn new(text: &str) -> Tokenizer {
        Tokenizer {
            text: text,
            chars: text.char_indices().peekable(),
        }
    }

    pub fn parse(&mut self) -> Result<Option<Lexeme>> {
        let mut value = String::new();
        let mut start;

        while let Some((char_offset, curr_char)) = self.chars.next() {
            // Skip leading whitespace
            if curr_char.is_whitespace() {
                continue;
            } else {
                let single_char_token = Token::from_char(curr_char);
                if value.is_empty() && single_char_token.is_some() {
                    if curr_char == '-' {
                        value.push(curr_char);
                        start = char_offset;

                        if let Some(&(_, peek_char)) = self.chars.peek() {
                            if peek_char.is_whitespace() {
                                return Ok(Some(Lexeme { token: Token::Minus, offset: Some(start) }))
                            } else if peek_char.is_numeric() {
                                while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                                    // Stop when we reach a non-numeric char
                                    if !next_char.is_numeric() && next_char != '.' {
                                        break;
                                    } else {
                                        value.push(next_char);
                                        self.chars.next();
                                    }
                                }

                                let value = match value.parse() {
                                    Ok(v) => v,
                                    Err(e) => return Err(SassError {
                                        offset: start,
                                        kind: ErrorKind::TokenizerError,
                                        message: format!(
                                            "Tried to parse `{}` into a f32 but failed.",
                                            value,
                                        ),
                                    })
                                };
                                return Ok(Some(Lexeme { token: Token::Number(value), offset: Some(start) }))

                            } else {
                                while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                                    // Stop when we reach a non-ident char (hyphens are special)
                                    if next_char.is_whitespace() || (
                                        is_single_char_token(next_char) && next_char != '-'
                                    ) {
                                        break;
                                    } else {
                                        value.push(next_char);
                                        self.chars.next();
                                    }
                                }
                                return Ok(Some(Lexeme { token: Token::Ident(value), offset: Some(start) }))
                            }
                        }
                    } else {
                        // We already tested that single_char_token was Some.
                        return Ok(Some(Lexeme {
                            token: single_char_token.unwrap(),
                            offset: Some(char_offset),
                        }))
                    }
                } else {

                    if curr_char.is_numeric() {
                        // Start of a multi-char numeric token
                        value.push(curr_char);
                        start = char_offset;

                        while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                            // Stop when we reach a non-numeric char
                            if !next_char.is_numeric() && next_char != '.' {
                                break;
                            } else {
                                value.push(next_char);
                                self.chars.next();
                            }
                        }
                        let value = match value.parse() {
                            Ok(v) => v,
                            Err(e) => return Err(SassError {
                                offset: start,
                                kind: ErrorKind::TokenizerError,
                                message: format!(
                                    "Tried to parse `{}` into a f32 but failed.",
                                    value,
                                ),
                            })
                        };
                        return Ok(Some(Lexeme { token: Token::Number(value), offset: Some(start) }))
                    } else {
                        // Start of a multi-char non-numeric token
                        value.push(curr_char);
                        start = char_offset;
                        while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                            // Stop when we reach a non-ident char (hyphens are special)
                            if next_char.is_whitespace() || (
                                is_single_char_token(next_char) && next_char != '-'
                            ) {
                                break;
                            } else {
                                value.push(next_char);
                                self.chars.next();
                            }
                        }
                        return Ok(Some(Lexeme { token: Token::Ident(value), offset: Some(start) }))
                    }
                }
            }
        }
        return Ok(None)
    }
}

fn is_single_char_token(ch: char) -> bool {
    Token::from_char(ch).is_some()
}

#[cfg(test)]
mod tests {
    use super::*;
    use token::{Lexeme, Token};
    use error::Result;

    fn assert_expected_lexeme(
        actual: Option<Result<Lexeme>>,
        expected_token: Token,
        expected_offset: usize) {
        let actual = actual.unwrap().unwrap();
        assert_eq!(actual.token, expected_token);
        assert_eq!(actual.offset, Some(expected_offset));
    }

    #[test]
    fn it_returns_none_for_empty_string() {
        let mut tokenizer = Tokenizer::new("");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_none_for_only_whitespace() {
        let mut tokenizer = Tokenizer::new("     ");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_words() {
        // Without regard to Sass word validity
        let mut tokenizer = Tokenizer::new(" \n  div   aoeu  ");
        assert_expected_lexeme(tokenizer.next(), Token::Ident("div".into()), 4);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("aoeu".into()), 10);
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_curly_braces() {
        // Without regard to matching
        let mut tokenizer = Tokenizer::new("{}}a{ blah}");
        assert_expected_lexeme(tokenizer.next(), Token::LeftCurlyBrace, 0);
        assert_expected_lexeme(tokenizer.next(), Token::RightCurlyBrace, 1);
        assert_expected_lexeme(tokenizer.next(), Token::RightCurlyBrace, 2);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("a".into()), 3);
        assert_expected_lexeme(tokenizer.next(), Token::LeftCurlyBrace, 4);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("blah".into()), 6);
        assert_expected_lexeme(tokenizer.next(), Token::RightCurlyBrace, 10);
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_colon() {
        let mut tokenizer = Tokenizer::new(":invalid: property::");
        // This might be wrong. I have a note somewhere else that colons can start idents.
        assert_expected_lexeme(tokenizer.next(), Token::Colon, 0);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("invalid".into()), 1);
        assert_expected_lexeme(tokenizer.next(), Token::Colon, 8);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("property".into()), 10);
        assert_expected_lexeme(tokenizer.next(), Token::Colon, 18);
        assert_expected_lexeme(tokenizer.next(), Token::Colon, 19);
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_semicolon() {
        let mut tokenizer = Tokenizer::new(";;\na;\nb\n;");
        assert_expected_lexeme(tokenizer.next(), Token::Semicolon, 0);
        assert_expected_lexeme(tokenizer.next(), Token::Semicolon, 1);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("a".into()), 3);
        assert_expected_lexeme(tokenizer.next(), Token::Semicolon, 4);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("b".into()), 6);
        assert_expected_lexeme(tokenizer.next(), Token::Semicolon, 8);
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_numbers() {
        let mut tokenizer = Tokenizer::new("border: 0px 1.5 11em;");
        assert_expected_lexeme(tokenizer.next(), Token::Ident("border".into()), 0);
        assert_expected_lexeme(tokenizer.next(), Token::Colon, 6);
        assert_expected_lexeme(tokenizer.next(), Token::Number(0.0), 8);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("px".into()), 9);
        assert_expected_lexeme(tokenizer.next(), Token::Number(1.5), 12);
        assert_expected_lexeme(tokenizer.next(), Token::Number(11.0), 16);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("em".into()), 18);
        assert_expected_lexeme(tokenizer.next(), Token::Semicolon, 20);
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_hyphen() {
        let mut tokenizer = Tokenizer::new("font-weight -webkit -3 - 4-5 a-1");
        assert_expected_lexeme(tokenizer.next(), Token::Ident("font-weight".into()), 0);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("-webkit".into()), 12);
        assert_expected_lexeme(tokenizer.next(), Token::Number(-3.0), 20);
        assert_expected_lexeme(tokenizer.next(), Token::Minus, 23);
        assert_expected_lexeme(tokenizer.next(), Token::Number(4.0), 25);
        assert_expected_lexeme(tokenizer.next(), Token::Number(-5.0), 26);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("a-1".into()), 29);
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_parens() {
        let mut tokenizer = Tokenizer::new("() rgb)()(");
        assert_expected_lexeme(tokenizer.next(), Token::LeftParen, 0);
        assert_expected_lexeme(tokenizer.next(), Token::RightParen, 1);
        assert_expected_lexeme(tokenizer.next(), Token::Ident("rgb".into()), 3);
        assert_expected_lexeme(tokenizer.next(), Token::RightParen, 6);
        assert_expected_lexeme(tokenizer.next(), Token::LeftParen, 7);
        assert_expected_lexeme(tokenizer.next(), Token::RightParen, 8);
        assert_expected_lexeme(tokenizer.next(), Token::LeftParen, 9);
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_slash() {
        let mut tokenizer = Tokenizer::new("/ / 3/4 / 8");
        assert_expected_lexeme(tokenizer.next(), Token::Slash, 0);
        assert_expected_lexeme(tokenizer.next(), Token::Slash, 2);
        assert_expected_lexeme(tokenizer.next(), Token::Number(3.0), 4);
        assert_expected_lexeme(tokenizer.next(), Token::Slash, 5);
        assert_expected_lexeme(tokenizer.next(), Token::Number(4.0), 6);
        assert_expected_lexeme(tokenizer.next(), Token::Slash, 8);
        assert_expected_lexeme(tokenizer.next(), Token::Number(8.0), 10);
        assert_eq!(tokenizer.next(), None);
    }
}
<commit_msg>Yeah not really feeling test fns that make line numbers mean zip<commit_after>use token::{Lexeme, Token};
use error::{Result, SassError, ErrorKind};

use std::str::CharIndices;
use std::iter::Peekable;

pub struct Tokenizer<'a> {
    text: &'a str,
    chars: Peekable<CharIndices<'a>>,
}

impl<'a> Iterator for Tokenizer<'a> {
    type Item = Result<Lexeme>;

    fn next(&mut self) -> Option<Result<Lexeme>> {
        match self.parse() {
            Ok(Some(t)) => Some(Ok(t)),
            Ok(None) => None,
            Err(e) => Some(Err(e)),
        }
    }
}

impl<'a> Tokenizer<'a> {
    pub fn new(text: &str) -> Tokenizer {
        Tokenizer {
            text: text,
            chars: text.char_indices().peekable(),
        }
    }

    pub fn parse(&mut self) -> Result<Option<Lexeme>> {
        let mut value = String::new();
        let mut start;

        while let Some((char_offset, curr_char)) = self.chars.next() {
            // Skip leading whitespace
            if curr_char.is_whitespace() {
                continue;
            } else {
                let single_char_token = Token::from_char(curr_char);
                if value.is_empty() && single_char_token.is_some() {
                    if curr_char == '-' {
                        value.push(curr_char);
                        start = char_offset;

                        if let Some(&(_, peek_char)) = self.chars.peek() {
                            if peek_char.is_whitespace() {
                                return Ok(Some(Lexeme { token: Token::Minus, offset: Some(start) }))
                            } else if peek_char.is_numeric() {
                                while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                                    // Stop when we reach a non-numeric char
                                    if !next_char.is_numeric() && next_char != '.' {
                                        break;
                                    } else {
                                        value.push(next_char);
                                        self.chars.next();
                                    }
                                }

                                let value = match value.parse() {
                                    Ok(v) => v,
                                    Err(e) => return Err(SassError {
                                        offset: start,
                                        kind: ErrorKind::TokenizerError,
                                        message: format!(
                                            "Tried to parse `{}` into a f32 but failed.",
                                            value,
                                        ),
                                    })
                                };
                                return Ok(Some(Lexeme { token: Token::Number(value), offset: Some(start) }))

                            } else {
                                while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                                    // Stop when we reach a non-ident char (hyphens are special)
                                    if next_char.is_whitespace() || (
                                        is_single_char_token(next_char) && next_char != '-'
                                    ) {
                                        break;
                                    } else {
                                        value.push(next_char);
                                        self.chars.next();
                                    }
                                }
                                return Ok(Some(Lexeme { token: Token::Ident(value), offset: Some(start) }))
                            }
                        }
                    } else {
                        // We already tested that single_char_token was Some.
                        return Ok(Some(Lexeme {
                            token: single_char_token.unwrap(),
                            offset: Some(char_offset),
                        }))
                    }
                } else {

                    if curr_char.is_numeric() {
                        // Start of a multi-char numeric token
                        value.push(curr_char);
                        start = char_offset;

                        while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                            // Stop when we reach a non-numeric char
                            if !next_char.is_numeric() && next_char != '.' {
                                break;
                            } else {
                                value.push(next_char);
                                self.chars.next();
                            }
                        }
                        let value = match value.parse() {
                            Ok(v) => v,
                            Err(e) => return Err(SassError {
                                offset: start,
                                kind: ErrorKind::TokenizerError,
                                message: format!(
                                    "Tried to parse `{}` into a f32 but failed.",
                                    value,
                                ),
                            })
                        };
                        return Ok(Some(Lexeme { token: Token::Number(value), offset: Some(start) }))
                    } else {
                        // Start of a multi-char non-numeric token
                        value.push(curr_char);
                        start = char_offset;
                        while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                            // Stop when we reach a non-ident char (hyphens are special)
                            if next_char.is_whitespace() || (
                                is_single_char_token(next_char) && next_char != '-'
                            ) {
                                break;
                            } else {
                                value.push(next_char);
                                self.chars.next();
                            }
                        }
                        return Ok(Some(Lexeme { token: Token::Ident(value), offset: Some(start) }))
                    }
                }
            }
        }
        return Ok(None)
    }
}

fn is_single_char_token(ch: char) -> bool {
    Token::from_char(ch).is_some()
}

#[cfg(test)]
mod tests {
    use super::*;
    use token::{Lexeme, Token};
    use error::Result;

    fn expected_lexeme(expected_token: Token, expected_offset: usize) -> Option<Result<Lexeme>> {
        Some(Ok(Lexeme {
            token: expected_token,
            offset: Some(expected_offset),
        }))
    }

    fn expected_ident(expected_value: &str, expected_offset: usize) -> Option<Result<Lexeme>> {
        expected_lexeme(Token::Ident(expected_value.into()), expected_offset)
    }

    #[test]
    fn it_returns_none_for_empty_string() {
        let mut tokenizer = Tokenizer::new("");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_none_for_only_whitespace() {
        let mut tokenizer = Tokenizer::new("     ");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_words() {
        // Without regard to Sass word validity
        let mut tokenizer = Tokenizer::new(" \n  div   aoeu  ");
        assert_eq!(tokenizer.next(), expected_ident("div", 4));
        assert_eq!(tokenizer.next(), expected_ident("aoeu", 10));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_curly_braces() {
        // Without regard to matching
        let mut tokenizer = Tokenizer::new("{}}a{ blah}");
        assert_eq!(tokenizer.next(), expected_lexeme(Token::LeftCurlyBrace, 0));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::RightCurlyBrace, 1));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::RightCurlyBrace, 2));
        assert_eq!(tokenizer.next(), expected_ident("a", 3));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::LeftCurlyBrace, 4));
        assert_eq!(tokenizer.next(), expected_ident("blah", 6));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::RightCurlyBrace, 10));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_colon() {
        let mut tokenizer = Tokenizer::new(":invalid: property::");
        // This might be wrong. I have a note somewhere else that colons can start idents.
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Colon, 0));
        assert_eq!(tokenizer.next(), expected_ident("invalid", 1));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Colon, 8));
        assert_eq!(tokenizer.next(), expected_ident("property", 10));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Colon, 18));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Colon, 19));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_semicolon() {
        let mut tokenizer = Tokenizer::new(";;\na;\nb\n;");
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Semicolon, 0));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Semicolon, 1));
        assert_eq!(tokenizer.next(), expected_ident("a", 3));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Semicolon, 4));
        assert_eq!(tokenizer.next(), expected_ident("b", 6));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Semicolon, 8));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_numbers() {
        let mut tokenizer = Tokenizer::new("border: 0px 1.5 11em;");
        assert_eq!(tokenizer.next(), expected_ident("border", 0));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Colon, 6));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(0.0), 8));
        assert_eq!(tokenizer.next(), expected_ident("px", 9));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(1.5), 12));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(11.0), 16));
        assert_eq!(tokenizer.next(), expected_ident("em", 18));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Semicolon, 20));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_hyphen() {
        let mut tokenizer = Tokenizer::new("font-weight -webkit -3 - 4-5 a-1");
        assert_eq!(tokenizer.next(), expected_ident("font-weight", 0));
        assert_eq!(tokenizer.next(), expected_ident("-webkit", 12));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(-3.0), 20));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Minus, 23));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(4.0), 25));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(-5.0), 26));
        assert_eq!(tokenizer.next(), expected_ident("a-1", 29));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_parens() {
        let mut tokenizer = Tokenizer::new("() rgb)()(");
        assert_eq!(tokenizer.next(), expected_lexeme(Token::LeftParen, 0));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::RightParen, 1));
        assert_eq!(tokenizer.next(), expected_ident("rgb", 3));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::RightParen, 6));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::LeftParen, 7));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::RightParen, 8));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::LeftParen, 9));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_slash() {
        let mut tokenizer = Tokenizer::new("/ / 3/4 / 8");
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Slash, 0));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Slash, 2));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(3.0), 4));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Slash, 5));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(4.0), 6));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Slash, 8));
        assert_eq!(tokenizer.next(), expected_lexeme(Token::Number(8.0), 10));
        assert_eq!(tokenizer.next(), None);
    }
}
<|endoftext|>


<commit_before>//! An rope.
//!
//! A rope is an efficient data structure for large mutable strings. It's
//! essentially a binary tree whose leaves are strings.
//!
//! For more information, see the following resources:
//! + http://scienceblogs.com/goodmath/2009/01/26/ropes-twining-together-strings/
//! + https://www.ibm.com/developerworks/library/j-ropes/
//! + http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.14.9450&rep=rep1&type=pdf

#![feature(const_fn)]
#![feature(box_syntax, box_patterns)]

use std::cmp;
use std::ops;
use std::convert;

#[derive(Debug)]
pub struct Rope<T> {
    // can we get away with having these be of &str or will they need
    // to be string?
    root: Node<T>
}

use self::Node::*;

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a vector of `T`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Debug)]
enum Node<T> {
    /// A leaf node
    Leaf(Vec<T>)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch {
        /// The length of this node
        len: usize
      , /// The weight of a node is the summed weight of its left subtree
        weight: usize
      , /// The left branch node
        left: Option<Box<Node<T>>>
      , /// The right branch node
        right: Option<Box<Node<T>>>
    }
}

impl<T> Node<T> {
    const fn none() -> Self {
        Branch { len: 0
               , weight: 0
               , left: None
               , right: None
               }
    }

    /// Concatenate two `Node`s to return a new `Branch` node.
    fn branch(left: Self, right: Self) -> Self {
        Branch { len: left.len() + right.len()
               , weight: left.weight()
               , left: Some(box left)
               , right: Some(box right)
        }
    }

    #[inline]
    fn leaf(data: Vec<T>) -> Self {
        Leaf(data)
    }

    /// Returns the height in the tree of a node
    #[inline]
    fn height(&self) -> usize {
        use std::cmp::max;

        match self {
            &Node::Leaf(_) => 1
          , &Node::Branch { ref left, ref right, ..} =>
                max( left.as_ref().map(Box::as_ref).map_or(0, Node::height)
                   , right.as_ref().map(Box::as_ref).map_or(0, Node::height)
                   ) + 1
            }
    }

    /// Returns the length of a node
    //  TODO: do we want to cache this?
    fn len(&self) -> usize {
        match self { &Node::Leaf(ref v) => v.len()
                   , &Node::Branch { ref left, ref right, .. } =>
                        left.as_ref().map(Box::as_ref).map_or(0, Node::len) +
                        right.as_ref().map(Box::as_ref).map_or(0, Node::len)
                    }
    }

    /// Returns the weight of a node
    fn weight (&self) -> usize {
        match self { &Node::Leaf(ref v) => v.len()
                   , &Node::Branch { ref left, .. } =>
                        left.as_ref().map(Box::as_ref).map_or(0, Node::weight)
                    }
    }
}

impl<T> ops::Add for Node<T> {
    type Output = Self;
    /// Concatenate two `Node`s, returning a `Branch` node.
    fn add(self, right: Self) -> Self { Node::branch(self, right) }
}

impl<T> Rope<T> {

    /// Returns a new empty Rope
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::<u8>::new();
    /// assert_eq!(an_rope.len(), 0);
    /// ```
    pub const fn new() -> Rope<T> {
        Rope { root: Node::<T>::none() }
    }

    /// Returns the length of this Rope
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_empty_rope = Rope::new();
    /// assert_eq!(an_empty_rope.len(), 0);
    /// ```
    /// ```
    /// use an_rope::Rope;
    /// let mut an_empty_rope = Rope::from(String::from(""));
    /// assert_eq!(an_empty_rope.len(), 0);
    /// ```
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::from(String::from("a string"));
    /// assert_eq!(an_rope.len(), "a string".len());
    /// ```
    pub fn len(&self) -> usize {
        // self.root.len()
        unimplemented!()
    }

    /// Appends a `Rope` to the end of this `Rope`, returning a new `Rope`
    ///
    /// Note that this is equivalent to using the `+` operator.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let an_rope = Rope::from(String::from("abcd"));
    /// let another_rope = an_rope.merge(Rope::from(String::from("efgh")))
    /// assert_eq!(another_rope, Rope::from(String::from("abcdefgh")));
    /// ```
    pub fn merge(&self, other: &Rope<T>) -> Rope<T> {
        unimplemented!()
    }

    /// Appends a `Rope` to the end of this `Rope`, updating it in place.
    ///
    /// Note that this is equivalent to using the `+=` operator.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::from(String::from("abcd"));
    /// an_rope.update(Rope::from(String::from("efgh")))
    /// assert_eq!(an_rope, Rope::from(String::from("abcdefgh")));
    /// ```
    pub fn update(&mut self, other: Rope<T>) {
        unimplemented!()
    }

    /// Splits the rope into two ropes at the given index.
    ///
    /// Consumes this rope.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::from(String::from("abcd"));
    /// let (ab, cd) = an_rope.split(2);
    /// assert_eq!(ab, Rope::from(String::from("ab")));
    /// assert_eq!(cd, Rope::from(String::from("cd")));
    /// ```
    pub fn split(self, index: usize) -> (Rope<T>, Rope<T>) {
        unimplemented!()
    }

    /// Rebalances this entire `Rope`, returning a balanced `Rope`.
    fn rebalance(self) -> Self {
        unimplemented!()
    }
}

impl<T> ops::Index<usize> for Node<T> {
    type Output = T;

    fn index(&self, i: usize) -> &T {
        // let len = self.len();
        // match self { &Node::Leaf(ref vec) => { &vec[i] }
        //             , &Node::Branch { right: Some(box ref r), .. } if len < i =>
        //                 &r[i - len]
        //             , &Node::Branch { left: Some(box ref l), .. } => &l[i]
        //             , &Node::Branch { left: None, right: None, .. } =>
        //                 panic!("Index out of bounds!")
        //             }
        unimplemented!()
    }
}

impl<T> convert::Into<Vec<T>> for Rope<T> {
    fn into(self) -> Vec<T> {
        unimplemented!()
    }

}

impl convert::From<String> for Rope<u8> {
    fn from(string: String) -> Rope<u8> {
        Rope {
            root: if string.len() == 0 { Node::none() }
                  else { Node::Leaf(string.into_bytes()) }
        }
    }
}

//-- comparisons ----------------------------------------------------
impl<T> cmp::PartialEq for Rope<T> {
    fn eq(&self, other: &Rope<T>) -> bool {
        unimplemented!()
    }
}

impl<T> cmp::PartialEq<str> for Rope<T> {
    fn eq(&self, other: &str) -> bool {
        unimplemented!()
    }
}

//-- concatenation --------------------------------------------------
impl<'a, T> ops::Add for &'a Rope<T> {
    type Output = Rope<T>;
    /// Non-destructively concatenate two `Rope`s, returning a new `Rope`.
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( &rope + &Rope::from(String::from("cd"))
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: Self) -> Rope<T> { self.merge(other) }

}

impl<T> ops::Add for Rope<T> {
    type Output = Rope<T>;
    /// Non-destructively concatenate two `Rope`s, returning a new `Rope`.
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( rope + Rope::from(String::from("cd"))
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: Self) -> Rope<T> { self.merge(&other) }
}

impl ops::Add<String> for Rope<u8> {
    type Output = Rope<u8>;
    /// Non-destructively concatenate a `Rope` and a `String`.
    ///
    /// Returns a new `Rope`
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( rope + String::from("cd"))
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: String) -> Rope<u8> {
         self.merge(&Rope::from(other))
    }
}

impl<'a, 'b> ops::Add<&'b str> for &'a Rope<u8> {
    type Output = Rope<u8>;
    /// Non-destructively concatenate a `Rope` and an `&str`.
    ///
    /// Returns a new `Rope`
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( &rope + "cd")
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: &'b str) -> Rope<u8> {
         self.merge(&Rope::from(other.to_owned()))
     }

}

impl<'a> ops::Add<&'a str> for Rope<u8> {
    type Output = Rope<u8>;
    /// Non-destructively concatenate a `Rope` and an `&str`.
    ///
    /// Returns a new `Rope`
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( rope + "cd")
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: &'a str) -> Rope<u8> {
         self.merge(&Rope::from(other.to_owned()))
     }

}

impl<T> ops::AddAssign for Rope<T> {

    /// Concatenate two `Rope`s mutably.
    ///
    /// # Examples
    /// ```
    /// let mut rope = Rope::from(String::from("ab"));
    /// rope += Rope::from(String::from("cd"));
    /// assert_eq!(rope, Rope::from(String::from("abcd")));
    /// ```
    #[inline]
    fn add_assign(&mut self, other: Rope<T>) {
        self.update(other)
    }
}

impl ops::AddAssign<String> for Rope<u8> {

    /// Concatenate a `String` onto a `Rope` mutably.
    ///
    /// # Examples
    /// ```
    /// let mut rope = Rope::from(String::from("ab"));
    /// rope += String::from("cd");
    /// assert_eq!(rope, Rope::from(String::from("abcd")));
    /// ```
    #[inline]
    fn add_assign(&mut self, string: String) {
        self.update(Rope::from(string))
    }
}

impl<'a> ops::AddAssign<&'a str> for Rope<u8> {

    /// Concatenate an `&str` onto a `Rope` mutably.
    ///
    /// # Examples
    /// ```
    /// let mut rope = Rope::from(String::from("ab"));
    /// rope += String::from("cd");
    /// assert_eq!(rope, Rope::from(String::from("abcd")));
    /// ```
    #[inline]
    fn add_assign(&mut self, string: &'a str) {
        self.update(Rope::from(string.to_owned()))
    }
}

impl<T> ops::Index<usize> for Rope<T> {
    type Output = T;

    /// Recursively index the Rope to return the `i` th character.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let an_rope = Rope::from(String::from("abcd"));
    /// assert_eq!(&an_rope[0], "a");
    /// assert_eq!(&an_rope[1], "b");
    /// assert_eq!(&an_rope[2], "c");
    /// assert_eq!(&an_rope[3], "d");
    /// ```
    ///
    /// # Time complexity
    /// _O_(log _n_)
    ///
    #[inline]
    fn index(&self, i: usize) -> &T {
        &self.root[i]
    }
}

//-- slicing operators ----------------------------------------------
impl<T> ops::Index<ops::Range<usize>> for Rope<T> {
    type Output = [T];

    // Index a substring
    fn index(&self, i: ops::Range<usize>) -> &[T] {
        unimplemented!()
    }
}

impl<T> ops::Index<ops::RangeTo<usize>> for Rope<T> {
    type Output = [T];

    fn index(&self, i: ops::RangeTo<usize>) -> &[T] {
        unimplemented!()
    }
}

impl<T> ops::Index<ops::RangeFrom<usize>> for Rope<T> {
    type Output = [T];

    fn index(&self, i: ops::RangeFrom<usize>) -> &[T] {
        unimplemented!()
    }
}

impl<T> ops::IndexMut<ops::Range<usize>> for Rope<T> {
    fn index_mut(&mut self, i: ops::Range<usize>) -> &mut [T] {
        unimplemented!()
    }
}

impl<T> ops::IndexMut<ops::RangeTo<usize>> for Rope<T> {
    fn index_mut(&mut self, i: ops::RangeTo<usize>) -> &mut [T] {
        unimplemented!()
    }
}

impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Rope<T> {
    fn index_mut(&mut self, i: ops::RangeFrom<usize>) -> &mut [T] {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>rope: more work on rebalancing<commit_after>//! An rope.
//!
//! A rope is an efficient data structure for large mutable strings. It's
//! essentially a binary tree whose leaves are strings.
//!
//! For more information, see the following resources:
//! + http://scienceblogs.com/goodmath/2009/01/26/ropes-twining-together-strings/
//! + https://www.ibm.com/developerworks/library/j-ropes/
//! + http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.14.9450&rep=rep1&type=pdf

#![feature(const_fn)]
#![feature(box_syntax, box_patterns)]

use std::cmp;
use std::ops;
use std::convert;

#[derive(Debug)]
pub struct Rope<T> {
    // can we get away with having these be of &str or will they need
    // to be string?
    root: Node<T>
}

use self::Node::*;

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a vector of `T`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Debug)]
enum Node<T> {
    /// A leaf node
    Leaf(Vec<T>)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch {
        /// The length of this node
        len: usize
      , /// The weight of a node is the summed weight of its left subtree
        weight: usize
      , /// The left branch node
        left: Option<Box<Node<T>>>
      , /// The right branch node
        right: Option<Box<Node<T>>>
    }
}

impl<T> Node<T> {
    const fn none() -> Self {
        Branch { len: 0
               , weight: 0
               , left: None
               , right: None
               }
    }

    /// Concatenate two `Node`s to return a new `Branch` node.
    fn branch(left: Self, right: Self) -> Self {
        Branch { len: left.len() + right.len()
               , weight: left.weight()
               , left: Some(box left)
               , right: Some(box right)
        }
    }

    #[inline]
    fn leaf(data: Vec<T>) -> Self {
        Leaf(data)
    }

    /// Returns true if this node is balanced
    #[inline]
    fn is_balanced(&self) -> bool {
        unimplemented!()
    }

    /// Returns the height in the tree of a node
    #[inline]
    fn height(&self) -> usize {
        use std::cmp::max;

        match self {
            &Node::Leaf(_) => 1
          , &Node::Branch { ref left, ref right, ..} =>
                max( left.as_ref().map(Box::as_ref).map_or(0, Node::height)
                   , right.as_ref().map(Box::as_ref).map_or(0, Node::height)
                   ) + 1
            }
    }

    /// Returns the length of a node
    //  TODO: do we want to cache this?
    fn len(&self) -> usize {
        match self { &Node::Leaf(ref v) => v.len()
                   , &Node::Branch { ref left, ref right, .. } =>
                        left.as_ref().map(Box::as_ref).map_or(0, Node::len) +
                        right.as_ref().map(Box::as_ref).map_or(0, Node::len)
                    }
    }

    /// Returns the weight of a node
    fn weight (&self) -> usize {
        match self { &Node::Leaf(ref v) => v.len()
                   , &Node::Branch { ref left, .. } =>
                        left.as_ref().map(Box::as_ref).map_or(0, Node::weight)
                    }
    }
}

impl<T> ops::Add for Node<T> {
    type Output = Self;
    /// Concatenate two `Node`s, returning a `Branch` node.
    fn add(self, right: Self) -> Self { Node::branch(self, right) }
}

impl<T> Rope<T> {

    /// Returns a new empty Rope
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::<u8>::new();
    /// assert_eq!(an_rope.len(), 0);
    /// ```
    pub const fn new() -> Rope<T> {
        Rope { root: Node::<T>::none() }
    }

    /// Returns the length of this Rope
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_empty_rope = Rope::new();
    /// assert_eq!(an_empty_rope.len(), 0);
    /// ```
    /// ```
    /// use an_rope::Rope;
    /// let mut an_empty_rope = Rope::from(String::from(""));
    /// assert_eq!(an_empty_rope.len(), 0);
    /// ```
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::from(String::from("a string"));
    /// assert_eq!(an_rope.len(), "a string".len());
    /// ```
    pub fn len(&self) -> usize {
        // self.root.len()
        unimplemented!()
    }

    /// Appends a `Rope` to the end of this `Rope`, returning a new `Rope`
    ///
    /// Note that this is equivalent to using the `+` operator.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let an_rope = Rope::from(String::from("abcd"));
    /// let another_rope = an_rope.merge(Rope::from(String::from("efgh")))
    /// assert_eq!(another_rope, Rope::from(String::from("abcdefgh")));
    /// ```
    pub fn merge(&self, other: &Rope<T>) -> Rope<T> {
        unimplemented!()
    }

    /// Appends a `Rope` to the end of this `Rope`, updating it in place.
    ///
    /// Note that this is equivalent to using the `+=` operator.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::from(String::from("abcd"));
    /// an_rope.update(Rope::from(String::from("efgh")))
    /// assert_eq!(an_rope, Rope::from(String::from("abcdefgh")));
    /// ```
    pub fn update(&mut self, other: Rope<T>) {
        unimplemented!()
    }

    /// Splits the rope into two ropes at the given index.
    ///
    /// Consumes this rope.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let mut an_rope = Rope::from(String::from("abcd"));
    /// let (ab, cd) = an_rope.split(2);
    /// assert_eq!(ab, Rope::from(String::from("ab")));
    /// assert_eq!(cd, Rope::from(String::from("cd")));
    /// ```
    pub fn split(self, index: usize) -> (Rope<T>, Rope<T>) {
        unimplemented!()
    }

    /// Rebalances this entire `Rope`, returning a balanced `Rope`.
    fn rebalance(self) -> Self {
        if self.is_balanced() {
            // the rope is already balanced, do nothing
            self
        } else {
            // rebalance the rope
            unimplemented!()
        }
    }

    /// Returns true if this `Rope` is balanced.
    #[inline]
    fn is_balanced(&self) -> bool {
        self.root.is_balanced()
    }
}

impl<T> ops::Index<usize> for Node<T> {
    type Output = T;

    fn index(&self, i: usize) -> &T {
        // let len = self.len();
        // match self { &Node::Leaf(ref vec) => { &vec[i] }
        //             , &Node::Branch { right: Some(box ref r), .. } if len < i =>
        //                 &r[i - len]
        //             , &Node::Branch { left: Some(box ref l), .. } => &l[i]
        //             , &Node::Branch { left: None, right: None, .. } =>
        //                 panic!("Index out of bounds!")
        //             }
        unimplemented!()
    }
}

impl<T> convert::Into<Vec<T>> for Rope<T> {
    fn into(self) -> Vec<T> {
        unimplemented!()
    }

}

impl convert::From<String> for Rope<u8> {
    fn from(string: String) -> Rope<u8> {
        Rope {
            root: if string.len() == 0 { Node::none() }
                  else { Node::Leaf(string.into_bytes()) }
        }
    }
}

//-- comparisons ----------------------------------------------------
impl<T> cmp::PartialEq for Rope<T> {
    fn eq(&self, other: &Rope<T>) -> bool {
        unimplemented!()
    }
}

impl<T> cmp::PartialEq<str> for Rope<T> {
    fn eq(&self, other: &str) -> bool {
        unimplemented!()
    }
}

//-- concatenation --------------------------------------------------
impl<'a, T> ops::Add for &'a Rope<T> {
    type Output = Rope<T>;
    /// Non-destructively concatenate two `Rope`s, returning a new `Rope`.
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( &rope + &Rope::from(String::from("cd"))
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: Self) -> Rope<T> { self.merge(other) }

}

impl<T> ops::Add for Rope<T> {
    type Output = Rope<T>;
    /// Non-destructively concatenate two `Rope`s, returning a new `Rope`.
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( rope + Rope::from(String::from("cd"))
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: Self) -> Rope<T> { self.merge(&other) }
}

impl ops::Add<String> for Rope<u8> {
    type Output = Rope<u8>;
    /// Non-destructively concatenate a `Rope` and a `String`.
    ///
    /// Returns a new `Rope`
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( rope + String::from("cd"))
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: String) -> Rope<u8> {
         self.merge(&Rope::from(other))
    }
}

impl<'a, 'b> ops::Add<&'b str> for &'a Rope<u8> {
    type Output = Rope<u8>;
    /// Non-destructively concatenate a `Rope` and an `&str`.
    ///
    /// Returns a new `Rope`
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( &rope + "cd")
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: &'b str) -> Rope<u8> {
         self.merge(&Rope::from(other.to_owned()))
     }

}

impl<'a> ops::Add<&'a str> for Rope<u8> {
    type Output = Rope<u8>;
    /// Non-destructively concatenate a `Rope` and an `&str`.
    ///
    /// Returns a new `Rope`
    ///
    /// # Examples
    /// ```
    /// let rope = Rope::from(String::from("ab"));
    /// assert_eq!( rope + "cd")
    ///           , Rope::from(String::from("abcd")));
    /// ```
    #[inline] fn add(self, other: &'a str) -> Rope<u8> {
         self.merge(&Rope::from(other.to_owned()))
     }

}

impl<T> ops::AddAssign for Rope<T> {

    /// Concatenate two `Rope`s mutably.
    ///
    /// # Examples
    /// ```
    /// let mut rope = Rope::from(String::from("ab"));
    /// rope += Rope::from(String::from("cd"));
    /// assert_eq!(rope, Rope::from(String::from("abcd")));
    /// ```
    #[inline]
    fn add_assign(&mut self, other: Rope<T>) {
        self.update(other)
    }
}

impl ops::AddAssign<String> for Rope<u8> {

    /// Concatenate a `String` onto a `Rope` mutably.
    ///
    /// # Examples
    /// ```
    /// let mut rope = Rope::from(String::from("ab"));
    /// rope += String::from("cd");
    /// assert_eq!(rope, Rope::from(String::from("abcd")));
    /// ```
    #[inline]
    fn add_assign(&mut self, string: String) {
        self.update(Rope::from(string))
    }
}

impl<'a> ops::AddAssign<&'a str> for Rope<u8> {

    /// Concatenate an `&str` onto a `Rope` mutably.
    ///
    /// # Examples
    /// ```
    /// let mut rope = Rope::from(String::from("ab"));
    /// rope += String::from("cd");
    /// assert_eq!(rope, Rope::from(String::from("abcd")));
    /// ```
    #[inline]
    fn add_assign(&mut self, string: &'a str) {
        self.update(Rope::from(string.to_owned()))
    }
}

impl<T> ops::Index<usize> for Rope<T> {
    type Output = T;

    /// Recursively index the Rope to return the `i` th character.
    ///
    /// # Examples
    /// ```
    /// use an_rope::Rope;
    /// let an_rope = Rope::from(String::from("abcd"));
    /// assert_eq!(&an_rope[0], "a");
    /// assert_eq!(&an_rope[1], "b");
    /// assert_eq!(&an_rope[2], "c");
    /// assert_eq!(&an_rope[3], "d");
    /// ```
    ///
    /// # Time complexity
    /// _O_(log _n_)
    ///
    #[inline]
    fn index(&self, i: usize) -> &T {
        &self.root[i]
    }
}

//-- slicing operators ----------------------------------------------
impl<T> ops::Index<ops::Range<usize>> for Rope<T> {
    type Output = [T];

    // Index a substring
    fn index(&self, i: ops::Range<usize>) -> &[T] {
        unimplemented!()
    }
}

impl<T> ops::Index<ops::RangeTo<usize>> for Rope<T> {
    type Output = [T];

    fn index(&self, i: ops::RangeTo<usize>) -> &[T] {
        unimplemented!()
    }
}

impl<T> ops::Index<ops::RangeFrom<usize>> for Rope<T> {
    type Output = [T];

    fn index(&self, i: ops::RangeFrom<usize>) -> &[T] {
        unimplemented!()
    }
}

impl<T> ops::IndexMut<ops::Range<usize>> for Rope<T> {
    fn index_mut(&mut self, i: ops::Range<usize>) -> &mut [T] {
        unimplemented!()
    }
}

impl<T> ops::IndexMut<ops::RangeTo<usize>> for Rope<T> {
    fn index_mut(&mut self, i: ops::RangeTo<usize>) -> &mut [T] {
        unimplemented!()
    }
}

impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Rope<T> {
    fn index_mut(&mut self, i: ops::RangeFrom<usize>) -> &mut [T] {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>use std::mem::swap;
use std::ops::{Index, IndexMut};

// Wow, I would really love having unboxed trait return types...
pub type BufIter<'a> = ::std::iter::Chain<::std::slice::Iter<'a, String>, ::std::iter::Rev<::std::slice::Iter<'a, String>>>;

/// The buffer data structure, that Sodium is using.
///
/// This structure consists of two "subbuffers", which are just vectors over lines (defined by
/// Strings). The split is where the cursor currently is.
///
/// The second buffer is in reverse order to get the particular efficiency we want.
pub struct SplitBuffer {
    before: Vec<String>,
    after: Vec<String>,
}

impl SplitBuffer {
    /// Create a new empty buffer
    pub fn new() -> Self {
        SplitBuffer {
            before: vec![String::new()],
            after: Vec::new(),
        }
    }

    pub fn from_str(s: &str) -> Self {
        SplitBuffer {
            before: s.lines().map(str::to_string).collect(),
            after: Vec::new(),
        }
    }

    fn cur_line(&self) -> &String {
        self.before.last().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    fn cur_line_mut(&mut self) -> &mut String {
        self.before.last_mut().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    fn up(&mut self) -> bool {
        if self.before.len() == 1 {
            false
        } else {
            self.after.push(self.before.pop().unwrap());
            true
        }
    }

    fn down(&mut self) -> bool {
        if self.after.len() == 0 {
            false
        } else {
            self.before.push(self.after.pop().unwrap());
            true
        }
    }

    fn y(&self) -> usize {
        self.before.len()
    }

    pub fn get_line(&self, n: usize) -> Option<&String> {
        if n < self.before.len() {
            Some(&self.before[n])
        } else if n < self.len() {
            Some(&self.after[n - self.before.len()])
        } else {
            None
        }
    }

    pub fn get_line_mut(&mut self, n: usize) -> Option<&mut String> {
        if n < self.before.len() {
            Some(&mut self.before[n])
        } else if n < self.len() {
            Some(&mut self.after[n - self.before.len()])
        } else {
            None
        }
    }

    pub fn remove_line(&mut self, n: usize) {
        if n < self.before.len() {
            self.before.remove(n);
        } else if n < self.len() {
            self.after.remove(n - self.before.len());
        } else {
            panic!("Out of bound");
        }
    }

    pub fn insert_line(&mut self, n: usize, line: String) {
        if n < self.before.len() {
            println!("C1 n: {}", n);
            self.before.insert(n, line);
        } else if n < self.len() {
            println!("C2");
            self.after.insert(n - self.before.len(), line);
        } else {
            panic!("Out of bound");
        }
    }

    pub fn from_lines(vec: Vec<String>) -> SplitBuffer {
        SplitBuffer {
            before: vec,
            after: Vec::new(),
        }
    }

    pub fn goto(&mut self, y: usize) {
        if y < self.y() {
            for _ in 0..self.y() - y {
                if !self.up() {
                    break;
                }
            }
        } else if y > self.y() {
            for _ in 0..y - self.y() {
                if !self.down() {
                    break;
                }
            }
        }
    }

    fn pop_line(&mut self) -> String {
        self.before.pop().expect("Unexpected condition (Popped the last line)")
    }

    pub fn len(&self) -> usize {
        self.before.len() + self.after.len()
    }

    pub fn lines<'a>(&'a self) -> BufIter<'a> {
        self.after.iter().chain(self.before.iter().rev())
    }

    /// Get the leading whitespaces of the nth line. Used for autoindenting.
    pub fn get_indent(&self, n: usize) -> &str {
        let ln = if let Some(s) = self.get_line(n) {
            s
        } else {
            return "";
        };
        let mut len = 0;
        for c in ln.chars() {
            match c {
                '\t' | ' ' => len += 1,
                _ => break,
            }
        }
        &ln[..len]
    }
}

impl Index<usize> for SplitBuffer {
    type Output = String;

    fn index<'a>(&'a self, index: usize) -> &'a String {
        self.get_line(index).expect("Out of bound")
    }
}
impl IndexMut<usize> for SplitBuffer {

    fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut String {
        self.get_line_mut(index).expect("Out of bound")
    }
}
<commit_msg>Fix line order<commit_after>use std::mem::swap;
use std::ops::{Index, IndexMut};

// Wow, I would really love having unboxed trait return types...
pub type BufIter<'a> = ::std::iter::Chain<::std::slice::Iter<'a, String>, ::std::iter::Rev<::std::slice::Iter<'a, String>>>;

/// The buffer data structure, that Sodium is using.
///
/// This structure consists of two "subbuffers", which are just vectors over lines (defined by
/// Strings). The split is where the cursor currently is.
///
/// The second buffer is in reverse order to get the particular efficiency we want.
pub struct SplitBuffer {
    before: Vec<String>,
    after: Vec<String>,
}

impl SplitBuffer {
    /// Create a new empty buffer
    pub fn new() -> Self {
        SplitBuffer {
            before: vec![String::new()],
            after: Vec::new(),
        }
    }

    pub fn from_str(s: &str) -> Self {
        SplitBuffer {
            before: s.lines().map(str::to_string).collect(),
            after: Vec::new(),
        }
    }

    fn cur_line(&self) -> &String {
        self.before.last().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    fn cur_line_mut(&mut self) -> &mut String {
        self.before.last_mut().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    fn up(&mut self) -> bool {
        if self.before.len() == 1 {
            false
        } else {
            self.after.push(self.before.pop().unwrap());
            true
        }
    }

    fn down(&mut self) -> bool {
        if self.after.len() == 0 {
            false
        } else {
            self.before.push(self.after.pop().unwrap());
            true
        }
    }

    fn y(&self) -> usize {
        self.before.len()
    }

    pub fn get_line(&self, n: usize) -> Option<&String> {
        if n < self.before.len() {
            Some(&self.before[n])
        } else if n < self.len() {
            let n = self.after.len() - (n - self.before.len()) - 1;
            Some(&self.after[n])
        } else {
            None
        }
    }

    pub fn get_line_mut(&mut self, n: usize) -> Option<&mut String> {
        if n < self.before.len() {
            Some(&mut self.before[n])
        } else if n < self.len() {
            let n = self.after.len() - (n - self.before.len()) - 1;
            Some(&mut self.after[n])
        } else {
            None
        }
    }

    pub fn remove_line(&mut self, n: usize) {
        if n < self.before.len() {
            self.before.remove(n);
        } else if n < self.len() {
            let n = self.after.len() - (n - self.before.len()) - 1;
            self.after.remove(n);
        } else {
            panic!("Out of bound");
        }
    }

    pub fn insert_line(&mut self, n: usize, line: String) {
        if n < self.before.len() {
            self.before.insert(n, line);
        } else if n < self.len() {
            let n = self.after.len() - (n - self.before.len()) - 1;
            self.after.insert(n, line);
        } else {
            panic!("Out of bound");
        }
    }

    pub fn from_lines(vec: Vec<String>) -> SplitBuffer {
        SplitBuffer {
            before: vec,
            after: Vec::new(),
        }
    }

    pub fn goto(&mut self, y: usize) {
        if y < self.y() {
            for _ in 0..self.y() - y {
                if !self.up() {
                    break;
                }
            }
        } else if y > self.y() {
            for _ in 0..y - self.y() {
                if !self.down() {
                    break;
                }
            }
        }
    }

    fn pop_line(&mut self) -> String {
        self.before.pop().expect("Unexpected condition (Popped the last line)")
    }

    pub fn len(&self) -> usize {
        self.before.len() + self.after.len()
    }

    pub fn lines<'a>(&'a self) -> BufIter<'a> {
        self.before.iter().chain(self.after.iter().rev())
    }

    /// Get the leading whitespaces of the nth line. Used for autoindenting.
    pub fn get_indent(&self, n: usize) -> &str {
        let ln = if let Some(s) = self.get_line(n) {
            s
        } else {
            return "";
        };
        let mut len = 0;
        for c in ln.chars() {
            match c {
                '\t' | ' ' => len += 1,
                _          => break,
            }
        }
        &ln[..len]
    }
}

impl Index<usize> for SplitBuffer {
    type Output = String;

    fn index<'a>(&'a self, index: usize) -> &'a String {
        self.get_line(index).expect("Out of bound")
    }
}
impl IndexMut<usize> for SplitBuffer {

    fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut String {
        self.get_line_mut(index).expect("Out of bound")
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-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.

#![feature(plugin_registrar, rustc_private)]

extern crate syntax;
extern crate rustc;

use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic::*;
use syntax::ext::deriving::generic::ty::*;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::ext::base::MultiDecorator;
use syntax::parse::token;

use rustc::plugin::Registry;

macro_rules! pathvec {
    ($($x:ident)::+) => (
        vec![ $( stringify!($x) ),+ ]
    )
}

macro_rules! path {
    ($($x:tt)*) => (
        ::syntax::ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
    )
}

macro_rules! path_local {
    ($x:ident) => (
        ::syntax::ext::deriving::generic::ty::Path::new_local(stringify!($x))
    )
}

macro_rules! pathvec_std {
    ($cx:expr, $first:ident :: $($rest:ident)::+) => ({
        let mut v = pathvec!($($rest)::+);
        if let Some(s) = $cx.crate_root {
            v.insert(0, s);
        }
        v
    })
}

pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                      span: Span,
                                      mitem: &MetaItem,
                                      item: &Annotatable,
                                      push: &mut FnMut(Annotatable))
{
    let inline = cx.meta_word(span, InternedString::new("inline"));
    let attrs = vec!(cx.attribute(span, inline));
    let trait_def = TraitDef {
        is_unsafe: false,
        span: span,
        attributes: Vec::new(),
        path: path!(num::FromPrimitive),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        methods: vec!(
            MethodDef {
                name: "from_i64",
                is_unsafe: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(i64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs.clone(),
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("i64", c, s, sub)
                })),
            },
            MethodDef {
                name: "from_u64",
                is_unsafe: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(u64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs,
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("u64", c, s, sub)
                })),
            }
        ),
        associated_types: Vec::new(),
    };

    trait_def.expand(cx, mitem, &item, push)
}

fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    if substr.nonself_args.len() != 1 {
        cx.span_bug(trait_span, "incorrect number of arguments in `derive(FromPrimitive)`")
    }

    let n = &substr.nonself_args[0];

    match *substr.fields {
        StaticStruct(..) => {
            cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs");
            return cx.expr_fail(trait_span, InternedString::new(""));
        }
        StaticEnum(enum_def, _) => {
            if enum_def.variants.is_empty() {
                cx.span_err(trait_span,
                            "`FromPrimitive` cannot be derived for enums with no variants");
                return cx.expr_fail(trait_span, InternedString::new(""));
            }

            let mut arms = Vec::new();

            for variant in &enum_def.variants {
                match variant.node.data {
                    ast::VariantData::Unit(..) => {
                        let span = variant.span;

                        // expr for `$n == $variant as $name`
                        let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
                        let variant = cx.expr_path(path);
                        let ty = cx.ty_ident(span, cx.ident_of(name));
                        let cast = cx.expr_cast(span, variant.clone(), ty);
                        let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);

                        // expr for `Some($variant)`
                        let body = cx.expr_some(span, variant);

                        // arm for `_ if $guard => $body`
                        let arm = ast::Arm {
                            attrs: vec!(),
                            pats: vec!(cx.pat_wild(span)),
                            guard: Some(guard),
                            body: body,
                        };

                        arms.push(arm);
                    }
                    ast::VariantData::Tuple(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for \
                                    enum variants with arguments");
                        return cx.expr_fail(trait_span,
                                            InternedString::new(""));
                    }
                    ast::VariantData::Struct(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for enums \
                                    with struct variants");
                        return cx.expr_fail(trait_span,
                                            InternedString::new(""));
                    }
                }
            }

            // arm for `_ => None`
            let arm = ast::Arm {
                attrs: vec!(),
                pats: vec!(cx.pat_wild(trait_span)),
                guard: None,
                body: cx.expr_none(trait_span),
            };
            arms.push(arm);

            cx.expr_match(trait_span, n.clone(), arms)
        }
        _ => cx.span_bug(trait_span, "expected StaticEnum in derive(FromPrimitive)")
    }
}

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(
        token::intern("derive_NumFromPrimitive"),
        MultiDecorator(Box::new(expand_deriving_from_primitive)));
}
<commit_msg>num-macros: rustc::plugin -> rustc_plugin<commit_after>// Copyright 2012-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.

#![feature(plugin_registrar, rustc_private)]

extern crate syntax;
extern crate rustc_plugin;

use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic::*;
use syntax::ext::deriving::generic::ty::*;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::ext::base::MultiDecorator;
use syntax::parse::token;

use rustc_plugin::Registry;

macro_rules! pathvec {
    ($($x:ident)::+) => (
        vec![ $( stringify!($x) ),+ ]
    )
}

macro_rules! path {
    ($($x:tt)*) => (
        ::syntax::ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
    )
}

macro_rules! path_local {
    ($x:ident) => (
        ::syntax::ext::deriving::generic::ty::Path::new_local(stringify!($x))
    )
}

macro_rules! pathvec_std {
    ($cx:expr, $first:ident :: $($rest:ident)::+) => ({
        let mut v = pathvec!($($rest)::+);
        if let Some(s) = $cx.crate_root {
            v.insert(0, s);
        }
        v
    })
}

pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                      span: Span,
                                      mitem: &MetaItem,
                                      item: &Annotatable,
                                      push: &mut FnMut(Annotatable))
{
    let inline = cx.meta_word(span, InternedString::new("inline"));
    let attrs = vec!(cx.attribute(span, inline));
    let trait_def = TraitDef {
        is_unsafe: false,
        span: span,
        attributes: Vec::new(),
        path: path!(num::FromPrimitive),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        methods: vec!(
            MethodDef {
                name: "from_i64",
                is_unsafe: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(i64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs.clone(),
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("i64", c, s, sub)
                })),
            },
            MethodDef {
                name: "from_u64",
                is_unsafe: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(u64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs,
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("u64", c, s, sub)
                })),
            }
        ),
        associated_types: Vec::new(),
    };

    trait_def.expand(cx, mitem, &item, push)
}

fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    if substr.nonself_args.len() != 1 {
        cx.span_bug(trait_span, "incorrect number of arguments in `derive(FromPrimitive)`")
    }

    let n = &substr.nonself_args[0];

    match *substr.fields {
        StaticStruct(..) => {
            cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs");
            return cx.expr_fail(trait_span, InternedString::new(""));
        }
        StaticEnum(enum_def, _) => {
            if enum_def.variants.is_empty() {
                cx.span_err(trait_span,
                            "`FromPrimitive` cannot be derived for enums with no variants");
                return cx.expr_fail(trait_span, InternedString::new(""));
            }

            let mut arms = Vec::new();

            for variant in &enum_def.variants {
                match variant.node.data {
                    ast::VariantData::Unit(..) => {
                        let span = variant.span;

                        // expr for `$n == $variant as $name`
                        let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
                        let variant = cx.expr_path(path);
                        let ty = cx.ty_ident(span, cx.ident_of(name));
                        let cast = cx.expr_cast(span, variant.clone(), ty);
                        let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);

                        // expr for `Some($variant)`
                        let body = cx.expr_some(span, variant);

                        // arm for `_ if $guard => $body`
                        let arm = ast::Arm {
                            attrs: vec!(),
                            pats: vec!(cx.pat_wild(span)),
                            guard: Some(guard),
                            body: body,
                        };

                        arms.push(arm);
                    }
                    ast::VariantData::Tuple(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for \
                                    enum variants with arguments");
                        return cx.expr_fail(trait_span,
                                            InternedString::new(""));
                    }
                    ast::VariantData::Struct(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for enums \
                                    with struct variants");
                        return cx.expr_fail(trait_span,
                                            InternedString::new(""));
                    }
                }
            }

            // arm for `_ => None`
            let arm = ast::Arm {
                attrs: vec!(),
                pats: vec!(cx.pat_wild(trait_span)),
                guard: None,
                body: cx.expr_none(trait_span),
            };
            arms.push(arm);

            cx.expr_match(trait_span, n.clone(), arms)
        }
        _ => cx.span_bug(trait_span, "expected StaticEnum in derive(FromPrimitive)")
    }
}

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(
        token::intern("derive_NumFromPrimitive"),
        MultiDecorator(Box::new(expand_deriving_from_primitive)));
}
<|endoftext|>


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

//! Random number generation traits
//!
//! This crate is mainly of interest to crates publishing implementations of
//! `RngCore`. Other users are encouraged to use the
//! [rand crate](https://crates.io/crates/rand) instead.
//!
//! `RngCore` is the core trait implemented by algorithmic pseudo-random number
//! generators and external random-number sources.
//!
//! `SeedableRng` is an extension trait for construction from fixed seeds and
//! other random number generators.
//!
//! `Error` is provided for error-handling. It is safe to use in `no_std`
//! environments.
//!
//! The `impls` and `le` sub-modules include a few small functions to assist
//! implementation of `RngCore`. Since this module is only of interest to
//! `RngCore` implementors, it is not re-exported from `rand`.

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
       html_root_url = "https://docs.rs/rand-core/0.1")]

#![deny(missing_debug_implementations)]

#![cfg_attr(not(feature="std"), no_std)]
#![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))]

#[cfg(feature="std")] extern crate core;
#[cfg(all(feature = "alloc", not(feature="std")))] extern crate alloc;

use core::default::Default;
use core::convert::AsMut;

#[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;

pub use error::{ErrorKind, Error};

mod error;
pub mod impls;
pub mod le;

/// The core of a random number generator.
///
/// This trait encapsulates the low-level functionality common to all
/// generators, and is the "back end", to be implemented by generators.
/// End users should normally use [`Rng`] instead.
///
/// Unlike [`Rng`], this trait is object-safe. To use a type-erased [`Rng`] —
/// i.e. dynamic dispatch — this trait must be used (also import [`Rng`] to
/// use its generic functions):
///
/// ```
/// use rand_core::RngCore;
///
/// fn use_rng(mut rng: &mut RngCore) -> u32 {
///     rng.next_u32()
/// }
///
/// // or:
/// fn use_any_rng<R: RngCore>(rng: &mut R) -> u32 {
///     rng.next_u32()
/// }
/// ```
///
/// Several extension traits exist:
///
/// *   [`Rng`] provides high-level functionality using generic functions
/// *   [`SeedableRng`] is another low-level trait to be implemented by PRNGs
///     (algorithmic RNGs), concerning creation and seeding
/// *   [`NewRng`] is a high-level trait providing a `new()` function, allowing
///     easy construction of freshly-seeded PRNGs
///
/// [`Rng`]: https://docs.rs/rand/0.5/rand/trait.Rng.html
/// [`SeedableRng`]: trait.SeedableRng.html
/// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html
pub trait RngCore {
    /// Return the next random `u32`.
    ///
    /// Implementations of this trait must implement at least one of
    /// `next_u32`, `next_u64` and `fill_bytes` directly. In the case this
    /// function is not implemented directly, it can be implemented using
    /// `self.next_u64() as u32` or via `fill_bytes`.
    fn next_u32(&mut self) -> u32;

    /// Return the next random `u64`.
    ///
    /// Implementations of this trait must implement at least one of
    /// `next_u32`, `next_u64` and `fill_bytes` directly. In the case this
    /// function is not implemented directly, the default implementation will
    /// generate values via `next_u32` in little-endian fashion, or this
    /// function can be implemented via `fill_bytes`.
    fn next_u64(&mut self) -> u64;

    /// Fill `dest` with random data.
    ///
    /// Implementations of this trait must implement at least one of
    /// `next_u32`, `next_u64` and `fill_bytes` directly. In the case this
    /// function is not implemented directly, the default implementation will
    /// generate values via `next_u64` in little-endian fashion.
    ///
    /// There is no requirement on how this method generates values relative to
    /// `next_u32` or `next_u64`; e.g. a `u64` cast to bytes is not required to
    /// have the same value as eight bytes filled via this function. There *is*
    /// a requirement of portability for reproducible generators which implies
    /// that any seedable generator must fix endianness when generating bytes.
    ///
    /// This method should guarantee that `dest` is entirely filled
    /// with new data, and may panic if this is impossible
    /// (e.g. reading past the end of a file that is being used as the
    /// source of randomness).
    fn fill_bytes(&mut self, dest: &mut [u8]);

    /// Fill `dest` entirely with random data.
    ///
    /// This is the only method which allows an RNG to report errors while
    /// generating random data; other methods either handle the error
    /// internally or panic. This method is
    /// the intended way to use external (true) RNGs, like `OsRng`. Its main
    /// use-cases are to generate keys and to seed (infallible) PRNGs.
    ///
    /// Other than error handling, this method is identical to [`fill_bytes`], and
    /// has a default implementation simply wrapping [`fill_bytes`].
    ///
    /// [`fill_bytes`]: trait.RngCore.html#method.fill_bytes
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
}

/// A marker trait for an `Rng` which may be considered for use in
/// cryptography.
///
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
/// satisfy an additional properties over other generators: given the first
/// *k* bits of an algorithm's output
/// sequence, it should not be possible using polynomial-time algorithms to
/// predict the next bit with probability significantly greater than 50%.
///
/// Some generators may satisfy an additional property, however this is not
/// required: if the CSPRNG's state is revealed, it should not be
/// computationally-feasible to reconstruct output prior to this. Some other
/// generators allow backwards-computation and are consided *reversible*.
///
/// Note that this trait is provided for guidance only and cannot guarantee
/// suitability for cryptographic applications. In general it should only be
/// implemented for well-reviewed code implementing well-regarded algorithms.
///
/// Note also that use of a `CryptoRng` does not protect against other
/// weaknesses such as seeding from a weak entropy source or leaking state.
pub trait CryptoRng: RngCore {}

/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
/// pseudo-random number generators (PRNGs, or algorithmic generators).
///
/// Normally users should use the [`NewRng`] extension trait, excepting when a
/// fixed seed must be used, in which case usage of [`SeedableRng::from_seed`]
/// is recommended.
///
/// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html
/// [`SeedableRng::from_seed`]: #tymethod.from_seed
pub trait SeedableRng: Sized {
    /// Seed type, which is restricted to types mutably-dereferencable as `u8`
    /// arrays (we recommend `[u8; N]` for some `N`).
    ///
    /// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
    /// which means an array of `[u8; 12]` or greater to avoid picking RNGs with
    /// partially overlapping periods.
    ///
    /// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
    type Seed: Sized + Default + AsMut<[u8]>;

    /// Create a new PRNG using the given seed.
    ///
    /// PRNG implementations are allowed to assume that bits in the seed are
    /// well distributed. That means usually that the number of one and zero
    /// bits are about equal, and values like 0, 1 and (size - 1) are unlikely.
    ///
    /// PRNG implementations are recommended to be reproducible. A PRNG seeded
    /// using this function with a fixed seed should produce the same sequence
    /// of output in the future and on different architectures (with for example
    /// different endianness).
    ///
    /// It is however not required that this function yield the same state as a
    /// reference implementation of the PRNG given equivalent seed; if necessary
    /// another constructor can be used.
    fn from_seed(seed: Self::Seed) -> Self;

    /// Create a new PRNG seeded from another `Rng`.
    ///
    /// This is the recommended way to initialize PRNGs with fresh entropy. The
    /// [`NewRng`] trait provides a convenient new method based on `from_rng`.
    ///
    /// Usage of this method is not recommended when reproducibility is required
    /// since implementing PRNGs are not required to fix Endianness and are
    /// allowed to modify implementations in new releases.
    ///
    /// It is important to use a good source of randomness to initialize the
    /// PRNG. Cryptographic PRNG may be rendered insecure when seeded from a
    /// non-cryptographic PRNG or with insufficient entropy.
    /// Many non-cryptographic PRNGs will show statistical bias in their first
    /// results if their seed numbers are small or if there is a simple pattern
    /// between them.
    ///
    /// Prefer to seed from a strong external entropy source like [`OsRng`] or
    /// from a cryptographic PRNG; if creating a new generator for cryptographic
    /// uses you *must* seed from a strong source.
    ///
    /// Seeding a small PRNG from another small PRNG is possible, but
    /// something to be careful with. An extreme example of how this can go
    /// wrong is seeding an [`XorShiftRng`] from another [`XorShiftRng`], which
    /// will effectively clone the generator. In general seeding from a
    /// generator which is hard to predict is probably okay.
    ///
    /// PRNG implementations are allowed to assume that a good RNG is provided
    /// for seeding, and that it is cryptographically secure when appropriate.
    ///
    /// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html
    /// [`OsRng`]: https://docs.rs/rand/0.5/rand/os/struct.OsRng.html
    /// [`XorShiftRng`]: https://docs.rs/rand/0.5/rand/prng/xorshift/struct.XorShiftRng.html
    fn from_rng<R: RngCore>(rng: &mut R) -> Result<Self, Error> {
        let mut seed = Self::Seed::default();
        rng.try_fill_bytes(seed.as_mut())?;
        Ok(Self::from_seed(seed))
    }
}

impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        (**self).next_u32()
    }

    #[inline]
    fn next_u64(&mut self) -> u64 {
        (**self).next_u64()
    }

    #[inline]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        (**self).fill_bytes(dest)
    }

    #[inline]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        (**self).try_fill_bytes(dest)
    }
}

#[cfg(any(feature="std", feature="alloc"))]
impl<R: RngCore + ?Sized> RngCore for Box<R> {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        (**self).next_u32()
    }

    #[inline]
    fn next_u64(&mut self) -> u64 {
        (**self).next_u64()
    }

    #[inline]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        (**self).fill_bytes(dest)
    }

    #[inline]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        (**self).try_fill_bytes(dest)
    }
}
<commit_msg>rand-core: update doc, especially of RngCore<commit_after>// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Random number generation traits
//!
//! This crate is mainly of interest to crates publishing implementations of
//! `RngCore`. Other users are encouraged to use the [rand] crate instead
//! which re-exports the main traits and error types.
//!
//! `RngCore` is the core trait implemented by algorithmic pseudo-random number
//! generators and external random-number sources.
//!
//! `SeedableRng` is an extension trait for construction from fixed seeds and
//! other random number generators.
//!
//! `Error` is provided for error-handling. It is safe to use in `no_std`
//! environments.
//!
//! The `impls` and `le` sub-modules include a few small functions to assist
//! implementation of `RngCore`.
//!
//! [rand]: https://crates.io/crates/rand

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
       html_root_url = "https://docs.rs/rand-core/0.1")]

#![deny(missing_debug_implementations)]

#![cfg_attr(not(feature="std"), no_std)]
#![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))]

#[cfg(feature="std")] extern crate core;
#[cfg(all(feature = "alloc", not(feature="std")))] extern crate alloc;

use core::default::Default;
use core::convert::AsMut;

#[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;

pub use error::{ErrorKind, Error};

mod error;
pub mod impls;
pub mod le;

/// The core of a random number generator.
///
/// This trait encapsulates the low-level functionality common to all
/// generators, and is the "back end", to be implemented by generators.
/// End users should normally use [`Rng`] from the [rand] crate, which is
/// automatically implemented for every type implementing `RngCore`.
///
/// Three different methods for generating random data are provided since the
/// optimal implementation of each is dependent on the type of generator. There
/// is no required relationship between the output of each; e.g. many
/// implementations of `fill_bytes` consume a whole number of `u32` or `u64`
/// values and drop any remaining unused bytes.
///
/// The `try_fill_bytes` method is a variant of `fill_bytes` allowing error
/// handling; it is not deemed sufficiently useful to add equivalents for
/// `next_u32` or `next_u64` since the latter methods are almost always used
/// with algorithmic generators (PRNGs), which are normally infallible.
///
/// Algorithmic generators implementing `SeedableRng` should normally have
/// *portable, reproducible* output, i.e. fix Endianness when converting values
/// to avoid platform differences, and avoid making any changes which affect
/// output (except by communicating that the release has breaking changes).
///
/// Typically implementators will implement only one of the methods available
/// in this trait directly, then use the helper functions from the [`impls`]
/// module to implement the other methods.
///
/// # Example
///
/// A simple example, obviously not generating very *random* output:
///
/// ```rust
/// use rand_core::{RngCore, Error, impls};
///
/// struct CountingRng(u64);
///
/// impl RngCore for CountingRng {
///     fn next_u32(&mut self) -> u32 {
///         self.next_u64() as u32
///     }
///
///     fn next_u64(&mut self) -> u64 {
///         self.0 += 1;
///         self.0
///     }
///
///     fn fill_bytes(&mut self, dest: &mut [u8]) {
///         impls::fill_bytes_via_u64(self, dest)
///     }
///
///     fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
///         Ok(self.fill_bytes(dest))
///     }
/// }
/// ```
///
/// [rand]: https://crates.io/crates/rand
/// [`Rng`]: https://docs.rs/rand/0.5/rand/trait.Rng.html
/// [`impls`]: impls/index.html
pub trait RngCore {
    /// Return the next random `u32`.
    ///
    /// RNGs must implement at least one method from this trait directly. In
    /// the case this method is not implemented directly, it can be implemented
    /// using `self.next_u64() as u32` or
    /// [via `fill_bytes`](impls/fn.next_u32_via_fill.html).
    fn next_u32(&mut self) -> u32;

    /// Return the next random `u64`.
    ///
    /// RNGs must implement at least one method from this trait directly. In
    /// the case this method is not implemented directly, it can be implemented
    /// [via `next_u32`](impls/fn.next_u64_via_u32.html) or
    /// [via `fill_bytes`](impls/fn.next_u64_via_fill.html).
    fn next_u64(&mut self) -> u64;

    /// Fill `dest` with random data.
    ///
    /// RNGs must implement at least one method from this trait directly. In
    /// the case this method is not implemented directly, it can be implemented
    /// [via `next_u32`](impls/fn.fill_bytes_via_u32.html) or
    /// [via `next_u64`](impls/fn.fill_bytes_via_u64.html) or
    /// via `try_fill_bytes`; if this generator can fail the implementation
    /// must choose how best to handle errors here (e.g. panic with a
    /// descriptive message or log a warning and retry a few times).
    ///
    /// This method should guarantee that `dest` is entirely filled
    /// with new data, and may panic if this is impossible
    /// (e.g. reading past the end of a file that is being used as the
    /// source of randomness).
    fn fill_bytes(&mut self, dest: &mut [u8]);

    /// Fill `dest` entirely with random data.
    ///
    /// This is the only method which allows an RNG to report errors while
    /// generating random data thus making this the primary method implemented
    /// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used
    /// directly to generate keys and to seed (infallible) PRNGs.
    ///
    /// Other than error handling, this method is identical to [`fill_bytes`];
    /// thus this may be implemented using `Ok(self.fill_bytes(dest))` or
    /// `fill_bytes` may be implemented with
    /// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
    ///
    /// [`fill_bytes`]: trait.RngCore.html#method.fill_bytes
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
}

/// A marker trait for an `Rng` which may be considered for use in
/// cryptography.
///
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
/// satisfy an additional properties over other generators: given the first
/// *k* bits of an algorithm's output
/// sequence, it should not be possible using polynomial-time algorithms to
/// predict the next bit with probability significantly greater than 50%.
///
/// Some generators may satisfy an additional property, however this is not
/// required: if the CSPRNG's state is revealed, it should not be
/// computationally-feasible to reconstruct output prior to this. Some other
/// generators allow backwards-computation and are consided *reversible*.
///
/// Note that this trait is provided for guidance only and cannot guarantee
/// suitability for cryptographic applications. In general it should only be
/// implemented for well-reviewed code implementing well-regarded algorithms.
///
/// Note also that use of a `CryptoRng` does not protect against other
/// weaknesses such as seeding from a weak entropy source or leaking state.
pub trait CryptoRng: RngCore {}

/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
/// pseudo-random number generators (PRNGs, or algorithmic generators).
///
/// [rand]'s [`NewRng`] trait is automatically implemented for every type
/// implementing `SeedableRng`, providing a convenient `new()` method.
///
/// [rand]: https://crates.io/crates/rand
/// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html
pub trait SeedableRng: Sized {
    /// Seed type, which is restricted to types mutably-dereferencable as `u8`
    /// arrays (we recommend `[u8; N]` for some `N`).
    ///
    /// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
    /// which means an array of `[u8; 12]` or greater to avoid picking RNGs with
    /// partially overlapping periods.
    ///
    /// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
    type Seed: Sized + Default + AsMut<[u8]>;

    /// Create a new PRNG using the given seed.
    ///
    /// PRNG implementations are allowed to assume that bits in the seed are
    /// well distributed. That means usually that the number of one and zero
    /// bits are about equal, and values like 0, 1 and (size - 1) are unlikely.
    ///
    /// PRNG implementations are recommended to be reproducible. A PRNG seeded
    /// using this function with a fixed seed should produce the same sequence
    /// of output in the future and on different architectures (with for example
    /// different endianness).
    ///
    /// It is however not required that this function yield the same state as a
    /// reference implementation of the PRNG given equivalent seed; if necessary
    /// another constructor replicating behaviour from a reference
    /// implementation can be added.
    fn from_seed(seed: Self::Seed) -> Self;

    /// Create a new PRNG seeded from another `Rng`.
    ///
    /// This is the recommended way to initialize PRNGs with fresh entropy. The
    /// [`NewRng`] trait provides a convenient new method based on `from_rng`.
    ///
    /// Usage of this method is not recommended when reproducibility is required
    /// since implementing PRNGs are not required to fix Endianness and are
    /// allowed to modify implementations in new releases.
    ///
    /// It is important to use a good source of randomness to initialize the
    /// PRNG. Cryptographic PRNG may be rendered insecure when seeded from a
    /// non-cryptographic PRNG or with insufficient entropy.
    /// Many non-cryptographic PRNGs will show statistical bias in their first
    /// results if their seed numbers are small or if there is a simple pattern
    /// between them.
    ///
    /// Prefer to seed from a strong external entropy source like [`OsRng`] or
    /// from a cryptographic PRNG; if creating a new generator for cryptographic
    /// uses you *must* seed from a strong source.
    ///
    /// Seeding a small PRNG from another small PRNG is possible, but
    /// something to be careful with. An extreme example of how this can go
    /// wrong is seeding an [`XorShiftRng`] from another [`XorShiftRng`], which
    /// will effectively clone the generator. In general seeding from a
    /// generator which is hard to predict is probably okay.
    ///
    /// PRNG implementations are allowed to assume that a good RNG is provided
    /// for seeding, and that it is cryptographically secure when appropriate.
    ///
    /// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html
    /// [`OsRng`]: https://docs.rs/rand/0.5/rand/os/struct.OsRng.html
    /// [`XorShiftRng`]: https://docs.rs/rand/0.5/rand/prng/xorshift/struct.XorShiftRng.html
    fn from_rng<R: RngCore>(rng: &mut R) -> Result<Self, Error> {
        let mut seed = Self::Seed::default();
        rng.try_fill_bytes(seed.as_mut())?;
        Ok(Self::from_seed(seed))
    }
}

impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        (**self).next_u32()
    }

    #[inline]
    fn next_u64(&mut self) -> u64 {
        (**self).next_u64()
    }

    #[inline]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        (**self).fill_bytes(dest)
    }

    #[inline]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        (**self).try_fill_bytes(dest)
    }
}

#[cfg(any(feature="std", feature="alloc"))]
impl<R: RngCore + ?Sized> RngCore for Box<R> {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        (**self).next_u32()
    }

    #[inline]
    fn next_u64(&mut self) -> u64 {
        (**self).next_u64()
    }

    #[inline]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        (**self).fill_bytes(dest)
    }

    #[inline]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        (**self).try_fill_bytes(dest)
    }
}
<|endoftext|>