fn convert_str_indices_slow()

in starlark/src/values/types/string/fast_string.rs [174:205]


fn convert_str_indices_slow(s: &str, start: NoneOr<i32>, end: NoneOr<i32>) -> Option<StrIndices> {
    // Slow version when we need to compute full string length
    // because at least one of the indices is negative.
    debug_assert!(
        matches!(start, NoneOr::Other(start) if start < 0)
            || matches!(end, NoneOr::Other(end) if end < 0)
    );
    // If both indices are negative, we should have ruled `start > end` case before.
    debug_assert!(
        matches!((start, end), (NoneOr::Other(start), NoneOr::Other(end))
                if start >= 0 || end >= 0 || (start <= end))
            || matches!(start, NoneOr::None)
            || matches!(end, NoneOr::None)
    );
    let len = len(s);
    let (start, end) = convert_indices(len.0 as i32, start, end);
    if start > end {
        return None;
    }
    let (start, end) = (CharIndex(start), CharIndex(end));
    debug_assert!(end <= len);
    let s = if len.0 == s.len() {
        // ASCII fast path: if char len is equal to byte len,
        // we know the string is ASCII.
        unsafe { s.get_unchecked(start.0..end.0) }
    } else {
        let (_, s) = split_at(s, start).unwrap();
        let (s, _) = split_at(s, end - start).unwrap();
        s
    };
    Some(StrIndices { start, haystack: s })
}