diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/text-size/src | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/text-size/src')
-rw-r--r-- | vendor/text-size/src/lib.rs | 64 | ||||
-rw-r--r-- | vendor/text-size/src/range.rs | 912 | ||||
-rw-r--r-- | vendor/text-size/src/serde_impls.rs | 96 | ||||
-rw-r--r-- | vendor/text-size/src/size.rs | 334 | ||||
-rw-r--r-- | vendor/text-size/src/traits.rs | 72 |
5 files changed, 745 insertions, 733 deletions
diff --git a/vendor/text-size/src/lib.rs b/vendor/text-size/src/lib.rs index 92bd36b19..af89999cc 100644 --- a/vendor/text-size/src/lib.rs +++ b/vendor/text-size/src/lib.rs @@ -1,32 +1,32 @@ -//! Newtypes for working with text sizes/ranges in a more type-safe manner. -//! -//! This library can help with two things: -//! * Reducing storage requirements for offsets and ranges, under the -//! assumption that 32 bits is enough. -//! * Providing standard vocabulary types for applications where text ranges -//! are pervasive. -//! -//! However, you should not use this library simply because you work with -//! strings. In the overwhelming majority of cases, using `usize` and -//! `std::ops::Range<usize>` is better. In particular, if you are publishing a -//! library, using only std types in the interface would make it more -//! interoperable. Similarly, if you are writing something like a lexer, which -//! produces, but does not *store* text ranges, then sticking to `usize` would -//! be better. -//! -//! Minimal Supported Rust Version: latest stable. - -#![forbid(unsafe_code)] -#![warn(missing_debug_implementations, missing_docs)] - -mod range; -mod size; -mod traits; - -#[cfg(feature = "serde")] -mod serde_impls; - -pub use crate::{range::TextRange, size::TextSize, traits::TextLen}; - -#[cfg(target_pointer_width = "16")] -compile_error!("text-size assumes usize >= u32 and does not work on 16-bit targets"); +//! Newtypes for working with text sizes/ranges in a more type-safe manner.
+//!
+//! This library can help with two things:
+//! * Reducing storage requirements for offsets and ranges, under the
+//! assumption that 32 bits is enough.
+//! * Providing standard vocabulary types for applications where text ranges
+//! are pervasive.
+//!
+//! However, you should not use this library simply because you work with
+//! strings. In the overwhelming majority of cases, using `usize` and
+//! `std::ops::Range<usize>` is better. In particular, if you are publishing a
+//! library, using only std types in the interface would make it more
+//! interoperable. Similarly, if you are writing something like a lexer, which
+//! produces, but does not *store* text ranges, then sticking to `usize` would
+//! be better.
+//!
+//! Minimal Supported Rust Version: latest stable.
+
+#![forbid(unsafe_code)]
+#![warn(missing_debug_implementations, missing_docs)]
+
+mod range;
+mod size;
+mod traits;
+
+#[cfg(feature = "serde")]
+mod serde_impls;
+
+pub use crate::{range::TextRange, size::TextSize, traits::TextLen};
+
+#[cfg(target_pointer_width = "16")]
+compile_error!("text-size assumes usize >= u32 and does not work on 16-bit targets");
diff --git a/vendor/text-size/src/range.rs b/vendor/text-size/src/range.rs index 4a98deec5..ab3c50d07 100644 --- a/vendor/text-size/src/range.rs +++ b/vendor/text-size/src/range.rs @@ -1,456 +1,456 @@ -use cmp::Ordering; - -use { - crate::TextSize, - std::{ - cmp, fmt, - ops::{Add, AddAssign, Bound, Index, IndexMut, Range, RangeBounds, Sub, SubAssign}, - }, -}; - -/// A range in text, represented as a pair of [`TextSize`][struct@TextSize]. -/// -/// It is a logic error for `start` to be greater than `end`. -#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)] -pub struct TextRange { - // Invariant: start <= end - start: TextSize, - end: TextSize, -} - -impl fmt::Debug for TextRange { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}..{}", self.start().raw, self.end().raw) - } -} - -impl TextRange { - /// Creates a new `TextRange` with the given `start` and `end` (`start..end`). - /// - /// # Panics - /// - /// Panics if `end < start`. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let start = TextSize::from(5); - /// let end = TextSize::from(10); - /// let range = TextRange::new(start, end); - /// - /// assert_eq!(range.start(), start); - /// assert_eq!(range.end(), end); - /// assert_eq!(range.len(), end - start); - /// ``` - #[inline] - pub fn new(start: TextSize, end: TextSize) -> TextRange { - assert!(start <= end); - TextRange { start, end } - } - - /// Create a new `TextRange` with the given `offset` and `len` (`offset..offset + len`). - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let text = "0123456789"; - /// - /// let offset = TextSize::from(2); - /// let length = TextSize::from(5); - /// let range = TextRange::at(offset, length); - /// - /// assert_eq!(range, TextRange::new(offset, offset + length)); - /// assert_eq!(&text[range], "23456") - /// ``` - #[inline] - pub fn at(offset: TextSize, len: TextSize) -> TextRange { - TextRange::new(offset, offset + len) - } - - /// Create a zero-length range at the specified offset (`offset..offset`). - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let point: TextSize; - /// # point = TextSize::from(3); - /// let range = TextRange::empty(point); - /// assert!(range.is_empty()); - /// assert_eq!(range, TextRange::new(point, point)); - /// ``` - #[inline] - pub fn empty(offset: TextSize) -> TextRange { - TextRange { - start: offset, - end: offset, - } - } - - /// Create a range up to the given end (`..end`). - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let point: TextSize; - /// # point = TextSize::from(12); - /// let range = TextRange::up_to(point); - /// - /// assert_eq!(range.len(), point); - /// assert_eq!(range, TextRange::new(0.into(), point)); - /// assert_eq!(range, TextRange::at(0.into(), point)); - /// ``` - #[inline] - pub fn up_to(end: TextSize) -> TextRange { - TextRange { - start: 0.into(), - end, - } - } -} - -/// Identity methods. -impl TextRange { - /// The start point of this range. - #[inline] - pub const fn start(self) -> TextSize { - self.start - } - - /// The end point of this range. - #[inline] - pub const fn end(self) -> TextSize { - self.end - } - - /// The size of this range. - #[inline] - pub const fn len(self) -> TextSize { - // HACK for const fn: math on primitives only - TextSize { - raw: self.end().raw - self.start().raw, - } - } - - /// Check if this range is empty. - #[inline] - pub const fn is_empty(self) -> bool { - // HACK for const fn: math on primitives only - self.start().raw == self.end().raw - } -} - -/// Manipulation methods. -impl TextRange { - /// Check if this range contains an offset. - /// - /// The end index is considered excluded. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let (start, end): (TextSize, TextSize); - /// # start = 10.into(); end = 20.into(); - /// let range = TextRange::new(start, end); - /// assert!(range.contains(start)); - /// assert!(!range.contains(end)); - /// ``` - #[inline] - pub fn contains(self, offset: TextSize) -> bool { - self.start() <= offset && offset < self.end() - } - - /// Check if this range contains an offset. - /// - /// The end index is considered included. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let (start, end): (TextSize, TextSize); - /// # start = 10.into(); end = 20.into(); - /// let range = TextRange::new(start, end); - /// assert!(range.contains_inclusive(start)); - /// assert!(range.contains_inclusive(end)); - /// ``` - #[inline] - pub fn contains_inclusive(self, offset: TextSize) -> bool { - self.start() <= offset && offset <= self.end() - } - - /// Check if this range completely contains another range. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let larger = TextRange::new(0.into(), 20.into()); - /// let smaller = TextRange::new(5.into(), 15.into()); - /// assert!(larger.contains_range(smaller)); - /// assert!(!smaller.contains_range(larger)); - /// - /// // a range always contains itself - /// assert!(larger.contains_range(larger)); - /// assert!(smaller.contains_range(smaller)); - /// ``` - #[inline] - pub fn contains_range(self, other: TextRange) -> bool { - self.start() <= other.start() && other.end() <= self.end() - } - - /// The range covered by both ranges, if it exists. - /// If the ranges touch but do not overlap, the output range is empty. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// assert_eq!( - /// TextRange::intersect( - /// TextRange::new(0.into(), 10.into()), - /// TextRange::new(5.into(), 15.into()), - /// ), - /// Some(TextRange::new(5.into(), 10.into())), - /// ); - /// ``` - #[inline] - pub fn intersect(self, other: TextRange) -> Option<TextRange> { - let start = cmp::max(self.start(), other.start()); - let end = cmp::min(self.end(), other.end()); - if end < start { - return None; - } - Some(TextRange::new(start, end)) - } - - /// Extends the range to cover `other` as well. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// assert_eq!( - /// TextRange::cover( - /// TextRange::new(0.into(), 5.into()), - /// TextRange::new(15.into(), 20.into()), - /// ), - /// TextRange::new(0.into(), 20.into()), - /// ); - /// ``` - #[inline] - pub fn cover(self, other: TextRange) -> TextRange { - let start = cmp::min(self.start(), other.start()); - let end = cmp::max(self.end(), other.end()); - TextRange::new(start, end) - } - - /// Extends the range to cover `other` offsets as well. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// assert_eq!( - /// TextRange::empty(0.into()).cover_offset(20.into()), - /// TextRange::new(0.into(), 20.into()), - /// ) - /// ``` - #[inline] - pub fn cover_offset(self, offset: TextSize) -> TextRange { - self.cover(TextRange::empty(offset)) - } - - /// Add an offset to this range. - /// - /// Note that this is not appropriate for changing where a `TextRange` is - /// within some string; rather, it is for changing the reference anchor - /// that the `TextRange` is measured against. - /// - /// The unchecked version (`Add::add`) will _always_ panic on overflow, - /// in contrast to primitive integers, which check in debug mode only. - #[inline] - pub fn checked_add(self, offset: TextSize) -> Option<TextRange> { - Some(TextRange { - start: self.start.checked_add(offset)?, - end: self.end.checked_add(offset)?, - }) - } - - /// Subtract an offset from this range. - /// - /// Note that this is not appropriate for changing where a `TextRange` is - /// within some string; rather, it is for changing the reference anchor - /// that the `TextRange` is measured against. - /// - /// The unchecked version (`Sub::sub`) will _always_ panic on overflow, - /// in contrast to primitive integers, which check in debug mode only. - #[inline] - pub fn checked_sub(self, offset: TextSize) -> Option<TextRange> { - Some(TextRange { - start: self.start.checked_sub(offset)?, - end: self.end.checked_sub(offset)?, - }) - } - - /// Relative order of the two ranges (overlapping ranges are considered - /// equal). - /// - /// - /// This is useful when, for example, binary searching an array of disjoint - /// ranges. - /// - /// # Examples - /// - /// ``` - /// # use text_size::*; - /// # use std::cmp::Ordering; - /// - /// let a = TextRange::new(0.into(), 3.into()); - /// let b = TextRange::new(4.into(), 5.into()); - /// assert_eq!(a.ordering(b), Ordering::Less); - /// - /// let a = TextRange::new(0.into(), 3.into()); - /// let b = TextRange::new(3.into(), 5.into()); - /// assert_eq!(a.ordering(b), Ordering::Less); - /// - /// let a = TextRange::new(0.into(), 3.into()); - /// let b = TextRange::new(2.into(), 5.into()); - /// assert_eq!(a.ordering(b), Ordering::Equal); - /// - /// let a = TextRange::new(0.into(), 3.into()); - /// let b = TextRange::new(2.into(), 2.into()); - /// assert_eq!(a.ordering(b), Ordering::Equal); - /// - /// let a = TextRange::new(2.into(), 3.into()); - /// let b = TextRange::new(2.into(), 2.into()); - /// assert_eq!(a.ordering(b), Ordering::Greater); - /// ``` - #[inline] - pub fn ordering(self, other: TextRange) -> Ordering { - if self.end() <= other.start() { - Ordering::Less - } else if other.end() <= self.start() { - Ordering::Greater - } else { - Ordering::Equal - } - } -} - -impl Index<TextRange> for str { - type Output = str; - #[inline] - fn index(&self, index: TextRange) -> &str { - &self[Range::<usize>::from(index)] - } -} - -impl Index<TextRange> for String { - type Output = str; - #[inline] - fn index(&self, index: TextRange) -> &str { - &self[Range::<usize>::from(index)] - } -} - -impl IndexMut<TextRange> for str { - #[inline] - fn index_mut(&mut self, index: TextRange) -> &mut str { - &mut self[Range::<usize>::from(index)] - } -} - -impl IndexMut<TextRange> for String { - #[inline] - fn index_mut(&mut self, index: TextRange) -> &mut str { - &mut self[Range::<usize>::from(index)] - } -} - -impl RangeBounds<TextSize> for TextRange { - fn start_bound(&self) -> Bound<&TextSize> { - Bound::Included(&self.start) - } - - fn end_bound(&self) -> Bound<&TextSize> { - Bound::Excluded(&self.end) - } -} - -impl<T> From<TextRange> for Range<T> -where - T: From<TextSize>, -{ - #[inline] - fn from(r: TextRange) -> Self { - r.start().into()..r.end().into() - } -} - -macro_rules! ops { - (impl $Op:ident for TextRange by fn $f:ident = $op:tt) => { - impl $Op<&TextSize> for TextRange { - type Output = TextRange; - #[inline] - fn $f(self, other: &TextSize) -> TextRange { - self $op *other - } - } - impl<T> $Op<T> for &TextRange - where - TextRange: $Op<T, Output=TextRange>, - { - type Output = TextRange; - #[inline] - fn $f(self, other: T) -> TextRange { - *self $op other - } - } - }; -} - -impl Add<TextSize> for TextRange { - type Output = TextRange; - #[inline] - fn add(self, offset: TextSize) -> TextRange { - self.checked_add(offset) - .expect("TextRange +offset overflowed") - } -} - -impl Sub<TextSize> for TextRange { - type Output = TextRange; - #[inline] - fn sub(self, offset: TextSize) -> TextRange { - self.checked_sub(offset) - .expect("TextRange -offset overflowed") - } -} - -ops!(impl Add for TextRange by fn add = +); -ops!(impl Sub for TextRange by fn sub = -); - -impl<A> AddAssign<A> for TextRange -where - TextRange: Add<A, Output = TextRange>, -{ - #[inline] - fn add_assign(&mut self, rhs: A) { - *self = *self + rhs - } -} - -impl<S> SubAssign<S> for TextRange -where - TextRange: Sub<S, Output = TextRange>, -{ - #[inline] - fn sub_assign(&mut self, rhs: S) { - *self = *self - rhs - } -} +use cmp::Ordering;
+
+use {
+ crate::TextSize,
+ std::{
+ cmp, fmt,
+ ops::{Add, AddAssign, Bound, Index, IndexMut, Range, RangeBounds, Sub, SubAssign},
+ },
+};
+
+/// A range in text, represented as a pair of [`TextSize`][struct@TextSize].
+///
+/// It is a logic error for `start` to be greater than `end`.
+#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct TextRange {
+ // Invariant: start <= end
+ start: TextSize,
+ end: TextSize,
+}
+
+impl fmt::Debug for TextRange {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}..{}", self.start().raw, self.end().raw)
+ }
+}
+
+impl TextRange {
+ /// Creates a new `TextRange` with the given `start` and `end` (`start..end`).
+ ///
+ /// # Panics
+ ///
+ /// Panics if `end < start`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let start = TextSize::from(5);
+ /// let end = TextSize::from(10);
+ /// let range = TextRange::new(start, end);
+ ///
+ /// assert_eq!(range.start(), start);
+ /// assert_eq!(range.end(), end);
+ /// assert_eq!(range.len(), end - start);
+ /// ```
+ #[inline]
+ pub const fn new(start: TextSize, end: TextSize) -> TextRange {
+ assert!(start.raw <= end.raw);
+ TextRange { start, end }
+ }
+
+ /// Create a new `TextRange` with the given `offset` and `len` (`offset..offset + len`).
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let text = "0123456789";
+ ///
+ /// let offset = TextSize::from(2);
+ /// let length = TextSize::from(5);
+ /// let range = TextRange::at(offset, length);
+ ///
+ /// assert_eq!(range, TextRange::new(offset, offset + length));
+ /// assert_eq!(&text[range], "23456")
+ /// ```
+ #[inline]
+ pub const fn at(offset: TextSize, len: TextSize) -> TextRange {
+ TextRange::new(offset, TextSize::new(offset.raw + len.raw))
+ }
+
+ /// Create a zero-length range at the specified offset (`offset..offset`).
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let point: TextSize;
+ /// # point = TextSize::from(3);
+ /// let range = TextRange::empty(point);
+ /// assert!(range.is_empty());
+ /// assert_eq!(range, TextRange::new(point, point));
+ /// ```
+ #[inline]
+ pub const fn empty(offset: TextSize) -> TextRange {
+ TextRange {
+ start: offset,
+ end: offset,
+ }
+ }
+
+ /// Create a range up to the given end (`..end`).
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let point: TextSize;
+ /// # point = TextSize::from(12);
+ /// let range = TextRange::up_to(point);
+ ///
+ /// assert_eq!(range.len(), point);
+ /// assert_eq!(range, TextRange::new(0.into(), point));
+ /// assert_eq!(range, TextRange::at(0.into(), point));
+ /// ```
+ #[inline]
+ pub const fn up_to(end: TextSize) -> TextRange {
+ TextRange {
+ start: TextSize::new(0),
+ end,
+ }
+ }
+}
+
+/// Identity methods.
+impl TextRange {
+ /// The start point of this range.
+ #[inline]
+ pub const fn start(self) -> TextSize {
+ self.start
+ }
+
+ /// The end point of this range.
+ #[inline]
+ pub const fn end(self) -> TextSize {
+ self.end
+ }
+
+ /// The size of this range.
+ #[inline]
+ pub const fn len(self) -> TextSize {
+ // HACK for const fn: math on primitives only
+ TextSize {
+ raw: self.end().raw - self.start().raw,
+ }
+ }
+
+ /// Check if this range is empty.
+ #[inline]
+ pub const fn is_empty(self) -> bool {
+ // HACK for const fn: math on primitives only
+ self.start().raw == self.end().raw
+ }
+}
+
+/// Manipulation methods.
+impl TextRange {
+ /// Check if this range contains an offset.
+ ///
+ /// The end index is considered excluded.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let (start, end): (TextSize, TextSize);
+ /// # start = 10.into(); end = 20.into();
+ /// let range = TextRange::new(start, end);
+ /// assert!(range.contains(start));
+ /// assert!(!range.contains(end));
+ /// ```
+ #[inline]
+ pub fn contains(self, offset: TextSize) -> bool {
+ self.start() <= offset && offset < self.end()
+ }
+
+ /// Check if this range contains an offset.
+ ///
+ /// The end index is considered included.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let (start, end): (TextSize, TextSize);
+ /// # start = 10.into(); end = 20.into();
+ /// let range = TextRange::new(start, end);
+ /// assert!(range.contains_inclusive(start));
+ /// assert!(range.contains_inclusive(end));
+ /// ```
+ #[inline]
+ pub fn contains_inclusive(self, offset: TextSize) -> bool {
+ self.start() <= offset && offset <= self.end()
+ }
+
+ /// Check if this range completely contains another range.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let larger = TextRange::new(0.into(), 20.into());
+ /// let smaller = TextRange::new(5.into(), 15.into());
+ /// assert!(larger.contains_range(smaller));
+ /// assert!(!smaller.contains_range(larger));
+ ///
+ /// // a range always contains itself
+ /// assert!(larger.contains_range(larger));
+ /// assert!(smaller.contains_range(smaller));
+ /// ```
+ #[inline]
+ pub fn contains_range(self, other: TextRange) -> bool {
+ self.start() <= other.start() && other.end() <= self.end()
+ }
+
+ /// The range covered by both ranges, if it exists.
+ /// If the ranges touch but do not overlap, the output range is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// assert_eq!(
+ /// TextRange::intersect(
+ /// TextRange::new(0.into(), 10.into()),
+ /// TextRange::new(5.into(), 15.into()),
+ /// ),
+ /// Some(TextRange::new(5.into(), 10.into())),
+ /// );
+ /// ```
+ #[inline]
+ pub fn intersect(self, other: TextRange) -> Option<TextRange> {
+ let start = cmp::max(self.start(), other.start());
+ let end = cmp::min(self.end(), other.end());
+ if end < start {
+ return None;
+ }
+ Some(TextRange::new(start, end))
+ }
+
+ /// Extends the range to cover `other` as well.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// assert_eq!(
+ /// TextRange::cover(
+ /// TextRange::new(0.into(), 5.into()),
+ /// TextRange::new(15.into(), 20.into()),
+ /// ),
+ /// TextRange::new(0.into(), 20.into()),
+ /// );
+ /// ```
+ #[inline]
+ pub fn cover(self, other: TextRange) -> TextRange {
+ let start = cmp::min(self.start(), other.start());
+ let end = cmp::max(self.end(), other.end());
+ TextRange::new(start, end)
+ }
+
+ /// Extends the range to cover `other` offsets as well.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// assert_eq!(
+ /// TextRange::empty(0.into()).cover_offset(20.into()),
+ /// TextRange::new(0.into(), 20.into()),
+ /// )
+ /// ```
+ #[inline]
+ pub fn cover_offset(self, offset: TextSize) -> TextRange {
+ self.cover(TextRange::empty(offset))
+ }
+
+ /// Add an offset to this range.
+ ///
+ /// Note that this is not appropriate for changing where a `TextRange` is
+ /// within some string; rather, it is for changing the reference anchor
+ /// that the `TextRange` is measured against.
+ ///
+ /// The unchecked version (`Add::add`) will _always_ panic on overflow,
+ /// in contrast to primitive integers, which check in debug mode only.
+ #[inline]
+ pub fn checked_add(self, offset: TextSize) -> Option<TextRange> {
+ Some(TextRange {
+ start: self.start.checked_add(offset)?,
+ end: self.end.checked_add(offset)?,
+ })
+ }
+
+ /// Subtract an offset from this range.
+ ///
+ /// Note that this is not appropriate for changing where a `TextRange` is
+ /// within some string; rather, it is for changing the reference anchor
+ /// that the `TextRange` is measured against.
+ ///
+ /// The unchecked version (`Sub::sub`) will _always_ panic on overflow,
+ /// in contrast to primitive integers, which check in debug mode only.
+ #[inline]
+ pub fn checked_sub(self, offset: TextSize) -> Option<TextRange> {
+ Some(TextRange {
+ start: self.start.checked_sub(offset)?,
+ end: self.end.checked_sub(offset)?,
+ })
+ }
+
+ /// Relative order of the two ranges (overlapping ranges are considered
+ /// equal).
+ ///
+ ///
+ /// This is useful when, for example, binary searching an array of disjoint
+ /// ranges.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use text_size::*;
+ /// # use std::cmp::Ordering;
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(4.into(), 5.into());
+ /// assert_eq!(a.ordering(b), Ordering::Less);
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(3.into(), 5.into());
+ /// assert_eq!(a.ordering(b), Ordering::Less);
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(2.into(), 5.into());
+ /// assert_eq!(a.ordering(b), Ordering::Equal);
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(2.into(), 2.into());
+ /// assert_eq!(a.ordering(b), Ordering::Equal);
+ ///
+ /// let a = TextRange::new(2.into(), 3.into());
+ /// let b = TextRange::new(2.into(), 2.into());
+ /// assert_eq!(a.ordering(b), Ordering::Greater);
+ /// ```
+ #[inline]
+ pub fn ordering(self, other: TextRange) -> Ordering {
+ if self.end() <= other.start() {
+ Ordering::Less
+ } else if other.end() <= self.start() {
+ Ordering::Greater
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Index<TextRange> for str {
+ type Output = str;
+ #[inline]
+ fn index(&self, index: TextRange) -> &str {
+ &self[Range::<usize>::from(index)]
+ }
+}
+
+impl Index<TextRange> for String {
+ type Output = str;
+ #[inline]
+ fn index(&self, index: TextRange) -> &str {
+ &self[Range::<usize>::from(index)]
+ }
+}
+
+impl IndexMut<TextRange> for str {
+ #[inline]
+ fn index_mut(&mut self, index: TextRange) -> &mut str {
+ &mut self[Range::<usize>::from(index)]
+ }
+}
+
+impl IndexMut<TextRange> for String {
+ #[inline]
+ fn index_mut(&mut self, index: TextRange) -> &mut str {
+ &mut self[Range::<usize>::from(index)]
+ }
+}
+
+impl RangeBounds<TextSize> for TextRange {
+ fn start_bound(&self) -> Bound<&TextSize> {
+ Bound::Included(&self.start)
+ }
+
+ fn end_bound(&self) -> Bound<&TextSize> {
+ Bound::Excluded(&self.end)
+ }
+}
+
+impl<T> From<TextRange> for Range<T>
+where
+ T: From<TextSize>,
+{
+ #[inline]
+ fn from(r: TextRange) -> Self {
+ r.start().into()..r.end().into()
+ }
+}
+
+macro_rules! ops {
+ (impl $Op:ident for TextRange by fn $f:ident = $op:tt) => {
+ impl $Op<&TextSize> for TextRange {
+ type Output = TextRange;
+ #[inline]
+ fn $f(self, other: &TextSize) -> TextRange {
+ self $op *other
+ }
+ }
+ impl<T> $Op<T> for &TextRange
+ where
+ TextRange: $Op<T, Output=TextRange>,
+ {
+ type Output = TextRange;
+ #[inline]
+ fn $f(self, other: T) -> TextRange {
+ *self $op other
+ }
+ }
+ };
+}
+
+impl Add<TextSize> for TextRange {
+ type Output = TextRange;
+ #[inline]
+ fn add(self, offset: TextSize) -> TextRange {
+ self.checked_add(offset)
+ .expect("TextRange +offset overflowed")
+ }
+}
+
+impl Sub<TextSize> for TextRange {
+ type Output = TextRange;
+ #[inline]
+ fn sub(self, offset: TextSize) -> TextRange {
+ self.checked_sub(offset)
+ .expect("TextRange -offset overflowed")
+ }
+}
+
+ops!(impl Add for TextRange by fn add = +);
+ops!(impl Sub for TextRange by fn sub = -);
+
+impl<A> AddAssign<A> for TextRange
+where
+ TextRange: Add<A, Output = TextRange>,
+{
+ #[inline]
+ fn add_assign(&mut self, rhs: A) {
+ *self = *self + rhs
+ }
+}
+
+impl<S> SubAssign<S> for TextRange
+where
+ TextRange: Sub<S, Output = TextRange>,
+{
+ #[inline]
+ fn sub_assign(&mut self, rhs: S) {
+ *self = *self - rhs
+ }
+}
diff --git a/vendor/text-size/src/serde_impls.rs b/vendor/text-size/src/serde_impls.rs index a94bee956..e55908bfd 100644 --- a/vendor/text-size/src/serde_impls.rs +++ b/vendor/text-size/src/serde_impls.rs @@ -1,48 +1,48 @@ -use { - crate::{TextRange, TextSize}, - serde::{de, Deserialize, Deserializer, Serialize, Serializer}, -}; - -impl Serialize for TextSize { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - self.raw.serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for TextSize { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: Deserializer<'de>, - { - u32::deserialize(deserializer).map(TextSize::from) - } -} - -impl Serialize for TextRange { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - (self.start(), self.end()).serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for TextRange { - #[allow(clippy::nonminimal_bool)] - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: Deserializer<'de>, - { - let (start, end) = Deserialize::deserialize(deserializer)?; - if !(start <= end) { - return Err(de::Error::custom(format!( - "invalid range: {:?}..{:?}", - start, end - ))); - } - Ok(TextRange::new(start, end)) - } -} +use {
+ crate::{TextRange, TextSize},
+ serde::{de, Deserialize, Deserializer, Serialize, Serializer},
+};
+
+impl Serialize for TextSize {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.raw.serialize(serializer)
+ }
+}
+
+impl<'de> Deserialize<'de> for TextSize {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ u32::deserialize(deserializer).map(TextSize::from)
+ }
+}
+
+impl Serialize for TextRange {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ (self.start(), self.end()).serialize(serializer)
+ }
+}
+
+impl<'de> Deserialize<'de> for TextRange {
+ #[allow(clippy::nonminimal_bool)]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let (start, end) = Deserialize::deserialize(deserializer)?;
+ if !(start <= end) {
+ return Err(de::Error::custom(format!(
+ "invalid range: {:?}..{:?}",
+ start, end
+ )));
+ }
+ Ok(TextRange::new(start, end))
+ }
+}
diff --git a/vendor/text-size/src/size.rs b/vendor/text-size/src/size.rs index ab2ec9a73..62f2752cc 100644 --- a/vendor/text-size/src/size.rs +++ b/vendor/text-size/src/size.rs @@ -1,161 +1,173 @@ -use { - crate::TextLen, - std::{ - convert::TryFrom, - fmt, iter, - num::TryFromIntError, - ops::{Add, AddAssign, Sub, SubAssign}, - u32, - }, -}; - -/// A measure of text length. Also, equivalently, an index into text. -/// -/// This is a UTF-8 bytes offset stored as `u32`, but -/// most clients should treat it as an opaque measure. -/// -/// For cases that need to escape `TextSize` and return to working directly -/// with primitive integers, `TextSize` can be converted losslessly to/from -/// `u32` via [`From`] conversions as well as losslessly be converted [`Into`] -/// `usize`. The `usize -> TextSize` direction can be done via [`TryFrom`]. -/// -/// These escape hatches are primarily required for unit testing and when -/// converting from UTF-8 size to another coordinate space, such as UTF-16. -#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct TextSize { - pub(crate) raw: u32, -} - -impl fmt::Debug for TextSize { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.raw) - } -} - -impl TextSize { - /// The text size of some primitive text-like object. - /// - /// Accepts `char`, `&str`, and `&String`. - /// - /// # Examples - /// - /// ```rust - /// # use text_size::*; - /// let char_size = TextSize::of('🦀'); - /// assert_eq!(char_size, TextSize::from(4)); - /// - /// let str_size = TextSize::of("rust-analyzer"); - /// assert_eq!(str_size, TextSize::from(13)); - /// ``` - #[inline] - pub fn of<T: TextLen>(text: T) -> TextSize { - text.text_len() - } -} - -/// Methods to act like a primitive integer type, where reasonably applicable. -// Last updated for parity with Rust 1.42.0. -impl TextSize { - /// Checked addition. Returns `None` if overflow occurred. - #[inline] - pub fn checked_add(self, rhs: TextSize) -> Option<TextSize> { - self.raw.checked_add(rhs.raw).map(|raw| TextSize { raw }) - } - - /// Checked subtraction. Returns `None` if overflow occurred. - #[inline] - pub fn checked_sub(self, rhs: TextSize) -> Option<TextSize> { - self.raw.checked_sub(rhs.raw).map(|raw| TextSize { raw }) - } -} - -impl From<u32> for TextSize { - #[inline] - fn from(raw: u32) -> Self { - TextSize { raw } - } -} - -impl From<TextSize> for u32 { - #[inline] - fn from(value: TextSize) -> Self { - value.raw - } -} - -impl TryFrom<usize> for TextSize { - type Error = TryFromIntError; - #[inline] - fn try_from(value: usize) -> Result<Self, TryFromIntError> { - Ok(u32::try_from(value)?.into()) - } -} - -impl From<TextSize> for usize { - #[inline] - fn from(value: TextSize) -> Self { - value.raw as usize - } -} - -macro_rules! ops { - (impl $Op:ident for TextSize by fn $f:ident = $op:tt) => { - impl $Op<TextSize> for TextSize { - type Output = TextSize; - #[inline] - fn $f(self, other: TextSize) -> TextSize { - TextSize { raw: self.raw $op other.raw } - } - } - impl $Op<&TextSize> for TextSize { - type Output = TextSize; - #[inline] - fn $f(self, other: &TextSize) -> TextSize { - self $op *other - } - } - impl<T> $Op<T> for &TextSize - where - TextSize: $Op<T, Output=TextSize>, - { - type Output = TextSize; - #[inline] - fn $f(self, other: T) -> TextSize { - *self $op other - } - } - }; -} - -ops!(impl Add for TextSize by fn add = +); -ops!(impl Sub for TextSize by fn sub = -); - -impl<A> AddAssign<A> for TextSize -where - TextSize: Add<A, Output = TextSize>, -{ - #[inline] - fn add_assign(&mut self, rhs: A) { - *self = *self + rhs - } -} - -impl<S> SubAssign<S> for TextSize -where - TextSize: Sub<S, Output = TextSize>, -{ - #[inline] - fn sub_assign(&mut self, rhs: S) { - *self = *self - rhs - } -} - -impl<A> iter::Sum<A> for TextSize -where - TextSize: Add<A, Output = TextSize>, -{ - #[inline] - fn sum<I: Iterator<Item = A>>(iter: I) -> TextSize { - iter.fold(0.into(), Add::add) - } -} +use {
+ crate::TextLen,
+ std::{
+ convert::TryFrom,
+ fmt, iter,
+ num::TryFromIntError,
+ ops::{Add, AddAssign, Sub, SubAssign},
+ u32,
+ },
+};
+
+/// A measure of text length. Also, equivalently, an index into text.
+///
+/// This is a UTF-8 bytes offset stored as `u32`, but
+/// most clients should treat it as an opaque measure.
+///
+/// For cases that need to escape `TextSize` and return to working directly
+/// with primitive integers, `TextSize` can be converted losslessly to/from
+/// `u32` via [`From`] conversions as well as losslessly be converted [`Into`]
+/// `usize`. The `usize -> TextSize` direction can be done via [`TryFrom`].
+///
+/// These escape hatches are primarily required for unit testing and when
+/// converting from UTF-8 size to another coordinate space, such as UTF-16.
+#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct TextSize {
+ pub(crate) raw: u32,
+}
+
+impl fmt::Debug for TextSize {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.raw)
+ }
+}
+
+impl TextSize {
+ /// Creates a new instance of `TextSize` from a raw `u32`.
+ #[inline]
+ pub const fn new(raw: u32) -> TextSize {
+ TextSize { raw }
+ }
+
+ /// The text size of some primitive text-like object.
+ ///
+ /// Accepts `char`, `&str`, and `&String`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let char_size = TextSize::of('🦀');
+ /// assert_eq!(char_size, TextSize::from(4));
+ ///
+ /// let str_size = TextSize::of("rust-analyzer");
+ /// assert_eq!(str_size, TextSize::from(13));
+ /// ```
+ #[inline]
+ pub fn of<T: TextLen>(text: T) -> TextSize {
+ text.text_len()
+ }
+}
+
+/// Methods to act like a primitive integer type, where reasonably applicable.
+// Last updated for parity with Rust 1.42.0.
+impl TextSize {
+ /// Checked addition. Returns `None` if overflow occurred.
+ #[inline]
+ pub const fn checked_add(self, rhs: TextSize) -> Option<TextSize> {
+ match self.raw.checked_add(rhs.raw) {
+ Some(raw) => Some(TextSize { raw }),
+ None => None,
+ }
+ }
+
+ /// Checked subtraction. Returns `None` if overflow occurred.
+ #[inline]
+ pub const fn checked_sub(self, rhs: TextSize) -> Option<TextSize> {
+ match self.raw.checked_sub(rhs.raw) {
+ Some(raw) => Some(TextSize { raw }),
+ None => None,
+ }
+ }
+}
+
+impl From<u32> for TextSize {
+ #[inline]
+ fn from(raw: u32) -> Self {
+ TextSize { raw }
+ }
+}
+
+impl From<TextSize> for u32 {
+ #[inline]
+ fn from(value: TextSize) -> Self {
+ value.raw
+ }
+}
+
+impl TryFrom<usize> for TextSize {
+ type Error = TryFromIntError;
+ #[inline]
+ fn try_from(value: usize) -> Result<Self, TryFromIntError> {
+ Ok(u32::try_from(value)?.into())
+ }
+}
+
+impl From<TextSize> for usize {
+ #[inline]
+ fn from(value: TextSize) -> Self {
+ value.raw as usize
+ }
+}
+
+macro_rules! ops {
+ (impl $Op:ident for TextSize by fn $f:ident = $op:tt) => {
+ impl $Op<TextSize> for TextSize {
+ type Output = TextSize;
+ #[inline]
+ fn $f(self, other: TextSize) -> TextSize {
+ TextSize { raw: self.raw $op other.raw }
+ }
+ }
+ impl $Op<&TextSize> for TextSize {
+ type Output = TextSize;
+ #[inline]
+ fn $f(self, other: &TextSize) -> TextSize {
+ self $op *other
+ }
+ }
+ impl<T> $Op<T> for &TextSize
+ where
+ TextSize: $Op<T, Output=TextSize>,
+ {
+ type Output = TextSize;
+ #[inline]
+ fn $f(self, other: T) -> TextSize {
+ *self $op other
+ }
+ }
+ };
+}
+
+ops!(impl Add for TextSize by fn add = +);
+ops!(impl Sub for TextSize by fn sub = -);
+
+impl<A> AddAssign<A> for TextSize
+where
+ TextSize: Add<A, Output = TextSize>,
+{
+ #[inline]
+ fn add_assign(&mut self, rhs: A) {
+ *self = *self + rhs
+ }
+}
+
+impl<S> SubAssign<S> for TextSize
+where
+ TextSize: Sub<S, Output = TextSize>,
+{
+ #[inline]
+ fn sub_assign(&mut self, rhs: S) {
+ *self = *self - rhs
+ }
+}
+
+impl<A> iter::Sum<A> for TextSize
+where
+ TextSize: Add<A, Output = TextSize>,
+{
+ #[inline]
+ fn sum<I: Iterator<Item = A>>(iter: I) -> TextSize {
+ iter.fold(0.into(), Add::add)
+ }
+}
diff --git a/vendor/text-size/src/traits.rs b/vendor/text-size/src/traits.rs index d0bb6c1f6..7de20dcc4 100644 --- a/vendor/text-size/src/traits.rs +++ b/vendor/text-size/src/traits.rs @@ -1,36 +1,36 @@ -use {crate::TextSize, std::convert::TryInto}; - -use priv_in_pub::Sealed; -mod priv_in_pub { - pub trait Sealed {} -} - -/// Primitives with a textual length that can be passed to [`TextSize::of`]. -pub trait TextLen: Copy + Sealed { - /// The textual length of this primitive. - fn text_len(self) -> TextSize; -} - -impl Sealed for &'_ str {} -impl TextLen for &'_ str { - #[inline] - fn text_len(self) -> TextSize { - self.len().try_into().unwrap() - } -} - -impl Sealed for &'_ String {} -impl TextLen for &'_ String { - #[inline] - fn text_len(self) -> TextSize { - self.as_str().text_len() - } -} - -impl Sealed for char {} -impl TextLen for char { - #[inline] - fn text_len(self) -> TextSize { - (self.len_utf8() as u32).into() - } -} +use {crate::TextSize, std::convert::TryInto};
+
+use priv_in_pub::Sealed;
+mod priv_in_pub {
+ pub trait Sealed {}
+}
+
+/// Primitives with a textual length that can be passed to [`TextSize::of`].
+pub trait TextLen: Copy + Sealed {
+ /// The textual length of this primitive.
+ fn text_len(self) -> TextSize;
+}
+
+impl Sealed for &'_ str {}
+impl TextLen for &'_ str {
+ #[inline]
+ fn text_len(self) -> TextSize {
+ self.len().try_into().unwrap()
+ }
+}
+
+impl Sealed for &'_ String {}
+impl TextLen for &'_ String {
+ #[inline]
+ fn text_len(self) -> TextSize {
+ self.as_str().text_len()
+ }
+}
+
+impl Sealed for char {}
+impl TextLen for char {
+ #[inline]
+ fn text_len(self) -> TextSize {
+ (self.len_utf8() as u32).into()
+ }
+}
|