pub fn strpos<H, N>(haystack: H, needle: N, offset: isize) -> Option<usize>
where
H: AsRef<str>,
N: AsRef<str> {
let mut haystack = haystack.as_ref().to_string();
let needle = needle.as_ref();
let mut offset = offset;
let haystack_length = haystack.len() as isize;
if offset > 0 && offset > haystack_length {
return None;
}
if offset < 0 {
if offset < (0 - haystack_length) {
return None;
}
offset = haystack_length + offset;
}
if offset == 0 {
return haystack.find(needle);
}
haystack = haystack.chars().skip(offset as usize).collect();
match haystack.find(needle) {
None => None,
Some(position) => Some(position + offset as usize),
}
}
#[cfg(test)]
mod tests {
use crate::string::strpos;
#[test]
fn test() {
let haystack = "Hello World";
let needle = "World";
assert_eq!(strpos(haystack, needle, 0), Some(6));
assert_eq!(strpos(haystack, needle, 6), Some(6));
assert_eq!(strpos(haystack, needle, -5), Some(6));
assert_eq!(strpos(haystack, needle, -11), Some(6));
assert_eq!(strpos(haystack, needle, 7), None);
assert_eq!(strpos(haystack, needle, 11), None);
assert_eq!(strpos(haystack, needle, -12), None);
}
}