//! Rope slices
//!
//! While we could just have the slicing methods on `Rope`s return `&str`s,
//! this would have some serious drawbacks: to slice a rope as `&str`, we'd have
//! to collect all the `Rope`'s characters into a `String` and then slice that
//! `String`. Creating an intermediate `String` would be slow, would cause
//! unnecessary allocations, and, in the case of `Rope::slice_mut()`, would
//! return a mutable slice of a _new `String`_ –- mutating the slice would _not_
//! mutate the underlying `Rope`.
// TODO: implement Borrow<RopeSlice> for Rope?
use fmt;
use cmp;
use convert;
use RangeArgument;
use Range;
use Rope;
use Node;
/// An immutable borrowed slice of a `Rope`.
///
/// A `RopeSlice` represents an immutable borrowed slice of some or all the
/// characters in a `Rope`.
//
// /// An mutable borrowed slice of a `Rope`.
// ///
// /// A `RopeSliceMut` represents a mutable borrowed slice of some or all the
// /// characters in a `Rope`.
// #[derive(Debug)]
// pub struct RopeSliceMut<'a> { node: &'a mut Node
// , offset: usize
// , len: usize
// }
//
// impl<'a> RopeSliceMut<'a> {
//
// // TODO: share duplicate functionality with non-mutable RopeSlice in a less
// // ugly way. Maybe an added generic?
// // - eliza, 12/23/16
//
// // TODO: add mutable iterators
//
// #[cfg(feature = "unstable")]
// pub fn new<R>(node: &'a mut Node, range: R) -> Self
// where R: RangeArgument<usize> {
// let len = node.len();
//
// // if the RangeArgument doesn't have a defined start index,
// // the slice begins at the 0th index.
// let start = *range.start().unwrap_or(&0);
// // similarly, if there's no defined end, then the end index
// // is the last index in the Rope.
// let end = *range.end().unwrap_or(&len);
//
// let slice_len = end - start;
//
// // find the lowest node that contains both the slice start index and
// // the end index
// let (node, offset) = if start == 0 && end == len {
// // if the slice contains the entire rope, then the spanning node
// // is the root node
// (node, 0)
// } else {
// node.spanning_mut(start, slice_len)
// };
//
// RopeSliceMut { node: node
// , offset: offset
// , len: slice_len }
// }
// #[cfg(not(feature = "unstable"))]
// pub fn new(node: &'a mut Node, range: Range<usize>) -> Self {
// let len = node.len();
// let slice_len = range.end - range.start;
//
// // find the lowest node that contains both the slice start index and
// // the end index
// let (node, offset) = if range.start == 0 && range.end == len {
// // if the slice contains the entire rope, then the spanning node
// // is the root node
// (node, 0)
// } else {
// node.spanning_mut(range.start, slice_len)
// };
//
// RopeSliceMut { node: node
// , offset: offset
// , len: slice_len }
// }
//
// #[cfg(feature = "unstable")]
// #[inline]
// fn slice_char_iter<I, T>(&'a self, i: I) -> impl Iterator<Item=T> + 'a
// where I: Iterator<Item=T>
// , I: 'a
// , T: Copy {
// i.skip(self.offset).take(self.len)
// }
//
// #[cfg(feature = "unstable")]
// fn slice_strings_iter<I>(&'a self, i: I) -> impl Iterator<Item=&'a str> +'a
// where I: Iterator<Item=&'a str>
// , I: 'a {
// i.scan((self.offset, self.len), |curr, s| {
// match *curr {
// (0, 0) => None
// , (0, ref mut remaining) if *remaining < s.len() => {
// let r = *remaining;
// *remaining = 0;
// Some(&s[..r])
// }
// , (0, ref mut remaining) => {
// *remaining -= s.len();
// Some(s)
// }
// , (ref mut offset, _) if *offset > s.len() => {
// *offset -= s.len();
// Some("")
// }
// , (ref mut offset, _) => {
// let c = *offset;
// *offset -= s.len();
// Some(&s[c..])
// }
// }
// })
// .skip_while(|&s| s == "")
// }
// #[cfg(not(feature = "unstable"))]
// #[inline]
// fn slice_char_iter<I, T>(&'a self, i: I) -> Box<Iterator<Item=T> + 'a>
// where I: Iterator<Item=T>
// , I: 'a
// , T: Copy {
// Box::new(i.skip(self.offset)
// .take(self.len))
// }
//
// #[cfg(not(feature = "unstable"))]
// fn slice_strings_iter<I>(&'a self, i: I) -> Box<Iterator<Item=&'a str> + 'a>
// where I: Iterator<Item=&'a str>
// , I: 'a {
// Box::new(i.scan((self.offset, self.len), |curr, s| {
// match *curr {
// (0, 0) => None
// , (0, ref mut remaining) if *remaining < s.len() => {
// let r = *remaining;
// *remaining = 0;
// Some(&s[..r])
// }
// , (0, ref mut remaining) => {
// *remaining -= s.len();
// Some(s)
// }
// , (ref mut offset, _) if *offset > s.len() => {
// *offset -= s.len();
// Some("")
// }
// , (ref mut offset, _) => {
// let c = *offset;
// *offset -= s.len();
// Some(&s[c..])
// }
// }
// })
// .skip_while(|&s| s == ""))
// }
//
// unstable_iters! {
// #[inline]
// pub fn chars(&'a self) -> impl Iterator<Item=char> + 'a {
// self.slice_char_iter(self.node.chars())
// }
// #[inline]
// pub fn char_indices(&'a self) -> impl Iterator<Item=(usize, char)> + 'a {
// self.chars().enumerate()
// }
// #[inline]
// pub fn bytes(&'a self) -> impl Iterator<Item=u8> + 'a {
// self.slice_char_iter(self.node.bytes())
// }
// #[inline]
// pub fn split_whitespace(&'a self) -> impl Iterator<Item=&'a str> + 'a {
// self.slice_strings_iter(self.node.split_whitespace())
// }
// }
//
// /// Returns true if the bytes in `self` equal the bytes in `other`
// #[inline]
// fn bytes_eq<I>(&self, other: I) -> bool
// where I: Iterator<Item=u8> {
// self.bytes().zip(other).all(|(a, b)| a == b)
// }
//
// /// Returns the length of `self.`
// ///
// /// This length is in bytes, not chars or graphemes. In other words, it may
// /// not be what a human considers the length of the string.
// #[inline]
// pub fn len(&self) -> usize { self.len }
//
// /// Returns `true` if this `RopeSliceMut` is empty.
// ///
// /// # Examples
// ///
// /// A `RopeSliceMut` into an empty rope should be empty:
// ///
// /// ```
// /// use an_rope::Rope;
// /// let mut an_empty_rope = Rope::new();
// /// assert!(an_empty_rope.slice_mut(0..0).is_empty());
// /// ```
// ///
// ///
// /// A `RopeSliceMut` that contains no characters should be empty,
// /// even fi the sliced `Rope` is not empty:
// ///
// /// ```
// /// use an_rope::Rope;
// /// let mut an_rope = Rope::from("a string that is not empty");
// /// assert!(an_rope.slice_mut(0..0).is_empty());
// /// ```
// ///
// /// A `RopeSliceMut` with characters should not be empty:
// ///
// /// ```
// /// use an_rope::Rope;
// /// let mut an_rope = Rope::from("a string");
// /// assert!(!an_rope.slice_mut(0..5).is_empty());
// /// ```
// #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 }
//
//
// // #[inline]
// // fn take_node(&mut self) -> Node {
// // use std::mem::replace;
// // replace(self.node, Node::empty())
// // }
//
// /// Insert `rope` into `index` in this mutable `RopeSlice`.
// ///
// /// Note that the index to insert into is relative to the beginning of this
// /// _slice_, not to the beginning of the sliced `Rope`.
// ///
// /// Consumes `rope`.
// ///
// /// # Panics
// /// * If `index` is greater than the length of this `RopeSlice`
// ///
// /// # Time Complexity
// /// O(log _n_)
// ///
// /// # Examples
// /// If built with `--features unstable`:
// /// ```
// /// #![feature(collections)]
// /// #![feature(collections_range)]
// /// ##[cfg(feature = "unstable")]
// /// extern crate collections;
// /// extern crate an_rope;
// /// ##[cfg(feature = "unstable")]
// /// # fn main() {
// ///
// /// use collections::range::RangeArgument;
// /// use an_rope::Rope;
// ///
// /// let mut rope = Rope::from("this is a string");
// /// { // we have to create a new block here so that the mutable borrow
// /// // on `Rope` will end
// /// let mut slice = rope.slice_mut(8..);
// /// slice.insert_rope(1, Rope::from("n example"));
// /// }
// /// assert_eq!(&rope, "this is an example string");
// /// # }
// /// ```
// #[inline]
// pub fn insert_rope<M>(&self, index: M, rope: Rope) -> Rope
// where M: Metric
// , Node: Measured<M>
// , BranchNode: Measured<M>
// , String: Measured<M> {
// // assert!( index <= self.len()
// // , "RopeSliceMut::insert_rope: index {} was > length {}"
// // , index, self.len());
// if !rope.is_empty() {
// // split the rope at the given index
// let (left, right) = self.split(index + self.offset);
//
// // construct the new root node with `Rope` inserted
// (left + rope.root + right).rebalance()
// } else {
// self.clone()
// }
// }
//
// /// Insert `ch` into `index` in this mutable `RopeSlice`.
// ///
// /// Note that the index to insert into is relative to the beginning of this
// /// _slice_, not to the beginning of the sliced `Rope`.
// ///
// /// Consumes `ch`.
// ///
// /// # Panics
// /// * If `index` is greater than the length of this `RopeSlice`
// ///
// /// # Time Complexity
// /// O(log _n_)
// ///
// /// # Examples
// /// If built with `--features unstable`:
// /// ```
// /// #![feature(collections)]
// /// #![feature(collections_range)]
// /// ##[cfg(feature = "unstable")]
// /// extern crate collections;
// /// extern crate an_rope;
// /// ##[cfg(feature = "unstable")]
// /// # fn main() {
// ///
// /// use collections::range::RangeArgument;
// /// use an_rope::Rope;
// ///
// /// let mut rope = Rope::from("this is a string");
// /// { // we have to create a new block here so that the mutable borrow
// /// // on `Rope` will end
// /// let mut slice = rope.slice_mut(8..);
// /// slice.insert(1, 'n');
// /// }
// /// assert_eq!(&rope, "this is an string");
// /// # }
// /// ```
// pub fn insert(&mut self, index: usize, ch: char) {
// assert!( index <= self.len()
// , "RopeSliceMut::insert: index {} was > length {}"
// , index, self.len());
// // TODO: this is gross...
// let mut s = String::new();
// s.push(ch);
// self.insert_rope(index, Rope::from(s))
// }
//
//
// /// Insert `s` into `index` in this mutable `RopeSlice`.
// ///
// /// Note that the index to insert into is relative to the beginning of this
// /// _slice_, not to the beginning of the sliced `Rope`.
// ///
// /// # Panics
// /// * If `index` is greater than the length of this `RopeSlice`
// ///
// /// # Time Complexity
// /// O(log _n_)
// ///
// /// # Examples
// /// If built with `--features unstable`:
// /// ```
// /// #![feature(collections)]
// /// #![feature(collections_range)]
// /// ##[cfg(feature = "unstable")]
// /// extern crate collections;
// /// extern crate an_rope;
// /// ##[cfg(feature = "unstable")]
// /// # fn main() {
// ///
// /// use collections::range::RangeArgument;
// /// use an_rope::Rope;
// ///
// /// let mut rope = Rope::from("this is a string");
// /// { // we have to create a new block here so that the mutable borrow
// /// // on `Rope` will end
// /// let mut slice = rope.slice_mut(8..);
// /// slice.insert_str(1, "n example");
// /// }
// /// assert_eq!(&rope, "this is an example string");
// /// # }
// /// ```
// pub fn insert_str(&mut self, index: usize, s: &str) {
// assert!( index <= self.len()
// , "RopeSliceMut::insert_str: index {} was > length {}"
// , index, self.len());
// self.insert_rope(index, Rope::from(s))
// }
//
// }
//-- comparisons ----------------------------------------------------
//
// impl<'a> cmp::Eq for RopeSliceMut<'a> {}
// impl<'a> cmp::PartialEq for RopeSliceMut<'a> {
// /// A rope equals another rope if all the bytes in both are equal.
// #[inline]
// fn eq(&self, other: &RopeSliceMut<'a>) -> bool {
// if self.len() == other.len() {
// self.bytes_eq(other.bytes())
// } else {
// false
// }
// }
// }
//
// impl<'a, 'b> cmp::PartialEq<RopeSlice<'b>> for RopeSliceMut<'a> {
// /// A rope equals another rope if all the bytes in both are equal.
//
// #[inline]
// fn eq(&self, other: &RopeSlice<'b>) -> bool {
// if self.len() == other.len() {
// self.bytes_eq(other.bytes())
// } else {
// false
// }
// }
// }
//
// impl<'a> cmp::PartialEq<str> for RopeSliceMut<'a> {
// /// A rope equals another rope if all the bytes in both are equal.
//
// #[inline]
// fn eq(&self, other: &str) -> bool {
// if self.len() == other.len() {
// self.bytes_eq(other.bytes())
// } else {
// false
// }
// }
// }
//
// impl<'a> convert::Into<Rope> for RopeSliceMut<'a> {
// /// Converts this `RopeSliceMut` into a new `Rope`
// fn into(self) -> Rope {
// Rope::from(self.chars().collect::<String>())
// }
// }
//
// impl<'a> convert::Into<String> for RopeSliceMut<'a> {
// /// Converts this `RopeSliceMut` into a new `String`
// fn into(self) -> String {
// self.chars().collect::<String>()
// }
// }