pub trait Substring {
fn substring(&self, start_index: usize, end_index: usize) -> &str;
}
impl Substring for str {
fn substring(&self, start_index: usize, end_index: usize) -> &str {
if end_index <= start_index {
return "";
}
let mut indices = self.char_indices();
let (start_byte, _start_char) = indices.nth(start_index).unwrap_or((self.len(), ' '));
let (end_byte, _end_char) = indices.nth(end_index - start_index - 1).unwrap_or((self.len(), ' '));
&self[start_byte..end_byte]
}
}
#[cfg(test)]
mod tests {
use crate::Substring;
#[test]
fn test_substring() {
assert_eq!("foobar".substring(0, 3), "foo");
}
#[test]
fn test_out_of_bounds() {
assert_eq!("foobar".substring(0, 10), "foobar");
assert_eq!("foobar".substring(6, 10), "");
}
#[test]
fn test_start_less_than_end() {
assert_eq!("foobar".substring(3, 2), "");
}
#[test]
fn test_start_and_end_equal() {
assert_eq!("foobar".substring(3, 3), "");
}
}