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