diff options
| author | Pg Biel <9021226+PgBiel@users.noreply.github.com> | 2023-05-29 15:15:32 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-29 20:15:32 +0200 |
| commit | e4557f66399daa848ce1b7cf6cd74b3dd03e74e5 (patch) | |
| tree | 91c5cac79fa445460362cd0f7a0bfdd60e2cd1ea /src/eval/str.rs | |
| parent | 31dfe32242ef7ab8304874fd0260d27649880df8 (diff) | |
Fix `.at(default: ...)` for strings and content (#1339)
Diffstat (limited to 'src/eval/str.rs')
| -rw-r--r-- | src/eval/str.rs | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/eval/str.rs b/src/eval/str.rs index d7e00bf6..3c377595 100644 --- a/src/eval/str.rs +++ b/src/eval/str.rs @@ -71,9 +71,9 @@ impl Str { /// Extract the grapheme cluster at the given index. pub fn at<'a>(&'a self, index: i64, default: Option<&'a str>) -> StrResult<Self> { let len = self.len(); - let grapheme = self.0[self.locate(index)?..] - .graphemes(true) - .next() + let grapheme = self + .locate_opt(index)? + .and_then(|i| self.0[i..].graphemes(true).next()) .or(default) .ok_or_else(|| no_default_and_out_of_bounds(index, len))?; Ok(grapheme.into()) @@ -325,22 +325,28 @@ impl Str { Ok(Self(self.0.repeat(n))) } - /// Resolve an index. - fn locate(&self, index: i64) -> StrResult<usize> { + /// Resolve an index, if it is within bounds. + /// Errors on invalid char boundaries. + fn locate_opt(&self, index: i64) -> StrResult<Option<usize>> { let wrapped = if index >= 0 { Some(index) } else { self.len().checked_add(index) }; let resolved = wrapped .and_then(|v| usize::try_from(v).ok()) - .filter(|&v| v <= self.0.len()) - .ok_or_else(|| out_of_bounds(index, self.len()))?; + .filter(|&v| v <= self.0.len()); - if !self.0.is_char_boundary(resolved) { + if resolved.map_or(false, |i| !self.0.is_char_boundary(i)) { return Err(not_a_char_boundary(index)); } Ok(resolved) } + + /// Resolve an index or throw an out of bounds error. + fn locate(&self, index: i64) -> StrResult<usize> { + self.locate_opt(index)? + .ok_or_else(|| out_of_bounds(index, self.len())) + } } /// The out of bounds access error message. |
