Fix crash on empty substrings

html_output
Wilfred Hughes 2022-02-13 16:27:00 +07:00
parent 653ebc8ad3
commit 714edd8f0c
1 changed files with 20 additions and 3 deletions

@ -18,15 +18,22 @@ pub enum BackgroundColor {
Light,
}
/// Slice `s` from `start` to `end` by codepoint. This is safer than
/// Slice `s` from `start` inclusive to `end` exclusive by codepoint. This is safer than
/// slicing by bytes, which panics if the byte isn't on a codepoint
/// boundary.
fn substring_by_codepoint(s: &str, start: usize, end: usize) -> &str {
if start == end {
return &s[0..0];
}
assert!(end > start);
let mut char_idx_iter = s.char_indices();
let byte_start = char_idx_iter.nth(start).expect("Expected a codepoint index inside `s`.").0;
match char_idx_iter.nth(end - 1 - start) {
let byte_start = char_idx_iter
.nth(start)
.expect("Expected a codepoint index inside `s`.")
.0;
match char_idx_iter.nth(end - start - 1) {
Some(byte_end) => &s[byte_start..byte_end.0],
None => &s[byte_start..],
}
@ -308,6 +315,16 @@ mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_substring_by_codepoint() {
assert_eq!(substring_by_codepoint("abcd", 0, 2), "ab");
}
#[test]
fn test_substring_by_codepoint_empty() {
assert_eq!(substring_by_codepoint("abcd", 0, 0), "");
}
#[test]
fn split_string_simple() {
assert_eq!(split_string("fooba", 3), vec!["foo", "ba "]);