fiberplane_models/utils/
mod.rs

1use std::borrow::Borrow;
2
3pub mod content_writer;
4
5/// Extension trait that adds methods used for working with Strings
6/// and &strs in terms of their UTF-8 characters, as opposed to bytes
7pub trait StringExt {
8    fn char_count(&self) -> u32;
9    fn char_index(&self, offset: u32) -> usize;
10    fn char_slice(&self, start: u32, end: u32) -> &str;
11    fn char_slice_from(&self, start: u32) -> &str;
12}
13
14impl<S> StringExt for S
15where
16    S: AsRef<str>,
17{
18    fn char_count(&self) -> u32 {
19        char_count(self.as_ref())
20    }
21
22    fn char_index(&self, offset: u32) -> usize {
23        char_index(self.as_ref(), offset)
24    }
25
26    fn char_slice(&self, start: u32, end: u32) -> &str {
27        char_slice(self.as_ref(), start, end)
28    }
29
30    fn char_slice_from(&self, start: u32) -> &str {
31        char_slice_from(self.as_ref(), start)
32    }
33}
34
35/// Counts the number of (USV) characters in a string.
36pub fn char_count<T>(text: &T) -> u32
37where
38    T: Borrow<str> + ?Sized,
39{
40    text.borrow().chars().count() as u32
41}
42
43/// Calculates the byte index at which the character with the given offset starts.
44pub fn char_index(text: &str, offset: u32) -> usize {
45    text.chars()
46        .take(offset as usize)
47        .map(|c| c.len_utf8())
48        .sum()
49}
50
51/// Returns a slice of a string, based on character offsets instead of byte
52/// indices.
53pub fn char_slice(text: &str, start: u32, end: u32) -> &str {
54    let start = char_index(text, start);
55    let end = char_index(text, end);
56    &text[start..end]
57}
58
59/// Returns a slice of a string, based on character offsets instead of byte
60/// indices.
61pub fn char_slice_from(text: &str, start: u32) -> &str {
62    let start = char_index(text, start);
63    &text[start..]
64}