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