pub fn charslice<S: Into<String>>(text: S, start: isize, end: isize) -> String {
let stext = text.into();
let from: usize;
let length: usize;
let charcount = stext.chars().count();
if start < 0 {
assert!(
-start as usize <= charcount,
"charslice: if 'start' is negative, the magnitude may not exceed the length"
);
from = (charcount as isize + start) as usize;
} else {
from = start as usize;
}
if end < 0 {
assert!(
-end as usize <= charcount,
"charslice: if 'end' is negative, the magnitude may not exceed the length"
);
let new_end = (charcount as isize + end) as usize;
assert!(new_end >= from, "charslice: 'start' may not be before 'end' (end was negative)");
length = new_end - from;
} else {
assert!(
end >= from as isize,
"charslice: 'start' may not be before 'end' (end was positive)"
);
length = end as usize - from;
}
stext.chars().skip(from).take(length).collect()
}
pub fn charslicefrom<S: Into<String>>(text: S, start: isize) -> String {
let stext = text.into();
let len = stext.chars().count() as isize;
charslice(stext, start, len)
}
pub fn charsliceto<S: Into<String>>(text: S, end: isize) -> String {
charslice(text, 0, end)
}
pub fn glyphat<S: Into<String>>(text: S, pos: isize) -> String {
charslice(text, pos, pos + 1)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_slice() {
assert_eq!(42isize as usize, 42usize);
assert_eq!("你好", charslice("你好!", 0, 2));
assert_eq!("!", charslicefrom("你好!", 2));
assert_eq!("你好", charsliceto("你好!", 2));
assert_eq!("好", glyphat("你好!", 1));
assert_eq!("你好", charslice("你好!", -3, -1));
assert_eq!("!", charslicefrom("你好!", -1));
assert_eq!("好", glyphat("你好!", -2));
}
}