Can we add a `slice_by_iterators` method to str?


#1

Here is a sample implementation of the method. Note there is no bounds checking in the following code, bounds checking can be done only if it is added to the rust std library code.

use std::slice;
use std::str::{self, Chars, Utf8Error};
use std::result::Result;

trait AdvanceableIterator<I: Iterator> {
    fn advance(&mut self, mut steps: usize);
}

impl<I: Iterator> AdvanceableIterator<I> for I {
    fn advance(&mut self, mut steps: usize) {
        for _ in self {
            steps -= 1;
            if steps <= 0 {
                break;
            }
        }
    }
}

trait AsStr {
    fn as_str(&self) -> &str;
}

impl<'a> AsStr for Chars<'a> {
    fn as_str(&self) -> &str {
        Chars::as_str(self)
    }
}

trait SliceByIterators<T: AsStr, E> {
    fn slice_by_iterators(&self, start: &T, end: &T) -> Result<&str, E>;
}

impl<'a, T: AsStr> SliceByIterators<T, Utf8Error> for str {
    fn slice_by_iterators(&self, start: &T, end: &T) -> Result<&str, Utf8Error> {
        let start = start.as_str().as_ptr();
        let end = end.as_str().as_ptr();
        assert!(start <= end);
        
        let len = (end as usize) - (start as usize);
        
        //Check if start and end are bounded by str
        //This can't be done here since the str bounds are private?

        unsafe {
            // First, we build a &[u8]...
            let slice = slice::from_raw_parts(start, len);

            // ... and then convert that slice into a string slice
            str::from_utf8(slice)
        }
    }
}

fn main() {
    let s = "abcdefghijklmnopqrstuvwxyz";
    let mut chars = s.chars();
    chars.advance(2);
    let cp0 = chars.clone();
    
    chars.advance(5);
    let cp1 = chars.clone();
    
    println!("{:?}", s.slice_by_iterators(&cp0, &cp1));
}

Playground.

I will try to work on a PR if you think this can be helpful.