11//! Derive Debug for types where not all fields implement Debug.
22//!
3- //! This relies on specialization and thus requires nightly.
3+ //! This crate works on stable and with `no_std`.
4+ //! On nightly the `unstable` feature can be used for specialization based trait detection and/or `..` formatting.
45//!
5- //! This crate works with 'no_std'.
6- //!
7- //! ### Non Exhaustive
8- //!
9- //! Requires the `debug_non_exhaustive` feature.
10- //! Only available for structs with named fields.
6+ //! ### Placeholder with Type Info
117//!
128//! ```
13- //! #![feature(debug_non_exhaustive)]
14- //! use partialdebug::non_exhaustive::PartialDebug;
9+ //! use partialdebug::placeholder::PartialDebug;
1510//!
1611//! # struct DNA;
1712//! #
3227//! # }
3328//! # }
3429//! #
35- //! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, .. }");
30+ //! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, dna: DNA }");
3631//! ```
3732//!
38- //! ### Placeholder with Type Info
33+ //! ### Placeholder with Custom Text
3934//!
4035//! ```
4136//! use partialdebug::placeholder::PartialDebug;
4237//!
4338//! # struct DNA;
4439//! #
4540//! #[derive(PartialDebug)]
41+ //! #[debug_placeholder = "Unknown"]
4642//! struct Dog {
4743//! legs: usize,
4844//! eyes: usize,
5955//! # }
6056//! # }
6157//! #
62- //! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, dna: DNA }");
58+ //! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, dna: Unknown }");
6359//! ```
6460//!
65- //! ### Placeholder with Custom Text
61+ //! ### Non Exhaustive
62+ //!
63+ //! Only available on nightly after setting the `unstable` feature.
64+ //!
65+ //! Requires the `debug_non_exhaustive` feature to be enabled in user code.
66+ //!
67+ //! Only available for structs with named fields.
68+
69+ #![ cfg_attr(
70+ feature = "unstable" ,
71+ doc = r##"
72+ ```
73+ #![feature(debug_non_exhaustive)]
74+ use partialdebug::non_exhaustive::PartialDebug;
75+ # struct DNA;
76+ #
77+ #[derive(PartialDebug)]
78+ struct Dog {
79+ legs: usize,
80+ eyes: usize,
81+ dna: DNA,
82+ }
83+ # impl Dog {
84+ # fn new() -> Dog {
85+ # Dog {
86+ # legs: 4,
87+ # eyes: 2,
88+ # dna: DNA,
89+ # }
90+ # }
91+ # }
92+ #
93+ assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, .. }");
94+ ```
95+ "##
96+ ) ]
97+
98+ //! ### Caveats
99+ //!
100+ //! Trait detection for generic types requires specialization.
101+ //! To enable specialization based trait detection use a nightly compiler and enable the `unstable` feature.
66102//!
67103//! ```
68104//! use partialdebug::placeholder::PartialDebug;
69105//!
70- //! # struct DNA;
71- //! #
72106//! #[derive(PartialDebug)]
73- //! #[debug_placeholder = "Unknown"]
74- //! struct Dog {
75- //! legs: usize,
76- //! eyes: usize,
77- //! dna: DNA,
78- //! }
107+ //! struct Container<T>(T);
79108//!
80- //! # impl Dog {
81- //! # fn new() -> Dog {
82- //! # Dog {
83- //! # legs: 4,
84- //! # eyes: 2,
85- //! # dna: DNA,
86- //! # }
87- //! # }
88- //! # }
89- //! #
90- //! assert_eq!(format!("{:?}", Dog::new()), "Dog { legs: 4, eyes: 2, dna: Unknown }");
109+ //! #[cfg(feature = "unstable")]
110+ //! assert_eq!(format!("{:?}", Container(42)), "Container(42)");
111+ //! #[cfg(not(feature = "unstable"))]
112+ //! assert_eq!(format!("{:?}", Container(42)), "Container(T)");
91113//! ```
92114
93115#![ no_std]
94- #![ allow( incomplete_features) ]
95- #![ feature( specialization) ]
96116#![ warn( missing_docs, trivial_casts, rust_2018_idioms) ]
117+ #![ cfg_attr( feature = "unstable" , allow( incomplete_features) ) ]
118+ #![ cfg_attr( feature = "unstable" , feature( specialization) ) ]
97119
98120use core:: fmt:: { Debug , Formatter , Result } ;
99121
100- /// Specialized trait used to distinguish between types that implement Debug and one's that don't.
101- /// ```
102- /// # use partialdebug::AsDebug;
103- /// # struct DNA;
104- /// # let dna = DNA;
105- /// assert!(42.as_debug().is_some());
106- /// assert!(dna.as_debug().is_none());
107- /// ```
108- pub trait AsDebug {
109- /// Try to get a reference to `self` as `dyn Debug`
110- fn as_debug ( & self ) -> Option < & dyn Debug > ;
111- }
112-
113- impl < T > AsDebug for T {
114- default fn as_debug ( & self ) -> Option < & dyn Debug > {
115- None
116- }
117- }
118-
119- impl < T : Debug > AsDebug for T {
120- fn as_debug ( & self ) -> Option < & dyn Debug > {
121- Some ( self )
122- }
123- }
124-
125122/// Placeholder struct for types that do not implement Debug
126123/// ```
127124/// # use partialdebug::Placeholder;
@@ -135,12 +132,21 @@ impl Debug for Placeholder {
135132 }
136133}
137134
138- /// The non exhaustive version of `PartialDebug`
139- pub mod non_exhaustive {
140- pub use partialdebug_derive:: NonExhaustivePartialDebug as PartialDebug ;
141- }
135+ #[ cfg( any( not( feature = "unstable" ) , doc) ) ]
136+ pub mod no_specialization;
137+ /// Trait detection logic using specialization
138+ #[ cfg( feature = "unstable" ) ]
139+ pub mod specialization;
142140
143141/// The placeholder version of `PartialDebug`
144142pub mod placeholder {
143+ #[ cfg( not( feature = "unstable" ) ) ]
144+ pub use crate :: no_specialization:: NotDebug as PartialDebug ; // needs to be in scope
145145 pub use partialdebug_derive:: PlaceholderPartialDebug as PartialDebug ;
146146}
147+
148+ /// The non exhaustive version of `PartialDebug`
149+ #[ cfg( feature = "unstable" ) ]
150+ pub mod non_exhaustive {
151+ pub use partialdebug_derive:: NonExhaustivePartialDebug as PartialDebug ;
152+ }
0 commit comments