1#[macro_export]
63macro_rules! forward_debug {
64 (<$($generic:ident),+> in $($rest:tt)+) => {
65 $crate::forward_debug!(@impl [$($generic: ::core::fmt::Debug),+] $($rest)+);
66 };
67
68 (<const $($rest:tt)+) => {
69 $crate::__impl_more_parse_generics!(@parse forward_debug [: ::core::fmt::Debug] [] const $($rest)+);
70 };
71
72 (<$generic:ident, $($rest:tt)+) => {
73 $crate::__impl_more_parse_generics!(@parse forward_debug [: ::core::fmt::Debug] [] $generic, $($rest)+);
74 };
75
76 (@impl [$($generic:tt)+] $this:ty => $field:tt $(,)?) => {
77 impl <$($generic)+> ::core::fmt::Debug for $this {
78 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
79 ::core::fmt::Debug::fmt(&self.$field, fmt)
80 }
81 }
82 };
83
84 (@impl [$($generic:tt)+] $this:ty $(,)?) => {
85 impl <$($generic)+> ::core::fmt::Debug for $this {
86 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
87 ::core::fmt::Debug::fmt(&self.0, fmt)
88 }
89 }
90 };
91
92 ($this:ty => $field:tt $(,)?) => {
93 impl ::core::fmt::Debug for $this {
94 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
95 ::core::fmt::Debug::fmt(&self.$field, fmt)
96 }
97 }
98 };
99
100 ($this:ty $(,)?) => {
101 impl ::core::fmt::Debug for $this {
102 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
103 ::core::fmt::Debug::fmt(&self.0, fmt)
104 }
105 }
106 };
107}
108
109#[macro_export]
161macro_rules! forward_binary {
162 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
163 impl <$($generic: ::core::fmt::Binary),+> ::core::fmt::Binary for $this {
164 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
165 ::core::fmt::Binary::fmt(&self.$field, fmt)
166 }
167 }
168 };
169 (<$($generic:ident),+> in $this:ty $(,)?) => {
170 impl <$($generic: ::core::fmt::Binary),+> ::core::fmt::Binary for $this {
171 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
172 ::core::fmt::Binary::fmt(&self.0, fmt)
173 }
174 }
175 };
176 ($this:ty => $field:tt $(,)?) => {
177 impl ::core::fmt::Binary for $this {
178 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
179 ::core::fmt::Binary::fmt(&self.$field, fmt)
180 }
181 }
182 };
183 ($this:ty $(,)?) => {
184 impl ::core::fmt::Binary for $this {
185 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
186 ::core::fmt::Binary::fmt(&self.0, fmt)
187 }
188 }
189 };
190}
191
192#[macro_export]
244macro_rules! forward_octal {
245 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
246 impl <$($generic: ::core::fmt::Octal),+> ::core::fmt::Octal for $this {
247 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
248 ::core::fmt::Octal::fmt(&self.$field, fmt)
249 }
250 }
251 };
252 (<$($generic:ident),+> in $this:ty $(,)?) => {
253 impl <$($generic: ::core::fmt::Octal),+> ::core::fmt::Octal for $this {
254 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
255 ::core::fmt::Octal::fmt(&self.0, fmt)
256 }
257 }
258 };
259 ($this:ty => $field:tt $(,)?) => {
260 impl ::core::fmt::Octal for $this {
261 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
262 ::core::fmt::Octal::fmt(&self.$field, fmt)
263 }
264 }
265 };
266 ($this:ty $(,)?) => {
267 impl ::core::fmt::Octal for $this {
268 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
269 ::core::fmt::Octal::fmt(&self.0, fmt)
270 }
271 }
272 };
273}
274
275#[macro_export]
327macro_rules! forward_lower_hex {
328 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
329 impl <$($generic: ::core::fmt::LowerHex),+> ::core::fmt::LowerHex for $this {
330 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
331 ::core::fmt::LowerHex::fmt(&self.$field, fmt)
332 }
333 }
334 };
335 (<$($generic:ident),+> in $this:ty $(,)?) => {
336 impl <$($generic: ::core::fmt::LowerHex),+> ::core::fmt::LowerHex for $this {
337 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
338 ::core::fmt::LowerHex::fmt(&self.0, fmt)
339 }
340 }
341 };
342 ($this:ty => $field:tt $(,)?) => {
343 impl ::core::fmt::LowerHex for $this {
344 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
345 ::core::fmt::LowerHex::fmt(&self.$field, fmt)
346 }
347 }
348 };
349 ($this:ty $(,)?) => {
350 impl ::core::fmt::LowerHex for $this {
351 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
352 ::core::fmt::LowerHex::fmt(&self.0, fmt)
353 }
354 }
355 };
356}
357
358#[macro_export]
410macro_rules! forward_upper_hex {
411 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
412 impl <$($generic: ::core::fmt::UpperHex),+> ::core::fmt::UpperHex for $this {
413 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
414 ::core::fmt::UpperHex::fmt(&self.$field, fmt)
415 }
416 }
417 };
418 (<$($generic:ident),+> in $this:ty $(,)?) => {
419 impl <$($generic: ::core::fmt::UpperHex),+> ::core::fmt::UpperHex for $this {
420 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
421 ::core::fmt::UpperHex::fmt(&self.0, fmt)
422 }
423 }
424 };
425 ($this:ty => $field:tt $(,)?) => {
426 impl ::core::fmt::UpperHex for $this {
427 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
428 ::core::fmt::UpperHex::fmt(&self.$field, fmt)
429 }
430 }
431 };
432 ($this:ty $(,)?) => {
433 impl ::core::fmt::UpperHex for $this {
434 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
435 ::core::fmt::UpperHex::fmt(&self.0, fmt)
436 }
437 }
438 };
439}
440
441#[macro_export]
493macro_rules! forward_lower_exp {
494 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
495 impl <$($generic: ::core::fmt::LowerExp),+> ::core::fmt::LowerExp for $this {
496 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
497 ::core::fmt::LowerExp::fmt(&self.$field, fmt)
498 }
499 }
500 };
501 (<$($generic:ident),+> in $this:ty $(,)?) => {
502 impl <$($generic: ::core::fmt::LowerExp),+> ::core::fmt::LowerExp for $this {
503 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
504 ::core::fmt::LowerExp::fmt(&self.0, fmt)
505 }
506 }
507 };
508 ($this:ty => $field:tt $(,)?) => {
509 impl ::core::fmt::LowerExp for $this {
510 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
511 ::core::fmt::LowerExp::fmt(&self.$field, fmt)
512 }
513 }
514 };
515 ($this:ty $(,)?) => {
516 impl ::core::fmt::LowerExp for $this {
517 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
518 ::core::fmt::LowerExp::fmt(&self.0, fmt)
519 }
520 }
521 };
522}
523
524#[macro_export]
576macro_rules! forward_upper_exp {
577 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
578 impl <$($generic: ::core::fmt::UpperExp),+> ::core::fmt::UpperExp for $this {
579 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
580 ::core::fmt::UpperExp::fmt(&self.$field, fmt)
581 }
582 }
583 };
584 (<$($generic:ident),+> in $this:ty $(,)?) => {
585 impl <$($generic: ::core::fmt::UpperExp),+> ::core::fmt::UpperExp for $this {
586 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
587 ::core::fmt::UpperExp::fmt(&self.0, fmt)
588 }
589 }
590 };
591 ($this:ty => $field:tt $(,)?) => {
592 impl ::core::fmt::UpperExp for $this {
593 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
594 ::core::fmt::UpperExp::fmt(&self.$field, fmt)
595 }
596 }
597 };
598 ($this:ty $(,)?) => {
599 impl ::core::fmt::UpperExp for $this {
600 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
601 ::core::fmt::UpperExp::fmt(&self.0, fmt)
602 }
603 }
604 };
605}
606
607#[macro_export]
659macro_rules! forward_pointer {
660 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
661 impl <$($generic: ::core::fmt::Pointer),+> ::core::fmt::Pointer for $this {
662 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
663 ::core::fmt::Pointer::fmt(&self.$field, fmt)
664 }
665 }
666 };
667 (<$($generic:ident),+> in $this:ty $(,)?) => {
668 impl <$($generic: ::core::fmt::Pointer),+> ::core::fmt::Pointer for $this {
669 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
670 ::core::fmt::Pointer::fmt(&self.0, fmt)
671 }
672 }
673 };
674 ($this:ty => $field:tt $(,)?) => {
675 impl ::core::fmt::Pointer for $this {
676 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
677 ::core::fmt::Pointer::fmt(&self.$field, fmt)
678 }
679 }
680 };
681 ($this:ty $(,)?) => {
682 impl ::core::fmt::Pointer for $this {
683 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
684 ::core::fmt::Pointer::fmt(&self.0, fmt)
685 }
686 }
687 };
688}
689
690#[cfg(test)]
691mod tests {
692 use alloc::{format, string::String, vec};
693
694 #[test]
695 fn debug_forwards_formatter_and_fields() {
696 struct Tuple(u32);
697 struct Named {
698 inner: u32,
699 }
700 struct Generic<T>(T);
701 struct GenericNamed<T> {
702 inner: T,
703 }
704 crate::forward_debug!(Tuple,);
705 crate::forward_debug!(Named => inner,);
706 crate::forward_debug!(<T> in Generic<T>);
707 crate::forward_debug!(<T> in GenericNamed<T> => inner);
708 let inner = 42u32;
709 let expected = format!("{:#012?}", inner);
710 assert_eq!(format!("{:#012?}", Tuple(inner)), expected);
711 assert_eq!(format!("{:#012?}", Named { inner }), expected);
712 assert_eq!(format!("{:#012?}", Generic(inner)), expected);
713 assert_eq!(format!("{:#012?}", GenericNamed { inner }), expected);
714 }
715
716 #[test]
717 fn binary_forwards_formatter_and_fields() {
718 struct Tuple(u32);
719 struct Named {
720 inner: u32,
721 }
722 struct Generic<T>(T);
723 struct GenericNamed<T> {
724 inner: T,
725 }
726 crate::forward_binary!(Tuple,);
727 crate::forward_binary!(Named => inner,);
728 crate::forward_binary!(<T> in Generic<T>);
729 crate::forward_binary!(<T> in GenericNamed<T> => inner);
730 let inner = 42u32;
731 let expected = format!("{:#012b}", inner);
732 assert_eq!(format!("{:#012b}", Tuple(inner)), expected);
733 assert_eq!(format!("{:#012b}", Named { inner }), expected);
734 assert_eq!(format!("{:#012b}", Generic(inner)), expected);
735 assert_eq!(format!("{:#012b}", GenericNamed { inner }), expected);
736 }
737
738 #[test]
739 fn octal_forwards_formatter_and_fields() {
740 struct Tuple(u32);
741 struct Named {
742 inner: u32,
743 }
744 struct Generic<T>(T);
745 struct GenericNamed<T> {
746 inner: T,
747 }
748 crate::forward_octal!(Tuple,);
749 crate::forward_octal!(Named => inner,);
750 crate::forward_octal!(<T> in Generic<T>);
751 crate::forward_octal!(<T> in GenericNamed<T> => inner);
752 let inner = 42u32;
753 let expected = format!("{:#012o}", inner);
754 assert_eq!(format!("{:#012o}", Tuple(inner)), expected);
755 assert_eq!(format!("{:#012o}", Named { inner }), expected);
756 assert_eq!(format!("{:#012o}", Generic(inner)), expected);
757 assert_eq!(format!("{:#012o}", GenericNamed { inner }), expected);
758 }
759
760 #[test]
761 fn lower_hex_forwards_formatter_and_fields() {
762 struct Tuple(u32);
763 struct Named {
764 inner: u32,
765 }
766 struct Generic<T>(T);
767 struct GenericNamed<T> {
768 inner: T,
769 }
770 crate::forward_lower_hex!(Tuple,);
771 crate::forward_lower_hex!(Named => inner,);
772 crate::forward_lower_hex!(<T> in Generic<T>);
773 crate::forward_lower_hex!(<T> in GenericNamed<T> => inner);
774 let inner = 42u32;
775 let expected = format!("{:#012x}", inner);
776 assert_eq!(format!("{:#012x}", Tuple(inner)), expected);
777 assert_eq!(format!("{:#012x}", Named { inner }), expected);
778 assert_eq!(format!("{:#012x}", Generic(inner)), expected);
779 assert_eq!(format!("{:#012x}", GenericNamed { inner }), expected);
780 }
781
782 #[test]
783 fn upper_hex_forwards_formatter_and_fields() {
784 struct Tuple(u32);
785 struct Named {
786 inner: u32,
787 }
788 struct Generic<T>(T);
789 struct GenericNamed<T> {
790 inner: T,
791 }
792 crate::forward_upper_hex!(Tuple,);
793 crate::forward_upper_hex!(Named => inner,);
794 crate::forward_upper_hex!(<T> in Generic<T>);
795 crate::forward_upper_hex!(<T> in GenericNamed<T> => inner);
796 let inner = 42u32;
797 let expected = format!("{:#012X}", inner);
798 assert_eq!(format!("{:#012X}", Tuple(inner)), expected);
799 assert_eq!(format!("{:#012X}", Named { inner }), expected);
800 assert_eq!(format!("{:#012X}", Generic(inner)), expected);
801 assert_eq!(format!("{:#012X}", GenericNamed { inner }), expected);
802 }
803
804 #[test]
805 fn lower_exp_forwards_formatter_and_fields() {
806 struct Tuple(u32);
807 struct Named {
808 inner: u32,
809 }
810 struct Generic<T>(T);
811 struct GenericNamed<T> {
812 inner: T,
813 }
814 crate::forward_lower_exp!(Tuple,);
815 crate::forward_lower_exp!(Named => inner,);
816 crate::forward_lower_exp!(<T> in Generic<T>);
817 crate::forward_lower_exp!(<T> in GenericNamed<T> => inner);
818 let inner = 42u32;
819 let expected = format!("{:#012e}", inner);
820 assert_eq!(format!("{:#012e}", Tuple(inner)), expected);
821 assert_eq!(format!("{:#012e}", Named { inner }), expected);
822 assert_eq!(format!("{:#012e}", Generic(inner)), expected);
823 assert_eq!(format!("{:#012e}", GenericNamed { inner }), expected);
824 }
825
826 #[test]
827 fn upper_exp_forwards_formatter_and_fields() {
828 struct Tuple(u32);
829 struct Named {
830 inner: u32,
831 }
832 struct Generic<T>(T);
833 struct GenericNamed<T> {
834 inner: T,
835 }
836 crate::forward_upper_exp!(Tuple,);
837 crate::forward_upper_exp!(Named => inner,);
838 crate::forward_upper_exp!(<T> in Generic<T>);
839 crate::forward_upper_exp!(<T> in GenericNamed<T> => inner);
840 let inner = 42u32;
841 let expected = format!("{:#012E}", inner);
842 assert_eq!(format!("{:#012E}", Tuple(inner)), expected);
843 assert_eq!(format!("{:#012E}", Named { inner }), expected);
844 assert_eq!(format!("{:#012E}", Generic(inner)), expected);
845 assert_eq!(format!("{:#012E}", GenericNamed { inner }), expected);
846 }
847
848 #[test]
849 fn pointer_forwards_formatter_and_fields() {
850 struct Tuple(*const i32);
851 struct Named {
852 inner: *const i32,
853 }
854 struct Generic<T>(T);
855 struct GenericNamed<T> {
856 inner: T,
857 }
858 crate::forward_pointer!(Tuple,);
859 crate::forward_pointer!(Named => inner,);
860 crate::forward_pointer!(<T> in Generic<T>);
861 crate::forward_pointer!(<T> in GenericNamed<T> => inner);
862 let inner = &42 as *const i32;
863 let expected = format!("{:#012p}", inner);
864 assert_eq!(format!("{:#012p}", Tuple(inner)), expected);
865 assert_eq!(format!("{:#012p}", Named { inner }), expected);
866 assert_eq!(format!("{:#012p}", Generic(inner)), expected);
867 assert_eq!(format!("{:#012p}", GenericNamed { inner }), expected);
868 }
869
870 #[test]
871 fn debug_preserves_pretty_layout_and_precision() {
872 struct Value<T>(T);
873 crate::forward_debug!(<T> in Value<T>);
874 assert_eq!(
875 format!("{:#?}", Value(vec![1, 2])),
876 format!("{:#?}", vec![1, 2])
877 );
878 assert_eq!(
879 format!("{:>12.3?}", Value(1.23456)),
880 format!("{:>12.3?}", 1.23456)
881 );
882 }
883
884 #[test]
885 fn forwards_format_errors() {
886 struct Fails;
887 impl core::fmt::LowerHex for Fails {
888 fn fmt(&self, _: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
889 Err(core::fmt::Error)
890 }
891 }
892 struct Value(Fails);
893 crate::forward_lower_hex!(Value);
894 let mut output = String::new();
895 assert!(core::fmt::write(&mut output, format_args!("{:x}", Value(Fails))).is_err());
896 }
897}