1use {
2 crate::TextLen,
3 std::{
4 convert::TryFrom,
5 fmt, iter,
6 num::TryFromIntError,
7 ops::{Add, AddAssign, Sub, SubAssign},
8 u32,
9 },
10};
11
12#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
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 #[inline]
38 pub const fn new(raw: u32) -> TextSize {
39 TextSize { raw }
40 }
41
42 #[inline]
57 pub fn of<T: TextLen>(text: T) -> TextSize {
58 text.text_len()
59 }
60}
61
62impl TextSize {
65 #[inline]
67 pub const fn checked_add(self, rhs: TextSize) -> Option<TextSize> {
68 match self.raw.checked_add(rhs.raw) {
69 Some(raw) => Some(TextSize { raw }),
70 None => None,
71 }
72 }
73
74 #[inline]
76 pub const fn checked_sub(self, rhs: TextSize) -> Option<TextSize> {
77 match self.raw.checked_sub(rhs.raw) {
78 Some(raw) => Some(TextSize { raw }),
79 None => None,
80 }
81 }
82}
83
84impl From<u32> for TextSize {
85 #[inline]
86 fn from(raw: u32) -> Self {
87 TextSize { raw }
88 }
89}
90
91impl From<TextSize> for u32 {
92 #[inline]
93 fn from(value: TextSize) -> Self {
94 value.raw
95 }
96}
97
98impl TryFrom<usize> for TextSize {
99 type Error = TryFromIntError;
100 #[inline]
101 fn try_from(value: usize) -> Result<Self, TryFromIntError> {
102 Ok(u32::try_from(value)?.into())
103 }
104}
105
106impl From<TextSize> for usize {
107 #[inline]
108 fn from(value: TextSize) -> Self {
109 value.raw as usize
110 }
111}
112
113macro_rules! ops {
114 (impl $Op:ident for TextSize by fn $f:ident = $op:tt) => {
115 impl $Op<TextSize> for TextSize {
116 type Output = TextSize;
117 #[inline]
118 fn $f(self, other: TextSize) -> TextSize {
119 TextSize { raw: self.raw $op other.raw }
120 }
121 }
122 impl $Op<&TextSize> for TextSize {
123 type Output = TextSize;
124 #[inline]
125 fn $f(self, other: &TextSize) -> TextSize {
126 self $op *other
127 }
128 }
129 impl<T> $Op<T> for &TextSize
130 where
131 TextSize: $Op<T, Output=TextSize>,
132 {
133 type Output = TextSize;
134 #[inline]
135 fn $f(self, other: T) -> TextSize {
136 *self $op other
137 }
138 }
139 };
140}
141
142ops!(impl Add for TextSize by fn add = +);
143ops!(impl Sub for TextSize by fn sub = -);
144
145impl<A> AddAssign<A> for TextSize
146where
147 TextSize: Add<A, Output = TextSize>,
148{
149 #[inline]
150 fn add_assign(&mut self, rhs: A) {
151 *self = *self + rhs
152 }
153}
154
155impl<S> SubAssign<S> for TextSize
156where
157 TextSize: Sub<S, Output = TextSize>,
158{
159 #[inline]
160 fn sub_assign(&mut self, rhs: S) {
161 *self = *self - rhs
162 }
163}
164
165impl<A> iter::Sum<A> for TextSize
166where
167 TextSize: Add<A, Output = TextSize>,
168{
169 #[inline]
170 fn sum<I: Iterator<Item = A>>(iter: I) -> TextSize {
171 iter.fold(0.into(), Add::add)
172 }
173}