3 use std
::ops
::{self, RangeFrom, RangeFull, RangeTo}
;
13 pub fn empty() -> Self {
21 pub fn new(doc
: &'a
[char], bounds
: impl RangeBounds
) -> Self {
22 let (offset
, len
) = bounds
.index(doc
.len());
23 Range { doc, offset, len }
26 pub fn is_empty(&self) -> bool
{
30 pub fn len_bytes(&self) -> usize {
31 self.chars().map(char::len_utf8
).sum()
34 pub fn substring(&self, bounds
: impl RangeBounds
) -> Self {
35 let (offset
, len
) = bounds
.index(self.len
);
38 offset
: self.offset
+ offset
,
43 pub fn get(&self, bounds
: impl RangeBounds
) -> Option
<Self> {
44 let (offset
, len
) = bounds
.try_index(self.len
)?
;
47 offset
: self.offset
+ offset
,
52 pub fn split_at(&self, mid
: usize) -> (Self, Self) {
53 (self.substring(..mid
), self.substring(mid
..))
58 ) -> impl Iterator
<Item
= char> + DoubleEndedIterator
+ ExactSizeIterator
+ 'a
{
59 slice(*self).iter().copied()
62 pub fn starts_with(&self, prefix
: impl AsRef
<[char]>) -> bool
{
63 slice(*self).starts_with(prefix
.as_ref())
66 pub fn ends_with(&self, suffix
: impl AsRef
<[char]>) -> bool
{
67 slice(*self).ends_with(suffix
.as_ref())
70 pub fn find(&self, needle
: impl AsRef
<[char]>) -> Option
<usize> {
71 find(slice(*self), needle
.as_ref())
75 pub fn slice(range
: Range
) -> &[char] {
79 .get(range
.offset
..range
.offset
+ range
.len
)
83 "doc={:?} offset={} len={}",
84 range
.doc
, range
.offset
, range
.len
87 &range
.doc
[range
.offset
..range
.offset
+ range
.len
]
90 impl AsRef
<[char]> for Range
<'_
> {
91 fn as_ref(&self) -> &[char] {
96 pub trait RangeBounds
: Sized
+ Clone
+ Debug
{
97 // Returns (offset, len).
98 fn try_index(self, len
: usize) -> Option
<(usize, usize)>;
99 fn index(self, len
: usize) -> (usize, usize) {
100 match self.clone().try_index(len
) {
101 Some(range
) => range
,
102 None
=> panic
!("index out of range, index={:?}, len={}", self, len
),
107 impl RangeBounds
for ops
::Range
<usize> {
108 fn try_index(self, len
: usize) -> Option
<(usize, usize)> {
109 if self.start
<= self.end
&& self.end
<= len
{
110 Some((self.start
, self.end
- self.start
))
117 impl RangeBounds
for RangeFrom
<usize> {
118 fn try_index(self, len
: usize) -> Option
<(usize, usize)> {
119 if self.start
<= len
{
120 Some((self.start
, len
- self.start
))
127 impl RangeBounds
for RangeTo
<usize> {
128 fn try_index(self, len
: usize) -> Option
<(usize, usize)> {
137 impl RangeBounds
for RangeFull
{
138 fn try_index(self, len
: usize) -> Option
<(usize, usize)> {