mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-12-30 16:11:41 +00:00
Make TextRange constructors more boring
Remove `fn TextRange(` as that's slightly unusual and surprising, which will add up to a lot of confusion over the long run. Instead add: * `new` as the biased, canonical way to create range from bounds * `from_len` as an alternative ctor from starting position and len * `empty` for empty ranges at a given offset * `up_to` for ranges at zero offset with given length * `default` for an empty range at zero
This commit is contained in:
parent
c69d303414
commit
8d9a1a4192
@ -10,18 +10,18 @@ use {
|
||||
///
|
||||
/// # Translation from `text_unit`
|
||||
///
|
||||
/// - `TextRange::from_to(from, to)` ⟹ `TextRange(from, to)`
|
||||
/// - `TextRange::offset_len(offset, size)` ⟹ `TextRange::up_to(size) + offset`
|
||||
/// - `TextRange::from_to(from, to)` ⟹ `TextRange::new(from, to)`
|
||||
/// - `TextRange::offset_len(offset, size)` ⟹ `TextRange::from_len(offset, size)`
|
||||
/// - `range.start()` ⟹ `range.start()`
|
||||
/// - `range.end()` ⟹ `range.end()`
|
||||
/// - `range.len()` ⟹ `range.len()`
|
||||
/// - `range.is_empty()` ⟹ `range.is_empty()`
|
||||
/// - `a.is_subrange(b)` ⟹ `b.contains_range(a)`
|
||||
/// - `a.intersection(b)` ⟹ `TextRange::intersection(a, b)`
|
||||
/// - `a.extend_to(b)` ⟹ `TextRange::covering(a, b)`
|
||||
/// - `a.intersection(b)` ⟹ `a.intersect(b)`
|
||||
/// - `a.extend_to(b)` ⟹ `a.cover(b)`
|
||||
/// - `range.contains(offset)` ⟹ `range.contains(point)`
|
||||
/// - `range.contains_inclusive(offset)` ⟹ `range.contains_inclusive(point)`
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct TextRange {
|
||||
// Invariant: start <= end
|
||||
start: TextSize,
|
||||
@ -34,19 +34,24 @@ impl fmt::Debug for TextRange {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `TextRange` with the given `start` and `end` (`start..end`).
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `end < start`.
|
||||
#[allow(non_snake_case)]
|
||||
#[inline]
|
||||
pub fn TextRange(start: TextSize, end: TextSize) -> TextRange {
|
||||
assert!(start <= end);
|
||||
TextRange { start, end }
|
||||
}
|
||||
|
||||
impl TextRange {
|
||||
/// Creates a new `TextRange` with the given `start` and `end` (`start..end`).
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `end < start`.
|
||||
#[inline]
|
||||
pub fn new(start: TextSize, end: TextSize) -> TextRange {
|
||||
assert!(start <= end);
|
||||
TextRange { start, end }
|
||||
}
|
||||
|
||||
/// Create a new `TextRange` with the given `start` and `len` (`start..start + len`).
|
||||
#[inline]
|
||||
pub fn from_len(start: TextSize, len: TextSize) -> TextRange {
|
||||
TextRange::new(start, start + len)
|
||||
}
|
||||
|
||||
/// Create a zero-length range at the specified offset (`offset..offset`).
|
||||
#[inline]
|
||||
pub const fn empty(offset: TextSize) -> TextRange {
|
||||
@ -59,10 +64,8 @@ impl TextRange {
|
||||
/// Create a range up to the given end (`..end`).
|
||||
#[inline]
|
||||
pub const fn up_to(end: TextSize) -> TextRange {
|
||||
TextRange {
|
||||
start: TextSize::zero(),
|
||||
end,
|
||||
}
|
||||
let start = TextSize::zero();
|
||||
TextRange { start, end }
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +87,9 @@ impl TextRange {
|
||||
#[inline]
|
||||
pub const fn len(self) -> TextSize {
|
||||
// HACK for const fn: math on primitives only
|
||||
TextSize(self.end().raw - self.start().raw)
|
||||
TextSize {
|
||||
raw: self.end().raw - self.start().raw,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this range is empty.
|
||||
@ -124,14 +129,14 @@ impl TextRange {
|
||||
if end < start {
|
||||
return None;
|
||||
}
|
||||
Some(TextRange(start, end))
|
||||
Some(TextRange::new(start, end))
|
||||
}
|
||||
|
||||
/// Extends the range to cover `other` as well.
|
||||
pub fn cover(self, other: TextRange) -> TextRange {
|
||||
let start = cmp::min(self.start(), other.start());
|
||||
let end = cmp::max(self.end(), other.end());
|
||||
TextRange(start, end)
|
||||
TextRange::new(start, end)
|
||||
}
|
||||
|
||||
/// Extends the range to cover `other` offsets as well.
|
||||
|
||||
@ -17,7 +17,7 @@ impl<'de> Deserialize<'de> for TextSize {
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Deserialize::deserialize(deserializer).map(TextSize)
|
||||
u32::deserialize(deserializer).map(TextSize::from)
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +43,6 @@ impl<'de> Deserialize<'de> for TextRange {
|
||||
start, end
|
||||
)));
|
||||
}
|
||||
Ok(TextRange(start, end))
|
||||
Ok(TextRange::new(start, end))
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,11 +33,6 @@ pub struct TextSize {
|
||||
pub(crate) raw: u32,
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub(crate) const fn TextSize(raw: u32) -> TextSize {
|
||||
TextSize { raw }
|
||||
}
|
||||
|
||||
impl fmt::Debug for TextSize {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.raw)
|
||||
@ -57,7 +52,7 @@ impl TextSize {
|
||||
/// but is more explicit on intent.
|
||||
#[inline]
|
||||
pub const fn zero() -> TextSize {
|
||||
TextSize(0)
|
||||
TextSize { raw: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,27 +60,27 @@ impl TextSize {
|
||||
// Last updated for parity with Rust 1.42.0.
|
||||
impl TextSize {
|
||||
/// The smallest representable text size. (`u32::MIN`)
|
||||
pub const MIN: TextSize = TextSize(u32::MIN);
|
||||
pub const MIN: TextSize = TextSize { raw: u32::MIN };
|
||||
/// The largest representable text size. (`u32::MAX`)
|
||||
pub const MAX: TextSize = TextSize(u32::MAX);
|
||||
pub const MAX: TextSize = TextSize { raw: u32::MAX };
|
||||
|
||||
/// Checked addition. Returns `None` if overflow occurred.
|
||||
#[inline]
|
||||
pub fn checked_add(self, rhs: TextSize) -> Option<TextSize> {
|
||||
self.raw.checked_add(rhs.raw).map(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(TextSize)
|
||||
self.raw.checked_sub(rhs.raw).map(|raw| TextSize { raw })
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for TextSize {
|
||||
#[inline]
|
||||
fn from(raw: u32) -> Self {
|
||||
TextSize(raw)
|
||||
TextSize { raw }
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,7 +112,7 @@ macro_rules! ops {
|
||||
type Output = TextSize;
|
||||
#[inline]
|
||||
fn $f(self, other: TextSize) -> TextSize {
|
||||
TextSize(self.raw $op other.raw)
|
||||
TextSize { raw: self.raw $op other.raw }
|
||||
}
|
||||
}
|
||||
impl $Op<&TextSize> for TextSize {
|
||||
|
||||
@ -18,6 +18,6 @@ impl TextSized for &'_ str {
|
||||
impl TextSized for char {
|
||||
#[inline]
|
||||
fn text_size(self) -> TextSize {
|
||||
TextSize(self.len_utf8() as u32)
|
||||
(self.len_utf8() as u32).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ fn size(x: u32) -> TextSize {
|
||||
}
|
||||
|
||||
fn range(x: ops::Range<u32>) -> TextRange {
|
||||
TextRange(x.start.into(), x.end.into())
|
||||
TextRange::new(x.start.into(), x.end.into())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -5,7 +5,7 @@ fn size(x: u32) -> TextSize {
|
||||
}
|
||||
|
||||
fn range(x: ops::Range<u32>) -> TextRange {
|
||||
TextRange(x.start.into(), x.end.into())
|
||||
TextRange::new(x.start.into(), x.end.into())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user