summaryrefslogtreecommitdiffstats
path: root/vendor/dissimilar/src/range.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/dissimilar/src/range.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/dissimilar/src/range.rs')
-rw-r--r--vendor/dissimilar/src/range.rs148
1 files changed, 148 insertions, 0 deletions
diff --git a/vendor/dissimilar/src/range.rs b/vendor/dissimilar/src/range.rs
new file mode 100644
index 000000000..565a94c06
--- /dev/null
+++ b/vendor/dissimilar/src/range.rs
@@ -0,0 +1,148 @@
+use crate::find::find;
+use std::fmt::Debug;
+use std::ops::{self, RangeFrom, RangeFull, RangeTo};
+use std::str::{CharIndices, Chars};
+
+#[derive(Copy, Clone)]
+pub struct Range<'a> {
+ pub doc: &'a str,
+ pub offset: usize,
+ pub len: usize,
+}
+
+impl<'a> Range<'a> {
+ pub fn empty() -> Self {
+ Range {
+ doc: "",
+ offset: 0,
+ len: 0,
+ }
+ }
+
+ pub fn new(doc: &'a str, bounds: impl RangeBounds) -> Self {
+ let (offset, len) = bounds.index(doc.len());
+ Range { doc, offset, len }
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.len == 0
+ }
+
+ pub fn substring(&self, bounds: impl RangeBounds) -> Self {
+ let (offset, len) = bounds.index(self.len);
+ Range {
+ doc: self.doc,
+ offset: self.offset + offset,
+ len,
+ }
+ }
+
+ pub fn get(&self, bounds: impl RangeBounds) -> Option<Self> {
+ let (offset, len) = bounds.try_index(self.len)?;
+ Some(Range {
+ doc: self.doc,
+ offset: self.offset + offset,
+ len,
+ })
+ }
+
+ pub fn split_at(&self, mid: usize) -> (Self, Self) {
+ (self.substring(..mid), self.substring(mid..))
+ }
+
+ pub fn chars(&self) -> Chars<'a> {
+ str(*self).chars()
+ }
+
+ pub fn char_indices(&self) -> CharIndices<'a> {
+ str(*self).char_indices()
+ }
+
+ pub fn bytes(&self) -> impl Iterator<Item = u8> + DoubleEndedIterator + ExactSizeIterator + 'a {
+ bytes(*self).iter().cloned()
+ }
+
+ pub fn starts_with(&self, prefix: impl AsRef<[u8]>) -> bool {
+ bytes(*self).starts_with(prefix.as_ref())
+ }
+
+ pub fn ends_with(&self, suffix: impl AsRef<[u8]>) -> bool {
+ bytes(*self).ends_with(suffix.as_ref())
+ }
+
+ pub fn find(&self, needle: impl AsRef<[u8]>) -> Option<usize> {
+ find(bytes(*self), needle.as_ref())
+ }
+}
+
+pub fn str(range: Range) -> &str {
+ if cfg!(debug)
+ && range
+ .doc
+ .get(range.offset..range.offset + range.len)
+ .is_none()
+ {
+ eprintln!(
+ "doc={:?} offset={} len={}",
+ range.doc, range.offset, range.len
+ );
+ }
+ &range.doc[range.offset..range.offset + range.len]
+}
+
+pub fn bytes(range: Range) -> &[u8] {
+ &range.doc.as_bytes()[range.offset..range.offset + range.len]
+}
+
+impl AsRef<[u8]> for Range<'_> {
+ fn as_ref(&self) -> &[u8] {
+ bytes(*self)
+ }
+}
+
+pub trait RangeBounds: Sized + Clone + Debug {
+ // Returns (offset, len).
+ fn try_index(self, len: usize) -> Option<(usize, usize)>;
+ fn index(self, len: usize) -> (usize, usize) {
+ match self.clone().try_index(len) {
+ Some(range) => range,
+ None => panic!("index out of range, index={:?}, len={}", self, len),
+ }
+ }
+}
+
+impl RangeBounds for ops::Range<usize> {
+ fn try_index(self, len: usize) -> Option<(usize, usize)> {
+ if self.start <= self.end && self.end <= len {
+ Some((self.start, self.end - self.start))
+ } else {
+ None
+ }
+ }
+}
+
+impl RangeBounds for RangeFrom<usize> {
+ fn try_index(self, len: usize) -> Option<(usize, usize)> {
+ if self.start <= len {
+ Some((self.start, len - self.start))
+ } else {
+ None
+ }
+ }
+}
+
+impl RangeBounds for RangeTo<usize> {
+ fn try_index(self, len: usize) -> Option<(usize, usize)> {
+ if self.end <= len {
+ Some((0, self.end))
+ } else {
+ None
+ }
+ }
+}
+
+impl RangeBounds for RangeFull {
+ fn try_index(self, len: usize) -> Option<(usize, usize)> {
+ Some((0, len))
+ }
+}