pub fn slice(s: &str, begin: usize, end: usize) -> &str {
if end < begin {
return "";
}
s.char_indices()
.nth(begin)
.and_then(|(start_pos, _)| {
if end >= len(s) {
return Some(&s[start_pos..]);
}
s[start_pos..]
.char_indices()
.nth(end - begin)
.map(|(end_pos, _)| &s[start_pos..start_pos + end_pos])
})
.unwrap_or("")
}
pub fn from(s: &str, begin: usize) -> &str {
slice(s, begin, len(s))
}
pub fn till(s: &str, end: usize) -> &str {
slice(s, 0, end)
}
pub fn len(s: &str) -> usize {
s.chars().count()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_same_as_std_slice() {
let s = "xjfdlskfaj sdfjlkj";
for i in 0..s.len() {
for j in i..s.len() + 1 {
assert_eq!(&s[i..j], slice(s, i, j));
}
}
}
#[test]
fn test_slice() {
assert_eq!(slice("\u{345}ab\u{898}xyz", 1, 4), "ab\u{898}");
assert_eq!(slice("\u{345}ab\u{898}xyz", 0, 4), "\u{345}ab\u{898}");
assert_eq!(slice("\u{345}ab\u{898}xyz", 5, 4), "");
assert_eq!(slice("\u{345}ab \u{898}xyz", 0, 1), "\u{345}");
assert_eq!(slice("abcdef", 0, 6), "abcdef");
assert_eq!(slice("\u{345}ab\u{898}xyz", 1, 7), "ab\u{898}xyz");
}
#[test]
fn test_from() {
assert_eq!(from("\u{345}ab\u{898}xyz", 1), "ab\u{898}xyz");
assert_eq!(from("\u{345}ab\u{898}xyz", 3), "\u{898}xyz");
assert_eq!(from("\u{345}ab\u{898}xyz", 10), "");
assert_eq!(from("\u{345}ab \u{898}xyz", 0), "\u{345}ab \u{898}xyz");
}
#[test]
fn test_till() {
assert_eq!(till("\u{345}ab\u{898}xyz", 1), "\u{345}");
assert_eq!(till("\u{345}ab\u{898}xyz", 3), "\u{345}ab");
assert_eq!(till("\u{345}ab\u{898}xyz", 0), "");
}
#[test]
fn test_len() {
assert_eq!(len(""), 0);
assert_eq!(len("👨🚀"), 3);
assert_eq!(len("abc"), 3);
assert_eq!(len("abd👨🚀"), 6);
}
}