rustpython_ruff_text_size/
size.rs1use {
2 crate::TextLen,
3 std::{
4 convert::TryFrom,
5 fmt, iter,
6 num::TryFromIntError,
7 ops::{Add, AddAssign, Sub, SubAssign},
8 },
9};
10
11#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
24#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
25pub struct TextSize {
26 pub(crate) raw: u32,
27}
28
29impl fmt::Debug for TextSize {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "{}", self.raw)
32 }
33}
34
35impl TextSize {
36 pub const ZERO: TextSize = TextSize::new(0);
38
39 pub const fn new(offset: u32) -> Self {
48 Self { raw: offset }
49 }
50
51 #[inline]
66 pub fn of<T: TextLen>(text: T) -> TextSize {
67 text.text_len()
68 }
69
70 pub const fn to_u32(&self) -> u32 {
79 self.raw
80 }
81
82 pub const fn to_usize(&self) -> usize {
91 self.raw as usize
92 }
93}
94
95impl TextSize {
98 #[inline]
100 pub fn checked_add(self, rhs: TextSize) -> Option<TextSize> {
101 self.raw.checked_add(rhs.raw).map(|raw| TextSize { raw })
102 }
103
104 #[inline]
106 pub fn checked_sub(self, rhs: TextSize) -> Option<TextSize> {
107 self.raw.checked_sub(rhs.raw).map(|raw| TextSize { raw })
108 }
109
110 #[inline]
112 #[must_use]
113 pub fn saturating_add(self, rhs: TextSize) -> TextSize {
114 TextSize {
115 raw: self.raw.saturating_add(rhs.raw),
116 }
117 }
118
119 #[inline]
122 #[must_use]
123 pub fn saturating_sub(self, rhs: TextSize) -> TextSize {
124 TextSize {
125 raw: self.raw.saturating_sub(rhs.raw),
126 }
127 }
128}
129
130impl From<u32> for TextSize {
131 #[inline]
132 fn from(raw: u32) -> Self {
133 TextSize::new(raw)
134 }
135}
136
137impl From<TextSize> for u32 {
138 #[inline]
139 fn from(value: TextSize) -> Self {
140 value.to_u32()
141 }
142}
143
144impl TryFrom<usize> for TextSize {
145 type Error = TryFromIntError;
146 #[inline]
147 fn try_from(value: usize) -> Result<Self, TryFromIntError> {
148 Ok(u32::try_from(value)?.into())
149 }
150}
151
152impl From<TextSize> for usize {
153 #[inline]
154 fn from(value: TextSize) -> Self {
155 value.to_usize()
156 }
157}
158
159macro_rules! ops {
160 (impl $Op:ident for TextSize by fn $f:ident = $op:tt) => {
161 impl $Op<TextSize> for TextSize {
162 type Output = TextSize;
163 #[inline]
164 fn $f(self, other: TextSize) -> TextSize {
165 TextSize { raw: self.raw $op other.raw }
166 }
167 }
168 impl $Op<&TextSize> for TextSize {
169 type Output = TextSize;
170 #[inline]
171 fn $f(self, other: &TextSize) -> TextSize {
172 self $op *other
173 }
174 }
175 impl<T> $Op<T> for &TextSize
176 where
177 TextSize: $Op<T, Output=TextSize>,
178 {
179 type Output = TextSize;
180 #[inline]
181 fn $f(self, other: T) -> TextSize {
182 *self $op other
183 }
184 }
185 };
186}
187
188ops!(impl Add for TextSize by fn add = +);
189ops!(impl Sub for TextSize by fn sub = -);
190
191impl<A> AddAssign<A> for TextSize
192where
193 TextSize: Add<A, Output = TextSize>,
194{
195 #[inline]
196 fn add_assign(&mut self, rhs: A) {
197 *self = *self + rhs;
198 }
199}
200
201impl<S> SubAssign<S> for TextSize
202where
203 TextSize: Sub<S, Output = TextSize>,
204{
205 #[inline]
206 fn sub_assign(&mut self, rhs: S) {
207 *self = *self - rhs;
208 }
209}
210
211impl<A> iter::Sum<A> for TextSize
212where
213 TextSize: Add<A, Output = TextSize>,
214{
215 #[inline]
216 fn sum<I: Iterator<Item = A>>(iter: I) -> TextSize {
217 iter.fold(0.into(), Add::add)
218 }
219}