1#[macro_export]
53macro_rules! forward_debug {
54 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
55 impl <$($generic: ::core::fmt::Debug),+> ::core::fmt::Debug for $this {
56 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
57 ::core::fmt::Debug::fmt(&self.$field, fmt)
58 }
59 }
60 };
61 (<$($generic:ident),+> in $this:ty $(,)?) => {
62 impl <$($generic: ::core::fmt::Debug),+> ::core::fmt::Debug for $this {
63 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
64 ::core::fmt::Debug::fmt(&self.0, fmt)
65 }
66 }
67 };
68 ($this:ty => $field:tt $(,)?) => {
69 impl ::core::fmt::Debug for $this {
70 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
71 ::core::fmt::Debug::fmt(&self.$field, fmt)
72 }
73 }
74 };
75 ($this:ty $(,)?) => {
76 impl ::core::fmt::Debug for $this {
77 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
78 ::core::fmt::Debug::fmt(&self.0, fmt)
79 }
80 }
81 };
82}
83
84#[macro_export]
136macro_rules! forward_binary {
137 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
138 impl <$($generic: ::core::fmt::Binary),+> ::core::fmt::Binary for $this {
139 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
140 ::core::fmt::Binary::fmt(&self.$field, fmt)
141 }
142 }
143 };
144 (<$($generic:ident),+> in $this:ty $(,)?) => {
145 impl <$($generic: ::core::fmt::Binary),+> ::core::fmt::Binary for $this {
146 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
147 ::core::fmt::Binary::fmt(&self.0, fmt)
148 }
149 }
150 };
151 ($this:ty => $field:tt $(,)?) => {
152 impl ::core::fmt::Binary for $this {
153 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
154 ::core::fmt::Binary::fmt(&self.$field, fmt)
155 }
156 }
157 };
158 ($this:ty $(,)?) => {
159 impl ::core::fmt::Binary for $this {
160 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
161 ::core::fmt::Binary::fmt(&self.0, fmt)
162 }
163 }
164 };
165}
166
167#[macro_export]
219macro_rules! forward_octal {
220 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
221 impl <$($generic: ::core::fmt::Octal),+> ::core::fmt::Octal for $this {
222 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
223 ::core::fmt::Octal::fmt(&self.$field, fmt)
224 }
225 }
226 };
227 (<$($generic:ident),+> in $this:ty $(,)?) => {
228 impl <$($generic: ::core::fmt::Octal),+> ::core::fmt::Octal for $this {
229 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
230 ::core::fmt::Octal::fmt(&self.0, fmt)
231 }
232 }
233 };
234 ($this:ty => $field:tt $(,)?) => {
235 impl ::core::fmt::Octal for $this {
236 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
237 ::core::fmt::Octal::fmt(&self.$field, fmt)
238 }
239 }
240 };
241 ($this:ty $(,)?) => {
242 impl ::core::fmt::Octal for $this {
243 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
244 ::core::fmt::Octal::fmt(&self.0, fmt)
245 }
246 }
247 };
248}
249
250#[macro_export]
302macro_rules! forward_lower_hex {
303 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
304 impl <$($generic: ::core::fmt::LowerHex),+> ::core::fmt::LowerHex for $this {
305 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
306 ::core::fmt::LowerHex::fmt(&self.$field, fmt)
307 }
308 }
309 };
310 (<$($generic:ident),+> in $this:ty $(,)?) => {
311 impl <$($generic: ::core::fmt::LowerHex),+> ::core::fmt::LowerHex for $this {
312 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
313 ::core::fmt::LowerHex::fmt(&self.0, fmt)
314 }
315 }
316 };
317 ($this:ty => $field:tt $(,)?) => {
318 impl ::core::fmt::LowerHex for $this {
319 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
320 ::core::fmt::LowerHex::fmt(&self.$field, fmt)
321 }
322 }
323 };
324 ($this:ty $(,)?) => {
325 impl ::core::fmt::LowerHex for $this {
326 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
327 ::core::fmt::LowerHex::fmt(&self.0, fmt)
328 }
329 }
330 };
331}
332
333#[macro_export]
385macro_rules! forward_upper_hex {
386 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
387 impl <$($generic: ::core::fmt::UpperHex),+> ::core::fmt::UpperHex for $this {
388 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
389 ::core::fmt::UpperHex::fmt(&self.$field, fmt)
390 }
391 }
392 };
393 (<$($generic:ident),+> in $this:ty $(,)?) => {
394 impl <$($generic: ::core::fmt::UpperHex),+> ::core::fmt::UpperHex for $this {
395 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
396 ::core::fmt::UpperHex::fmt(&self.0, fmt)
397 }
398 }
399 };
400 ($this:ty => $field:tt $(,)?) => {
401 impl ::core::fmt::UpperHex for $this {
402 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
403 ::core::fmt::UpperHex::fmt(&self.$field, fmt)
404 }
405 }
406 };
407 ($this:ty $(,)?) => {
408 impl ::core::fmt::UpperHex for $this {
409 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
410 ::core::fmt::UpperHex::fmt(&self.0, fmt)
411 }
412 }
413 };
414}
415
416#[macro_export]
468macro_rules! forward_lower_exp {
469 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
470 impl <$($generic: ::core::fmt::LowerExp),+> ::core::fmt::LowerExp for $this {
471 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
472 ::core::fmt::LowerExp::fmt(&self.$field, fmt)
473 }
474 }
475 };
476 (<$($generic:ident),+> in $this:ty $(,)?) => {
477 impl <$($generic: ::core::fmt::LowerExp),+> ::core::fmt::LowerExp for $this {
478 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
479 ::core::fmt::LowerExp::fmt(&self.0, fmt)
480 }
481 }
482 };
483 ($this:ty => $field:tt $(,)?) => {
484 impl ::core::fmt::LowerExp for $this {
485 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
486 ::core::fmt::LowerExp::fmt(&self.$field, fmt)
487 }
488 }
489 };
490 ($this:ty $(,)?) => {
491 impl ::core::fmt::LowerExp for $this {
492 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
493 ::core::fmt::LowerExp::fmt(&self.0, fmt)
494 }
495 }
496 };
497}
498
499#[macro_export]
551macro_rules! forward_upper_exp {
552 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
553 impl <$($generic: ::core::fmt::UpperExp),+> ::core::fmt::UpperExp for $this {
554 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
555 ::core::fmt::UpperExp::fmt(&self.$field, fmt)
556 }
557 }
558 };
559 (<$($generic:ident),+> in $this:ty $(,)?) => {
560 impl <$($generic: ::core::fmt::UpperExp),+> ::core::fmt::UpperExp for $this {
561 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
562 ::core::fmt::UpperExp::fmt(&self.0, fmt)
563 }
564 }
565 };
566 ($this:ty => $field:tt $(,)?) => {
567 impl ::core::fmt::UpperExp for $this {
568 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
569 ::core::fmt::UpperExp::fmt(&self.$field, fmt)
570 }
571 }
572 };
573 ($this:ty $(,)?) => {
574 impl ::core::fmt::UpperExp for $this {
575 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
576 ::core::fmt::UpperExp::fmt(&self.0, fmt)
577 }
578 }
579 };
580}
581
582#[macro_export]
634macro_rules! forward_pointer {
635 (<$($generic:ident),+> in $this:ty => $field:tt $(,)?) => {
636 impl <$($generic: ::core::fmt::Pointer),+> ::core::fmt::Pointer for $this {
637 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
638 ::core::fmt::Pointer::fmt(&self.$field, fmt)
639 }
640 }
641 };
642 (<$($generic:ident),+> in $this:ty $(,)?) => {
643 impl <$($generic: ::core::fmt::Pointer),+> ::core::fmt::Pointer for $this {
644 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
645 ::core::fmt::Pointer::fmt(&self.0, fmt)
646 }
647 }
648 };
649 ($this:ty => $field:tt $(,)?) => {
650 impl ::core::fmt::Pointer for $this {
651 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
652 ::core::fmt::Pointer::fmt(&self.$field, fmt)
653 }
654 }
655 };
656 ($this:ty $(,)?) => {
657 impl ::core::fmt::Pointer for $this {
658 fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
659 ::core::fmt::Pointer::fmt(&self.0, fmt)
660 }
661 }
662 };
663}
664
665#[cfg(test)]
666mod tests {
667 use alloc::{format, string::String, vec};
668
669 #[test]
670 fn debug_forwards_formatter_and_fields() {
671 struct Tuple(u32);
672 struct Named {
673 inner: u32,
674 }
675 struct Generic<T>(T);
676 struct GenericNamed<T> {
677 inner: T,
678 }
679 crate::forward_debug!(Tuple,);
680 crate::forward_debug!(Named => inner,);
681 crate::forward_debug!(<T> in Generic<T>);
682 crate::forward_debug!(<T> in GenericNamed<T> => inner);
683 let inner = 42u32;
684 let expected = format!("{:#012?}", inner);
685 assert_eq!(format!("{:#012?}", Tuple(inner)), expected);
686 assert_eq!(format!("{:#012?}", Named { inner }), expected);
687 assert_eq!(format!("{:#012?}", Generic(inner)), expected);
688 assert_eq!(format!("{:#012?}", GenericNamed { inner }), expected);
689 }
690
691 #[test]
692 fn binary_forwards_formatter_and_fields() {
693 struct Tuple(u32);
694 struct Named {
695 inner: u32,
696 }
697 struct Generic<T>(T);
698 struct GenericNamed<T> {
699 inner: T,
700 }
701 crate::forward_binary!(Tuple,);
702 crate::forward_binary!(Named => inner,);
703 crate::forward_binary!(<T> in Generic<T>);
704 crate::forward_binary!(<T> in GenericNamed<T> => inner);
705 let inner = 42u32;
706 let expected = format!("{:#012b}", inner);
707 assert_eq!(format!("{:#012b}", Tuple(inner)), expected);
708 assert_eq!(format!("{:#012b}", Named { inner }), expected);
709 assert_eq!(format!("{:#012b}", Generic(inner)), expected);
710 assert_eq!(format!("{:#012b}", GenericNamed { inner }), expected);
711 }
712
713 #[test]
714 fn octal_forwards_formatter_and_fields() {
715 struct Tuple(u32);
716 struct Named {
717 inner: u32,
718 }
719 struct Generic<T>(T);
720 struct GenericNamed<T> {
721 inner: T,
722 }
723 crate::forward_octal!(Tuple,);
724 crate::forward_octal!(Named => inner,);
725 crate::forward_octal!(<T> in Generic<T>);
726 crate::forward_octal!(<T> in GenericNamed<T> => inner);
727 let inner = 42u32;
728 let expected = format!("{:#012o}", inner);
729 assert_eq!(format!("{:#012o}", Tuple(inner)), expected);
730 assert_eq!(format!("{:#012o}", Named { inner }), expected);
731 assert_eq!(format!("{:#012o}", Generic(inner)), expected);
732 assert_eq!(format!("{:#012o}", GenericNamed { inner }), expected);
733 }
734
735 #[test]
736 fn lower_hex_forwards_formatter_and_fields() {
737 struct Tuple(u32);
738 struct Named {
739 inner: u32,
740 }
741 struct Generic<T>(T);
742 struct GenericNamed<T> {
743 inner: T,
744 }
745 crate::forward_lower_hex!(Tuple,);
746 crate::forward_lower_hex!(Named => inner,);
747 crate::forward_lower_hex!(<T> in Generic<T>);
748 crate::forward_lower_hex!(<T> in GenericNamed<T> => inner);
749 let inner = 42u32;
750 let expected = format!("{:#012x}", inner);
751 assert_eq!(format!("{:#012x}", Tuple(inner)), expected);
752 assert_eq!(format!("{:#012x}", Named { inner }), expected);
753 assert_eq!(format!("{:#012x}", Generic(inner)), expected);
754 assert_eq!(format!("{:#012x}", GenericNamed { inner }), expected);
755 }
756
757 #[test]
758 fn upper_hex_forwards_formatter_and_fields() {
759 struct Tuple(u32);
760 struct Named {
761 inner: u32,
762 }
763 struct Generic<T>(T);
764 struct GenericNamed<T> {
765 inner: T,
766 }
767 crate::forward_upper_hex!(Tuple,);
768 crate::forward_upper_hex!(Named => inner,);
769 crate::forward_upper_hex!(<T> in Generic<T>);
770 crate::forward_upper_hex!(<T> in GenericNamed<T> => inner);
771 let inner = 42u32;
772 let expected = format!("{:#012X}", inner);
773 assert_eq!(format!("{:#012X}", Tuple(inner)), expected);
774 assert_eq!(format!("{:#012X}", Named { inner }), expected);
775 assert_eq!(format!("{:#012X}", Generic(inner)), expected);
776 assert_eq!(format!("{:#012X}", GenericNamed { inner }), expected);
777 }
778
779 #[test]
780 fn lower_exp_forwards_formatter_and_fields() {
781 struct Tuple(u32);
782 struct Named {
783 inner: u32,
784 }
785 struct Generic<T>(T);
786 struct GenericNamed<T> {
787 inner: T,
788 }
789 crate::forward_lower_exp!(Tuple,);
790 crate::forward_lower_exp!(Named => inner,);
791 crate::forward_lower_exp!(<T> in Generic<T>);
792 crate::forward_lower_exp!(<T> in GenericNamed<T> => inner);
793 let inner = 42u32;
794 let expected = format!("{:#012e}", inner);
795 assert_eq!(format!("{:#012e}", Tuple(inner)), expected);
796 assert_eq!(format!("{:#012e}", Named { inner }), expected);
797 assert_eq!(format!("{:#012e}", Generic(inner)), expected);
798 assert_eq!(format!("{:#012e}", GenericNamed { inner }), expected);
799 }
800
801 #[test]
802 fn upper_exp_forwards_formatter_and_fields() {
803 struct Tuple(u32);
804 struct Named {
805 inner: u32,
806 }
807 struct Generic<T>(T);
808 struct GenericNamed<T> {
809 inner: T,
810 }
811 crate::forward_upper_exp!(Tuple,);
812 crate::forward_upper_exp!(Named => inner,);
813 crate::forward_upper_exp!(<T> in Generic<T>);
814 crate::forward_upper_exp!(<T> in GenericNamed<T> => inner);
815 let inner = 42u32;
816 let expected = format!("{:#012E}", inner);
817 assert_eq!(format!("{:#012E}", Tuple(inner)), expected);
818 assert_eq!(format!("{:#012E}", Named { inner }), expected);
819 assert_eq!(format!("{:#012E}", Generic(inner)), expected);
820 assert_eq!(format!("{:#012E}", GenericNamed { inner }), expected);
821 }
822
823 #[test]
824 fn pointer_forwards_formatter_and_fields() {
825 struct Tuple(*const i32);
826 struct Named {
827 inner: *const i32,
828 }
829 struct Generic<T>(T);
830 struct GenericNamed<T> {
831 inner: T,
832 }
833 crate::forward_pointer!(Tuple,);
834 crate::forward_pointer!(Named => inner,);
835 crate::forward_pointer!(<T> in Generic<T>);
836 crate::forward_pointer!(<T> in GenericNamed<T> => inner);
837 let inner = &42 as *const i32;
838 let expected = format!("{:#012p}", inner);
839 assert_eq!(format!("{:#012p}", Tuple(inner)), expected);
840 assert_eq!(format!("{:#012p}", Named { inner }), expected);
841 assert_eq!(format!("{:#012p}", Generic(inner)), expected);
842 assert_eq!(format!("{:#012p}", GenericNamed { inner }), expected);
843 }
844
845 #[test]
846 fn debug_preserves_pretty_layout_and_precision() {
847 struct Value<T>(T);
848 crate::forward_debug!(<T> in Value<T>);
849 assert_eq!(
850 format!("{:#?}", Value(vec![1, 2])),
851 format!("{:#?}", vec![1, 2])
852 );
853 assert_eq!(
854 format!("{:>12.3?}", Value(1.23456)),
855 format!("{:>12.3?}", 1.23456)
856 );
857 }
858
859 #[test]
860 fn forwards_format_errors() {
861 struct Fails;
862 impl core::fmt::LowerHex for Fails {
863 fn fmt(&self, _: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
864 Err(core::fmt::Error)
865 }
866 }
867 struct Value(Fails);
868 crate::forward_lower_hex!(Value);
869 let mut output = String::new();
870 assert!(core::fmt::write(&mut output, format_args!("{:x}", Value(Fails))).is_err());
871 }
872}