diff --git a/src/with_indices.rs b/src/with_indices.rs index 69e7db1..974e2e7 100644 --- a/src/with_indices.rs +++ b/src/with_indices.rs @@ -1,20 +1,17 @@ +use once_cell::sync::OnceCell; + #[derive(Debug, Clone)] pub struct WithIndices> { /// line is a string reference pub line: T, /// the byte position of each `char` in `line` string slice . - pub indices_indexes: Box<[u32]>, + pub indices_indexes: OnceCell>, } impl> WithIndices { pub fn new(line: T) -> Self { Self { - indices_indexes: line - .as_ref() - .char_indices() - .map(|(i, _)| i as u32) - .collect::>() - .into_boxed_slice(), + indices_indexes: OnceCell::new(), line, } } @@ -26,17 +23,26 @@ impl> WithIndices { return ""; } + let indices_indexes = self.indices_indexes.get_or_init(|| { + self + .line + .as_ref() + .char_indices() + .map(|(i, _)| i as u32) + .collect::>() + .into_boxed_slice() + }); + let str_len = self.line.as_ref().len() as u32; - let start = *self.indices_indexes.get(start_index).unwrap_or(&str_len); - let end = *self.indices_indexes.get(end_index).unwrap_or(&str_len); + let start = + indices_indexes.get(start_index).unwrap_or(&str_len).clone() as usize; + let end = + indices_indexes.get(end_index).unwrap_or(&str_len).clone() as usize; unsafe { // SAFETY: Since `indices` iterates over the `CharIndices` of `self`, we can guarantee // that the indices obtained from it will always be within the bounds of `self` and they // will always lie on UTF-8 sequence boundaries. - self - .line - .as_ref() - .get_unchecked(start as usize..end as usize) + self.line.as_ref().get_unchecked(start..end) } } }