file_system/fundamentals/
size.rs1use core::{
8 fmt::{self, Display, Formatter},
9 ops::{Add, AddAssign},
10};
11
12#[derive(Default, PartialOrd, PartialEq, Eq, Ord, Clone, Copy, Debug)]
42#[repr(transparent)]
43pub struct Size(u64);
44
45impl Display for Size {
46 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
47 write!(f, "{}", self.0)
48 }
49}
50
51impl Size {
52 pub const fn new(item: u64) -> Self {
67 Size(item)
68 }
69
70 pub const fn as_u64(&self) -> u64 {
85 self.0
86 }
87}
88
89impl PartialEq<usize> for Size {
90 fn eq(&self, other: &usize) -> bool {
91 self.0 == *other as u64
92 }
93}
94
95impl From<usize> for Size {
96 fn from(item: usize) -> Self {
97 Size(item as u64)
98 }
99}
100
101impl From<u64> for Size {
102 fn from(item: u64) -> Self {
103 Size(item)
104 }
105}
106
107impl From<Size> for usize {
108 fn from(item: Size) -> Self {
109 item.0 as usize
110 }
111}
112
113impl From<Size> for u64 {
114 fn from(item: Size) -> Self {
115 item.0
116 }
117}
118
119impl Add<Size> for Size {
120 type Output = Size;
121
122 fn add(self, rhs: Size) -> Self::Output {
123 Size(self.0 + rhs.0)
124 }
125}
126
127impl Add<usize> for Size {
128 type Output = Size;
129
130 fn add(self, rhs: usize) -> Self::Output {
131 Size(self.0 + rhs as u64)
132 }
133}
134
135impl Add<u64> for Size {
136 type Output = Size;
137
138 fn add(self, rhs: u64) -> Self::Output {
139 Size(self.0 + rhs)
140 }
141}
142
143impl Add<Size> for usize {
144 type Output = Size;
145
146 fn add(self, rhs: Size) -> Self::Output {
147 Size(self as u64 + rhs.0)
148 }
149}
150
151impl Add<Size> for u64 {
152 type Output = Size;
153
154 fn add(self, rhs: Size) -> Self::Output {
155 Size(self + rhs.0)
156 }
157}
158
159impl AddAssign<Size> for Size {
160 fn add_assign(&mut self, rhs: Size) {
161 self.0 += rhs.0;
162 }
163}
164
165impl AddAssign<usize> for Size {
166 fn add_assign(&mut self, rhs: usize) {
167 self.0 += rhs as u64;
168 }
169}
170
171impl AddAssign<u64> for Size {
172 fn add_assign(&mut self, rhs: u64) {
173 self.0 += rhs;
174 }
175}
176
177impl AddAssign<Size> for usize {
178 fn add_assign(&mut self, rhs: Size) {
179 *self += rhs.0 as usize;
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186 use alloc::format;
187
188 #[test]
189 fn test_size_creation() {
190 let size = Size::new(1024);
191 assert_eq!(size.as_u64(), 1024);
192 }
193
194 #[test]
195 fn test_size_default() {
196 let size = Size::default();
197 assert_eq!(size.as_u64(), 0);
198 }
199
200 #[test]
201 fn test_size_conversions() {
202 let size_from_usize: Size = 512usize.into();
204 assert_eq!(size_from_usize.as_u64(), 512);
205
206 let size_from_u64: Size = 1024u64.into();
208 assert_eq!(size_from_u64.as_u64(), 1024);
209
210 let as_usize: usize = size_from_u64.into();
212 assert_eq!(as_usize, 1024);
213
214 let as_u64: u64 = size_from_u64.into();
216 assert_eq!(as_u64, 1024);
217 }
218
219 #[test]
220 fn test_size_equality() {
221 let size1 = Size::new(100);
222 let size2 = Size::new(100);
223 let size3 = Size::new(200);
224
225 assert_eq!(size1, size2);
226 assert_ne!(size1, size3);
227
228 assert_eq!(size1, 100usize);
230 assert_ne!(size1, 200usize);
231 }
232
233 #[test]
234 fn test_size_comparison() {
235 let small = Size::new(100);
236 let large = Size::new(200);
237
238 assert!(small < large);
239 assert!(large > small);
240 assert!(small <= large);
241 assert!(large >= small);
242 assert!(small <= small);
243 assert!(large >= large);
244 }
245
246 #[test]
247 fn test_size_addition_with_size() {
248 let size1 = Size::new(100);
249 let size2 = Size::new(200);
250 let result = size1 + size2;
251 assert_eq!(result.as_u64(), 300);
252 }
253
254 #[test]
255 fn test_size_addition_with_usize() {
256 let size = Size::new(100);
257 let result = size + 50usize;
258 assert_eq!(result.as_u64(), 150);
259
260 let result2 = 50usize + size;
262 assert_eq!(result2.as_u64(), 150);
263 }
264
265 #[test]
266 fn test_size_addition_with_u64() {
267 let size = Size::new(100);
268 let result = size + 75u64;
269 assert_eq!(result.as_u64(), 175);
270
271 let result2 = 75u64 + size;
273 assert_eq!(result2.as_u64(), 175);
274 }
275
276 #[test]
277 fn test_size_add_assign_with_size() {
278 let mut size = Size::new(100);
279 let other = Size::new(50);
280 size += other;
281 assert_eq!(size.as_u64(), 150);
282 }
283
284 #[test]
285 fn test_size_add_assign_with_usize() {
286 let mut size = Size::new(100);
287 size += 25usize;
288 assert_eq!(size.as_u64(), 125);
289
290 let mut value = 100usize;
292 value += Size::new(25);
293 assert_eq!(value, 125);
294 }
295
296 #[test]
297 fn test_size_add_assign_with_u64() {
298 let mut size = Size::new(100);
299 size += 30u64;
300 assert_eq!(size.as_u64(), 130);
301 }
302
303 #[test]
304 fn test_size_display() {
305 let size = Size::new(12345);
306 let display_str = format!("{size}");
307 assert_eq!(display_str, "12345");
308 }
309
310 #[test]
311 fn test_size_debug() {
312 let size = Size::new(67890);
313 let debug_str = format!("{size:?}");
314 assert_eq!(debug_str, "Size(67890)");
315 }
316
317 #[test]
318 fn test_size_clone_copy() {
319 let original = Size::new(999);
320 let cloned = original;
321 let copied = original;
322
323 assert_eq!(original, cloned);
324 assert_eq!(original, copied);
325 assert_eq!(cloned, copied);
326
327 assert_eq!(original.as_u64(), 999);
329 }
330
331 #[test]
332 fn test_size_zero() {
333 let zero = Size::new(0);
334 assert_eq!(zero.as_u64(), 0);
335 assert_eq!(zero, 0usize);
336 assert_eq!(zero, Size::default());
337 }
338
339 #[test]
340 fn test_size_max_value() {
341 let max_size = Size::new(u64::MAX);
342 assert_eq!(max_size.as_u64(), u64::MAX);
343 }
344
345 #[test]
346 fn test_size_arithmetic_overflow_safety() {
347 let large1 = Size::new(u64::MAX / 2);
349 let large2 = Size::new(u64::MAX / 2);
350
351 let _ = large1 + large2; }
355
356 #[test]
357 fn test_size_type_safety() {
358 use core::mem::{align_of, size_of};
360
361 assert_eq!(size_of::<Size>(), size_of::<u64>());
362 assert_eq!(align_of::<Size>(), align_of::<u64>());
363 }
364
365 #[test]
366 fn test_size_const_operations() {
367 const SIZE: Size = Size::new(42);
369 const VALUE: u64 = SIZE.as_u64();
370
371 assert_eq!(VALUE, 42);
372 assert_eq!(SIZE.as_u64(), 42);
373 }
374
375 #[test]
376 fn test_size_mixed_arithmetic() {
377 let size = Size::new(100);
378
379 let result = size + 50usize + 25u64 + Size::new(10);
381 assert_eq!(result.as_u64(), 185);
382 }
383
384 #[test]
385 fn test_size_compound_assignments() {
386 let mut size = Size::new(10);
387
388 size += 5usize;
389 size += 3u64;
390 size += Size::new(2);
391
392 assert_eq!(size.as_u64(), 20);
393 }
394
395 #[test]
396 fn test_size_comparison_edge_cases() {
397 let zero = Size::new(0);
398 let one = Size::new(1);
399 let max = Size::new(u64::MAX);
400
401 assert!(zero < one);
402 assert!(one < max);
403 assert!(zero < max);
404
405 assert!(max > one);
406 assert!(one > zero);
407 assert!(max > zero);
408 }
409
410 #[test]
411 fn test_size_conversion_edge_cases() {
412 let max_usize_as_size: Size = usize::MAX.into();
414 let back_to_usize: usize = max_usize_as_size.into();
415
416 if core::mem::size_of::<usize>() == 8 {
419 assert_eq!(back_to_usize, usize::MAX);
420 }
421 }
422
423 #[test]
424 fn test_size_ordering() {
425 let mut sizes = [
426 Size::new(300),
427 Size::new(100),
428 Size::new(200),
429 Size::new(50),
430 ];
431
432 sizes.sort();
433
434 assert_eq!(sizes[0], Size::new(50));
435 assert_eq!(sizes[1], Size::new(100));
436 assert_eq!(sizes[2], Size::new(200));
437 assert_eq!(sizes[3], Size::new(300));
438 }
439}