Skip to main content

ps_uuid/implementations/
from_int.rs

1use std::num::TryFromIntError;
2
3use crate::UUID;
4
5// ---------------------------------------------------------------------------
6// Into UUID: every integer widens to u128/i128, then big-endian encodes.
7// ---------------------------------------------------------------------------
8
9impl From<u128> for UUID {
10    fn from(v: u128) -> Self {
11        Self::from_u128(v)
12    }
13}
14
15impl From<i128> for UUID {
16    fn from(v: i128) -> Self {
17        Self::from(v.cast_unsigned())
18    }
19}
20
21macro_rules! impl_from_small_unsigned {
22    ($($t:ty),*) => { $(
23        impl From<$t> for UUID {
24            fn from(v: $t) -> Self {
25                Self::from_u128(u128::from(v))
26            }
27        }
28    )* };
29}
30
31macro_rules! impl_from_small_signed {
32    ($($t:ty),*) => { $(
33        impl From<$t> for UUID {
34            fn from(v: $t) -> Self {
35                Self::from(i128::from(v))
36            }
37        }
38    )* };
39}
40
41impl_from_small_unsigned!(u8, u16, u32, u64);
42impl_from_small_signed!(i8, i16, i32, i64);
43
44impl From<usize> for UUID {
45    fn from(v: usize) -> Self {
46        Self::from_u128(v as u128)
47    }
48}
49
50impl From<isize> for UUID {
51    fn from(v: isize) -> Self {
52        Self::from_u128((v as i128).cast_unsigned())
53    }
54}
55
56// ---------------------------------------------------------------------------
57// From UUID: only 128-bit integers get infallible From.
58// ---------------------------------------------------------------------------
59
60impl From<UUID> for u128 {
61    fn from(uuid: UUID) -> Self {
62        uuid.to_u128()
63    }
64}
65
66impl From<UUID> for i128 {
67    fn from(uuid: UUID) -> Self {
68        uuid.to_u128().cast_signed()
69    }
70}
71
72// ---------------------------------------------------------------------------
73// From UUID: smaller integers get TryFrom, delegating to TryFrom<u128>.
74// ---------------------------------------------------------------------------
75
76macro_rules! impl_try_from_uuid_unsigned {
77    ($($t:ty),*) => { $(
78        impl TryFrom<UUID> for $t {
79            type Error = TryFromIntError;
80
81            fn try_from(uuid: UUID) -> Result<Self, Self::Error> {
82                <$t>::try_from(uuid.to_u128())
83            }
84        }
85    )* };
86}
87
88macro_rules! impl_try_from_uuid_signed {
89    ($($t:ty),*) => { $(
90        impl TryFrom<UUID> for $t {
91            type Error = TryFromIntError;
92
93            fn try_from(uuid: UUID) -> Result<Self, Self::Error> {
94                <$t>::try_from(i128::from(uuid))
95            }
96        }
97    )* };
98}
99
100impl_try_from_uuid_unsigned!(u8, u16, u32, u64, usize);
101impl_try_from_uuid_signed!(i8, i16, i32, i64, isize);
102
103#[cfg(test)]
104mod tests {
105    #![allow(clippy::expect_used)]
106    use super::*;
107
108    // -----------------------------------------------------------------------
109    // u128 <-> UUID
110    // -----------------------------------------------------------------------
111
112    #[test]
113    fn u128_zero() {
114        let uuid = UUID::from(0u128);
115        assert_eq!(uuid, UUID::nil());
116        assert_eq!(u128::from(uuid), 0);
117    }
118
119    #[test]
120    fn u128_one() {
121        let uuid = UUID::from(1u128);
122        assert_eq!(u128::from(uuid), 1);
123    }
124
125    #[test]
126    fn u128_max() {
127        let uuid = UUID::from(u128::MAX);
128        assert_eq!(uuid, UUID::max());
129        assert_eq!(u128::from(uuid), u128::MAX);
130    }
131
132    #[test]
133    fn u128_roundtrip() {
134        let v: u128 = 0x0123_4567_89ab_cdef_0123_4567_89ab_cdef;
135        let uuid = UUID::from(v);
136        assert_eq!(u128::from(uuid), v);
137    }
138
139    // -----------------------------------------------------------------------
140    // i128 <-> UUID
141    // -----------------------------------------------------------------------
142
143    #[test]
144    fn i128_zero() {
145        let uuid = UUID::from(0i128);
146        assert_eq!(uuid, UUID::nil());
147        assert_eq!(i128::from(uuid), 0);
148    }
149
150    #[test]
151    fn i128_one() {
152        let uuid = UUID::from(1i128);
153        assert_eq!(i128::from(uuid), 1);
154    }
155
156    #[test]
157    fn i128_minus_one() {
158        let uuid = UUID::from(-1i128);
159        assert_eq!(uuid, UUID::max());
160        assert_eq!(i128::from(uuid), -1);
161    }
162
163    #[test]
164    fn i128_min() {
165        let uuid = UUID::from(i128::MIN);
166        assert_eq!(i128::from(uuid), i128::MIN);
167        // i128::MIN is 0x8000..00, so the high bit is set
168        assert_eq!(uuid.as_bytes()[0], 0x80);
169        assert!(uuid.as_bytes()[1..].iter().all(|&b| b == 0));
170    }
171
172    #[test]
173    fn i128_max() {
174        let uuid = UUID::from(i128::MAX);
175        assert_eq!(i128::from(uuid), i128::MAX);
176        assert_eq!(uuid.as_bytes()[0], 0x7F);
177        assert!(uuid.as_bytes()[1..].iter().all(|&b| b == 0xFF));
178    }
179
180    #[test]
181    fn i128_roundtrip_negative() {
182        let v: i128 = -0x0123_4567_89ab_cdef_0123_4567_89ab_cdef;
183        let uuid = UUID::from(v);
184        assert_eq!(i128::from(uuid), v);
185    }
186
187    // -----------------------------------------------------------------------
188    // Big-endian byte layout
189    // -----------------------------------------------------------------------
190
191    #[test]
192    fn big_endian_one() {
193        let uuid = UUID::from(1u128);
194        let bytes = uuid.as_bytes();
195        assert!(bytes[..15].iter().all(|&b| b == 0));
196        assert_eq!(bytes[15], 1);
197    }
198
199    #[test]
200    fn big_endian_high_bit() {
201        let uuid = UUID::from(1u128 << 127);
202        let bytes = uuid.as_bytes();
203        assert_eq!(bytes[0], 0x80);
204        assert!(bytes[1..].iter().all(|&b| b == 0));
205    }
206
207    #[test]
208    fn big_endian_known_pattern() {
209        let v: u128 = 0x0011_2233_4455_6677_8899_aabb_ccdd_eeff;
210        let uuid = UUID::from(v);
211        assert_eq!(
212            *uuid.as_bytes(),
213            [
214                0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
215                0xee, 0xff
216            ]
217        );
218    }
219
220    // -----------------------------------------------------------------------
221    // From<small unsigned> for UUID
222    // -----------------------------------------------------------------------
223
224    #[test]
225    fn from_u8_zero() {
226        assert_eq!(u128::from(UUID::from(0u8)), 0);
227    }
228
229    #[test]
230    fn from_u8_max() {
231        assert_eq!(u128::from(UUID::from(u8::MAX)), u128::from(u8::MAX));
232    }
233
234    #[test]
235    fn from_u16_zero() {
236        assert_eq!(u128::from(UUID::from(0u16)), 0);
237    }
238
239    #[test]
240    fn from_u16_max() {
241        assert_eq!(u128::from(UUID::from(u16::MAX)), u128::from(u16::MAX));
242    }
243
244    #[test]
245    fn from_u32_zero() {
246        assert_eq!(u128::from(UUID::from(0u32)), 0);
247    }
248
249    #[test]
250    fn from_u32_max() {
251        assert_eq!(u128::from(UUID::from(u32::MAX)), u128::from(u32::MAX));
252    }
253
254    #[test]
255    fn from_u64_zero() {
256        assert_eq!(u128::from(UUID::from(0u64)), 0);
257    }
258
259    #[test]
260    fn from_u64_max() {
261        assert_eq!(u128::from(UUID::from(u64::MAX)), u128::from(u64::MAX));
262    }
263
264    #[test]
265    fn from_usize_zero() {
266        assert_eq!(u128::from(UUID::from(0usize)), 0);
267    }
268
269    #[test]
270    fn from_usize_max() {
271        assert_eq!(u128::from(UUID::from(usize::MAX)), usize::MAX as u128);
272    }
273
274    // -----------------------------------------------------------------------
275    // From<small signed> for UUID — sign extension
276    // -----------------------------------------------------------------------
277
278    #[test]
279    fn from_i8_zero() {
280        assert_eq!(UUID::from(0i8), UUID::nil());
281    }
282
283    #[test]
284    fn from_i8_one() {
285        assert_eq!(u128::from(UUID::from(1i8)), 1);
286    }
287
288    #[test]
289    fn from_i8_minus_one() {
290        // -1i8 sign-extends through i128 to u128::MAX
291        assert_eq!(UUID::from(-1i8), UUID::max());
292    }
293
294    #[test]
295    fn from_i8_min() {
296        assert_eq!(i128::from(UUID::from(i8::MIN)), i128::from(i8::MIN));
297    }
298
299    #[test]
300    fn from_i8_max() {
301        assert_eq!(u128::from(UUID::from(i8::MAX)), i8::MAX as u128);
302    }
303
304    #[test]
305    fn from_i16_minus_one() {
306        assert_eq!(UUID::from(-1i16), UUID::max());
307    }
308
309    #[test]
310    fn from_i16_min() {
311        assert_eq!(i128::from(UUID::from(i16::MIN)), i128::from(i16::MIN));
312    }
313
314    #[test]
315    fn from_i16_max() {
316        assert_eq!(u128::from(UUID::from(i16::MAX)), i16::MAX as u128);
317    }
318
319    #[test]
320    fn from_i32_minus_one() {
321        assert_eq!(UUID::from(-1i32), UUID::max());
322    }
323
324    #[test]
325    fn from_i32_min() {
326        assert_eq!(i128::from(UUID::from(i32::MIN)), i128::from(i32::MIN));
327    }
328
329    #[test]
330    fn from_i32_max() {
331        assert_eq!(u128::from(UUID::from(i32::MAX)), i32::MAX as u128);
332    }
333
334    #[test]
335    fn from_i64_minus_one() {
336        assert_eq!(UUID::from(-1i64), UUID::max());
337    }
338
339    #[test]
340    fn from_i64_min() {
341        assert_eq!(i128::from(UUID::from(i64::MIN)), i128::from(i64::MIN));
342    }
343
344    #[test]
345    fn from_i64_max() {
346        assert_eq!(u128::from(UUID::from(i64::MAX)), i64::MAX as u128);
347    }
348
349    #[test]
350    fn from_isize_minus_one() {
351        assert_eq!(UUID::from(-1isize), UUID::max());
352    }
353
354    #[test]
355    fn from_isize_min() {
356        assert_eq!(i128::from(UUID::from(isize::MIN)), isize::MIN as i128);
357    }
358
359    #[test]
360    fn from_isize_max() {
361        assert_eq!(u128::from(UUID::from(isize::MAX)), isize::MAX as u128);
362    }
363
364    // -----------------------------------------------------------------------
365    // All negative signed values produce all-FF high bytes (sign extension)
366    // -----------------------------------------------------------------------
367
368    #[test]
369    fn sign_extension_fills_high_bytes_i8() {
370        let uuid = UUID::from(-2i8);
371        // -2i8 as i128 = -2, as u128 = u128::MAX - 1 = 0xFFFF...FFFE
372        assert!(uuid.as_bytes()[..15].iter().all(|&b| b == 0xFF));
373        assert_eq!(uuid.as_bytes()[15], 0xFE);
374    }
375
376    #[test]
377    fn sign_extension_fills_high_bytes_i16() {
378        let uuid = UUID::from(-256i16);
379        // -256i16 as i128 = -256, as u128 = 0xFFFF...FF00
380        assert!(uuid.as_bytes()[..14].iter().all(|&b| b == 0xFF));
381        assert_eq!(uuid.as_bytes()[14], 0xFF);
382        assert_eq!(uuid.as_bytes()[15], 0x00);
383    }
384
385    #[test]
386    fn sign_extension_fills_high_bytes_i32() {
387        let uuid = UUID::from(i32::MIN);
388        // i32::MIN = -2147483648 => 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_8000_0000
389        assert!(uuid.as_bytes()[..12].iter().all(|&b| b == 0xFF));
390        assert_eq!(uuid.as_bytes()[12], 0x80);
391        assert!(uuid.as_bytes()[13..].iter().all(|&b| b == 0x00));
392    }
393
394    #[test]
395    fn sign_extension_fills_high_bytes_i64() {
396        let uuid = UUID::from(i64::MIN);
397        // i64::MIN => 0xFFFF_FFFF_FFFF_FFFF_8000_0000_0000_0000
398        assert!(uuid.as_bytes()[..8].iter().all(|&b| b == 0xFF));
399        assert_eq!(uuid.as_bytes()[8], 0x80);
400        assert!(uuid.as_bytes()[9..].iter().all(|&b| b == 0x00));
401    }
402
403    // -----------------------------------------------------------------------
404    // Positive signed values zero-extend (no high-byte contamination)
405    // -----------------------------------------------------------------------
406
407    #[test]
408    fn positive_signed_zero_extends_i8() {
409        let uuid = UUID::from(i8::MAX);
410        assert!(uuid.as_bytes()[..15].iter().all(|&b| b == 0));
411        assert_eq!(uuid.as_bytes()[15], 0x7F);
412    }
413
414    #[test]
415    fn positive_signed_zero_extends_i64() {
416        let uuid = UUID::from(1i64);
417        assert!(uuid.as_bytes()[..15].iter().all(|&b| b == 0));
418        assert_eq!(uuid.as_bytes()[15], 1);
419    }
420
421    // -----------------------------------------------------------------------
422    // TryFrom<UUID> for u8: boundary
423    // -----------------------------------------------------------------------
424
425    #[test]
426    fn try_from_uuid_u8_zero() {
427        assert_eq!(
428            u8::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
429            0
430        );
431    }
432
433    #[test]
434    fn try_from_uuid_u8_max() {
435        assert_eq!(
436            u8::try_from(UUID::from(u128::from(u8::MAX)))
437                .expect("in-range UUID conversion to integer should succeed"),
438            u8::MAX
439        );
440    }
441
442    #[test]
443    fn try_from_uuid_u8_max_plus_one() {
444        assert!(u8::try_from(UUID::from(u128::from(u8::MAX) + 1)).is_err());
445    }
446
447    // -----------------------------------------------------------------------
448    // TryFrom<UUID> for u16: boundary
449    // -----------------------------------------------------------------------
450
451    #[test]
452    fn try_from_uuid_u16_zero() {
453        assert_eq!(
454            u16::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
455            0
456        );
457    }
458
459    #[test]
460    fn try_from_uuid_u16_max() {
461        assert_eq!(
462            u16::try_from(UUID::from(u128::from(u16::MAX)))
463                .expect("in-range UUID conversion to integer should succeed"),
464            u16::MAX
465        );
466    }
467
468    #[test]
469    fn try_from_uuid_u16_max_plus_one() {
470        assert!(u16::try_from(UUID::from(u128::from(u16::MAX) + 1)).is_err());
471    }
472
473    // -----------------------------------------------------------------------
474    // TryFrom<UUID> for u32: boundary
475    // -----------------------------------------------------------------------
476
477    #[test]
478    fn try_from_uuid_u32_zero() {
479        assert_eq!(
480            u32::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
481            0
482        );
483    }
484
485    #[test]
486    fn try_from_uuid_u32_max() {
487        assert_eq!(
488            u32::try_from(UUID::from(u128::from(u32::MAX)))
489                .expect("in-range UUID conversion to integer should succeed"),
490            u32::MAX
491        );
492    }
493
494    #[test]
495    fn try_from_uuid_u32_max_plus_one() {
496        assert!(u32::try_from(UUID::from(u128::from(u32::MAX) + 1)).is_err());
497    }
498
499    // -----------------------------------------------------------------------
500    // TryFrom<UUID> for u64: boundary
501    // -----------------------------------------------------------------------
502
503    #[test]
504    fn try_from_uuid_u64_zero() {
505        assert_eq!(
506            u64::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
507            0
508        );
509    }
510
511    #[test]
512    fn try_from_uuid_u64_max() {
513        assert_eq!(
514            u64::try_from(UUID::from(u128::from(u64::MAX)))
515                .expect("in-range UUID conversion to integer should succeed"),
516            u64::MAX
517        );
518    }
519
520    #[test]
521    fn try_from_uuid_u64_max_plus_one() {
522        assert!(u64::try_from(UUID::from(u128::from(u64::MAX) + 1)).is_err());
523    }
524
525    // -----------------------------------------------------------------------
526    // TryFrom<UUID> for usize: boundary
527    // -----------------------------------------------------------------------
528
529    #[test]
530    fn try_from_uuid_usize_zero() {
531        assert_eq!(
532            usize::try_from(UUID::nil())
533                .expect("in-range UUID conversion to integer should succeed"),
534            0
535        );
536    }
537
538    #[test]
539    fn try_from_uuid_usize_max() {
540        assert_eq!(
541            usize::try_from(UUID::from(usize::MAX as u128))
542                .expect("in-range UUID conversion to integer should succeed"),
543            usize::MAX
544        );
545    }
546
547    #[test]
548    fn try_from_uuid_usize_overflow() {
549        // usize::MAX as u128 + 1 overflows usize on any platform
550        assert!(usize::try_from(UUID::from(usize::MAX as u128 + 1)).is_err());
551    }
552
553    // -----------------------------------------------------------------------
554    // TryFrom<UUID> for i8: boundary
555    // -----------------------------------------------------------------------
556
557    #[test]
558    fn try_from_uuid_i8_zero() {
559        assert_eq!(
560            i8::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
561            0
562        );
563    }
564
565    #[test]
566    fn try_from_uuid_i8_max() {
567        assert_eq!(
568            i8::try_from(UUID::from(i8::MAX as u128))
569                .expect("in-range UUID conversion to integer should succeed"),
570            i8::MAX
571        );
572    }
573
574    #[test]
575    fn try_from_uuid_i8_max_plus_one() {
576        // 128 doesn't fit in i8
577        assert!(i8::try_from(UUID::from(i8::MAX as u128 + 1)).is_err());
578    }
579
580    #[test]
581    fn try_from_uuid_i8_from_negative() {
582        // A UUID built from -1i8 has u128 value u128::MAX, which via i128
583        // is -1, which fits in i8.
584        let uuid = UUID::from(-1i8);
585        assert_eq!(
586            i8::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
587            -1
588        );
589    }
590
591    #[test]
592    fn try_from_uuid_i8_from_i8_min() {
593        // UUID from i8::MIN round-trips back through i128 -> i8
594        let uuid = UUID::from(i8::MIN);
595        assert_eq!(
596            i8::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
597            i8::MIN
598        );
599    }
600
601    // -----------------------------------------------------------------------
602    // TryFrom<UUID> for i16: boundary
603    // -----------------------------------------------------------------------
604
605    #[test]
606    fn try_from_uuid_i16_zero() {
607        assert_eq!(
608            i16::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
609            0
610        );
611    }
612
613    #[test]
614    fn try_from_uuid_i16_max() {
615        assert_eq!(
616            i16::try_from(UUID::from(i16::MAX as u128))
617                .expect("in-range UUID conversion to integer should succeed"),
618            i16::MAX
619        );
620    }
621
622    #[test]
623    fn try_from_uuid_i16_max_plus_one() {
624        assert!(i16::try_from(UUID::from(i16::MAX as u128 + 1)).is_err());
625    }
626
627    #[test]
628    fn try_from_uuid_i16_from_negative() {
629        let uuid = UUID::from(-1i16);
630        assert_eq!(
631            i16::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
632            -1
633        );
634    }
635
636    #[test]
637    fn try_from_uuid_i16_from_i16_min() {
638        let uuid = UUID::from(i16::MIN);
639        assert_eq!(
640            i16::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
641            i16::MIN
642        );
643    }
644
645    // -----------------------------------------------------------------------
646    // TryFrom<UUID> for i32: boundary
647    // -----------------------------------------------------------------------
648
649    #[test]
650    fn try_from_uuid_i32_zero() {
651        assert_eq!(
652            i32::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
653            0
654        );
655    }
656
657    #[test]
658    fn try_from_uuid_i32_max() {
659        assert_eq!(
660            i32::try_from(UUID::from(i32::MAX as u128))
661                .expect("in-range UUID conversion to integer should succeed"),
662            i32::MAX
663        );
664    }
665
666    #[test]
667    fn try_from_uuid_i32_max_plus_one() {
668        assert!(i32::try_from(UUID::from(i32::MAX as u128 + 1)).is_err());
669    }
670
671    #[test]
672    fn try_from_uuid_i32_from_negative() {
673        let uuid = UUID::from(-1i32);
674        assert_eq!(
675            i32::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
676            -1
677        );
678    }
679
680    #[test]
681    fn try_from_uuid_i32_from_i32_min() {
682        let uuid = UUID::from(i32::MIN);
683        assert_eq!(
684            i32::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
685            i32::MIN
686        );
687    }
688
689    // -----------------------------------------------------------------------
690    // TryFrom<UUID> for i64: boundary
691    // -----------------------------------------------------------------------
692
693    #[test]
694    fn try_from_uuid_i64_zero() {
695        assert_eq!(
696            i64::try_from(UUID::nil()).expect("in-range UUID conversion to integer should succeed"),
697            0
698        );
699    }
700
701    #[test]
702    fn try_from_uuid_i64_max() {
703        assert_eq!(
704            i64::try_from(UUID::from(i64::MAX as u128))
705                .expect("in-range UUID conversion to integer should succeed"),
706            i64::MAX
707        );
708    }
709
710    #[test]
711    fn try_from_uuid_i64_max_plus_one() {
712        assert!(i64::try_from(UUID::from(i64::MAX as u128 + 1)).is_err());
713    }
714
715    #[test]
716    fn try_from_uuid_i64_from_negative() {
717        let uuid = UUID::from(-1i64);
718        assert_eq!(
719            i64::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
720            -1
721        );
722    }
723
724    #[test]
725    fn try_from_uuid_i64_from_i64_min() {
726        let uuid = UUID::from(i64::MIN);
727        assert_eq!(
728            i64::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
729            i64::MIN
730        );
731    }
732
733    // -----------------------------------------------------------------------
734    // TryFrom<UUID> for isize: boundary
735    // -----------------------------------------------------------------------
736
737    #[test]
738    fn try_from_uuid_isize_zero() {
739        assert_eq!(
740            isize::try_from(UUID::nil())
741                .expect("in-range UUID conversion to integer should succeed"),
742            0
743        );
744    }
745
746    #[test]
747    fn try_from_uuid_isize_max() {
748        assert_eq!(
749            isize::try_from(UUID::from(isize::MAX as u128))
750                .expect("in-range UUID conversion to integer should succeed"),
751            isize::MAX
752        );
753    }
754
755    #[test]
756    fn try_from_uuid_isize_overflow() {
757        assert!(isize::try_from(UUID::from(isize::MAX as u128 + 1)).is_err());
758    }
759
760    #[test]
761    fn try_from_uuid_isize_from_negative() {
762        let uuid = UUID::from(-1isize);
763        assert_eq!(
764            isize::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
765            -1
766        );
767    }
768
769    #[test]
770    fn try_from_uuid_isize_from_isize_min() {
771        let uuid = UUID::from(isize::MIN);
772        assert_eq!(
773            isize::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
774            isize::MIN
775        );
776    }
777
778    // -----------------------------------------------------------------------
779    // TryFrom<UUID> for small types rejects UUID::max()
780    // -----------------------------------------------------------------------
781
782    #[test]
783    fn try_from_max_uuid_fails_u8() {
784        assert!(u8::try_from(UUID::max()).is_err());
785    }
786
787    #[test]
788    fn try_from_max_uuid_fails_u16() {
789        assert!(u16::try_from(UUID::max()).is_err());
790    }
791
792    #[test]
793    fn try_from_max_uuid_fails_u32() {
794        assert!(u32::try_from(UUID::max()).is_err());
795    }
796
797    #[test]
798    fn try_from_max_uuid_fails_u64() {
799        assert!(u64::try_from(UUID::max()).is_err());
800    }
801
802    #[test]
803    fn try_from_max_uuid_fails_usize() {
804        assert!(usize::try_from(UUID::max()).is_err());
805    }
806
807    // -----------------------------------------------------------------------
808    // TryFrom<UUID> for small signed: UUID holding a large positive u128
809    // that doesn't fit in the signed i128 interpretation either
810    // -----------------------------------------------------------------------
811
812    #[test]
813    fn try_from_uuid_i8_large_positive() {
814        // u128 value 1000 — i128 is 1000, doesn't fit in i8
815        assert!(i8::try_from(UUID::from(1000u128)).is_err());
816    }
817
818    #[test]
819    fn try_from_uuid_i16_large_positive() {
820        assert!(i16::try_from(UUID::from(100_000u128)).is_err());
821    }
822
823    #[test]
824    fn try_from_uuid_i32_large_positive() {
825        assert!(i32::try_from(UUID::from(u128::from(u32::MAX))).is_err());
826    }
827
828    // -----------------------------------------------------------------------
829    // Signed roundtrips: From<signed> then TryFrom back
830    // -----------------------------------------------------------------------
831
832    #[test]
833    fn signed_roundtrip_i8() {
834        for v in [i8::MIN, -42, -1, 0, 1, 42, i8::MAX] {
835            let uuid = UUID::from(v);
836            assert_eq!(
837                i8::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
838                v,
839                "roundtrip failed for {v}"
840            );
841        }
842    }
843
844    #[test]
845    fn signed_roundtrip_i16() {
846        for v in [i16::MIN, -1000, -1, 0, 1, 1000, i16::MAX] {
847            let uuid = UUID::from(v);
848            assert_eq!(
849                i16::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
850                v,
851                "roundtrip failed for {v}"
852            );
853        }
854    }
855
856    #[test]
857    fn signed_roundtrip_i32() {
858        for v in [i32::MIN, -100_000, -1, 0, 1, 100_000, i32::MAX] {
859            let uuid = UUID::from(v);
860            assert_eq!(
861                i32::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
862                v,
863                "roundtrip failed for {v}"
864            );
865        }
866    }
867
868    #[test]
869    fn signed_roundtrip_i64() {
870        for v in [i64::MIN, -1_000_000_000, -1, 0, 1, 1_000_000_000, i64::MAX] {
871            let uuid = UUID::from(v);
872            assert_eq!(
873                i64::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
874                v,
875                "roundtrip failed for {v}"
876            );
877        }
878    }
879
880    // -----------------------------------------------------------------------
881    // Unsigned roundtrips: From<unsigned> then TryFrom back
882    // -----------------------------------------------------------------------
883
884    #[test]
885    fn unsigned_roundtrip_u8() {
886        for v in [0u8, 1, 127, 128, u8::MAX] {
887            let uuid = UUID::from(v);
888            assert_eq!(
889                u8::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
890                v,
891                "roundtrip failed for {v}"
892            );
893        }
894    }
895
896    #[test]
897    fn unsigned_roundtrip_u16() {
898        for v in [0u16, 1, 255, 256, u16::MAX] {
899            let uuid = UUID::from(v);
900            assert_eq!(
901                u16::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
902                v,
903                "roundtrip failed for {v}"
904            );
905        }
906    }
907
908    #[test]
909    fn unsigned_roundtrip_u32() {
910        for v in [
911            0u32,
912            1,
913            u32::from(u16::MAX),
914            u32::from(u16::MAX) + 1,
915            u32::MAX,
916        ] {
917            let uuid = UUID::from(v);
918            assert_eq!(
919                u32::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
920                v,
921                "roundtrip failed for {v}"
922            );
923        }
924    }
925
926    #[test]
927    fn unsigned_roundtrip_u64() {
928        for v in [
929            0u64,
930            1,
931            u64::from(u32::MAX),
932            u64::from(u32::MAX) + 1,
933            u64::MAX,
934        ] {
935            let uuid = UUID::from(v);
936            assert_eq!(
937                u64::try_from(uuid).expect("in-range UUID conversion to integer should succeed"),
938                v,
939                "roundtrip failed for {v}"
940            );
941        }
942    }
943
944    // -----------------------------------------------------------------------
945    // Same integer value via different source types produces same UUID
946    // -----------------------------------------------------------------------
947
948    #[test]
949    fn same_value_same_uuid_unsigned() {
950        let v = 42u128;
951        assert_eq!(UUID::from(42u8), UUID::from(v));
952        assert_eq!(UUID::from(42u16), UUID::from(v));
953        assert_eq!(UUID::from(42u32), UUID::from(v));
954        assert_eq!(UUID::from(42u64), UUID::from(v));
955        assert_eq!(UUID::from(42usize), UUID::from(v));
956        assert_eq!(UUID::from(42u128), UUID::from(v));
957    }
958
959    #[test]
960    fn same_value_same_uuid_signed_positive() {
961        let v = 42u128;
962        assert_eq!(UUID::from(42i8), UUID::from(v));
963        assert_eq!(UUID::from(42i16), UUID::from(v));
964        assert_eq!(UUID::from(42i32), UUID::from(v));
965        assert_eq!(UUID::from(42i64), UUID::from(v));
966        assert_eq!(UUID::from(42isize), UUID::from(v));
967        assert_eq!(UUID::from(42i128), UUID::from(v));
968    }
969
970    #[test]
971    fn minus_one_same_uuid_all_signed() {
972        let expected = UUID::max();
973        assert_eq!(UUID::from(-1i8), expected);
974        assert_eq!(UUID::from(-1i16), expected);
975        assert_eq!(UUID::from(-1i32), expected);
976        assert_eq!(UUID::from(-1i64), expected);
977        assert_eq!(UUID::from(-1isize), expected);
978        assert_eq!(UUID::from(-1i128), expected);
979    }
980
981    // -----------------------------------------------------------------------
982    // Ordering is preserved: larger integer → larger UUID
983    // -----------------------------------------------------------------------
984
985    #[test]
986    fn ordering_preserved_unsigned() {
987        assert!(UUID::from(0u128) < UUID::from(1u128));
988        assert!(UUID::from(1u128) < UUID::from(u128::MAX));
989    }
990
991    #[test]
992    fn ordering_preserved_for_positive_signed() {
993        assert!(UUID::from(0i128) < UUID::from(1i128));
994        assert!(UUID::from(1i128) < UUID::from(i128::MAX));
995    }
996
997    // -----------------------------------------------------------------------
998    // Nil and max UUID → integer identity
999    // -----------------------------------------------------------------------
1000
1001    #[test]
1002    fn nil_uuid_to_all_unsigned() {
1003        let nil = UUID::nil();
1004        assert_eq!(u128::from(nil), 0);
1005        assert_eq!(
1006            u8::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1007            0
1008        );
1009        assert_eq!(
1010            u16::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1011            0
1012        );
1013        assert_eq!(
1014            u32::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1015            0
1016        );
1017        assert_eq!(
1018            u64::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1019            0
1020        );
1021        assert_eq!(
1022            usize::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1023            0
1024        );
1025    }
1026
1027    #[test]
1028    fn nil_uuid_to_all_signed() {
1029        let nil = UUID::nil();
1030        assert_eq!(i128::from(nil), 0);
1031        assert_eq!(
1032            i8::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1033            0
1034        );
1035        assert_eq!(
1036            i16::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1037            0
1038        );
1039        assert_eq!(
1040            i32::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1041            0
1042        );
1043        assert_eq!(
1044            i64::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1045            0
1046        );
1047        assert_eq!(
1048            isize::try_from(nil).expect("in-range UUID conversion to integer should succeed"),
1049            0
1050        );
1051    }
1052
1053    #[test]
1054    fn max_uuid_to_u128() {
1055        assert_eq!(u128::from(UUID::max()), u128::MAX);
1056    }
1057
1058    #[test]
1059    fn max_uuid_to_i128() {
1060        assert_eq!(i128::from(UUID::max()), -1);
1061    }
1062}