Skip to content

Instantly share code, notes, and snippets.

@beeb
Created February 14, 2023 16:49
Show Gist options
  • Save beeb/25acbbbb0cff350d4f11a0880fdaac7f to your computer and use it in GitHub Desktop.
Save beeb/25acbbbb0cff350d4f11a0880fdaac7f to your computer and use it in GitHub Desktop.
Substring
use std::ops::{Bound, RangeBounds};
/// Utilities to take a substring of a string slice, taking into account UTF-8.
pub trait StringUtils {
/// Get a substring of a string slice, with start and length.
fn substring(&self, start: usize, len: usize) -> &str;
/// Get a substring of a string slice, with a range.
fn slice(&self, range: impl RangeBounds<usize>) -> &str;
}
impl StringUtils for str {
fn substring(&self, start: usize, len: usize) -> &str {
self.char_indices()
.nth(start)
.map(|(start_byte, _)| {
self.char_indices()
.nth(start + len)
.map(|(end_byte, _)| &self[start_byte..end_byte])
.unwrap_or(&self[start_byte..])
})
.unwrap_or("")
}
fn slice(&self, range: impl RangeBounds<usize>) -> &str {
let start = match range.start_bound() {
Bound::Included(bound) | Bound::Excluded(bound) => *bound,
Bound::Unbounded => 0,
};
let len = match range.end_bound() {
Bound::Included(bound) => *bound + 1,
Bound::Excluded(bound) => *bound,
Bound::Unbounded => self.len(),
} - start;
self.substring(start, len)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment