1 #![allow(dead_code, unused_imports)]
2 #[macro_use]
3 extern crate derive_more;
4 
5 use std::path::PathBuf;
6 
7 // Here just to make sure that this doesn't conflict with
8 // the derives in some way
9 use std::fmt::Binary;
10 
11 #[derive(Display, Octal, Binary)]
12 struct MyInt(i32);
13 
14 #[derive(UpperHex)]
15 enum IntEnum {
16     U8(u8),
17     I8(i8),
18 }
19 
20 #[derive(Display)]
21 #[display(fmt = "({}, {})", x, y)]
22 struct Point2D {
23     x: i32,
24     y: i32,
25 }
26 
27 #[derive(Display)]
28 #[display(fmt = "{}", "self.sign()")]
29 struct PositiveOrNegative {
30     x: i32,
31 }
32 
33 impl PositiveOrNegative {
sign(&self) -> &str34     fn sign(&self) -> &str {
35         if self.x >= 0 {
36             "Positive"
37         } else {
38             "Negative"
39         }
40     }
41 }
42 
43 #[derive(Display)]
44 #[display(fmt = "{}", message)]
45 struct Error {
46     message: &'static str,
47     backtrace: (),
48 }
49 
50 impl Error {
new(message: &'static str) -> Self51     fn new(message: &'static str) -> Self {
52         Self {
53             message,
54             backtrace: (),
55         }
56     }
57 }
58 
59 #[derive(Display)]
60 enum E {
61     Uint(u32),
62     #[display(fmt = "I am B {:b}", i)]
63     Binary {
64         i: i8,
65     },
66     #[display(fmt = "I am C {}", "_0.display()")]
67     Path(PathBuf),
68 }
69 
70 #[derive(Display)]
71 #[display(fmt = "Java EE")]
72 enum EE {
73     A,
74     B,
75 }
76 
77 #[derive(Display)]
78 #[display(fmt = "Hello there!")]
79 union U {
80     i: u32,
81 }
82 
83 #[derive(Octal)]
84 #[octal(fmt = "7")]
85 struct S;
86 
87 #[derive(UpperHex)]
88 #[upper_hex(fmt = "UpperHex")]
89 struct UH;
90 
91 #[derive(DebugCustom)]
92 #[debug(fmt = "MyDebug")]
93 struct D;
94 
95 #[derive(Display)]
96 struct Unit;
97 
98 #[derive(Display)]
99 struct UnitStruct {}
100 
101 #[derive(Display)]
102 enum EmptyEnum {}
103 
104 #[derive(Display)]
105 #[display(fmt = "Generic")]
106 struct Generic<T>(T);
107 
108 #[derive(Display)]
109 #[display(fmt = "Here's a prefix for {} and a suffix")]
110 enum Affix {
111     A(u32),
112     #[display(fmt = "{} -- {}", wat, stuff)]
113     B {
114         wat: String,
115         stuff: bool,
116     },
117 }
118 
119 #[derive(Debug, Display)]
120 #[display(fmt = "{:?}", self)]
121 struct DebugStructAsDisplay;
122 
123 #[test]
check_display()124 fn check_display() {
125     assert_eq!(MyInt(-2).to_string(), "-2");
126     assert_eq!(format!("{:b}", MyInt(9)), "1001");
127     assert_eq!(format!("{:#b}", MyInt(9)), "0b1001");
128     assert_eq!(format!("{:o}", MyInt(9)), "11");
129     assert_eq!(format!("{:X}", IntEnum::I8(-1)), "FF");
130     assert_eq!(format!("{:#X}", IntEnum::U8(255)), "0xFF");
131     assert_eq!(Point2D { x: 3, y: 4 }.to_string(), "(3, 4)");
132     assert_eq!(PositiveOrNegative { x: 123 }.to_string(), "Positive");
133     assert_eq!(PositiveOrNegative { x: 0 }.to_string(), "Positive");
134     assert_eq!(PositiveOrNegative { x: -465 }.to_string(), "Negative");
135     assert_eq!(Error::new("Error").to_string(), "Error");
136     assert_eq!(E::Uint(2).to_string(), "2");
137     assert_eq!(E::Binary { i: -2 }.to_string(), "I am B 11111110");
138     assert_eq!(E::Path("abc".into()).to_string(), "I am C abc");
139     assert_eq!(EE::A.to_string(), "Java EE");
140     assert_eq!(EE::B.to_string(), "Java EE");
141     assert_eq!(U { i: 2 }.to_string(), "Hello there!");
142     assert_eq!(format!("{:o}", S), "7");
143     assert_eq!(format!("{:X}", UH), "UpperHex");
144     assert_eq!(format!("{:?}", D), "MyDebug");
145     assert_eq!(Unit.to_string(), "Unit");
146     assert_eq!(UnitStruct {}.to_string(), "UnitStruct");
147     assert_eq!(Generic(()).to_string(), "Generic");
148     assert_eq!(
149         Affix::A(2).to_string(),
150         "Here's a prefix for 2 and a suffix"
151     );
152     assert_eq!(
153         Affix::B {
154             wat: "things".to_owned(),
155             stuff: false,
156         }
157         .to_string(),
158         "Here's a prefix for things -- false and a suffix"
159     );
160     assert_eq!(DebugStructAsDisplay.to_string(), "DebugStructAsDisplay");
161 }
162 
163 mod generic {
164     #[derive(Display)]
165     #[display(fmt = "Generic {}", field)]
166     struct NamedGenericStruct<T> {
167         field: T,
168     }
169     #[test]
named_generic_struct()170     fn named_generic_struct() {
171         assert_eq!(NamedGenericStruct { field: 1 }.to_string(), "Generic 1");
172     }
173 
174     #[derive(Display)]
175     struct AutoNamedGenericStruct<T> {
176         field: T,
177     }
178     #[test]
auto_named_generic_struct()179     fn auto_named_generic_struct() {
180         assert_eq!(AutoNamedGenericStruct { field: 1 }.to_string(), "1");
181     }
182 
183     #[derive(Display)]
184     #[display(fmt = "Generic {}", "_0")]
185     struct UnnamedGenericStruct<T>(T);
186     #[test]
unnamed_generic_struct()187     fn unnamed_generic_struct() {
188         assert_eq!(UnnamedGenericStruct(2).to_string(), "Generic 2");
189     }
190 
191     #[derive(Display)]
192     struct AutoUnnamedGenericStruct<T>(T);
193     #[test]
auto_unnamed_generic_struct()194     fn auto_unnamed_generic_struct() {
195         assert_eq!(AutoUnnamedGenericStruct(2).to_string(), "2");
196     }
197 
198     #[derive(Display)]
199     enum GenericEnum<A, B> {
200         #[display(fmt = "Gen::A {}", field)]
201         A { field: A },
202         #[display(fmt = "Gen::B {}", "_0")]
203         B(B),
204     }
205     #[test]
generic_enum()206     fn generic_enum() {
207         assert_eq!(GenericEnum::A::<_, u8> { field: 1 }.to_string(), "Gen::A 1");
208         assert_eq!(GenericEnum::B::<u8, _>(2).to_string(), "Gen::B 2");
209     }
210 
211     #[derive(Display)]
212     enum AutoGenericEnum<A, B> {
213         A { field: A },
214         B(B),
215     }
216     #[test]
auto_generic_enum()217     fn auto_generic_enum() {
218         assert_eq!(AutoGenericEnum::A::<_, u8> { field: 1 }.to_string(), "1");
219         assert_eq!(AutoGenericEnum::B::<u8, _>(2).to_string(), "2");
220     }
221 
222     #[derive(Display)]
223     #[display(fmt = "{} {} <-> {0:o} {1:#x} <-> {0:?} {1:X?}", a, b)]
224     struct MultiTraitNamedGenericStruct<A, B> {
225         a: A,
226         b: B,
227     }
228     #[test]
multi_trait_named_generic_struct()229     fn multi_trait_named_generic_struct() {
230         let s = MultiTraitNamedGenericStruct { a: 8u8, b: 255 };
231         assert_eq!(s.to_string(), "8 255 <-> 10 0xff <-> 8 FF");
232     }
233 
234     #[derive(Display)]
235     #[display(fmt = "{} {} {{}} {0:o} {1:#x} - {0:>4?} {1:^4X?}", "_0", "_1")]
236     struct MultiTraitUnnamedGenericStruct<A, B>(A, B);
237     #[test]
multi_trait_unnamed_generic_struct()238     fn multi_trait_unnamed_generic_struct() {
239         let s = MultiTraitUnnamedGenericStruct(8u8, 255);
240         assert_eq!(s.to_string(), "8 255 {} 10 0xff -    8  FF ");
241     }
242 
243     #[derive(Display)]
244     #[display(fmt = "{}", "3 * 4")]
245     struct UnusedGenericStruct<T>(T);
246     #[test]
unused_generic_struct()247     fn unused_generic_struct() {
248         let s = UnusedGenericStruct(());
249         assert_eq!(s.to_string(), "12");
250     }
251 
252     mod associated_type_field_enumerator {
253         use super::*;
254 
255         trait Trait {
256             type Type;
257         }
258 
259         struct Struct;
260 
261         impl Trait for Struct {
262             type Type = i32;
263         }
264 
265         #[test]
auto_generic_named_struct_associated()266         fn auto_generic_named_struct_associated() {
267             #[derive(Display)]
268             struct AutoGenericNamedStructAssociated<T: Trait> {
269                 field: <T as Trait>::Type,
270             }
271 
272             let s = AutoGenericNamedStructAssociated::<Struct> { field: 10 };
273             assert_eq!(s.to_string(), "10");
274         }
275 
276         #[test]
auto_generic_unnamed_struct_associated()277         fn auto_generic_unnamed_struct_associated() {
278             #[derive(Display)]
279             struct AutoGenericUnnamedStructAssociated<T: Trait>(<T as Trait>::Type);
280 
281             let s = AutoGenericUnnamedStructAssociated::<Struct>(10);
282             assert_eq!(s.to_string(), "10");
283         }
284 
285         #[test]
auto_generic_enum_associated()286         fn auto_generic_enum_associated() {
287             #[derive(Display)]
288             enum AutoGenericEnumAssociated<T: Trait> {
289                 Enumerator(<T as Trait>::Type),
290             }
291 
292             let e = AutoGenericEnumAssociated::<Struct>::Enumerator(10);
293             assert_eq!(e.to_string(), "10");
294         }
295     }
296 
297     mod complex_type_field_enumerator {
298         use super::*;
299 
300         #[derive(Display)]
301         struct Struct<T>(T);
302 
303         #[test]
auto_generic_named_struct_complex()304         fn auto_generic_named_struct_complex() {
305             #[derive(Display)]
306             struct AutoGenericNamedStructComplex<T> {
307                 field: Struct<T>,
308             }
309 
310             let s = AutoGenericNamedStructComplex { field: Struct(10) };
311             assert_eq!(s.to_string(), "10");
312         }
313 
314         #[test]
auto_generic_unnamed_struct_complex()315         fn auto_generic_unnamed_struct_complex() {
316             #[derive(Display)]
317             struct AutoGenericUnnamedStructComplex<T>(Struct<T>);
318 
319             let s = AutoGenericUnnamedStructComplex(Struct(10));
320             assert_eq!(s.to_string(), "10");
321         }
322 
323         #[test]
auto_generic_enum_complex()324         fn auto_generic_enum_complex() {
325             #[derive(Display)]
326             enum AutoGenericEnumComplex<T> {
327                 Enumerator(Struct<T>),
328             }
329 
330             let e = AutoGenericEnumComplex::Enumerator(Struct(10));
331             assert_eq!(e.to_string(), "10")
332         }
333     }
334 
335     mod reference {
336         use super::*;
337 
338         #[test]
auto_generic_reference()339         fn auto_generic_reference() {
340             #[derive(Display)]
341             struct AutoGenericReference<'a, T>(&'a T);
342 
343             let s = AutoGenericReference(&10);
344             assert_eq!(s.to_string(), "10");
345         }
346 
347         #[test]
auto_generic_static_reference()348         fn auto_generic_static_reference() {
349             #[derive(Display)]
350             struct AutoGenericStaticReference<T: 'static>(&'static T);
351 
352             let s = AutoGenericStaticReference(&10);
353             assert_eq!(s.to_string(), "10");
354         }
355     }
356 
357     mod indirect {
358         use super::*;
359 
360         #[derive(Display)]
361         struct Struct<T>(T);
362 
363         #[test]
auto_generic_indirect()364         fn auto_generic_indirect() {
365             #[derive(Display)]
366             struct AutoGenericIndirect<T: 'static>(Struct<&'static T>);
367 
368             const V: i32 = 10;
369             let s = AutoGenericIndirect(Struct(&V));
370             assert_eq!(s.to_string(), "10");
371         }
372     }
373 
374     mod bound {
375         use super::*;
376 
377         #[test]
simple()378         fn simple() {
379             #[derive(Display)]
380             #[display(fmt = "{} {}", _0, _1)]
381             struct Struct<T1, T2>(T1, T2);
382 
383             let s = Struct(10, 20);
384             assert_eq!(s.to_string(), "10 20");
385         }
386 
387         #[test]
redundant()388         fn redundant() {
389             #[derive(Display)]
390             #[display(bound = "T1: ::core::fmt::Display, T2: ::core::fmt::Display")]
391             #[display(fmt = "{} {}", _0, _1)]
392             struct Struct<T1, T2>(T1, T2);
393 
394             let s = Struct(10, 20);
395             assert_eq!(s.to_string(), "10 20");
396         }
397 
398         #[test]
complex()399         fn complex() {
400             trait Trait1 {
401                 fn function1(&self) -> &'static str;
402             }
403 
404             trait Trait2 {
405                 fn function2(&self) -> &'static str;
406             }
407 
408             impl Trait1 for i32 {
409                 fn function1(&self) -> &'static str {
410                     "WHAT"
411                 }
412             }
413 
414             impl Trait2 for i32 {
415                 fn function2(&self) -> &'static str {
416                     "EVER"
417                 }
418             }
419 
420             #[derive(Display)]
421             #[display(bound = "T1: Trait1 + Trait2, T2: Trait1 + Trait2")]
422             #[display(fmt = "{} {} {} {}", "_0.function1()", _0, "_1.function2()", _1)]
423             struct Struct<T1, T2>(T1, T2);
424 
425             let s = Struct(10, 20);
426             assert_eq!(s.to_string(), "WHAT 10 EVER 20");
427         }
428     }
429 }
430