From 8d9a1a4192dd4e78b62e19b52b2ecf4e17ff95f9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Mar 2020 09:15:28 +0100 Subject: [PATCH] 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 --- lib/text-size/src/range.rs | 53 +++++++++++++++++--------------- lib/text-size/src/serde_impls.rs | 4 +-- lib/text-size/src/size.rs | 19 +++++------- lib/text-size/src/traits.rs | 2 +- lib/text-size/tests/main.rs | 2 +- lib/text-size/tests/serde.rs | 2 +- 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/lib/text-size/src/range.rs b/lib/text-size/src/range.rs index b52a64af39..0e5809114a 100644 --- a/lib/text-size/src/range.rs +++ b/lib/text-size/src/range.rs @@ -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. diff --git a/lib/text-size/src/serde_impls.rs b/lib/text-size/src/serde_impls.rs index 6a0d040bfa..a94bee9567 100644 --- a/lib/text-size/src/serde_impls.rs +++ b/lib/text-size/src/serde_impls.rs @@ -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)) } } diff --git a/lib/text-size/src/size.rs b/lib/text-size/src/size.rs index 5239ea6691..14f7b37df0 100644 --- a/lib/text-size/src/size.rs +++ b/lib/text-size/src/size.rs @@ -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 { - 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 { - self.raw.checked_sub(rhs.raw).map(TextSize) + self.raw.checked_sub(rhs.raw).map(|raw| TextSize { raw }) } } impl From 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 { diff --git a/lib/text-size/src/traits.rs b/lib/text-size/src/traits.rs index 8d197db8c1..7064dbc658 100644 --- a/lib/text-size/src/traits.rs +++ b/lib/text-size/src/traits.rs @@ -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() } } diff --git a/lib/text-size/tests/main.rs b/lib/text-size/tests/main.rs index 5a9e678618..f8eb6d6735 100644 --- a/lib/text-size/tests/main.rs +++ b/lib/text-size/tests/main.rs @@ -5,7 +5,7 @@ fn size(x: u32) -> TextSize { } fn range(x: ops::Range) -> TextRange { - TextRange(x.start.into(), x.end.into()) + TextRange::new(x.start.into(), x.end.into()) } #[test] diff --git a/lib/text-size/tests/serde.rs b/lib/text-size/tests/serde.rs index a32f89e865..874258a35f 100644 --- a/lib/text-size/tests/serde.rs +++ b/lib/text-size/tests/serde.rs @@ -5,7 +5,7 @@ fn size(x: u32) -> TextSize { } fn range(x: ops::Range) -> TextRange { - TextRange(x.start.into(), x.end.into()) + TextRange::new(x.start.into(), x.end.into()) } #[test]