1#[doc(hidden)]
309#[macro_export]
310macro_rules! _nt_base {
311 ($name:ident, $inner:ty) => {
312 #[repr(transparent)]
313 #[derive(Debug)]
314 pub struct $name($inner);
315
316 impl From<$name> for $inner {
317 fn from(value: $name) -> $inner {
318 value.0
319 }
320 }
321 };
322
323 ($name:ident, $inner:ty; $($derive:path),+) => {
324 #[repr(transparent)]
325 #[derive(Debug, $($derive),+)]
326 pub struct $name($inner);
327
328 impl From<$name> for $inner {
329 fn from(value: $name) -> $inner {
330 value.0
331 }
332 }
333 };
334}
335
336#[doc(hidden)]
337#[macro_export]
338macro_rules! _nt_clone_traits {
339 ($name:ident) => {
340 impl Clone for $name {
341 fn clone(&self) -> Self {
342 Self(self.0.clone())
343 }
344 }
345 };
346}
347
348#[doc(hidden)]
349#[macro_export]
350macro_rules! _nt_copy_traits {
351 ($name:ident) => {
352 impl Clone for $name {
353 fn clone(&self) -> Self {
354 *self
355 }
356 }
357
358 impl Copy for $name {}
359 };
360}
361
362#[doc(hidden)]
363#[macro_export]
364macro_rules! _nt_partialeq_traits {
365 ($name:ident) => {
366 impl PartialEq for $name {
367 fn eq(&self, other: &Self) -> bool {
368 self.0 == other.0
369 }
370 }
371 };
372}
373
374#[doc(hidden)]
375#[macro_export]
376macro_rules! _nt_eq_traits {
377 ($name:ident) => {
378 $crate::_nt_partialeq_traits!($name);
379 impl Eq for $name {}
380 };
381}
382
383#[doc(hidden)]
384#[macro_export]
385macro_rules! _nt_partialord_traits {
386 ($name:ident) => {
387 impl PartialOrd for $name {
388 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
389 self.0.partial_cmp(&other.0)
390 }
391 }
392 };
393}
394
395#[doc(hidden)]
396#[macro_export]
397macro_rules! _nt_ord_traits {
398 ($name:ident) => {
399 impl Ord for $name {
400 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
401 self.0.cmp(&other.0)
402 }
403 }
404
405 impl PartialOrd for $name {
406 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
407 Some(self.cmp(other))
408 }
409 }
410 };
411}
412
413#[doc(hidden)]
414#[macro_export]
415macro_rules! _nt_hash_traits {
416 ($name:ident) => {
417 impl std::hash::Hash for $name {
418 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
419 self.0.hash(state);
420 }
421 }
422 };
423}
424
425#[doc(hidden)]
426#[macro_export]
427macro_rules! _nt_addsub_traits {
428 ($name:ident) => {
429 impl Default for $name {
430 fn default() -> Self {
431 Self(Default::default())
432 }
433 }
434
435 impl std::ops::Add<$name> for $name {
436 type Output = $name;
437
438 fn add(self, rhs: Self) -> Self::Output {
439 $name(self.0 + rhs.0)
440 }
441 }
442
443 impl std::ops::Add<&$name> for $name {
444 type Output = $name;
445
446 fn add(self, rhs: &$name) -> Self::Output {
447 $name(self.0 + rhs.0)
448 }
449 }
450
451 impl std::ops::Add<$name> for &$name {
452 type Output = $name;
453
454 fn add(self, rhs: $name) -> Self::Output {
455 $name(self.0 + rhs.0)
456 }
457 }
458
459 impl std::ops::Add<&$name> for &$name {
460 type Output = $name;
461
462 fn add(self, rhs: &$name) -> Self::Output {
463 $name(self.0 + rhs.0)
464 }
465 }
466
467 impl std::ops::Sub<$name> for $name {
468 type Output = $name;
469
470 fn sub(self, rhs: Self) -> Self::Output {
471 $name(self.0 - rhs.0)
472 }
473 }
474
475 impl std::ops::Sub<&$name> for $name {
476 type Output = $name;
477
478 fn sub(self, rhs: &$name) -> Self::Output {
479 $name(self.0 - rhs.0)
480 }
481 }
482
483 impl std::ops::Sub<$name> for &$name {
484 type Output = $name;
485
486 fn sub(self, rhs: $name) -> Self::Output {
487 $name(self.0 - rhs.0)
488 }
489 }
490
491 impl std::ops::Sub<&$name> for &$name {
492 type Output = $name;
493
494 fn sub(self, rhs: &$name) -> Self::Output {
495 $name(self.0 - rhs.0)
496 }
497 }
498
499 impl std::ops::AddAssign<$name> for $name {
500 fn add_assign(&mut self, rhs: $name) {
501 self.0 += rhs.0;
502 }
503 }
504
505 impl std::ops::AddAssign<&$name> for $name {
506 fn add_assign(&mut self, rhs: &$name) {
507 self.0 += rhs.0;
508 }
509 }
510
511 impl std::ops::SubAssign<$name> for $name {
512 fn sub_assign(&mut self, rhs: $name) {
513 self.0 -= rhs.0;
514 }
515 }
516
517 impl std::ops::SubAssign<&$name> for $name {
518 fn sub_assign(&mut self, rhs: &$name) {
519 self.0 -= rhs.0;
520 }
521 }
522 };
523}
524
525#[doc(hidden)]
526#[macro_export]
527macro_rules! _nt_clone {
528 ($name:ident, $inner:ty) => {
529 $crate::_nt_base!($name, $inner);
530 $crate::_nt_clone_traits!($name);
531 };
532
533 ($name:ident, $inner:ty; $($derive:path),+) => {
534 $crate::_nt_base!($name, $inner; $($derive),+);
535 $crate::_nt_clone_traits!($name);
536 };
537}
538
539#[doc(hidden)]
540#[macro_export]
541macro_rules! _nt_copy {
542 ($name:ident, $inner:ty) => {
543 $crate::_nt_base!($name, $inner);
544 $crate::_nt_copy_traits!($name);
545 };
546
547 ($name:ident, $inner:ty; $($derive:path),+) => {
548 $crate::_nt_base!($name, $inner; $($derive),+);
549 $crate::_nt_copy_traits!($name);
550 };
551}
552
553#[doc(hidden)]
554#[macro_export]
555macro_rules! _nt_int {
556 ($name:ident, $inner:ty) => {
557 $crate::_nt_copy!($name, $inner);
558 $crate::_nt_eq_traits!($name);
559 $crate::_nt_hash_traits!($name);
560 };
561
562 ($name:ident, $inner:ty; $($derive:path),+) => {
563 $crate::_nt_copy!($name, $inner; $($derive),+);
564 $crate::_nt_eq_traits!($name);
565 $crate::_nt_hash_traits!($name);
566 };
567}
568
569#[doc(hidden)]
570#[macro_export]
571macro_rules! _nt_float {
572 ($name:ident, $inner:ty) => {
573 $crate::_nt_copy!($name, $inner);
574 $crate::_nt_partialeq_traits!($name);
575 };
576
577 ($name:ident, $inner:ty; $($derive:path),+) => {
578 $crate::_nt_copy!($name, $inner; $($derive),+);
579 $crate::_nt_partialeq_traits!($name);
580 };
581}
582
583#[doc(hidden)]
584#[macro_export]
585macro_rules! _nt_string {
586 ($name:ident) => {
587 $crate::_nt_clone!($name, String);
588 $crate::_nt_eq_traits!($name);
589 $crate::_nt_hash_traits!($name);
590 };
591
592 ($name:ident; $($derive:path),+) => {
593 $crate::_nt_clone!($name, String; $($derive),+);
594 $crate::_nt_eq_traits!($name);
595 $crate::_nt_hash_traits!($name);
596 };
597}
598
599#[doc(hidden)]
600#[macro_export]
601macro_rules! _nt_int_ord {
602 ($name:ident, $inner:ty) => {
603 $crate::_nt_int!($name, $inner);
604 $crate::_nt_ord_traits!($name);
605 };
606
607 ($name:ident, $inner:ty; $($derive:path),+) => {
608 $crate::_nt_int!($name, $inner; $($derive),+);
609 $crate::_nt_ord_traits!($name);
610 };
611}
612
613#[doc(hidden)]
614#[macro_export]
615macro_rules! _nt_float_ord {
616 ($name:ident, $inner:ty) => {
617 $crate::_nt_float!($name, $inner);
618 $crate::_nt_partialord_traits!($name);
619 };
620
621 ($name:ident, $inner:ty; $($derive:path),+) => {
622 $crate::_nt_float!($name, $inner; $($derive),+);
623 $crate::_nt_partialord_traits!($name);
624 };
625}
626
627#[doc(hidden)]
628#[macro_export]
629macro_rules! _nt_string_ord {
630 ($name:ident) => {
631 $crate::_nt_string!($name);
632 $crate::_nt_ord_traits!($name);
633 };
634
635 ($name:ident; $($derive:path),+) => {
636 $crate::_nt_string!($name; $($derive),+);
637 $crate::_nt_ord_traits!($name);
638 };
639}
640
641#[doc(hidden)]
642#[macro_export]
643macro_rules! _nt_int_unit {
644 ($name:ident, $inner:ty) => {
645 $crate::_nt_int_ord!($name, $inner);
646 $crate::_nt_addsub_traits!($name);
647 };
648
649 ($name:ident, $inner:ty; $($derive:path),+) => {
650 $crate::_nt_int_ord!($name, $inner; $($derive),+);
651 $crate::_nt_addsub_traits!($name);
652 };
653}
654
655#[doc(hidden)]
656#[macro_export]
657macro_rules! _nt_float_unit {
658 ($name:ident, $inner:ty) => {
659 $crate::_nt_float_ord!($name, $inner);
660 $crate::_nt_addsub_traits!($name);
661 };
662
663 ($name:ident, $inner:ty; $($derive:path),+) => {
664 $crate::_nt_float_ord!($name, $inner; $($derive),+);
665 $crate::_nt_addsub_traits!($name);
666 };
667}
668
669#[doc(hidden)]
670#[macro_export]
671macro_rules! _nt_from_traits {
672 ($name:ident, $inner:ty) => {
673 impl From<$inner> for $name {
674 #[inline(always)]
675 fn from(value: $inner) -> Self {
676 $name(value)
677 }
678 }
679 };
680}
681
682#[doc(hidden)]
683#[macro_export]
684macro_rules! _nt_fromstr_traits {
685 ($name:ident, $inner:ty, $err:ty) => {
686 impl std::str::FromStr for $name {
687 type Err = $err;
688
689 fn from_str(s: &str) -> Result<Self, Self::Err> {
690 match <$inner>::from_str(s) {
691 Ok(v) => Ok($name(v)),
692 Err(e) => Err(e),
693 }
694 }
695 }
696 };
697}
698
699#[doc(hidden)]
700#[macro_export]
701macro_rules! _nt_int_from {
702 ($name:ident, $inner:ty) => {
703 $crate::_nt_from_traits!($name, $inner);
704 $crate::_nt_fromstr_traits!($name, $inner, std::num::ParseIntError);
705 };
706}
707
708#[doc(hidden)]
709#[macro_export]
710macro_rules! _nt_float_from {
711 ($name:ident, $inner:ty) => {
712 $crate::_nt_from_traits!($name, $inner);
713 $crate::_nt_fromstr_traits!($name, $inner, std::num::ParseFloatError);
714 };
715}
716
717#[macro_export]
747macro_rules! newtype {
748 ($name:ident, i8) => { $crate::_nt_int!($name, i8); };
749 ($name:ident, u8) => { $crate::_nt_int!($name, u8); };
750 ($name:ident, i16) => { $crate::_nt_int!($name, i16); };
751 ($name:ident, u16) => { $crate::_nt_int!($name, u16); };
752 ($name:ident, i32) => { $crate::_nt_int!($name, i32); };
753 ($name:ident, u32) => { $crate::_nt_int!($name, u32); };
754 ($name:ident, i64) => { $crate::_nt_int!($name, i64); };
755 ($name:ident, u64) => { $crate::_nt_int!($name, u64); };
756 ($name:ident, i128) => { $crate::_nt_int!($name, i128); };
757 ($name:ident, u128) => { $crate::_nt_int!($name, u128); };
758 ($name:ident, isize) => { $crate::_nt_int!($name, isize); };
759 ($name:ident, usize) => { $crate::_nt_int!($name, usize); };
760 ($name:ident, i8; $($derive:path),+) => { $crate::_nt_int!($name, i8; $($derive),+); };
761 ($name:ident, u8; $($derive:path),+) => { $crate::_nt_int!($name, u8; $($derive),+); };
762 ($name:ident, i16; $($derive:path),+) => { $crate::_nt_int!($name, i16; $($derive),+); };
763 ($name:ident, u16; $($derive:path),+) => { $crate::_nt_int!($name, u16; $($derive),+); };
764 ($name:ident, i32; $($derive:path),+) => { $crate::_nt_int!($name, i32; $($derive),+); };
765 ($name:ident, u32; $($derive:path),+) => { $crate::_nt_int!($name, u32; $($derive),+); };
766 ($name:ident, i64; $($derive:path),+) => { $crate::_nt_int!($name, i64; $($derive),+); };
767 ($name:ident, u64; $($derive:path),+) => { $crate::_nt_int!($name, u64; $($derive),+); };
768 ($name:ident, i128; $($derive:path),+) => { $crate::_nt_int!($name, i128; $($derive),+); };
769 ($name:ident, u128; $($derive:path),+) => { $crate::_nt_int!($name, u128; $($derive),+); };
770 ($name:ident, isize; $($derive:path),+) => { $crate::_nt_int!($name, isize; $($derive),+); };
771 ($name:ident, usize; $($derive:path),+) => { $crate::_nt_int!($name, usize; $($derive),+); };
772
773 ($name:ident, f32) => { $crate::_nt_float!($name, f32); };
774 ($name:ident, f64) => { $crate::_nt_float!($name, f64); };
775 ($name:ident, f32; $($derive:path),+) => { $crate::_nt_float!($name, f32; $($derive),+); };
776 ($name:ident, f64; $($derive:path),+) => { $crate::_nt_float!($name, f64; $($derive),+); };
777
778 ($name:ident, String) => { $crate::_nt_string!($name); };
779 ($name:ident, String; $($derive:path),+) => { $crate::_nt_string!($name; $($derive),+); };
780
781 ($name:ident, $inner:ty) => {
782 $crate::_nt_base!($name, $inner);
783 };
784 ($name:ident, $inner:ty; $($derive:path),+) => {
785 $crate::_nt_base!($name, $inner; $($derive),+);
786 }
787}
788
789#[macro_export]
807macro_rules! newtype_ord {
808 ($name:ident, i8) => { $crate::_nt_int_ord!($name, i8); };
809 ($name:ident, u8) => { $crate::_nt_int_ord!($name, u8); };
810 ($name:ident, i16) => { $crate::_nt_int_ord!($name, i16); };
811 ($name:ident, u16) => { $crate::_nt_int_ord!($name, u16); };
812 ($name:ident, i32) => { $crate::_nt_int_ord!($name, i32); };
813 ($name:ident, u32) => { $crate::_nt_int_ord!($name, u32); };
814 ($name:ident, i64) => { $crate::_nt_int_ord!($name, i64); };
815 ($name:ident, u64) => { $crate::_nt_int_ord!($name, u64); };
816 ($name:ident, i128) => { $crate::_nt_int_ord!($name, i128); };
817 ($name:ident, u128) => { $crate::_nt_int_ord!($name, u128); };
818 ($name:ident, isize) => { $crate::_nt_int_ord!($name, isize); };
819 ($name:ident, usize) => { $crate::_nt_int_ord!($name, usize); };
820 ($name:ident, i8; $($derive:path),+) => { $crate::_nt_int_ord!($name, i8; $($derive),+); };
821 ($name:ident, u8; $($derive:path),+) => { $crate::_nt_int_ord!($name, u8; $($derive),+); };
822 ($name:ident, i16; $($derive:path),+) => { $crate::_nt_int_ord!($name, i16; $($derive),+); };
823 ($name:ident, u16; $($derive:path),+) => { $crate::_nt_int_ord!($name, u16; $($derive),+); };
824 ($name:ident, i32; $($derive:path),+) => { $crate::_nt_int_ord!($name, i32; $($derive),+); };
825 ($name:ident, u32; $($derive:path),+) => { $crate::_nt_int_ord!($name, u32; $($derive),+); };
826 ($name:ident, i64; $($derive:path),+) => { $crate::_nt_int_ord!($name, i64; $($derive),+); };
827 ($name:ident, u64; $($derive:path),+) => { $crate::_nt_int_ord!($name, u64; $($derive),+); };
828 ($name:ident, i128; $($derive:path),+) => { $crate::_nt_int_ord!($name, i128; $($derive),+); };
829 ($name:ident, u128; $($derive:path),+) => { $crate::_nt_int_ord!($name, u128; $($derive),+); };
830 ($name:ident, isize; $($derive:path),+) => { $crate::_nt_int_ord!($name, isize; $($derive),+); };
831 ($name:ident, usize; $($derive:path),+) => { $crate::_nt_int_ord!($name, usize; $($derive),+); };
832
833 ($name:ident, f32) => { $crate::_nt_float_ord!($name, f32); };
834 ($name:ident, f64) => { $crate::_nt_float_ord!($name, f64); };
835 ($name:ident, f32; $($derive:path),+) => { $crate::_nt_float_ord!($name, f32; $($derive),+); };
836 ($name:ident, f64; $($derive:path),+) => { $crate::_nt_float_ord!($name, f64; $($derive),+); };
837
838 ($name:ident, String) => { $crate::_nt_string_ord!($name); };
839 ($name:ident, String; $($derive:path),+) => { $crate::_nt_string_ord!($name; $($derive),+); };
840}
841
842#[macro_export]
866macro_rules! newtype_unit {
867 ($name:ident, i8) => { $crate::_nt_int_unit!($name, i8); };
868 ($name:ident, u8) => { $crate::_nt_int_unit!($name, u8); };
869 ($name:ident, i16) => { $crate::_nt_int_unit!($name, i16); };
870 ($name:ident, u16) => { $crate::_nt_int_unit!($name, u16); };
871 ($name:ident, i32) => { $crate::_nt_int_unit!($name, i32); };
872 ($name:ident, u32) => { $crate::_nt_int_unit!($name, u32); };
873 ($name:ident, i64) => { $crate::_nt_int_unit!($name, i64); };
874 ($name:ident, u64) => { $crate::_nt_int_unit!($name, u64); };
875 ($name:ident, i128) => { $crate::_nt_int_unit!($name, i128); };
876 ($name:ident, u128) => { $crate::_nt_int_unit!($name, u128); };
877 ($name:ident, isize) => { $crate::_nt_int_unit!($name, isize); };
878 ($name:ident, usize) => { $crate::_nt_int_unit!($name, usize); };
879 ($name:ident, i8; $($derive:path),+) => { $crate::_nt_int_unit!($name, i8; $($derive),+); };
880 ($name:ident, u8; $($derive:path),+) => { $crate::_nt_int_unit!($name, u8; $($derive),+); };
881 ($name:ident, i16; $($derive:path),+) => { $crate::_nt_int_unit!($name, i16; $($derive),+); };
882 ($name:ident, u16; $($derive:path),+) => { $crate::_nt_int_unit!($name, u16; $($derive),+); };
883 ($name:ident, i32; $($derive:path),+) => { $crate::_nt_int_unit!($name, i32; $($derive),+); };
884 ($name:ident, u32; $($derive:path),+) => { $crate::_nt_int_unit!($name, u32; $($derive),+); };
885 ($name:ident, i64; $($derive:path),+) => { $crate::_nt_int_unit!($name, i64; $($derive),+); };
886 ($name:ident, u64; $($derive:path),+) => { $crate::_nt_int_unit!($name, u64; $($derive),+); };
887 ($name:ident, i128; $($derive:path),+) => { $crate::_nt_int_unit!($name, i128; $($derive),+); };
888 ($name:ident, u128; $($derive:path),+) => { $crate::_nt_int_unit!($name, u128; $($derive),+); };
889 ($name:ident, isize; $($derive:path),+) => { $crate::_nt_int_unit!($name, isize; $($derive),+); };
890 ($name:ident, usize; $($derive:path),+) => { $crate::_nt_int_unit!($name, usize; $($derive),+); };
891
892 ($name:ident, f32) => { $crate::_nt_float_unit!($name, f32); };
893 ($name:ident, f64) => { $crate::_nt_float_unit!($name, f64); };
894 ($name:ident, f32; $($derive:path),+) => { $crate::_nt_float_unit!($name, f32; $($derive),+); };
895 ($name:ident, f64; $($derive:path),+) => { $crate::_nt_float_unit!($name, f64; $($derive),+); };
896}
897
898#[macro_export]
928macro_rules! newtype_struct {
929 ($name:ident, $inner:ty) => {
930 $crate::_nt_base!($name, $inner);
931 $crate::_nt_clone_traits!($name);
932 $crate::_nt_partialeq_traits!($name);
933 };
934
935 ($name:ident, $inner:ty; $($derive:path),+) => {
936 $crate::_nt_base!($name, $inner; $($derive),+);
937 $crate::_nt_clone_traits!($name);
938 $crate::_nt_partialeq_traits!($name);
939 };
940}
941
942#[doc(hidden)]
943#[macro_export]
944macro_rules! _nt_validated_impls {
945 ($name:ident, $err:ident, $inner:ty, $validator:expr) => {
946 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
947 pub struct $err;
948
949 impl ::std::fmt::Display for $err {
950 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
951 write!(f, concat!("invalid ", stringify!($name), " value"))
952 }
953 }
954
955 impl ::std::error::Error for $err {}
956
957 impl $name {
958 pub fn new(value: $inner) -> ::std::result::Result<Self, $err> {
959 if ($validator)(&value) {
960 Ok($name(value))
961 } else {
962 Err($err)
963 }
964 }
965 }
966
967 impl ::std::convert::TryFrom<$inner> for $name {
968 type Error = $err;
969
970 fn try_from(value: $inner) -> ::std::result::Result<Self, Self::Error> {
971 Self::new(value)
972 }
973 }
974 };
975}
976
977#[macro_export]
1023macro_rules! newtype_validated {
1024 ($name:ident, $err:ident, $inner:ty, $validator:expr) => {
1025 $crate::_nt_base!($name, $inner);
1026 $crate::_nt_clone_traits!($name);
1027 $crate::_nt_partialeq_traits!($name);
1028 $crate::_nt_validated_impls!($name, $err, $inner, $validator);
1029 };
1030
1031 ($name:ident, $err:ident, $inner:ty, $validator:expr; $($derive:path),+) => {
1032 $crate::_nt_base!($name, $inner; $($derive),+);
1033 $crate::_nt_clone_traits!($name);
1034 $crate::_nt_partialeq_traits!($name);
1035 $crate::_nt_validated_impls!($name, $err, $inner, $validator);
1036 };
1037}
1038
1039#[doc(hidden)]
1040#[macro_export]
1041macro_rules! _nt_array_base {
1042 ($name:ident, $t:ty, $n:expr) => {
1043 #[repr(transparent)]
1044 #[derive(Debug)]
1045 pub struct $name([$t; $n]);
1046
1047 impl From<$name> for [$t; $n] {
1048 fn from(value: $name) -> [$t; $n] {
1049 value.0
1050 }
1051 }
1052 };
1053
1054 ($name:ident, $t:ty, $n:expr; $($derive:path),+) => {
1055 #[repr(transparent)]
1056 #[derive(Debug, $($derive),+)]
1057 pub struct $name([$t; $n]);
1058
1059 impl From<$name> for [$t; $n] {
1060 fn from(value: $name) -> [$t; $n] {
1061 value.0
1062 }
1063 }
1064 };
1065}
1066
1067#[doc(hidden)]
1068#[macro_export]
1069macro_rules! _nt_array_ops {
1070 ($name:ident, $t:ty, $n:expr) => {
1071 impl<I: std::slice::SliceIndex<[$t]>> std::ops::Index<I> for $name {
1072 type Output = I::Output;
1073
1074 #[inline]
1075 fn index(&self, index: I) -> &Self::Output {
1076 std::ops::Index::index(&self.0[..], index)
1077 }
1078 }
1079
1080 impl<I: std::slice::SliceIndex<[$t]>> std::ops::IndexMut<I> for $name {
1081 #[inline]
1082 fn index_mut(&mut self, index: I) -> &mut Self::Output {
1083 std::ops::IndexMut::index_mut(&mut self.0[..], index)
1084 }
1085 }
1086
1087 impl AsRef<[$t]> for $name {
1088 #[inline]
1089 fn as_ref(&self) -> &[$t] {
1090 &self.0[..]
1091 }
1092 }
1093
1094 impl AsMut<[$t]> for $name {
1095 #[inline]
1096 fn as_mut(&mut self) -> &mut [$t] {
1097 &mut self.0[..]
1098 }
1099 }
1100
1101 impl<'a> IntoIterator for &'a $name {
1102 type Item = &'a $t;
1103 type IntoIter = std::slice::Iter<'a, $t>;
1104
1105 #[inline]
1106 fn into_iter(self) -> Self::IntoIter {
1107 self.0.iter()
1108 }
1109 }
1110
1111 impl<'a> IntoIterator for &'a mut $name {
1112 type Item = &'a mut $t;
1113 type IntoIter = std::slice::IterMut<'a, $t>;
1114
1115 #[inline]
1116 fn into_iter(self) -> Self::IntoIter {
1117 self.0.iter_mut()
1118 }
1119 }
1120
1121 impl IntoIterator for $name {
1122 type Item = $t;
1123 type IntoIter = std::array::IntoIter<$t, $n>;
1124
1125 #[inline]
1126 fn into_iter(self) -> Self::IntoIter {
1127 self.0.into_iter()
1128 }
1129 }
1130
1131 impl $name {
1132 #[inline]
1133 pub const fn len(&self) -> usize {
1134 $n
1135 }
1136
1137 #[inline]
1138 pub const fn is_empty(&self) -> bool {
1139 $n == 0
1140 }
1141
1142 #[inline]
1143 pub fn iter(&self) -> std::slice::Iter<'_, $t> {
1144 self.0.iter()
1145 }
1146
1147 #[inline]
1148 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, $t> {
1149 self.0.iter_mut()
1150 }
1151
1152 #[inline]
1153 pub const fn as_array(&self) -> &[$t; $n] {
1154 &self.0
1155 }
1156
1157 #[inline]
1158 pub const fn as_array_mut(&mut self) -> &mut [$t; $n] {
1159 &mut self.0
1160 }
1161 }
1162 };
1163}
1164
1165#[doc(hidden)]
1166#[macro_export]
1167macro_rules! _nt_array_deref_impls {
1168 ($name:ident, $t:ty) => {
1169 impl std::ops::Deref for $name {
1170 type Target = [$t];
1171
1172 #[inline]
1173 fn deref(&self) -> &[$t] {
1174 &self.0[..]
1175 }
1176 }
1177
1178 impl std::ops::DerefMut for $name {
1179 #[inline]
1180 fn deref_mut(&mut self) -> &mut [$t] {
1181 &mut self.0[..]
1182 }
1183 }
1184 };
1185}
1186
1187#[doc(hidden)]
1188#[macro_export]
1189macro_rules! _nt_array_int {
1190 ($name:ident, $t:ty, $n:expr) => {
1191 $crate::_nt_array_base!($name, $t, $n);
1192 $crate::_nt_copy_traits!($name);
1193 $crate::_nt_eq_traits!($name);
1194 $crate::_nt_hash_traits!($name);
1195 $crate::_nt_array_ops!($name, $t, $n);
1196 };
1197
1198 ($name:ident, $t:ty, $n:expr; $($derive:path),+) => {
1199 $crate::_nt_array_base!($name, $t, $n; $($derive),+);
1200 $crate::_nt_copy_traits!($name);
1201 $crate::_nt_eq_traits!($name);
1202 $crate::_nt_hash_traits!($name);
1203 $crate::_nt_array_ops!($name, $t, $n);
1204 };
1205}
1206
1207#[doc(hidden)]
1208#[macro_export]
1209macro_rules! _nt_array_float {
1210 ($name:ident, $t:ty, $n:expr) => {
1211 $crate::_nt_array_base!($name, $t, $n);
1212 $crate::_nt_copy_traits!($name);
1213 $crate::_nt_partialeq_traits!($name);
1214 $crate::_nt_array_ops!($name, $t, $n);
1215 };
1216
1217 ($name:ident, $t:ty, $n:expr; $($derive:path),+) => {
1218 $crate::_nt_array_base!($name, $t, $n; $($derive),+);
1219 $crate::_nt_copy_traits!($name);
1220 $crate::_nt_partialeq_traits!($name);
1221 $crate::_nt_array_ops!($name, $t, $n);
1222 };
1223}
1224
1225#[doc(hidden)]
1226#[macro_export]
1227macro_rules! _nt_array_string {
1228 ($name:ident, $n:expr) => {
1229 $crate::_nt_array_base!($name, String, $n);
1230 $crate::_nt_clone_traits!($name);
1231 $crate::_nt_eq_traits!($name);
1232 $crate::_nt_hash_traits!($name);
1233 $crate::_nt_array_ops!($name, String, $n);
1234 };
1235
1236 ($name:ident, $n:expr; $($derive:path),+) => {
1237 $crate::_nt_array_base!($name, String, $n; $($derive),+);
1238 $crate::_nt_clone_traits!($name);
1239 $crate::_nt_eq_traits!($name);
1240 $crate::_nt_hash_traits!($name);
1241 $crate::_nt_array_ops!($name, String, $n);
1242 };
1243}
1244
1245#[doc(hidden)]
1246#[macro_export]
1247macro_rules! _nt_array_generic {
1248 ($name:ident, $t:ty, $n:expr) => {
1249 $crate::_nt_array_base!($name, $t, $n);
1250 $crate::_nt_clone_traits!($name);
1251 $crate::_nt_partialeq_traits!($name);
1252 $crate::_nt_array_ops!($name, $t, $n);
1253 };
1254
1255 ($name:ident, $t:ty, $n:expr; $($derive:path),+) => {
1256 $crate::_nt_array_base!($name, $t, $n; $($derive),+);
1257 $crate::_nt_clone_traits!($name);
1258 $crate::_nt_partialeq_traits!($name);
1259 $crate::_nt_array_ops!($name, $t, $n);
1260 };
1261}
1262
1263#[macro_export]
1308macro_rules! newtype_array {
1309 ($name:ident, i8, $n:expr) => { $crate::_nt_array_int!($name, i8, $n); };
1310 ($name:ident, u8, $n:expr) => { $crate::_nt_array_int!($name, u8, $n); };
1311 ($name:ident, i16, $n:expr) => { $crate::_nt_array_int!($name, i16, $n); };
1312 ($name:ident, u16, $n:expr) => { $crate::_nt_array_int!($name, u16, $n); };
1313 ($name:ident, i32, $n:expr) => { $crate::_nt_array_int!($name, i32, $n); };
1314 ($name:ident, u32, $n:expr) => { $crate::_nt_array_int!($name, u32, $n); };
1315 ($name:ident, i64, $n:expr) => { $crate::_nt_array_int!($name, i64, $n); };
1316 ($name:ident, u64, $n:expr) => { $crate::_nt_array_int!($name, u64, $n); };
1317 ($name:ident, i128, $n:expr) => { $crate::_nt_array_int!($name, i128, $n); };
1318 ($name:ident, u128, $n:expr) => { $crate::_nt_array_int!($name, u128, $n); };
1319 ($name:ident, isize, $n:expr) => { $crate::_nt_array_int!($name, isize, $n); };
1320 ($name:ident, usize, $n:expr) => { $crate::_nt_array_int!($name, usize, $n); };
1321 ($name:ident, i8, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i8, $n; $($derive),+); };
1322 ($name:ident, u8, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u8, $n; $($derive),+); };
1323 ($name:ident, i16, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i16, $n; $($derive),+); };
1324 ($name:ident, u16, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u16, $n; $($derive),+); };
1325 ($name:ident, i32, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i32, $n; $($derive),+); };
1326 ($name:ident, u32, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u32, $n; $($derive),+); };
1327 ($name:ident, i64, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i64, $n; $($derive),+); };
1328 ($name:ident, u64, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u64, $n; $($derive),+); };
1329 ($name:ident, i128, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i128, $n; $($derive),+); };
1330 ($name:ident, u128, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u128, $n; $($derive),+); };
1331 ($name:ident, isize, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, isize, $n; $($derive),+); };
1332 ($name:ident, usize, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, usize, $n; $($derive),+); };
1333
1334 ($name:ident, f32, $n:expr) => { $crate::_nt_array_float!($name, f32, $n); };
1335 ($name:ident, f64, $n:expr) => { $crate::_nt_array_float!($name, f64, $n); };
1336 ($name:ident, f32, $n:expr; $($derive:path),+) => { $crate::_nt_array_float!($name, f32, $n; $($derive),+); };
1337 ($name:ident, f64, $n:expr; $($derive:path),+) => { $crate::_nt_array_float!($name, f64, $n; $($derive),+); };
1338
1339 ($name:ident, String, $n:expr) => { $crate::_nt_array_string!($name, $n); };
1340 ($name:ident, String, $n:expr; $($derive:path),+) => { $crate::_nt_array_string!($name, $n; $($derive),+); };
1341
1342 ($name:ident, $t:ty, $n:expr) => { $crate::_nt_array_generic!($name, $t, $n); };
1343 ($name:ident, $t:ty, $n:expr; $($derive:path),+) => { $crate::_nt_array_generic!($name, $t, $n; $($derive),+); };
1344}
1345
1346#[macro_export]
1373macro_rules! newtype_array_deref {
1374 ($name:ident, i8, $n:expr) => { $crate::_nt_array_int!($name, i8, $n); $crate::_nt_array_deref_impls!($name, i8); };
1375 ($name:ident, u8, $n:expr) => { $crate::_nt_array_int!($name, u8, $n); $crate::_nt_array_deref_impls!($name, u8); };
1376 ($name:ident, i16, $n:expr) => { $crate::_nt_array_int!($name, i16, $n); $crate::_nt_array_deref_impls!($name, i16); };
1377 ($name:ident, u16, $n:expr) => { $crate::_nt_array_int!($name, u16, $n); $crate::_nt_array_deref_impls!($name, u16); };
1378 ($name:ident, i32, $n:expr) => { $crate::_nt_array_int!($name, i32, $n); $crate::_nt_array_deref_impls!($name, i32); };
1379 ($name:ident, u32, $n:expr) => { $crate::_nt_array_int!($name, u32, $n); $crate::_nt_array_deref_impls!($name, u32); };
1380 ($name:ident, i64, $n:expr) => { $crate::_nt_array_int!($name, i64, $n); $crate::_nt_array_deref_impls!($name, i64); };
1381 ($name:ident, u64, $n:expr) => { $crate::_nt_array_int!($name, u64, $n); $crate::_nt_array_deref_impls!($name, u64); };
1382 ($name:ident, i128, $n:expr) => { $crate::_nt_array_int!($name, i128, $n); $crate::_nt_array_deref_impls!($name, i128); };
1383 ($name:ident, u128, $n:expr) => { $crate::_nt_array_int!($name, u128, $n); $crate::_nt_array_deref_impls!($name, u128); };
1384 ($name:ident, isize, $n:expr) => { $crate::_nt_array_int!($name, isize, $n); $crate::_nt_array_deref_impls!($name, isize); };
1385 ($name:ident, usize, $n:expr) => { $crate::_nt_array_int!($name, usize, $n); $crate::_nt_array_deref_impls!($name, usize); };
1386 ($name:ident, i8, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i8, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, i8); };
1387 ($name:ident, u8, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u8, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, u8); };
1388 ($name:ident, i16, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i16, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, i16); };
1389 ($name:ident, u16, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u16, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, u16); };
1390 ($name:ident, i32, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i32, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, i32); };
1391 ($name:ident, u32, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u32, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, u32); };
1392 ($name:ident, i64, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i64, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, i64); };
1393 ($name:ident, u64, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u64, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, u64); };
1394 ($name:ident, i128, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, i128, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, i128); };
1395 ($name:ident, u128, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, u128, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, u128); };
1396 ($name:ident, isize, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, isize, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, isize); };
1397 ($name:ident, usize, $n:expr; $($derive:path),+) => { $crate::_nt_array_int!($name, usize, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, usize); };
1398
1399 ($name:ident, f32, $n:expr) => { $crate::_nt_array_float!($name, f32, $n); $crate::_nt_array_deref_impls!($name, f32); };
1400 ($name:ident, f64, $n:expr) => { $crate::_nt_array_float!($name, f64, $n); $crate::_nt_array_deref_impls!($name, f64); };
1401 ($name:ident, f32, $n:expr; $($derive:path),+) => { $crate::_nt_array_float!($name, f32, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, f32); };
1402 ($name:ident, f64, $n:expr; $($derive:path),+) => { $crate::_nt_array_float!($name, f64, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, f64); };
1403
1404 ($name:ident, String, $n:expr) => { $crate::_nt_array_string!($name, $n); $crate::_nt_array_deref_impls!($name, String); };
1405 ($name:ident, String, $n:expr; $($derive:path),+) => { $crate::_nt_array_string!($name, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, String); };
1406
1407 ($name:ident, $t:ty, $n:expr) => { $crate::_nt_array_generic!($name, $t, $n); $crate::_nt_array_deref_impls!($name, $t); };
1408 ($name:ident, $t:ty, $n:expr; $($derive:path),+) => { $crate::_nt_array_generic!($name, $t, $n; $($derive),+); $crate::_nt_array_deref_impls!($name, $t); };
1409}
1410
1411#[macro_export]
1427macro_rules! newtype_from {
1428 ($name:ident, i8) => {
1429 $crate::_nt_int_from!($name, i8);
1430 };
1431 ($name:ident, u8) => {
1432 $crate::_nt_int_from!($name, u8);
1433 };
1434 ($name:ident, i16) => {
1435 $crate::_nt_int_from!($name, i16);
1436 };
1437 ($name:ident, u16) => {
1438 $crate::_nt_int_from!($name, u16);
1439 };
1440 ($name:ident, i32) => {
1441 $crate::_nt_int_from!($name, i32);
1442 };
1443 ($name:ident, u32) => {
1444 $crate::_nt_int_from!($name, u32);
1445 };
1446 ($name:ident, i64) => {
1447 $crate::_nt_int_from!($name, i64);
1448 };
1449 ($name:ident, u64) => {
1450 $crate::_nt_int_from!($name, u64);
1451 };
1452 ($name:ident, i128) => {
1453 $crate::_nt_int_from!($name, i128);
1454 };
1455 ($name:ident, u128) => {
1456 $crate::_nt_int_from!($name, u128);
1457 };
1458 ($name:ident, isize) => {
1459 $crate::_nt_int_from!($name, isize);
1460 };
1461 ($name:ident, usize) => {
1462 $crate::_nt_int_from!($name, usize);
1463 };
1464
1465 ($name:ident, f32) => {
1466 $crate::_nt_float_from!($name, f32);
1467 };
1468 ($name:ident, f64) => {
1469 $crate::_nt_float_from!($name, f64);
1470 };
1471
1472 ($name:ident, String) => {
1473 impl From<String> for $name {
1474 #[inline(always)]
1475 fn from(value: String) -> Self {
1476 $name(value)
1477 }
1478 }
1479
1480 impl From<&str> for $name {
1481 #[inline(always)]
1482 fn from(value: &str) -> Self {
1483 $name(value.into())
1484 }
1485 }
1486
1487 impl std::str::FromStr for $name {
1488 type Err = std::convert::Infallible;
1489
1490 #[inline(always)]
1491 fn from_str(s: &str) -> Result<Self, Self::Err> {
1492 Ok($name(String::from_str(s).unwrap()))
1493 }
1494 }
1495 };
1496
1497 ($name:ident, $inner:ty) => {
1498 impl From<$inner> for $name {
1499 #[inline(always)]
1500 fn from(value: $inner) -> Self {
1501 $name(value)
1502 }
1503 }
1504 };
1505}
1506
1507#[macro_export]
1525macro_rules! newtype_from_only {
1526 ($name:ident, i8) => {
1527 $crate::_nt_from_traits!($name, i8);
1528 };
1529 ($name:ident, u8) => {
1530 $crate::_nt_from_traits!($name, u8);
1531 };
1532 ($name:ident, i16) => {
1533 $crate::_nt_from_traits!($name, i16);
1534 };
1535 ($name:ident, u16) => {
1536 $crate::_nt_from_traits!($name, u16);
1537 };
1538 ($name:ident, i32) => {
1539 $crate::_nt_from_traits!($name, i32);
1540 };
1541 ($name:ident, u32) => {
1542 $crate::_nt_from_traits!($name, u32);
1543 };
1544 ($name:ident, i64) => {
1545 $crate::_nt_from_traits!($name, i64);
1546 };
1547 ($name:ident, u64) => {
1548 $crate::_nt_from_traits!($name, u64);
1549 };
1550 ($name:ident, i128) => {
1551 $crate::_nt_from_traits!($name, i128);
1552 };
1553 ($name:ident, u128) => {
1554 $crate::_nt_from_traits!($name, u128);
1555 };
1556 ($name:ident, isize) => {
1557 $crate::_nt_from_traits!($name, isize);
1558 };
1559 ($name:ident, usize) => {
1560 $crate::_nt_from_traits!($name, usize);
1561 };
1562
1563 ($name:ident, f32) => {
1564 $crate::_nt_from_traits!($name, f32);
1565 };
1566 ($name:ident, f64) => {
1567 $crate::_nt_from_traits!($name, f64);
1568 };
1569
1570 ($name:ident, String) => {
1571 impl From<String> for $name {
1572 #[inline(always)]
1573 fn from(value: String) -> Self {
1574 $name(value)
1575 }
1576 }
1577
1578 impl From<&str> for $name {
1579 #[inline(always)]
1580 fn from(value: &str) -> Self {
1581 $name(value.into())
1582 }
1583 }
1584 };
1585
1586 ($name:ident, $inner:ty) => {
1587 $crate::_nt_from_traits!($name, $inner);
1588 };
1589}
1590
1591#[macro_export]
1613macro_rules! newtype_fromstr {
1614 ($name:ident, i8) => {
1615 $crate::_nt_fromstr_traits!($name, i8, std::num::ParseIntError);
1616 };
1617 ($name:ident, u8) => {
1618 $crate::_nt_fromstr_traits!($name, u8, std::num::ParseIntError);
1619 };
1620 ($name:ident, i16) => {
1621 $crate::_nt_fromstr_traits!($name, i16, std::num::ParseIntError);
1622 };
1623 ($name:ident, u16) => {
1624 $crate::_nt_fromstr_traits!($name, u16, std::num::ParseIntError);
1625 };
1626 ($name:ident, i32) => {
1627 $crate::_nt_fromstr_traits!($name, i32, std::num::ParseIntError);
1628 };
1629 ($name:ident, u32) => {
1630 $crate::_nt_fromstr_traits!($name, u32, std::num::ParseIntError);
1631 };
1632 ($name:ident, i64) => {
1633 $crate::_nt_fromstr_traits!($name, i64, std::num::ParseIntError);
1634 };
1635 ($name:ident, u64) => {
1636 $crate::_nt_fromstr_traits!($name, u64, std::num::ParseIntError);
1637 };
1638 ($name:ident, i128) => {
1639 $crate::_nt_fromstr_traits!($name, i128, std::num::ParseIntError);
1640 };
1641 ($name:ident, u128) => {
1642 $crate::_nt_fromstr_traits!($name, u128, std::num::ParseIntError);
1643 };
1644 ($name:ident, isize) => {
1645 $crate::_nt_fromstr_traits!($name, isize, std::num::ParseIntError);
1646 };
1647 ($name:ident, usize) => {
1648 $crate::_nt_fromstr_traits!($name, usize, std::num::ParseIntError);
1649 };
1650
1651 ($name:ident, f32) => {
1652 $crate::_nt_fromstr_traits!($name, f32, std::num::ParseFloatError);
1653 };
1654 ($name:ident, f64) => {
1655 $crate::_nt_fromstr_traits!($name, f64, std::num::ParseFloatError);
1656 };
1657
1658 ($name:ident, String) => {
1659 impl std::str::FromStr for $name {
1660 type Err = std::convert::Infallible;
1661
1662 #[inline(always)]
1663 fn from_str(s: &str) -> Result<Self, Self::Err> {
1664 Ok($name(String::from_str(s).unwrap()))
1665 }
1666 }
1667 };
1668}
1669
1670#[cfg(test)]
1671mod tests_newtype {
1672 newtype!(UserId, u32);
1673 newtype_from!(UserId, u32);
1674
1675 newtype!(Weight, f32);
1676 newtype_from!(Weight, f32);
1677
1678 newtype!(StrId, String);
1679 newtype_from!(StrId, String);
1680
1681 #[test]
1682 fn test_integers_cmp() {
1683 let v1 = UserId::from(42);
1684 let v2 = UserId::from(1001);
1685 let v3 = UserId::from(42);
1686
1687 assert!(v1 != v2);
1688 assert!(v2 != v3);
1689 assert!(v1 == v1);
1690 assert!(v1 == v3);
1691 }
1692
1693 #[test]
1694 #[allow(clippy::clone_on_copy)]
1695 fn test_integers_copy() {
1696 let v1 = UserId::from(42);
1697 let v2 = UserId::from(1001);
1698
1699 #[allow(unused)]
1700 let mut v3 = UserId::from(0);
1701
1702 v3 = v1;
1703 assert_eq!(UserId(42), v3);
1704 v3 = v2;
1705 assert_eq!(UserId(1001), v3);
1706
1707 v3 = v1.clone();
1708 assert_eq!(UserId(42), v3);
1709 v3 = v2.clone();
1710 assert_eq!(UserId(1001), v3);
1711 }
1712
1713 #[test]
1714 fn test_integers_into() {
1715 let v1 = UserId::from(42);
1716 assert_eq!(42_u32, v1.into());
1717 }
1718
1719 #[test]
1720 fn test_float_cmp() {
1721 let v1 = Weight::from(42.0);
1722 let v2 = Weight::from(1001.0);
1723 let v3 = Weight::from(42.0);
1724
1725 assert!(v1 != v2);
1726 assert!(v2 != v3);
1727 assert!(v1 == v1);
1728 assert!(v1 == v3);
1729 }
1730
1731 #[test]
1732 #[allow(clippy::clone_on_copy)]
1733 fn test_float_copy() {
1734 let v1 = Weight::from(42.0);
1735 let v2 = Weight::from(1001.0);
1736
1737 #[allow(unused)]
1738 let mut v3 = Weight::from(0.0);
1739
1740 v3 = v1;
1741 assert_eq!(Weight(42.0), v3);
1742 v3 = v2;
1743 assert_eq!(Weight(1001.0), v3);
1744
1745 v3 = v1.clone();
1746 assert_eq!(Weight(42.0), v3);
1747 v3 = v2.clone();
1748 assert_eq!(Weight(1001.0), v3);
1749 }
1750
1751 #[test]
1752 fn test_float_into() {
1753 let v1 = Weight::from(42.0);
1754 assert_eq!(42_f32, v1.into());
1755 }
1756
1757 #[test]
1758 fn test_string_cmp() {
1759 let v1 = StrId::from("42");
1760 let v2 = StrId::from("1001");
1761 let v3 = StrId::from("42");
1762
1763 assert!(v1 != v2);
1764 assert!(v2 != v3);
1765 assert!(v1 == v1);
1766 assert!(v1 == v3);
1767 }
1768
1769 #[test]
1770 fn test_string_copy() {
1771 let v1 = StrId::from("42");
1772 let v2 = StrId::from("1001");
1773
1774 #[allow(unused)]
1775 let mut v3 = StrId::from("0");
1776
1777 v3 = v1.clone();
1778 assert_eq!(StrId("42".into()), v3);
1779 v3 = v2.clone();
1780 assert_eq!(StrId("1001".into()), v3);
1781 }
1782
1783 #[test]
1784 fn test_string_into() {
1785 let v1 = StrId::from("42");
1786
1787 let s: String = v1.into();
1788 assert_eq!("42", s);
1789 }
1790}
1791
1792#[cfg(test)]
1793mod tests_newtype_ord {
1794 newtype_ord!(Weight, u32);
1795 newtype_from!(Weight, u32);
1796
1797 newtype_ord!(Height, f32);
1798 newtype_from!(Height, f32);
1799
1800 newtype_ord!(Name, String);
1801 newtype_from!(Name, String);
1802
1803 #[test]
1804 fn test_integers_cmp() {
1805 let w1 = Weight::from(100);
1806 let w2 = Weight::from(150);
1807
1808 assert!(w1 <= w2);
1809 assert!(w1 < w2);
1810 assert!(w2 >= w1);
1811 assert!(w2 > w1);
1812 }
1813
1814 #[test]
1815 fn test_float_cmp() {
1816 let h1 = Height::from(100.0);
1817 let h2 = Height::from(150.0);
1818
1819 assert!(h1 <= h2);
1820 assert!(h1 < h2);
1821 assert!(h2 >= h1);
1822 assert!(h2 > h1);
1823 }
1824
1825 #[test]
1826 fn test_string_cmp() {
1827 let n1 = Name::from("Alan");
1828 let n2 = Name::from("Julia");
1829
1830 assert!(n1 <= n2);
1831 assert!(n1 < n2);
1832 assert!(n2 >= n1);
1833 assert!(n2 > n1);
1834 }
1835}
1836
1837#[cfg(test)]
1838mod tests_newtype_unit {
1839 newtype_unit!(Units, i32);
1840 newtype_from!(Units, i32);
1841
1842 #[test]
1843 fn test_integers_add() {
1844 let u1 = Units::from(100);
1845 let u2 = Units::from(50);
1846 let mut u3 = Units::from(200);
1847
1848 assert_eq!(Units(150), u1 + u2);
1849 assert_eq!(Units(150), u2 + u1);
1850
1851 u3 += u2;
1852 assert_eq!(Units(250), u3);
1853 }
1854
1855 #[test]
1856 fn test_integers_sub() {
1857 let u1 = Units::from(100);
1858 let u2 = Units::from(50);
1859 let mut u3 = Units::from(200);
1860
1861 assert_eq!(Units(50), u1 - u2);
1862 assert_eq!(Units(-50), u2 - u1);
1863
1864 u3 -= u2;
1865 assert_eq!(Units(150), u3);
1866 }
1867}
1868
1869#[cfg(test)]
1870mod tests_newtype_from {
1871 use std::str::FromStr;
1872
1873 newtype!(UserId, u32);
1874 newtype_from!(UserId, u32);
1875
1876 newtype!(Weight, f32);
1877 newtype_from!(Weight, f32);
1878
1879 newtype!(Name, String);
1880 newtype_from!(Name, String);
1881
1882 #[test]
1883 fn test_integer_fromstr() {
1884 assert_eq!(Ok(UserId(42)), UserId::from_str("42"));
1885 assert!(UserId::from_str("hello").is_err());
1886 }
1887
1888 #[test]
1889 fn test_float_fromstr() {
1890 assert_eq!(Ok(Weight(42.0)), Weight::from_str("42.0"));
1891 assert!(Weight::from_str("hello").is_err());
1892 }
1893
1894 #[test]
1895 fn test_string_fromstr() {
1896 assert_eq!(Ok(Name("John".into())), Name::from_str("John"));
1897 }
1898}
1899
1900#[cfg(test)]
1901mod tests_newtype_from_split {
1902 use std::str::FromStr;
1903
1904 newtype!(IntFromOnly, u32);
1905 newtype_from_only!(IntFromOnly, u32);
1906
1907 newtype!(FloatFromOnly, f32);
1908 newtype_from_only!(FloatFromOnly, f32);
1909
1910 newtype!(StrFromOnly, String);
1911 newtype_from_only!(StrFromOnly, String);
1912
1913 #[derive(Debug)]
1914 pub struct Inner(u32);
1915 newtype!(StructFromOnly, Inner);
1916 newtype_from_only!(StructFromOnly, Inner);
1917
1918 newtype!(IntFromStr, u32);
1919 newtype_fromstr!(IntFromStr, u32);
1920
1921 newtype!(FloatFromStr, f32);
1922 newtype_fromstr!(FloatFromStr, f32);
1923
1924 newtype!(StrFromStr, String);
1925 newtype_fromstr!(StrFromStr, String);
1926
1927 newtype!(BothInt, u32);
1928 newtype_from_only!(BothInt, u32);
1929 newtype_fromstr!(BothInt, u32);
1930
1931 #[test]
1932 fn test_from_only_integer() {
1933 let v: IntFromOnly = 42_u32.into();
1934 let n: u32 = v.into();
1935 assert_eq!(42, n);
1936 }
1937
1938 #[test]
1939 fn test_from_only_float() {
1940 let v: FloatFromOnly = 1.5_f32.into();
1941 let n: f32 = v.into();
1942 assert!((n - 1.5).abs() < f32::EPSILON);
1943 }
1944
1945 #[test]
1946 fn test_from_only_string_owned() {
1947 let v: StrFromOnly = String::from("hello").into();
1948 let s: String = v.into();
1949 assert_eq!("hello", s);
1950 }
1951
1952 #[test]
1953 fn test_from_only_string_slice() {
1954 let v: StrFromOnly = "world".into();
1955 let s: String = v.into();
1956 assert_eq!("world", s);
1957 }
1958
1959 #[test]
1960 fn test_from_only_struct() {
1961 let v: StructFromOnly = Inner(7).into();
1962 let inner: Inner = v.into();
1963 assert_eq!(7, inner.0);
1964 }
1965
1966 #[test]
1967 fn test_fromstr_integer() {
1968 let v = IntFromStr::from_str("99").unwrap();
1969 assert_eq!(99_u32, v.into());
1970 assert!(IntFromStr::from_str("nope").is_err());
1971 }
1972
1973 #[test]
1974 fn test_fromstr_float() {
1975 let v = FloatFromStr::from_str("3.25").unwrap();
1976 let n: f32 = v.into();
1977 assert!((n - 3.25).abs() < f32::EPSILON);
1978 assert!(FloatFromStr::from_str("nope").is_err());
1979 }
1980
1981 #[test]
1982 fn test_fromstr_string() {
1983 let v = StrFromStr::from_str("greetings").unwrap();
1984 let s: String = v.into();
1985 assert_eq!("greetings", s);
1986 }
1987
1988 #[test]
1989 fn test_combined_equivalent_to_newtype_from() {
1990 let from_int: BothInt = 7_u32.into();
1991 let parsed = BothInt::from_str("7").unwrap();
1992 assert_eq!(7_u32, from_int.into());
1993 assert_eq!(7_u32, parsed.into());
1994 }
1995}
1996
1997#[cfg(test)]
1998mod tests_newtype_struct {
1999 #[derive(Debug, Clone, PartialEq)]
2000 pub struct Point2D {
2001 pub x: f32,
2002 pub y: f32,
2003 }
2004
2005 newtype_struct!(Vertex, Point2D);
2006
2007 newtype_struct!(Numbers, Vec<u32>);
2008
2009 #[derive(Debug, Clone, PartialEq)]
2010 struct Container {
2011 head: Vertex,
2012 tail: Vertex,
2013 }
2014
2015 #[test]
2016 fn test_struct_clone_and_eq() {
2017 let a = Vertex(Point2D { x: 1.0, y: 2.0 });
2018 let b = a.clone();
2019 assert_eq!(a, b);
2020 let c = Vertex(Point2D { x: 1.0, y: 3.0 });
2021 assert!(a != c);
2022 }
2023
2024 #[test]
2025 fn test_struct_into() {
2026 let v = Vertex(Point2D { x: 4.0, y: 5.0 });
2027 let inner: Point2D = v.into();
2028 assert_eq!(Point2D { x: 4.0, y: 5.0 }, inner);
2029 }
2030
2031 #[test]
2032 fn test_struct_debug() {
2033 let v = Vertex(Point2D { x: 0.0, y: 0.0 });
2034 let dbg = format!("{:?}", v);
2035 assert!(dbg.contains("Vertex"));
2036 assert!(dbg.contains("Point2D"));
2037 }
2038
2039 #[test]
2040 fn test_struct_wrapping_vec() {
2041 let n = Numbers(vec![1, 2, 3]);
2042 let m = n.clone();
2043 assert_eq!(n, m);
2044 let inner: Vec<u32> = n.into();
2045 assert_eq!(vec![1, 2, 3], inner);
2046 }
2047
2048 #[test]
2049 fn test_struct_composes_in_outer_struct() {
2050 let c1 = Container {
2051 head: Vertex(Point2D { x: 0.0, y: 0.0 }),
2052 tail: Vertex(Point2D { x: 1.0, y: 1.0 }),
2053 };
2054 let c2 = c1.clone();
2055 assert_eq!(c1, c2);
2056 }
2057}
2058
2059#[cfg(test)]
2060mod tests_newtype_validated {
2061 use std::error::Error;
2062
2063 newtype_validated!(Probability, ProbabilityError, f32, |x: &f32| (0.0..=1.0)
2064 .contains(x));
2065
2066 fn is_even(x: &u32) -> bool {
2067 x.is_multiple_of(2)
2068 }
2069 newtype_validated!(EvenU32, EvenU32Error, u32, is_even);
2070
2071 newtype_validated!(NonEmpty, NonEmptyError, String, |s: &String| !s.is_empty());
2072
2073 #[derive(Debug, Clone, PartialEq)]
2074 pub struct Range {
2075 pub lo: i32,
2076 pub hi: i32,
2077 }
2078 newtype_validated!(SortedRange, SortedRangeError, Range, |r: &Range| r.lo
2079 <= r.hi);
2080
2081 #[test]
2082 fn test_closure_validator_valid() {
2083 let p = Probability::new(0.5).unwrap();
2084 let inner: f32 = p.into();
2085 assert!((inner - 0.5).abs() < f32::EPSILON);
2086 }
2087
2088 #[test]
2089 fn test_closure_validator_invalid() {
2090 assert_eq!(Err(ProbabilityError), Probability::new(2.0));
2091 assert_eq!(Err(ProbabilityError), Probability::new(-0.1));
2092 }
2093
2094 #[test]
2095 fn test_closure_validator_boundaries() {
2096 assert!(Probability::new(0.0).is_ok());
2097 assert!(Probability::new(1.0).is_ok());
2098 }
2099
2100 #[test]
2101 fn test_function_path_validator() {
2102 assert!(EvenU32::new(4).is_ok());
2103 assert_eq!(Err(EvenU32Error), EvenU32::new(5));
2104 }
2105
2106 #[test]
2107 fn test_string_validator() {
2108 assert!(NonEmpty::new("hello".to_string()).is_ok());
2109 assert_eq!(Err(NonEmptyError), NonEmpty::new(String::new()));
2110 }
2111
2112 #[test]
2113 fn test_struct_validator() {
2114 assert!(SortedRange::new(Range { lo: 1, hi: 5 }).is_ok());
2115 assert_eq!(
2116 Err(SortedRangeError),
2117 SortedRange::new(Range { lo: 5, hi: 1 })
2118 );
2119 }
2120
2121 #[test]
2122 fn test_tryfrom_valid() {
2123 let p: Probability = (0.5_f32).try_into().unwrap();
2124 let inner: f32 = p.into();
2125 assert!((inner - 0.5).abs() < f32::EPSILON);
2126 }
2127
2128 #[test]
2129 fn test_tryfrom_invalid() {
2130 let r: Result<Probability, _> = (2.0_f32).try_into();
2131 assert_eq!(Err(ProbabilityError), r);
2132 }
2133
2134 #[test]
2135 fn test_error_traits() {
2136 let e = ProbabilityError;
2137 let dbg = format!("{:?}", e);
2138 assert!(dbg.contains("ProbabilityError"));
2139 let disp = format!("{}", e);
2140 assert_eq!("invalid Probability value", disp);
2141 let copy = e;
2142 assert_eq!(e, copy);
2143 let _src: Option<&(dyn Error + 'static)> = e.source();
2144 }
2145
2146 #[test]
2147 fn test_clone_and_eq_on_validated_value() {
2148 let a = Probability::new(0.25).unwrap();
2149 let b = a.clone();
2150 assert_eq!(a, b);
2151 }
2152}
2153
2154#[cfg(test)]
2155mod tests_pointer_sized_ints {
2156 use std::str::FromStr;
2157
2158 newtype!(UsizeId, usize);
2159 newtype_from!(UsizeId, usize);
2160
2161 newtype_ord!(UsizeOrd, usize);
2162 newtype_from!(UsizeOrd, usize);
2163
2164 newtype_unit!(UsizeUnit, usize);
2165 newtype_from!(UsizeUnit, usize);
2166
2167 newtype!(UsizeOnly, usize);
2168 newtype_from_only!(UsizeOnly, usize);
2169
2170 newtype!(UsizeStr, usize);
2171 newtype_fromstr!(UsizeStr, usize);
2172
2173 newtype!(IsizeId, isize);
2174 newtype_from!(IsizeId, isize);
2175
2176 newtype_ord!(IsizeOrd, isize);
2177 newtype_from!(IsizeOrd, isize);
2178
2179 newtype_unit!(IsizeUnit, isize);
2180 newtype_from!(IsizeUnit, isize);
2181
2182 newtype!(IsizeOnly, isize);
2183 newtype_from_only!(IsizeOnly, isize);
2184
2185 newtype!(IsizeStr, isize);
2186 newtype_fromstr!(IsizeStr, isize);
2187
2188 #[test]
2189 fn test_usize_basics() {
2190 let a = UsizeId::from(42);
2191 let b = UsizeId::from(42);
2192 let c = UsizeId::from(7);
2193 assert_eq!(a, b);
2194 assert!(a != c);
2195 let n: usize = a.into();
2196 assert_eq!(42, n);
2197 }
2198
2199 #[test]
2200 fn test_usize_ord() {
2201 let a = UsizeOrd::from(1);
2202 let b = UsizeOrd::from(2);
2203 assert!(a < b);
2204 }
2205
2206 #[test]
2207 fn test_usize_unit_arithmetic() {
2208 let a = UsizeUnit::from(10);
2209 let b = UsizeUnit::from(3);
2210 let c = a + b;
2211 let n: usize = c.into();
2212 assert_eq!(13, n);
2213 }
2214
2215 #[test]
2216 fn test_usize_fromstr_via_newtype_from() {
2217 assert_eq!(Ok(UsizeId(99)), UsizeId::from_str("99"));
2218 assert!(UsizeId::from_str("nope").is_err());
2219 }
2220
2221 #[test]
2222 fn test_usize_from_only() {
2223 let a = UsizeOnly::from(5);
2224 let n: usize = a.into();
2225 assert_eq!(5, n);
2226 }
2227
2228 #[test]
2229 fn test_usize_fromstr_only() {
2230 let a = UsizeStr::from_str("123").unwrap();
2231 let n: usize = a.into();
2232 assert_eq!(123, n);
2233 }
2234
2235 #[test]
2236 fn test_isize_basics() {
2237 let a = IsizeId::from(-42);
2238 let b = IsizeId::from(-42);
2239 let c = IsizeId::from(7);
2240 assert_eq!(a, b);
2241 assert!(a != c);
2242 let n: isize = a.into();
2243 assert_eq!(-42, n);
2244 }
2245
2246 #[test]
2247 fn test_isize_ord() {
2248 let a = IsizeOrd::from(-1);
2249 let b = IsizeOrd::from(2);
2250 assert!(a < b);
2251 }
2252
2253 #[test]
2254 fn test_isize_unit_arithmetic() {
2255 let a = IsizeUnit::from(10);
2256 let b = IsizeUnit::from(-3);
2257 let c = a + b;
2258 let n: isize = c.into();
2259 assert_eq!(7, n);
2260 }
2261
2262 #[test]
2263 fn test_isize_fromstr_via_newtype_from() {
2264 assert_eq!(Ok(IsizeId(-99)), IsizeId::from_str("-99"));
2265 assert!(IsizeId::from_str("nope").is_err());
2266 }
2267
2268 #[test]
2269 fn test_isize_from_only() {
2270 let a = IsizeOnly::from(-5);
2271 let n: isize = a.into();
2272 assert_eq!(-5, n);
2273 }
2274
2275 #[test]
2276 fn test_isize_fromstr_only() {
2277 let a = IsizeStr::from_str("-123").unwrap();
2278 let n: isize = a.into();
2279 assert_eq!(-123, n);
2280 }
2281}
2282
2283#[cfg(test)]
2284mod tests_layout {
2285 use std::mem::{align_of, size_of};
2286
2287 newtype!(LayoutI8, i8);
2288 newtype!(LayoutU64, u64);
2289 newtype!(LayoutI128, i128);
2290 newtype!(LayoutF32, f32);
2291 newtype!(LayoutF64, f64);
2292 newtype!(LayoutString, String);
2293
2294 #[derive(Debug)]
2295 #[allow(dead_code)]
2296 struct Wide {
2297 a: u64,
2298 b: u32,
2299 }
2300 newtype!(LayoutStruct, Wide);
2301
2302 #[test]
2303 fn test_size_matches_inner() {
2304 assert_eq!(size_of::<i8>(), size_of::<LayoutI8>());
2305 assert_eq!(size_of::<u64>(), size_of::<LayoutU64>());
2306 assert_eq!(size_of::<i128>(), size_of::<LayoutI128>());
2307 assert_eq!(size_of::<f32>(), size_of::<LayoutF32>());
2308 assert_eq!(size_of::<f64>(), size_of::<LayoutF64>());
2309 assert_eq!(size_of::<String>(), size_of::<LayoutString>());
2310 assert_eq!(size_of::<Wide>(), size_of::<LayoutStruct>());
2311 }
2312
2313 #[test]
2314 fn test_align_matches_inner() {
2315 assert_eq!(align_of::<i8>(), align_of::<LayoutI8>());
2316 assert_eq!(align_of::<u64>(), align_of::<LayoutU64>());
2317 assert_eq!(align_of::<i128>(), align_of::<LayoutI128>());
2318 assert_eq!(align_of::<f32>(), align_of::<LayoutF32>());
2319 assert_eq!(align_of::<f64>(), align_of::<LayoutF64>());
2320 assert_eq!(align_of::<String>(), align_of::<LayoutString>());
2321 assert_eq!(align_of::<Wide>(), align_of::<LayoutStruct>());
2322 }
2323}
2324
2325#[cfg(test)]
2326mod tests_newtype_array {
2327 newtype_array!(Mac, u8, 6);
2328 newtype_array!(Floats, f32, 4);
2329 newtype_array!(Names, String, 2);
2330 newtype_array!(Empty, u8, 0);
2331
2332 #[derive(Debug, Clone, PartialEq)]
2333 pub struct Tag(pub u32);
2334 newtype_array!(Tags, Tag, 3);
2335
2336 #[test]
2337 fn test_index_usize() {
2338 let m = Mac([1, 2, 3, 4, 5, 6]);
2339 assert_eq!(1, m[0]);
2340 assert_eq!(6, m[5]);
2341 }
2342
2343 #[test]
2344 fn test_index_mut_usize() {
2345 let mut m = Mac([0; 6]);
2346 m[0] = 42;
2347 m[5] = 7;
2348 assert_eq!(42, m[0]);
2349 assert_eq!(7, m[5]);
2350 }
2351
2352 #[test]
2353 fn test_range_index() {
2354 let m = Mac([1, 2, 3, 4, 5, 6]);
2355 let s: &[u8] = &m[1..3];
2356 assert_eq!(&[2u8, 3], s);
2357 let s: &[u8] = &m[..];
2358 assert_eq!(&[1u8, 2, 3, 4, 5, 6], s);
2359 let s: &[u8] = &m[2..];
2360 assert_eq!(&[3u8, 4, 5, 6], s);
2361 let s: &[u8] = &m[..=1];
2362 assert_eq!(&[1u8, 2], s);
2363 }
2364
2365 #[test]
2366 fn test_range_index_mut() {
2367 let mut m = Mac([1, 2, 3, 4, 5, 6]);
2368 m[1..3].copy_from_slice(&[20, 30]);
2369 assert_eq!(20, m[1]);
2370 assert_eq!(30, m[2]);
2371 }
2372
2373 #[test]
2374 fn test_iter_inherent() {
2375 let m = Mac([1, 2, 3, 4, 5, 6]);
2376 let sum: u32 = m.iter().map(|&x| x as u32).sum();
2377 assert_eq!(21, sum);
2378 }
2379
2380 #[test]
2381 fn test_iter_mut_inherent() {
2382 let mut m = Mac([1, 2, 3, 4, 5, 6]);
2383 for x in m.iter_mut() {
2384 *x *= 2;
2385 }
2386 assert_eq!(2, m[0]);
2387 assert_eq!(12, m[5]);
2388 }
2389
2390 #[test]
2391 fn test_into_iter_ref() {
2392 let m = Mac([1, 2, 3, 4, 5, 6]);
2393 let sum: u32 = (&m).into_iter().map(|&x| x as u32).sum();
2394 assert_eq!(21, sum);
2395 }
2396
2397 #[test]
2398 fn test_into_iter_owned() {
2399 let m = Mac([1, 2, 3, 4, 5, 6]);
2400 let v: Vec<u8> = m.into_iter().collect();
2401 assert_eq!(vec![1u8, 2, 3, 4, 5, 6], v);
2402 }
2403
2404 #[test]
2405 fn test_for_loop_ref() {
2406 let m = Mac([1, 2, 3, 4, 5, 6]);
2407 let mut total: u32 = 0;
2408 for x in &m {
2409 total += *x as u32;
2410 }
2411 assert_eq!(21, total);
2412 }
2413
2414 #[test]
2415 fn test_for_loop_mut() {
2416 let mut m = Mac([1, 2, 3, 4, 5, 6]);
2417 for x in &mut m {
2418 *x += 1;
2419 }
2420 assert_eq!(2, m[0]);
2421 assert_eq!(7, m[5]);
2422 }
2423
2424 #[test]
2425 fn test_len_and_is_empty() {
2426 let m = Mac([0; 6]);
2427 assert_eq!(6, m.len());
2428 assert!(!m.is_empty());
2429
2430 let e = Empty([]);
2431 assert_eq!(0, e.len());
2432 assert!(e.is_empty());
2433 }
2434
2435 #[test]
2436 fn test_as_array() {
2437 let m = Mac([1, 2, 3, 4, 5, 6]);
2438 let a: &[u8; 6] = m.as_array();
2439 assert_eq!(&[1u8, 2, 3, 4, 5, 6], a);
2440 }
2441
2442 #[test]
2443 fn test_as_array_mut() {
2444 let mut m = Mac([0; 6]);
2445 m.as_array_mut()[0] = 9;
2446 assert_eq!(9, m[0]);
2447 }
2448
2449 #[test]
2450 fn test_into_array() {
2451 let m = Mac([1, 2, 3, 4, 5, 6]);
2452 let a: [u8; 6] = m.into();
2453 assert_eq!([1u8, 2, 3, 4, 5, 6], a);
2454 }
2455
2456 #[test]
2457 fn test_as_ref_slice() {
2458 let m = Mac([1, 2, 3, 4, 5, 6]);
2459 let s: &[u8] = m.as_ref();
2460 assert_eq!(&[1u8, 2, 3, 4, 5, 6], s);
2461 }
2462
2463 #[test]
2464 fn test_as_mut_slice() {
2465 let mut m = Mac([1, 2, 3, 4, 5, 6]);
2466 let s: &mut [u8] = m.as_mut();
2467 s[0] = 99;
2468 assert_eq!(99, m[0]);
2469 }
2470
2471 #[test]
2472 fn test_eq_and_hash_for_int_array() {
2473 use std::collections::HashSet;
2474 let a = Mac([1, 2, 3, 4, 5, 6]);
2475 let b = Mac([1, 2, 3, 4, 5, 6]);
2476 let c = Mac([6, 5, 4, 3, 2, 1]);
2477 assert_eq!(a, b);
2478 assert!(a != c);
2479 let mut set: HashSet<Mac> = HashSet::new();
2480 set.insert(a);
2481 assert!(set.contains(&b));
2482 assert!(!set.contains(&c));
2483 }
2484
2485 #[test]
2486 fn test_copy_for_int_array() {
2487 let a = Mac([1, 2, 3, 4, 5, 6]);
2488 let b = a;
2489 let c = a;
2490 assert_eq!(a, b);
2491 assert_eq!(a, c);
2492 }
2493
2494 #[test]
2495 fn test_float_array_partialeq() {
2496 let a = Floats([1.0, 2.0, 3.0, 4.0]);
2497 let b = Floats([1.0, 2.0, 3.0, 4.0]);
2498 let c = Floats([1.0, 2.0, 3.0, 5.0]);
2499 assert!(a == b);
2500 assert!(a != c);
2501 }
2502
2503 #[test]
2504 fn test_string_array() {
2505 let n = Names(["alice".into(), "bob".into()]);
2506 let m = n.clone();
2507 assert_eq!(n, m);
2508 assert_eq!("alice", n[0]);
2509 assert_eq!("bob", n[1]);
2510 }
2511
2512 #[test]
2513 fn test_generic_struct_array() {
2514 let t = Tags([Tag(1), Tag(2), Tag(3)]);
2515 let u = t.clone();
2516 assert_eq!(t, u);
2517 assert_eq!(Tag(2), t[1]);
2518 }
2519
2520 #[test]
2521 fn test_empty_array_iter() {
2522 let e = Empty([]);
2523 let count = e.iter().count();
2524 assert_eq!(0, count);
2525 let count = e.into_iter().count();
2526 assert_eq!(0, count);
2527 }
2528}
2529
2530#[cfg(test)]
2531mod tests_newtype_array_deref {
2532 newtype_array_deref!(Buf, u8, 4);
2533
2534 #[test]
2535 fn test_deref_slice_methods() {
2536 let b = Buf([1, 2, 3, 4]);
2537 assert_eq!(Some(&1u8), b.first());
2538 assert_eq!(Some(&4u8), b.last());
2539 assert!(b.contains(&3));
2540 assert!(!b.contains(&99));
2541 }
2542
2543 #[test]
2544 fn test_deref_mut_slice_method() {
2545 let mut b = Buf([1, 2, 3, 4]);
2546 b.fill(0);
2547 assert_eq!([0u8, 0, 0, 0], *b.as_array());
2548 }
2549
2550 #[test]
2551 fn test_deref_target_is_slice() {
2552 let b = Buf([10, 20, 30, 40]);
2553 let s: &[u8] = &b;
2554 assert_eq!(&[10u8, 20, 30, 40], s);
2555 }
2556
2557 #[test]
2558 fn test_deref_does_not_break_inherent_iter() {
2559 let b = Buf([1, 2, 3, 4]);
2560 let sum: u32 = b.iter().map(|&x| x as u32).sum();
2561 assert_eq!(10, sum);
2562 }
2563}
2564
2565#[cfg(test)]
2566mod tests_newtype_array_layout {
2567 use std::mem::{align_of, size_of};
2568
2569 newtype_array!(LU8x6, u8, 6);
2570 newtype_array!(LU64x4, u64, 4);
2571 newtype_array!(LF32x3, f32, 3);
2572 newtype_array_deref!(LDU8x4, u8, 4);
2573
2574 #[test]
2575 fn test_size_matches_inner() {
2576 assert_eq!(size_of::<[u8; 6]>(), size_of::<LU8x6>());
2577 assert_eq!(size_of::<[u64; 4]>(), size_of::<LU64x4>());
2578 assert_eq!(size_of::<[f32; 3]>(), size_of::<LF32x3>());
2579 assert_eq!(size_of::<[u8; 4]>(), size_of::<LDU8x4>());
2580 }
2581
2582 #[test]
2583 fn test_align_matches_inner() {
2584 assert_eq!(align_of::<[u8; 6]>(), align_of::<LU8x6>());
2585 assert_eq!(align_of::<[u64; 4]>(), align_of::<LU64x4>());
2586 assert_eq!(align_of::<[f32; 3]>(), align_of::<LF32x3>());
2587 assert_eq!(align_of::<[u8; 4]>(), align_of::<LDU8x4>());
2588 }
2589}