]>
Commit | Line | Data |
---|---|---|
1 | //! Utilities for formatting and printing strings. | |
2 | ||
3 | #![stable(feature = "rust1", since = "1.0.0")] | |
4 | ||
5 | use crate::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; | |
6 | use crate::marker::PhantomData; | |
7 | use crate::mem; | |
8 | use crate::num::flt2dec; | |
9 | use crate::ops::Deref; | |
10 | use crate::result; | |
11 | use crate::str; | |
12 | ||
13 | mod builders; | |
14 | mod float; | |
15 | mod num; | |
16 | ||
17 | #[stable(feature = "fmt_flags_align", since = "1.28.0")] | |
18 | /// Possible alignments returned by `Formatter::align` | |
19 | #[derive(Debug)] | |
20 | pub enum Alignment { | |
21 | #[stable(feature = "fmt_flags_align", since = "1.28.0")] | |
22 | /// Indication that contents should be left-aligned. | |
23 | Left, | |
24 | #[stable(feature = "fmt_flags_align", since = "1.28.0")] | |
25 | /// Indication that contents should be right-aligned. | |
26 | Right, | |
27 | #[stable(feature = "fmt_flags_align", since = "1.28.0")] | |
28 | /// Indication that contents should be center-aligned. | |
29 | Center, | |
30 | } | |
31 | ||
32 | #[stable(feature = "debug_builders", since = "1.2.0")] | |
33 | pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; | |
34 | ||
35 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
36 | #[doc(hidden)] | |
37 | pub mod rt { | |
38 | pub mod v1; | |
39 | } | |
40 | ||
41 | /// The type returned by formatter methods. | |
42 | /// | |
43 | /// # Examples | |
44 | /// | |
45 | /// ``` | |
46 | /// use std::fmt; | |
47 | /// | |
48 | /// #[derive(Debug)] | |
49 | /// struct Triangle { | |
50 | /// a: f32, | |
51 | /// b: f32, | |
52 | /// c: f32 | |
53 | /// } | |
54 | /// | |
55 | /// impl fmt::Display for Triangle { | |
56 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
57 | /// write!(f, "({}, {}, {})", self.a, self.b, self.c) | |
58 | /// } | |
59 | /// } | |
60 | /// | |
61 | /// let pythagorean_triple = Triangle { a: 3.0, b: 4.0, c: 5.0 }; | |
62 | /// | |
63 | /// assert_eq!(format!("{}", pythagorean_triple), "(3, 4, 5)"); | |
64 | /// ``` | |
65 | #[stable(feature = "rust1", since = "1.0.0")] | |
66 | pub type Result = result::Result<(), Error>; | |
67 | ||
68 | /// The error type which is returned from formatting a message into a stream. | |
69 | /// | |
70 | /// This type does not support transmission of an error other than that an error | |
71 | /// occurred. Any extra information must be arranged to be transmitted through | |
72 | /// some other means. | |
73 | /// | |
74 | /// An important thing to remember is that the type `fmt::Error` should not be | |
75 | /// confused with [`std::io::Error`] or [`std::error::Error`], which you may also | |
76 | /// have in scope. | |
77 | /// | |
78 | /// [`std::io::Error`]: ../../std/io/struct.Error.html | |
79 | /// [`std::error::Error`]: ../../std/error/trait.Error.html | |
80 | /// | |
81 | /// # Examples | |
82 | /// | |
83 | /// ```rust | |
84 | /// use std::fmt::{self, write}; | |
85 | /// | |
86 | /// let mut output = String::new(); | |
87 | /// if let Err(fmt::Error) = write(&mut output, format_args!("Hello {}!", "world")) { | |
88 | /// panic!("An error occurred"); | |
89 | /// } | |
90 | /// ``` | |
91 | #[stable(feature = "rust1", since = "1.0.0")] | |
92 | #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] | |
93 | pub struct Error; | |
94 | ||
95 | /// A trait for writing or formatting into Unicode-accepting buffers or streams. | |
96 | /// | |
97 | /// This trait only accepts UTF-8–encoded data and is not [flushable]. If you only | |
98 | /// want to accept Unicode and you don't need flushing, you should implement this trait; | |
99 | /// otherwise you should implement [`std::io::Write`]. | |
100 | /// | |
101 | /// [`std::io::Write`]: ../../std/io/trait.Write.html | |
102 | /// [flushable]: ../../std/io/trait.Write.html#tymethod.flush | |
103 | #[stable(feature = "rust1", since = "1.0.0")] | |
104 | pub trait Write { | |
105 | /// Writes a string slice into this writer, returning whether the write | |
106 | /// succeeded. | |
107 | /// | |
108 | /// This method can only succeed if the entire string slice was successfully | |
109 | /// written, and this method will not return until all data has been | |
110 | /// written or an error occurs. | |
111 | /// | |
112 | /// # Errors | |
113 | /// | |
114 | /// This function will return an instance of [`Error`] on error. | |
115 | /// | |
116 | /// # Examples | |
117 | /// | |
118 | /// ``` | |
119 | /// use std::fmt::{Error, Write}; | |
120 | /// | |
121 | /// fn writer<W: Write>(f: &mut W, s: &str) -> Result<(), Error> { | |
122 | /// f.write_str(s) | |
123 | /// } | |
124 | /// | |
125 | /// let mut buf = String::new(); | |
126 | /// writer(&mut buf, "hola").unwrap(); | |
127 | /// assert_eq!(&buf, "hola"); | |
128 | /// ``` | |
129 | #[stable(feature = "rust1", since = "1.0.0")] | |
130 | fn write_str(&mut self, s: &str) -> Result; | |
131 | ||
132 | /// Writes a [`char`] into this writer, returning whether the write succeeded. | |
133 | /// | |
134 | /// A single [`char`] may be encoded as more than one byte. | |
135 | /// This method can only succeed if the entire byte sequence was successfully | |
136 | /// written, and this method will not return until all data has been | |
137 | /// written or an error occurs. | |
138 | /// | |
139 | /// # Errors | |
140 | /// | |
141 | /// This function will return an instance of [`Error`] on error. | |
142 | /// | |
143 | /// # Examples | |
144 | /// | |
145 | /// ``` | |
146 | /// use std::fmt::{Error, Write}; | |
147 | /// | |
148 | /// fn writer<W: Write>(f: &mut W, c: char) -> Result<(), Error> { | |
149 | /// f.write_char(c) | |
150 | /// } | |
151 | /// | |
152 | /// let mut buf = String::new(); | |
153 | /// writer(&mut buf, 'a').unwrap(); | |
154 | /// writer(&mut buf, 'b').unwrap(); | |
155 | /// assert_eq!(&buf, "ab"); | |
156 | /// ``` | |
157 | #[stable(feature = "fmt_write_char", since = "1.1.0")] | |
158 | fn write_char(&mut self, c: char) -> Result { | |
159 | self.write_str(c.encode_utf8(&mut [0; 4])) | |
160 | } | |
161 | ||
162 | /// Glue for usage of the [`write!`] macro with implementors of this trait. | |
163 | /// | |
164 | /// This method should generally not be invoked manually, but rather through | |
165 | /// the [`write!`] macro itself. | |
166 | /// | |
167 | /// # Examples | |
168 | /// | |
169 | /// ``` | |
170 | /// use std::fmt::{Error, Write}; | |
171 | /// | |
172 | /// fn writer<W: Write>(f: &mut W, s: &str) -> Result<(), Error> { | |
173 | /// f.write_fmt(format_args!("{}", s)) | |
174 | /// } | |
175 | /// | |
176 | /// let mut buf = String::new(); | |
177 | /// writer(&mut buf, "world").unwrap(); | |
178 | /// assert_eq!(&buf, "world"); | |
179 | /// ``` | |
180 | #[stable(feature = "rust1", since = "1.0.0")] | |
181 | fn write_fmt(mut self: &mut Self, args: Arguments<'_>) -> Result { | |
182 | write(&mut self, args) | |
183 | } | |
184 | } | |
185 | ||
186 | #[stable(feature = "fmt_write_blanket_impl", since = "1.4.0")] | |
187 | impl<W: Write + ?Sized> Write for &mut W { | |
188 | fn write_str(&mut self, s: &str) -> Result { | |
189 | (**self).write_str(s) | |
190 | } | |
191 | ||
192 | fn write_char(&mut self, c: char) -> Result { | |
193 | (**self).write_char(c) | |
194 | } | |
195 | ||
196 | fn write_fmt(&mut self, args: Arguments<'_>) -> Result { | |
197 | (**self).write_fmt(args) | |
198 | } | |
199 | } | |
200 | ||
201 | /// Configuration for formatting. | |
202 | /// | |
203 | /// A `Formatter` represents various options related to formatting. Users do not | |
204 | /// construct `Formatter`s directly; a mutable reference to one is passed to | |
205 | /// the `fmt` method of all formatting traits, like [`Debug`] and [`Display`]. | |
206 | /// | |
207 | /// To interact with a `Formatter`, you'll call various methods to change the | |
208 | /// various options related to formatting. For examples, please see the | |
209 | /// documentation of the methods defined on `Formatter` below. | |
210 | #[allow(missing_debug_implementations)] | |
211 | #[stable(feature = "rust1", since = "1.0.0")] | |
212 | pub struct Formatter<'a> { | |
213 | flags: u32, | |
214 | fill: char, | |
215 | align: rt::v1::Alignment, | |
216 | width: Option<usize>, | |
217 | precision: Option<usize>, | |
218 | ||
219 | buf: &'a mut (dyn Write + 'a), | |
220 | } | |
221 | ||
222 | // NB. Argument is essentially an optimized partially applied formatting function, | |
223 | // equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`. | |
224 | ||
225 | extern "C" { | |
226 | type Opaque; | |
227 | } | |
228 | ||
229 | /// This struct represents the generic "argument" which is taken by the Xprintf | |
230 | /// family of functions. It contains a function to format the given value. At | |
231 | /// compile time it is ensured that the function and the value have the correct | |
232 | /// types, and then this struct is used to canonicalize arguments to one type. | |
233 | #[derive(Copy, Clone)] | |
234 | #[allow(missing_debug_implementations)] | |
235 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
236 | #[doc(hidden)] | |
237 | pub struct ArgumentV1<'a> { | |
238 | value: &'a Opaque, | |
239 | formatter: fn(&Opaque, &mut Formatter<'_>) -> Result, | |
240 | } | |
241 | ||
242 | // This guarantees a single stable value for the function pointer associated with | |
243 | // indices/counts in the formatting infrastructure. | |
244 | // | |
245 | // Note that a function defined as such would not be correct as functions are | |
246 | // always tagged unnamed_addr with the current lowering to LLVM IR, so their | |
247 | // address is not considered important to LLVM and as such the as_usize cast | |
248 | // could have been miscompiled. In practice, we never call as_usize on non-usize | |
249 | // containing data (as a matter of static generation of the formatting | |
250 | // arguments), so this is merely an additional check. | |
251 | // | |
252 | // We primarily want to ensure that the function pointer at `USIZE_MARKER` has | |
253 | // an address corresponding *only* to functions that also take `&usize` as their | |
254 | // first argument. The read_volatile here ensures that we can safely ready out a | |
255 | // usize from the passed reference and that this address does not point at a | |
256 | // non-usize taking function. | |
257 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
258 | static USIZE_MARKER: fn(&usize, &mut Formatter<'_>) -> Result = |ptr, _| { | |
259 | // SAFETY: ptr is a reference | |
260 | let _v: usize = unsafe { crate::ptr::read_volatile(ptr) }; | |
261 | loop {} | |
262 | }; | |
263 | ||
264 | impl<'a> ArgumentV1<'a> { | |
265 | #[doc(hidden)] | |
266 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
267 | pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> { | |
268 | // SAFETY: `mem::transmute(x)` is safe because | |
269 | // 1. `&'b T` keeps the lifetime it originated with `'b` | |
270 | // (so as to not have an unbounded lifetime) | |
271 | // 2. `&'b T` and `&'b Opaque` have the same memory layout | |
272 | // (when `T` is `Sized`, as it is here) | |
273 | // `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result` | |
274 | // and `fn(&Opaque, &mut Formatter<'_>) -> Result` have the same ABI | |
275 | // (as long as `T` is `Sized`) | |
276 | unsafe { ArgumentV1 { formatter: mem::transmute(f), value: mem::transmute(x) } } | |
277 | } | |
278 | ||
279 | #[doc(hidden)] | |
280 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
281 | pub fn from_usize(x: &usize) -> ArgumentV1<'_> { | |
282 | ArgumentV1::new(x, USIZE_MARKER) | |
283 | } | |
284 | ||
285 | fn as_usize(&self) -> Option<usize> { | |
286 | if self.formatter as usize == USIZE_MARKER as usize { | |
287 | // SAFETY: The `formatter` field is only set to USIZE_MARKER if | |
288 | // the value is a usize, so this is safe | |
289 | Some(unsafe { *(self.value as *const _ as *const usize) }) | |
290 | } else { | |
291 | None | |
292 | } | |
293 | } | |
294 | } | |
295 | ||
296 | // flags available in the v1 format of format_args | |
297 | #[derive(Copy, Clone)] | |
298 | enum FlagV1 { | |
299 | SignPlus, | |
300 | SignMinus, | |
301 | Alternate, | |
302 | SignAwareZeroPad, | |
303 | DebugLowerHex, | |
304 | DebugUpperHex, | |
305 | } | |
306 | ||
307 | impl<'a> Arguments<'a> { | |
308 | /// When using the format_args!() macro, this function is used to generate the | |
309 | /// Arguments structure. | |
310 | #[doc(hidden)] | |
311 | #[inline] | |
312 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
313 | pub fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { | |
314 | Arguments { pieces, fmt: None, args } | |
315 | } | |
316 | ||
317 | /// This function is used to specify nonstandard formatting parameters. | |
318 | /// The `pieces` array must be at least as long as `fmt` to construct | |
319 | /// a valid Arguments structure. Also, any `Count` within `fmt` that is | |
320 | /// `CountIsParam` or `CountIsNextParam` has to point to an argument | |
321 | /// created with `argumentusize`. However, failing to do so doesn't cause | |
322 | /// unsafety, but will ignore invalid . | |
323 | #[doc(hidden)] | |
324 | #[inline] | |
325 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
326 | pub fn new_v1_formatted( | |
327 | pieces: &'a [&'static str], | |
328 | args: &'a [ArgumentV1<'a>], | |
329 | fmt: &'a [rt::v1::Argument], | |
330 | ) -> Arguments<'a> { | |
331 | Arguments { pieces, fmt: Some(fmt), args } | |
332 | } | |
333 | ||
334 | /// Estimates the length of the formatted text. | |
335 | /// | |
336 | /// This is intended to be used for setting initial `String` capacity | |
337 | /// when using `format!`. Note: this is neither the lower nor upper bound. | |
338 | #[doc(hidden)] | |
339 | #[inline] | |
340 | #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] | |
341 | pub fn estimated_capacity(&self) -> usize { | |
342 | let pieces_length: usize = self.pieces.iter().map(|x| x.len()).sum(); | |
343 | ||
344 | if self.args.is_empty() { | |
345 | pieces_length | |
346 | } else if self.pieces[0] == "" && pieces_length < 16 { | |
347 | // If the format string starts with an argument, | |
348 | // don't preallocate anything, unless length | |
349 | // of pieces is significant. | |
350 | 0 | |
351 | } else { | |
352 | // There are some arguments, so any additional push | |
353 | // will reallocate the string. To avoid that, | |
354 | // we're "pre-doubling" the capacity here. | |
355 | pieces_length.checked_mul(2).unwrap_or(0) | |
356 | } | |
357 | } | |
358 | } | |
359 | ||
360 | /// This structure represents a safely precompiled version of a format string | |
361 | /// and its arguments. This cannot be generated at runtime because it cannot | |
362 | /// safely be done, so no constructors are given and the fields are private | |
363 | /// to prevent modification. | |
364 | /// | |
365 | /// The [`format_args!`] macro will safely create an instance of this structure. | |
366 | /// The macro validates the format string at compile-time so usage of the | |
367 | /// [`write()`] and [`format()`] functions can be safely performed. | |
368 | /// | |
369 | /// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug` | |
370 | /// and `Display` contexts as seen below. The example also shows that `Debug` | |
371 | /// and `Display` format to the same thing: the interpolated format string | |
372 | /// in `format_args!`. | |
373 | /// | |
374 | /// ```rust | |
375 | /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); | |
376 | /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2)); | |
377 | /// assert_eq!("1 foo 2", display); | |
378 | /// assert_eq!(display, debug); | |
379 | /// ``` | |
380 | /// | |
381 | /// [`format()`]: ../../std/fmt/fn.format.html | |
382 | #[stable(feature = "rust1", since = "1.0.0")] | |
383 | #[derive(Copy, Clone)] | |
384 | pub struct Arguments<'a> { | |
385 | // Format string pieces to print. | |
386 | pieces: &'a [&'static str], | |
387 | ||
388 | // Placeholder specs, or `None` if all specs are default (as in "{}{}"). | |
389 | fmt: Option<&'a [rt::v1::Argument]>, | |
390 | ||
391 | // Dynamic arguments for interpolation, to be interleaved with string | |
392 | // pieces. (Every argument is preceded by a string piece.) | |
393 | args: &'a [ArgumentV1<'a>], | |
394 | } | |
395 | ||
396 | impl<'a> Arguments<'a> { | |
397 | /// Get the formatted string, if it has no arguments to be formatted. | |
398 | /// | |
399 | /// This can be used to avoid allocations in the most trivial case. | |
400 | /// | |
401 | /// # Examples | |
402 | /// | |
403 | /// ```rust | |
404 | /// use std::fmt::Arguments; | |
405 | /// | |
406 | /// fn write_str(_: &str) { /* ... */ } | |
407 | /// | |
408 | /// fn write_fmt(args: &Arguments) { | |
409 | /// if let Some(s) = args.as_str() { | |
410 | /// write_str(s) | |
411 | /// } else { | |
412 | /// write_str(&args.to_string()); | |
413 | /// } | |
414 | /// } | |
415 | /// ``` | |
416 | /// | |
417 | /// ```rust | |
418 | /// assert_eq!(format_args!("hello").as_str(), Some("hello")); | |
419 | /// assert_eq!(format_args!("").as_str(), Some("")); | |
420 | /// assert_eq!(format_args!("{}", 1).as_str(), None); | |
421 | /// ``` | |
422 | #[stable(feature = "fmt_as_str", since = "1.52.0")] | |
423 | #[inline] | |
424 | pub fn as_str(&self) -> Option<&'static str> { | |
425 | match (self.pieces, self.args) { | |
426 | ([], []) => Some(""), | |
427 | ([s], []) => Some(s), | |
428 | _ => None, | |
429 | } | |
430 | } | |
431 | } | |
432 | ||
433 | #[stable(feature = "rust1", since = "1.0.0")] | |
434 | impl Debug for Arguments<'_> { | |
435 | fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { | |
436 | Display::fmt(self, fmt) | |
437 | } | |
438 | } | |
439 | ||
440 | #[stable(feature = "rust1", since = "1.0.0")] | |
441 | impl Display for Arguments<'_> { | |
442 | fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { | |
443 | write(fmt.buf, *self) | |
444 | } | |
445 | } | |
446 | ||
447 | /// `?` formatting. | |
448 | /// | |
449 | /// `Debug` should format the output in a programmer-facing, debugging context. | |
450 | /// | |
451 | /// Generally speaking, you should just `derive` a `Debug` implementation. | |
452 | /// | |
453 | /// When used with the alternate format specifier `#?`, the output is pretty-printed. | |
454 | /// | |
455 | /// For more information on formatters, see [the module-level documentation][module]. | |
456 | /// | |
457 | /// [module]: ../../std/fmt/index.html | |
458 | /// | |
459 | /// This trait can be used with `#[derive]` if all fields implement `Debug`. When | |
460 | /// `derive`d for structs, it will use the name of the `struct`, then `{`, then a | |
461 | /// comma-separated list of each field's name and `Debug` value, then `}`. For | |
462 | /// `enum`s, it will use the name of the variant and, if applicable, `(`, then the | |
463 | /// `Debug` values of the fields, then `)`. | |
464 | /// | |
465 | /// # Stability | |
466 | /// | |
467 | /// Derived `Debug` formats are not stable, and so may change with future Rust | |
468 | /// versions. Additionally, `Debug` implementations of types provided by the | |
469 | /// standard library (`libstd`, `libcore`, `liballoc`, etc.) are not stable, and | |
470 | /// may also change with future Rust versions. | |
471 | /// | |
472 | /// # Examples | |
473 | /// | |
474 | /// Deriving an implementation: | |
475 | /// | |
476 | /// ``` | |
477 | /// #[derive(Debug)] | |
478 | /// struct Point { | |
479 | /// x: i32, | |
480 | /// y: i32, | |
481 | /// } | |
482 | /// | |
483 | /// let origin = Point { x: 0, y: 0 }; | |
484 | /// | |
485 | /// assert_eq!(format!("The origin is: {:?}", origin), "The origin is: Point { x: 0, y: 0 }"); | |
486 | /// ``` | |
487 | /// | |
488 | /// Manually implementing: | |
489 | /// | |
490 | /// ``` | |
491 | /// use std::fmt; | |
492 | /// | |
493 | /// struct Point { | |
494 | /// x: i32, | |
495 | /// y: i32, | |
496 | /// } | |
497 | /// | |
498 | /// impl fmt::Debug for Point { | |
499 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
500 | /// f.debug_struct("Point") | |
501 | /// .field("x", &self.x) | |
502 | /// .field("y", &self.y) | |
503 | /// .finish() | |
504 | /// } | |
505 | /// } | |
506 | /// | |
507 | /// let origin = Point { x: 0, y: 0 }; | |
508 | /// | |
509 | /// assert_eq!(format!("The origin is: {:?}", origin), "The origin is: Point { x: 0, y: 0 }"); | |
510 | /// ``` | |
511 | /// | |
512 | /// There are a number of helper methods on the [`Formatter`] struct to help you with manual | |
513 | /// implementations, such as [`debug_struct`]. | |
514 | /// | |
515 | /// `Debug` implementations using either `derive` or the debug builder API | |
516 | /// on [`Formatter`] support pretty-printing using the alternate flag: `{:#?}`. | |
517 | /// | |
518 | /// [`debug_struct`]: Formatter::debug_struct | |
519 | /// | |
520 | /// Pretty-printing with `#?`: | |
521 | /// | |
522 | /// ``` | |
523 | /// #[derive(Debug)] | |
524 | /// struct Point { | |
525 | /// x: i32, | |
526 | /// y: i32, | |
527 | /// } | |
528 | /// | |
529 | /// let origin = Point { x: 0, y: 0 }; | |
530 | /// | |
531 | /// assert_eq!(format!("The origin is: {:#?}", origin), | |
532 | /// "The origin is: Point { | |
533 | /// x: 0, | |
534 | /// y: 0, | |
535 | /// }"); | |
536 | /// ``` | |
537 | ||
538 | #[stable(feature = "rust1", since = "1.0.0")] | |
539 | #[rustc_on_unimplemented( | |
540 | on( | |
541 | crate_local, | |
542 | label = "`{Self}` cannot be formatted using `{{:?}}`", | |
543 | note = "add `#[derive(Debug)]` or manually implement `{Debug}`" | |
544 | ), | |
545 | message = "`{Self}` doesn't implement `{Debug}`", | |
546 | label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`" | |
547 | )] | |
548 | #[doc(alias = "{:?}")] | |
549 | #[rustc_diagnostic_item = "debug_trait"] | |
550 | pub trait Debug { | |
551 | /// Formats the value using the given formatter. | |
552 | /// | |
553 | /// # Examples | |
554 | /// | |
555 | /// ``` | |
556 | /// use std::fmt; | |
557 | /// | |
558 | /// struct Position { | |
559 | /// longitude: f32, | |
560 | /// latitude: f32, | |
561 | /// } | |
562 | /// | |
563 | /// impl fmt::Debug for Position { | |
564 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
565 | /// f.debug_tuple("") | |
566 | /// .field(&self.longitude) | |
567 | /// .field(&self.latitude) | |
568 | /// .finish() | |
569 | /// } | |
570 | /// } | |
571 | /// | |
572 | /// let position = Position { longitude: 1.987, latitude: 2.983 }; | |
573 | /// assert_eq!(format!("{:?}", position), "(1.987, 2.983)"); | |
574 | /// | |
575 | /// assert_eq!(format!("{:#?}", position), "( | |
576 | /// 1.987, | |
577 | /// 2.983, | |
578 | /// )"); | |
579 | /// ``` | |
580 | #[stable(feature = "rust1", since = "1.0.0")] | |
581 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
582 | } | |
583 | ||
584 | // Separate module to reexport the macro `Debug` from prelude without the trait `Debug`. | |
585 | pub(crate) mod macros { | |
586 | /// Derive macro generating an impl of the trait `Debug`. | |
587 | #[rustc_builtin_macro] | |
588 | #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] | |
589 | #[allow_internal_unstable(core_intrinsics)] | |
590 | pub macro Debug($item:item) { | |
591 | /* compiler built-in */ | |
592 | } | |
593 | } | |
594 | #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] | |
595 | #[doc(inline)] | |
596 | pub use macros::Debug; | |
597 | ||
598 | /// Format trait for an empty format, `{}`. | |
599 | /// | |
600 | /// `Display` is similar to [`Debug`], but `Display` is for user-facing | |
601 | /// output, and so cannot be derived. | |
602 | /// | |
603 | /// For more information on formatters, see [the module-level documentation][module]. | |
604 | /// | |
605 | /// [module]: ../../std/fmt/index.html | |
606 | /// | |
607 | /// # Examples | |
608 | /// | |
609 | /// Implementing `Display` on a type: | |
610 | /// | |
611 | /// ``` | |
612 | /// use std::fmt; | |
613 | /// | |
614 | /// struct Point { | |
615 | /// x: i32, | |
616 | /// y: i32, | |
617 | /// } | |
618 | /// | |
619 | /// impl fmt::Display for Point { | |
620 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
621 | /// write!(f, "({}, {})", self.x, self.y) | |
622 | /// } | |
623 | /// } | |
624 | /// | |
625 | /// let origin = Point { x: 0, y: 0 }; | |
626 | /// | |
627 | /// assert_eq!(format!("The origin is: {}", origin), "The origin is: (0, 0)"); | |
628 | /// ``` | |
629 | #[rustc_on_unimplemented( | |
630 | on( | |
631 | _Self = "std::path::Path", | |
632 | label = "`{Self}` cannot be formatted with the default formatter; call `.display()` on it", | |
633 | note = "call `.display()` or `.to_string_lossy()` to safely print paths, \ | |
634 | as they may contain non-Unicode data" | |
635 | ), | |
636 | message = "`{Self}` doesn't implement `{Display}`", | |
637 | label = "`{Self}` cannot be formatted with the default formatter", | |
638 | note = "in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead" | |
639 | )] | |
640 | #[doc(alias = "{}")] | |
641 | #[stable(feature = "rust1", since = "1.0.0")] | |
642 | pub trait Display { | |
643 | /// Formats the value using the given formatter. | |
644 | /// | |
645 | /// # Examples | |
646 | /// | |
647 | /// ``` | |
648 | /// use std::fmt; | |
649 | /// | |
650 | /// struct Position { | |
651 | /// longitude: f32, | |
652 | /// latitude: f32, | |
653 | /// } | |
654 | /// | |
655 | /// impl fmt::Display for Position { | |
656 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
657 | /// write!(f, "({}, {})", self.longitude, self.latitude) | |
658 | /// } | |
659 | /// } | |
660 | /// | |
661 | /// assert_eq!("(1.987, 2.983)", | |
662 | /// format!("{}", Position { longitude: 1.987, latitude: 2.983, })); | |
663 | /// ``` | |
664 | #[stable(feature = "rust1", since = "1.0.0")] | |
665 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
666 | } | |
667 | ||
668 | /// `o` formatting. | |
669 | /// | |
670 | /// The `Octal` trait should format its output as a number in base-8. | |
671 | /// | |
672 | /// For primitive signed integers (`i8` to `i128`, and `isize`), | |
673 | /// negative values are formatted as the two’s complement representation. | |
674 | /// | |
675 | /// The alternate flag, `#`, adds a `0o` in front of the output. | |
676 | /// | |
677 | /// For more information on formatters, see [the module-level documentation][module]. | |
678 | /// | |
679 | /// [module]: ../../std/fmt/index.html | |
680 | /// | |
681 | /// # Examples | |
682 | /// | |
683 | /// Basic usage with `i32`: | |
684 | /// | |
685 | /// ``` | |
686 | /// let x = 42; // 42 is '52' in octal | |
687 | /// | |
688 | /// assert_eq!(format!("{:o}", x), "52"); | |
689 | /// assert_eq!(format!("{:#o}", x), "0o52"); | |
690 | /// | |
691 | /// assert_eq!(format!("{:o}", -16), "37777777760"); | |
692 | /// ``` | |
693 | /// | |
694 | /// Implementing `Octal` on a type: | |
695 | /// | |
696 | /// ``` | |
697 | /// use std::fmt; | |
698 | /// | |
699 | /// struct Length(i32); | |
700 | /// | |
701 | /// impl fmt::Octal for Length { | |
702 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
703 | /// let val = self.0; | |
704 | /// | |
705 | /// fmt::Octal::fmt(&val, f) // delegate to i32's implementation | |
706 | /// } | |
707 | /// } | |
708 | /// | |
709 | /// let l = Length(9); | |
710 | /// | |
711 | /// assert_eq!(format!("l as octal is: {:o}", l), "l as octal is: 11"); | |
712 | /// | |
713 | /// assert_eq!(format!("l as octal is: {:#06o}", l), "l as octal is: 0o0011"); | |
714 | /// ``` | |
715 | #[stable(feature = "rust1", since = "1.0.0")] | |
716 | pub trait Octal { | |
717 | /// Formats the value using the given formatter. | |
718 | #[stable(feature = "rust1", since = "1.0.0")] | |
719 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
720 | } | |
721 | ||
722 | /// `b` formatting. | |
723 | /// | |
724 | /// The `Binary` trait should format its output as a number in binary. | |
725 | /// | |
726 | /// For primitive signed integers ([`i8`] to [`i128`], and [`isize`]), | |
727 | /// negative values are formatted as the two’s complement representation. | |
728 | /// | |
729 | /// The alternate flag, `#`, adds a `0b` in front of the output. | |
730 | /// | |
731 | /// For more information on formatters, see [the module-level documentation][module]. | |
732 | /// | |
733 | /// [module]: ../../std/fmt/index.html | |
734 | /// | |
735 | /// # Examples | |
736 | /// | |
737 | /// Basic usage with [`i32`]: | |
738 | /// | |
739 | /// ``` | |
740 | /// let x = 42; // 42 is '101010' in binary | |
741 | /// | |
742 | /// assert_eq!(format!("{:b}", x), "101010"); | |
743 | /// assert_eq!(format!("{:#b}", x), "0b101010"); | |
744 | /// | |
745 | /// assert_eq!(format!("{:b}", -16), "11111111111111111111111111110000"); | |
746 | /// ``` | |
747 | /// | |
748 | /// Implementing `Binary` on a type: | |
749 | /// | |
750 | /// ``` | |
751 | /// use std::fmt; | |
752 | /// | |
753 | /// struct Length(i32); | |
754 | /// | |
755 | /// impl fmt::Binary for Length { | |
756 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
757 | /// let val = self.0; | |
758 | /// | |
759 | /// fmt::Binary::fmt(&val, f) // delegate to i32's implementation | |
760 | /// } | |
761 | /// } | |
762 | /// | |
763 | /// let l = Length(107); | |
764 | /// | |
765 | /// assert_eq!(format!("l as binary is: {:b}", l), "l as binary is: 1101011"); | |
766 | /// | |
767 | /// assert_eq!( | |
768 | /// format!("l as binary is: {:#032b}", l), | |
769 | /// "l as binary is: 0b000000000000000000000001101011" | |
770 | /// ); | |
771 | /// ``` | |
772 | #[stable(feature = "rust1", since = "1.0.0")] | |
773 | pub trait Binary { | |
774 | /// Formats the value using the given formatter. | |
775 | #[stable(feature = "rust1", since = "1.0.0")] | |
776 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
777 | } | |
778 | ||
779 | /// `x` formatting. | |
780 | /// | |
781 | /// The `LowerHex` trait should format its output as a number in hexadecimal, with `a` through `f` | |
782 | /// in lower case. | |
783 | /// | |
784 | /// For primitive signed integers (`i8` to `i128`, and `isize`), | |
785 | /// negative values are formatted as the two’s complement representation. | |
786 | /// | |
787 | /// The alternate flag, `#`, adds a `0x` in front of the output. | |
788 | /// | |
789 | /// For more information on formatters, see [the module-level documentation][module]. | |
790 | /// | |
791 | /// [module]: ../../std/fmt/index.html | |
792 | /// | |
793 | /// # Examples | |
794 | /// | |
795 | /// Basic usage with `i32`: | |
796 | /// | |
797 | /// ``` | |
798 | /// let x = 42; // 42 is '2a' in hex | |
799 | /// | |
800 | /// assert_eq!(format!("{:x}", x), "2a"); | |
801 | /// assert_eq!(format!("{:#x}", x), "0x2a"); | |
802 | /// | |
803 | /// assert_eq!(format!("{:x}", -16), "fffffff0"); | |
804 | /// ``` | |
805 | /// | |
806 | /// Implementing `LowerHex` on a type: | |
807 | /// | |
808 | /// ``` | |
809 | /// use std::fmt; | |
810 | /// | |
811 | /// struct Length(i32); | |
812 | /// | |
813 | /// impl fmt::LowerHex for Length { | |
814 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
815 | /// let val = self.0; | |
816 | /// | |
817 | /// fmt::LowerHex::fmt(&val, f) // delegate to i32's implementation | |
818 | /// } | |
819 | /// } | |
820 | /// | |
821 | /// let l = Length(9); | |
822 | /// | |
823 | /// assert_eq!(format!("l as hex is: {:x}", l), "l as hex is: 9"); | |
824 | /// | |
825 | /// assert_eq!(format!("l as hex is: {:#010x}", l), "l as hex is: 0x00000009"); | |
826 | /// ``` | |
827 | #[stable(feature = "rust1", since = "1.0.0")] | |
828 | pub trait LowerHex { | |
829 | /// Formats the value using the given formatter. | |
830 | #[stable(feature = "rust1", since = "1.0.0")] | |
831 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
832 | } | |
833 | ||
834 | /// `X` formatting. | |
835 | /// | |
836 | /// The `UpperHex` trait should format its output as a number in hexadecimal, with `A` through `F` | |
837 | /// in upper case. | |
838 | /// | |
839 | /// For primitive signed integers (`i8` to `i128`, and `isize`), | |
840 | /// negative values are formatted as the two’s complement representation. | |
841 | /// | |
842 | /// The alternate flag, `#`, adds a `0x` in front of the output. | |
843 | /// | |
844 | /// For more information on formatters, see [the module-level documentation][module]. | |
845 | /// | |
846 | /// [module]: ../../std/fmt/index.html | |
847 | /// | |
848 | /// # Examples | |
849 | /// | |
850 | /// Basic usage with `i32`: | |
851 | /// | |
852 | /// ``` | |
853 | /// let x = 42; // 42 is '2A' in hex | |
854 | /// | |
855 | /// assert_eq!(format!("{:X}", x), "2A"); | |
856 | /// assert_eq!(format!("{:#X}", x), "0x2A"); | |
857 | /// | |
858 | /// assert_eq!(format!("{:X}", -16), "FFFFFFF0"); | |
859 | /// ``` | |
860 | /// | |
861 | /// Implementing `UpperHex` on a type: | |
862 | /// | |
863 | /// ``` | |
864 | /// use std::fmt; | |
865 | /// | |
866 | /// struct Length(i32); | |
867 | /// | |
868 | /// impl fmt::UpperHex for Length { | |
869 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
870 | /// let val = self.0; | |
871 | /// | |
872 | /// fmt::UpperHex::fmt(&val, f) // delegate to i32's implementation | |
873 | /// } | |
874 | /// } | |
875 | /// | |
876 | /// let l = Length(i32::MAX); | |
877 | /// | |
878 | /// assert_eq!(format!("l as hex is: {:X}", l), "l as hex is: 7FFFFFFF"); | |
879 | /// | |
880 | /// assert_eq!(format!("l as hex is: {:#010X}", l), "l as hex is: 0x7FFFFFFF"); | |
881 | /// ``` | |
882 | #[stable(feature = "rust1", since = "1.0.0")] | |
883 | pub trait UpperHex { | |
884 | /// Formats the value using the given formatter. | |
885 | #[stable(feature = "rust1", since = "1.0.0")] | |
886 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
887 | } | |
888 | ||
889 | /// `p` formatting. | |
890 | /// | |
891 | /// The `Pointer` trait should format its output as a memory location. This is commonly presented | |
892 | /// as hexadecimal. | |
893 | /// | |
894 | /// For more information on formatters, see [the module-level documentation][module]. | |
895 | /// | |
896 | /// [module]: ../../std/fmt/index.html | |
897 | /// | |
898 | /// # Examples | |
899 | /// | |
900 | /// Basic usage with `&i32`: | |
901 | /// | |
902 | /// ``` | |
903 | /// let x = &42; | |
904 | /// | |
905 | /// let address = format!("{:p}", x); // this produces something like '0x7f06092ac6d0' | |
906 | /// ``` | |
907 | /// | |
908 | /// Implementing `Pointer` on a type: | |
909 | /// | |
910 | /// ``` | |
911 | /// use std::fmt; | |
912 | /// | |
913 | /// struct Length(i32); | |
914 | /// | |
915 | /// impl fmt::Pointer for Length { | |
916 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
917 | /// // use `as` to convert to a `*const T`, which implements Pointer, which we can use | |
918 | /// | |
919 | /// let ptr = self as *const Self; | |
920 | /// fmt::Pointer::fmt(&ptr, f) | |
921 | /// } | |
922 | /// } | |
923 | /// | |
924 | /// let l = Length(42); | |
925 | /// | |
926 | /// println!("l is in memory here: {:p}", l); | |
927 | /// | |
928 | /// let l_ptr = format!("{:018p}", l); | |
929 | /// assert_eq!(l_ptr.len(), 18); | |
930 | /// assert_eq!(&l_ptr[..2], "0x"); | |
931 | /// ``` | |
932 | #[stable(feature = "rust1", since = "1.0.0")] | |
933 | #[rustc_diagnostic_item = "pointer_trait"] | |
934 | pub trait Pointer { | |
935 | /// Formats the value using the given formatter. | |
936 | #[stable(feature = "rust1", since = "1.0.0")] | |
937 | #[rustc_diagnostic_item = "pointer_trait_fmt"] | |
938 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
939 | } | |
940 | ||
941 | /// `e` formatting. | |
942 | /// | |
943 | /// The `LowerExp` trait should format its output in scientific notation with a lower-case `e`. | |
944 | /// | |
945 | /// For more information on formatters, see [the module-level documentation][module]. | |
946 | /// | |
947 | /// [module]: ../../std/fmt/index.html | |
948 | /// | |
949 | /// # Examples | |
950 | /// | |
951 | /// Basic usage with `f64`: | |
952 | /// | |
953 | /// ``` | |
954 | /// let x = 42.0; // 42.0 is '4.2e1' in scientific notation | |
955 | /// | |
956 | /// assert_eq!(format!("{:e}", x), "4.2e1"); | |
957 | /// ``` | |
958 | /// | |
959 | /// Implementing `LowerExp` on a type: | |
960 | /// | |
961 | /// ``` | |
962 | /// use std::fmt; | |
963 | /// | |
964 | /// struct Length(i32); | |
965 | /// | |
966 | /// impl fmt::LowerExp for Length { | |
967 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
968 | /// let val = f64::from(self.0); | |
969 | /// fmt::LowerExp::fmt(&val, f) // delegate to f64's implementation | |
970 | /// } | |
971 | /// } | |
972 | /// | |
973 | /// let l = Length(100); | |
974 | /// | |
975 | /// assert_eq!( | |
976 | /// format!("l in scientific notation is: {:e}", l), | |
977 | /// "l in scientific notation is: 1e2" | |
978 | /// ); | |
979 | /// | |
980 | /// assert_eq!( | |
981 | /// format!("l in scientific notation is: {:05e}", l), | |
982 | /// "l in scientific notation is: 001e2" | |
983 | /// ); | |
984 | /// ``` | |
985 | #[stable(feature = "rust1", since = "1.0.0")] | |
986 | pub trait LowerExp { | |
987 | /// Formats the value using the given formatter. | |
988 | #[stable(feature = "rust1", since = "1.0.0")] | |
989 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
990 | } | |
991 | ||
992 | /// `E` formatting. | |
993 | /// | |
994 | /// The `UpperExp` trait should format its output in scientific notation with an upper-case `E`. | |
995 | /// | |
996 | /// For more information on formatters, see [the module-level documentation][module]. | |
997 | /// | |
998 | /// [module]: ../../std/fmt/index.html | |
999 | /// | |
1000 | /// # Examples | |
1001 | /// | |
1002 | /// Basic usage with `f64`: | |
1003 | /// | |
1004 | /// ``` | |
1005 | /// let x = 42.0; // 42.0 is '4.2E1' in scientific notation | |
1006 | /// | |
1007 | /// assert_eq!(format!("{:E}", x), "4.2E1"); | |
1008 | /// ``` | |
1009 | /// | |
1010 | /// Implementing `UpperExp` on a type: | |
1011 | /// | |
1012 | /// ``` | |
1013 | /// use std::fmt; | |
1014 | /// | |
1015 | /// struct Length(i32); | |
1016 | /// | |
1017 | /// impl fmt::UpperExp for Length { | |
1018 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
1019 | /// let val = f64::from(self.0); | |
1020 | /// fmt::UpperExp::fmt(&val, f) // delegate to f64's implementation | |
1021 | /// } | |
1022 | /// } | |
1023 | /// | |
1024 | /// let l = Length(100); | |
1025 | /// | |
1026 | /// assert_eq!( | |
1027 | /// format!("l in scientific notation is: {:E}", l), | |
1028 | /// "l in scientific notation is: 1E2" | |
1029 | /// ); | |
1030 | /// | |
1031 | /// assert_eq!( | |
1032 | /// format!("l in scientific notation is: {:05E}", l), | |
1033 | /// "l in scientific notation is: 001E2" | |
1034 | /// ); | |
1035 | /// ``` | |
1036 | #[stable(feature = "rust1", since = "1.0.0")] | |
1037 | pub trait UpperExp { | |
1038 | /// Formats the value using the given formatter. | |
1039 | #[stable(feature = "rust1", since = "1.0.0")] | |
1040 | fn fmt(&self, f: &mut Formatter<'_>) -> Result; | |
1041 | } | |
1042 | ||
1043 | /// The `write` function takes an output stream, and an `Arguments` struct | |
1044 | /// that can be precompiled with the `format_args!` macro. | |
1045 | /// | |
1046 | /// The arguments will be formatted according to the specified format string | |
1047 | /// into the output stream provided. | |
1048 | /// | |
1049 | /// # Examples | |
1050 | /// | |
1051 | /// Basic usage: | |
1052 | /// | |
1053 | /// ``` | |
1054 | /// use std::fmt; | |
1055 | /// | |
1056 | /// let mut output = String::new(); | |
1057 | /// fmt::write(&mut output, format_args!("Hello {}!", "world")) | |
1058 | /// .expect("Error occurred while trying to write in String"); | |
1059 | /// assert_eq!(output, "Hello world!"); | |
1060 | /// ``` | |
1061 | /// | |
1062 | /// Please note that using [`write!`] might be preferable. Example: | |
1063 | /// | |
1064 | /// ``` | |
1065 | /// use std::fmt::Write; | |
1066 | /// | |
1067 | /// let mut output = String::new(); | |
1068 | /// write!(&mut output, "Hello {}!", "world") | |
1069 | /// .expect("Error occurred while trying to write in String"); | |
1070 | /// assert_eq!(output, "Hello world!"); | |
1071 | /// ``` | |
1072 | /// | |
1073 | /// [`write!`]: crate::write! | |
1074 | #[stable(feature = "rust1", since = "1.0.0")] | |
1075 | pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { | |
1076 | let mut formatter = Formatter { | |
1077 | flags: 0, | |
1078 | width: None, | |
1079 | precision: None, | |
1080 | buf: output, | |
1081 | align: rt::v1::Alignment::Unknown, | |
1082 | fill: ' ', | |
1083 | }; | |
1084 | ||
1085 | let mut idx = 0; | |
1086 | ||
1087 | match args.fmt { | |
1088 | None => { | |
1089 | // We can use default formatting parameters for all arguments. | |
1090 | for (arg, piece) in args.args.iter().zip(args.pieces.iter()) { | |
1091 | formatter.buf.write_str(*piece)?; | |
1092 | (arg.formatter)(arg.value, &mut formatter)?; | |
1093 | idx += 1; | |
1094 | } | |
1095 | } | |
1096 | Some(fmt) => { | |
1097 | // Every spec has a corresponding argument that is preceded by | |
1098 | // a string piece. | |
1099 | for (arg, piece) in fmt.iter().zip(args.pieces.iter()) { | |
1100 | formatter.buf.write_str(*piece)?; | |
1101 | // SAFETY: arg and args.args come from the same Arguments, | |
1102 | // which guarantees the indexes are always within bounds. | |
1103 | unsafe { run(&mut formatter, arg, &args.args) }?; | |
1104 | idx += 1; | |
1105 | } | |
1106 | } | |
1107 | } | |
1108 | ||
1109 | // There can be only one trailing string piece left. | |
1110 | if let Some(piece) = args.pieces.get(idx) { | |
1111 | formatter.buf.write_str(*piece)?; | |
1112 | } | |
1113 | ||
1114 | Ok(()) | |
1115 | } | |
1116 | ||
1117 | unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result { | |
1118 | fmt.fill = arg.format.fill; | |
1119 | fmt.align = arg.format.align; | |
1120 | fmt.flags = arg.format.flags; | |
1121 | // SAFETY: arg and args come from the same Arguments, | |
1122 | // which guarantees the indexes are always within bounds. | |
1123 | unsafe { | |
1124 | fmt.width = getcount(args, &arg.format.width); | |
1125 | fmt.precision = getcount(args, &arg.format.precision); | |
1126 | } | |
1127 | ||
1128 | // Extract the correct argument | |
1129 | debug_assert!(arg.position < args.len()); | |
1130 | // SAFETY: arg and args come from the same Arguments, | |
1131 | // which guarantees its index is always within bounds. | |
1132 | let value = unsafe { args.get_unchecked(arg.position) }; | |
1133 | ||
1134 | // Then actually do some printing | |
1135 | (value.formatter)(value.value, fmt) | |
1136 | } | |
1137 | ||
1138 | unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize> { | |
1139 | match *cnt { | |
1140 | rt::v1::Count::Is(n) => Some(n), | |
1141 | rt::v1::Count::Implied => None, | |
1142 | rt::v1::Count::Param(i) => { | |
1143 | debug_assert!(i < args.len()); | |
1144 | // SAFETY: cnt and args come from the same Arguments, | |
1145 | // which guarantees this index is always within bounds. | |
1146 | unsafe { args.get_unchecked(i).as_usize() } | |
1147 | } | |
1148 | } | |
1149 | } | |
1150 | ||
1151 | /// Padding after the end of something. Returned by `Formatter::padding`. | |
1152 | #[must_use = "don't forget to write the post padding"] | |
1153 | struct PostPadding { | |
1154 | fill: char, | |
1155 | padding: usize, | |
1156 | } | |
1157 | ||
1158 | impl PostPadding { | |
1159 | fn new(fill: char, padding: usize) -> PostPadding { | |
1160 | PostPadding { fill, padding } | |
1161 | } | |
1162 | ||
1163 | /// Write this post padding. | |
1164 | fn write(self, buf: &mut dyn Write) -> Result { | |
1165 | for _ in 0..self.padding { | |
1166 | buf.write_char(self.fill)?; | |
1167 | } | |
1168 | Ok(()) | |
1169 | } | |
1170 | } | |
1171 | ||
1172 | impl<'a> Formatter<'a> { | |
1173 | fn wrap_buf<'b, 'c, F>(&'b mut self, wrap: F) -> Formatter<'c> | |
1174 | where | |
1175 | 'b: 'c, | |
1176 | F: FnOnce(&'b mut (dyn Write + 'b)) -> &'c mut (dyn Write + 'c), | |
1177 | { | |
1178 | Formatter { | |
1179 | // We want to change this | |
1180 | buf: wrap(self.buf), | |
1181 | ||
1182 | // And preserve these | |
1183 | flags: self.flags, | |
1184 | fill: self.fill, | |
1185 | align: self.align, | |
1186 | width: self.width, | |
1187 | precision: self.precision, | |
1188 | } | |
1189 | } | |
1190 | ||
1191 | // Helper methods used for padding and processing formatting arguments that | |
1192 | // all formatting traits can use. | |
1193 | ||
1194 | /// Performs the correct padding for an integer which has already been | |
1195 | /// emitted into a str. The str should *not* contain the sign for the | |
1196 | /// integer, that will be added by this method. | |
1197 | /// | |
1198 | /// # Arguments | |
1199 | /// | |
1200 | /// * is_nonnegative - whether the original integer was either positive or zero. | |
1201 | /// * prefix - if the '#' character (Alternate) is provided, this | |
1202 | /// is the prefix to put in front of the number. | |
1203 | /// * buf - the byte array that the number has been formatted into | |
1204 | /// | |
1205 | /// This function will correctly account for the flags provided as well as | |
1206 | /// the minimum width. It will not take precision into account. | |
1207 | /// | |
1208 | /// # Examples | |
1209 | /// | |
1210 | /// ``` | |
1211 | /// use std::fmt; | |
1212 | /// | |
1213 | /// struct Foo { nb: i32 } | |
1214 | /// | |
1215 | /// impl Foo { | |
1216 | /// fn new(nb: i32) -> Foo { | |
1217 | /// Foo { | |
1218 | /// nb, | |
1219 | /// } | |
1220 | /// } | |
1221 | /// } | |
1222 | /// | |
1223 | /// impl fmt::Display for Foo { | |
1224 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1225 | /// // We need to remove "-" from the number output. | |
1226 | /// let tmp = self.nb.abs().to_string(); | |
1227 | /// | |
1228 | /// formatter.pad_integral(self.nb > 0, "Foo ", &tmp) | |
1229 | /// } | |
1230 | /// } | |
1231 | /// | |
1232 | /// assert_eq!(&format!("{}", Foo::new(2)), "2"); | |
1233 | /// assert_eq!(&format!("{}", Foo::new(-1)), "-1"); | |
1234 | /// assert_eq!(&format!("{:#}", Foo::new(-1)), "-Foo 1"); | |
1235 | /// assert_eq!(&format!("{:0>#8}", Foo::new(-1)), "00-Foo 1"); | |
1236 | /// ``` | |
1237 | #[stable(feature = "rust1", since = "1.0.0")] | |
1238 | pub fn pad_integral(&mut self, is_nonnegative: bool, prefix: &str, buf: &str) -> Result { | |
1239 | let mut width = buf.len(); | |
1240 | ||
1241 | let mut sign = None; | |
1242 | if !is_nonnegative { | |
1243 | sign = Some('-'); | |
1244 | width += 1; | |
1245 | } else if self.sign_plus() { | |
1246 | sign = Some('+'); | |
1247 | width += 1; | |
1248 | } | |
1249 | ||
1250 | let prefix = if self.alternate() { | |
1251 | width += prefix.chars().count(); | |
1252 | Some(prefix) | |
1253 | } else { | |
1254 | None | |
1255 | }; | |
1256 | ||
1257 | // Writes the sign if it exists, and then the prefix if it was requested | |
1258 | #[inline(never)] | |
1259 | fn write_prefix(f: &mut Formatter<'_>, sign: Option<char>, prefix: Option<&str>) -> Result { | |
1260 | if let Some(c) = sign { | |
1261 | f.buf.write_char(c)?; | |
1262 | } | |
1263 | if let Some(prefix) = prefix { f.buf.write_str(prefix) } else { Ok(()) } | |
1264 | } | |
1265 | ||
1266 | // The `width` field is more of a `min-width` parameter at this point. | |
1267 | match self.width { | |
1268 | // If there's no minimum length requirements then we can just | |
1269 | // write the bytes. | |
1270 | None => { | |
1271 | write_prefix(self, sign, prefix)?; | |
1272 | self.buf.write_str(buf) | |
1273 | } | |
1274 | // Check if we're over the minimum width, if so then we can also | |
1275 | // just write the bytes. | |
1276 | Some(min) if width >= min => { | |
1277 | write_prefix(self, sign, prefix)?; | |
1278 | self.buf.write_str(buf) | |
1279 | } | |
1280 | // The sign and prefix goes before the padding if the fill character | |
1281 | // is zero | |
1282 | Some(min) if self.sign_aware_zero_pad() => { | |
1283 | let old_fill = crate::mem::replace(&mut self.fill, '0'); | |
1284 | let old_align = crate::mem::replace(&mut self.align, rt::v1::Alignment::Right); | |
1285 | write_prefix(self, sign, prefix)?; | |
1286 | let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; | |
1287 | self.buf.write_str(buf)?; | |
1288 | post_padding.write(self.buf)?; | |
1289 | self.fill = old_fill; | |
1290 | self.align = old_align; | |
1291 | Ok(()) | |
1292 | } | |
1293 | // Otherwise, the sign and prefix goes after the padding | |
1294 | Some(min) => { | |
1295 | let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; | |
1296 | write_prefix(self, sign, prefix)?; | |
1297 | self.buf.write_str(buf)?; | |
1298 | post_padding.write(self.buf) | |
1299 | } | |
1300 | } | |
1301 | } | |
1302 | ||
1303 | /// This function takes a string slice and emits it to the internal buffer | |
1304 | /// after applying the relevant formatting flags specified. The flags | |
1305 | /// recognized for generic strings are: | |
1306 | /// | |
1307 | /// * width - the minimum width of what to emit | |
1308 | /// * fill/align - what to emit and where to emit it if the string | |
1309 | /// provided needs to be padded | |
1310 | /// * precision - the maximum length to emit, the string is truncated if it | |
1311 | /// is longer than this length | |
1312 | /// | |
1313 | /// Notably this function ignores the `flag` parameters. | |
1314 | /// | |
1315 | /// # Examples | |
1316 | /// | |
1317 | /// ``` | |
1318 | /// use std::fmt; | |
1319 | /// | |
1320 | /// struct Foo; | |
1321 | /// | |
1322 | /// impl fmt::Display for Foo { | |
1323 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1324 | /// formatter.pad("Foo") | |
1325 | /// } | |
1326 | /// } | |
1327 | /// | |
1328 | /// assert_eq!(&format!("{:<4}", Foo), "Foo "); | |
1329 | /// assert_eq!(&format!("{:0>4}", Foo), "0Foo"); | |
1330 | /// ``` | |
1331 | #[stable(feature = "rust1", since = "1.0.0")] | |
1332 | pub fn pad(&mut self, s: &str) -> Result { | |
1333 | // Make sure there's a fast path up front | |
1334 | if self.width.is_none() && self.precision.is_none() { | |
1335 | return self.buf.write_str(s); | |
1336 | } | |
1337 | // The `precision` field can be interpreted as a `max-width` for the | |
1338 | // string being formatted. | |
1339 | let s = if let Some(max) = self.precision { | |
1340 | // If our string is longer that the precision, then we must have | |
1341 | // truncation. However other flags like `fill`, `width` and `align` | |
1342 | // must act as always. | |
1343 | if let Some((i, _)) = s.char_indices().nth(max) { | |
1344 | // LLVM here can't prove that `..i` won't panic `&s[..i]`, but | |
1345 | // we know that it can't panic. Use `get` + `unwrap_or` to avoid | |
1346 | // `unsafe` and otherwise don't emit any panic-related code | |
1347 | // here. | |
1348 | s.get(..i).unwrap_or(&s) | |
1349 | } else { | |
1350 | &s | |
1351 | } | |
1352 | } else { | |
1353 | &s | |
1354 | }; | |
1355 | // The `width` field is more of a `min-width` parameter at this point. | |
1356 | match self.width { | |
1357 | // If we're under the maximum length, and there's no minimum length | |
1358 | // requirements, then we can just emit the string | |
1359 | None => self.buf.write_str(s), | |
1360 | // If we're under the maximum width, check if we're over the minimum | |
1361 | // width, if so it's as easy as just emitting the string. | |
1362 | Some(width) if s.chars().count() >= width => self.buf.write_str(s), | |
1363 | // If we're under both the maximum and the minimum width, then fill | |
1364 | // up the minimum width with the specified string + some alignment. | |
1365 | Some(width) => { | |
1366 | let align = rt::v1::Alignment::Left; | |
1367 | let post_padding = self.padding(width - s.chars().count(), align)?; | |
1368 | self.buf.write_str(s)?; | |
1369 | post_padding.write(self.buf) | |
1370 | } | |
1371 | } | |
1372 | } | |
1373 | ||
1374 | /// Write the pre-padding and return the unwritten post-padding. Callers are | |
1375 | /// responsible for ensuring post-padding is written after the thing that is | |
1376 | /// being padded. | |
1377 | fn padding( | |
1378 | &mut self, | |
1379 | padding: usize, | |
1380 | default: rt::v1::Alignment, | |
1381 | ) -> result::Result<PostPadding, Error> { | |
1382 | let align = match self.align { | |
1383 | rt::v1::Alignment::Unknown => default, | |
1384 | _ => self.align, | |
1385 | }; | |
1386 | ||
1387 | let (pre_pad, post_pad) = match align { | |
1388 | rt::v1::Alignment::Left => (0, padding), | |
1389 | rt::v1::Alignment::Right | rt::v1::Alignment::Unknown => (padding, 0), | |
1390 | rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2), | |
1391 | }; | |
1392 | ||
1393 | for _ in 0..pre_pad { | |
1394 | self.buf.write_char(self.fill)?; | |
1395 | } | |
1396 | ||
1397 | Ok(PostPadding::new(self.fill, post_pad)) | |
1398 | } | |
1399 | ||
1400 | /// Takes the formatted parts and applies the padding. | |
1401 | /// Assumes that the caller already has rendered the parts with required precision, | |
1402 | /// so that `self.precision` can be ignored. | |
1403 | fn pad_formatted_parts(&mut self, formatted: &flt2dec::Formatted<'_>) -> Result { | |
1404 | if let Some(mut width) = self.width { | |
1405 | // for the sign-aware zero padding, we render the sign first and | |
1406 | // behave as if we had no sign from the beginning. | |
1407 | let mut formatted = formatted.clone(); | |
1408 | let old_fill = self.fill; | |
1409 | let old_align = self.align; | |
1410 | let mut align = old_align; | |
1411 | if self.sign_aware_zero_pad() { | |
1412 | // a sign always goes first | |
1413 | let sign = formatted.sign; | |
1414 | self.buf.write_str(sign)?; | |
1415 | ||
1416 | // remove the sign from the formatted parts | |
1417 | formatted.sign = ""; | |
1418 | width = width.saturating_sub(sign.len()); | |
1419 | align = rt::v1::Alignment::Right; | |
1420 | self.fill = '0'; | |
1421 | self.align = rt::v1::Alignment::Right; | |
1422 | } | |
1423 | ||
1424 | // remaining parts go through the ordinary padding process. | |
1425 | let len = formatted.len(); | |
1426 | let ret = if width <= len { | |
1427 | // no padding | |
1428 | self.write_formatted_parts(&formatted) | |
1429 | } else { | |
1430 | let post_padding = self.padding(width - len, align)?; | |
1431 | self.write_formatted_parts(&formatted)?; | |
1432 | post_padding.write(self.buf) | |
1433 | }; | |
1434 | self.fill = old_fill; | |
1435 | self.align = old_align; | |
1436 | ret | |
1437 | } else { | |
1438 | // this is the common case and we take a shortcut | |
1439 | self.write_formatted_parts(formatted) | |
1440 | } | |
1441 | } | |
1442 | ||
1443 | fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted<'_>) -> Result { | |
1444 | fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result { | |
1445 | // SAFETY: This is used for `flt2dec::Part::Num` and `flt2dec::Part::Copy`. | |
1446 | // It's safe to use for `flt2dec::Part::Num` since every char `c` is between | |
1447 | // `b'0'` and `b'9'`, which means `s` is valid UTF-8. | |
1448 | // It's also probably safe in practice to use for `flt2dec::Part::Copy(buf)` | |
1449 | // since `buf` should be plain ASCII, but it's possible for someone to pass | |
1450 | // in a bad value for `buf` into `flt2dec::to_shortest_str` since it is a | |
1451 | // public function. | |
1452 | // FIXME: Determine whether this could result in UB. | |
1453 | buf.write_str(unsafe { str::from_utf8_unchecked(s) }) | |
1454 | } | |
1455 | ||
1456 | if !formatted.sign.is_empty() { | |
1457 | self.buf.write_str(formatted.sign)?; | |
1458 | } | |
1459 | for part in formatted.parts { | |
1460 | match *part { | |
1461 | flt2dec::Part::Zero(mut nzeroes) => { | |
1462 | const ZEROES: &str = // 64 zeroes | |
1463 | "0000000000000000000000000000000000000000000000000000000000000000"; | |
1464 | while nzeroes > ZEROES.len() { | |
1465 | self.buf.write_str(ZEROES)?; | |
1466 | nzeroes -= ZEROES.len(); | |
1467 | } | |
1468 | if nzeroes > 0 { | |
1469 | self.buf.write_str(&ZEROES[..nzeroes])?; | |
1470 | } | |
1471 | } | |
1472 | flt2dec::Part::Num(mut v) => { | |
1473 | let mut s = [0; 5]; | |
1474 | let len = part.len(); | |
1475 | for c in s[..len].iter_mut().rev() { | |
1476 | *c = b'0' + (v % 10) as u8; | |
1477 | v /= 10; | |
1478 | } | |
1479 | write_bytes(self.buf, &s[..len])?; | |
1480 | } | |
1481 | flt2dec::Part::Copy(buf) => { | |
1482 | write_bytes(self.buf, buf)?; | |
1483 | } | |
1484 | } | |
1485 | } | |
1486 | Ok(()) | |
1487 | } | |
1488 | ||
1489 | /// Writes some data to the underlying buffer contained within this | |
1490 | /// formatter. | |
1491 | /// | |
1492 | /// # Examples | |
1493 | /// | |
1494 | /// ``` | |
1495 | /// use std::fmt; | |
1496 | /// | |
1497 | /// struct Foo; | |
1498 | /// | |
1499 | /// impl fmt::Display for Foo { | |
1500 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1501 | /// formatter.write_str("Foo") | |
1502 | /// // This is equivalent to: | |
1503 | /// // write!(formatter, "Foo") | |
1504 | /// } | |
1505 | /// } | |
1506 | /// | |
1507 | /// assert_eq!(&format!("{}", Foo), "Foo"); | |
1508 | /// assert_eq!(&format!("{:0>8}", Foo), "Foo"); | |
1509 | /// ``` | |
1510 | #[stable(feature = "rust1", since = "1.0.0")] | |
1511 | pub fn write_str(&mut self, data: &str) -> Result { | |
1512 | self.buf.write_str(data) | |
1513 | } | |
1514 | ||
1515 | /// Writes some formatted information into this instance. | |
1516 | /// | |
1517 | /// # Examples | |
1518 | /// | |
1519 | /// ``` | |
1520 | /// use std::fmt; | |
1521 | /// | |
1522 | /// struct Foo(i32); | |
1523 | /// | |
1524 | /// impl fmt::Display for Foo { | |
1525 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1526 | /// formatter.write_fmt(format_args!("Foo {}", self.0)) | |
1527 | /// } | |
1528 | /// } | |
1529 | /// | |
1530 | /// assert_eq!(&format!("{}", Foo(-1)), "Foo -1"); | |
1531 | /// assert_eq!(&format!("{:0>8}", Foo(2)), "Foo 2"); | |
1532 | /// ``` | |
1533 | #[stable(feature = "rust1", since = "1.0.0")] | |
1534 | pub fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result { | |
1535 | write(self.buf, fmt) | |
1536 | } | |
1537 | ||
1538 | /// Flags for formatting | |
1539 | #[stable(feature = "rust1", since = "1.0.0")] | |
1540 | #[rustc_deprecated( | |
1541 | since = "1.24.0", | |
1542 | reason = "use the `sign_plus`, `sign_minus`, `alternate`, \ | |
1543 | or `sign_aware_zero_pad` methods instead" | |
1544 | )] | |
1545 | pub fn flags(&self) -> u32 { | |
1546 | self.flags | |
1547 | } | |
1548 | ||
1549 | /// Character used as 'fill' whenever there is alignment. | |
1550 | /// | |
1551 | /// # Examples | |
1552 | /// | |
1553 | /// ``` | |
1554 | /// use std::fmt; | |
1555 | /// | |
1556 | /// struct Foo; | |
1557 | /// | |
1558 | /// impl fmt::Display for Foo { | |
1559 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1560 | /// let c = formatter.fill(); | |
1561 | /// if let Some(width) = formatter.width() { | |
1562 | /// for _ in 0..width { | |
1563 | /// write!(formatter, "{}", c)?; | |
1564 | /// } | |
1565 | /// Ok(()) | |
1566 | /// } else { | |
1567 | /// write!(formatter, "{}", c) | |
1568 | /// } | |
1569 | /// } | |
1570 | /// } | |
1571 | /// | |
1572 | /// // We set alignment to the right with ">". | |
1573 | /// assert_eq!(&format!("{:G>3}", Foo), "GGG"); | |
1574 | /// assert_eq!(&format!("{:t>6}", Foo), "tttttt"); | |
1575 | /// ``` | |
1576 | #[stable(feature = "fmt_flags", since = "1.5.0")] | |
1577 | pub fn fill(&self) -> char { | |
1578 | self.fill | |
1579 | } | |
1580 | ||
1581 | /// Flag indicating what form of alignment was requested. | |
1582 | /// | |
1583 | /// # Examples | |
1584 | /// | |
1585 | /// ``` | |
1586 | /// extern crate core; | |
1587 | /// | |
1588 | /// use std::fmt::{self, Alignment}; | |
1589 | /// | |
1590 | /// struct Foo; | |
1591 | /// | |
1592 | /// impl fmt::Display for Foo { | |
1593 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1594 | /// let s = if let Some(s) = formatter.align() { | |
1595 | /// match s { | |
1596 | /// Alignment::Left => "left", | |
1597 | /// Alignment::Right => "right", | |
1598 | /// Alignment::Center => "center", | |
1599 | /// } | |
1600 | /// } else { | |
1601 | /// "into the void" | |
1602 | /// }; | |
1603 | /// write!(formatter, "{}", s) | |
1604 | /// } | |
1605 | /// } | |
1606 | /// | |
1607 | /// assert_eq!(&format!("{:<}", Foo), "left"); | |
1608 | /// assert_eq!(&format!("{:>}", Foo), "right"); | |
1609 | /// assert_eq!(&format!("{:^}", Foo), "center"); | |
1610 | /// assert_eq!(&format!("{}", Foo), "into the void"); | |
1611 | /// ``` | |
1612 | #[stable(feature = "fmt_flags_align", since = "1.28.0")] | |
1613 | pub fn align(&self) -> Option<Alignment> { | |
1614 | match self.align { | |
1615 | rt::v1::Alignment::Left => Some(Alignment::Left), | |
1616 | rt::v1::Alignment::Right => Some(Alignment::Right), | |
1617 | rt::v1::Alignment::Center => Some(Alignment::Center), | |
1618 | rt::v1::Alignment::Unknown => None, | |
1619 | } | |
1620 | } | |
1621 | ||
1622 | /// Optionally specified integer width that the output should be. | |
1623 | /// | |
1624 | /// # Examples | |
1625 | /// | |
1626 | /// ``` | |
1627 | /// use std::fmt; | |
1628 | /// | |
1629 | /// struct Foo(i32); | |
1630 | /// | |
1631 | /// impl fmt::Display for Foo { | |
1632 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1633 | /// if let Some(width) = formatter.width() { | |
1634 | /// // If we received a width, we use it | |
1635 | /// write!(formatter, "{:width$}", &format!("Foo({})", self.0), width = width) | |
1636 | /// } else { | |
1637 | /// // Otherwise we do nothing special | |
1638 | /// write!(formatter, "Foo({})", self.0) | |
1639 | /// } | |
1640 | /// } | |
1641 | /// } | |
1642 | /// | |
1643 | /// assert_eq!(&format!("{:10}", Foo(23)), "Foo(23) "); | |
1644 | /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); | |
1645 | /// ``` | |
1646 | #[stable(feature = "fmt_flags", since = "1.5.0")] | |
1647 | pub fn width(&self) -> Option<usize> { | |
1648 | self.width | |
1649 | } | |
1650 | ||
1651 | /// Optionally specified precision for numeric types. Alternatively, the | |
1652 | /// maximum width for string types. | |
1653 | /// | |
1654 | /// # Examples | |
1655 | /// | |
1656 | /// ``` | |
1657 | /// use std::fmt; | |
1658 | /// | |
1659 | /// struct Foo(f32); | |
1660 | /// | |
1661 | /// impl fmt::Display for Foo { | |
1662 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1663 | /// if let Some(precision) = formatter.precision() { | |
1664 | /// // If we received a precision, we use it. | |
1665 | /// write!(formatter, "Foo({1:.*})", precision, self.0) | |
1666 | /// } else { | |
1667 | /// // Otherwise we default to 2. | |
1668 | /// write!(formatter, "Foo({:.2})", self.0) | |
1669 | /// } | |
1670 | /// } | |
1671 | /// } | |
1672 | /// | |
1673 | /// assert_eq!(&format!("{:.4}", Foo(23.2)), "Foo(23.2000)"); | |
1674 | /// assert_eq!(&format!("{}", Foo(23.2)), "Foo(23.20)"); | |
1675 | /// ``` | |
1676 | #[stable(feature = "fmt_flags", since = "1.5.0")] | |
1677 | pub fn precision(&self) -> Option<usize> { | |
1678 | self.precision | |
1679 | } | |
1680 | ||
1681 | /// Determines if the `+` flag was specified. | |
1682 | /// | |
1683 | /// # Examples | |
1684 | /// | |
1685 | /// ``` | |
1686 | /// use std::fmt; | |
1687 | /// | |
1688 | /// struct Foo(i32); | |
1689 | /// | |
1690 | /// impl fmt::Display for Foo { | |
1691 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1692 | /// if formatter.sign_plus() { | |
1693 | /// write!(formatter, | |
1694 | /// "Foo({}{})", | |
1695 | /// if self.0 < 0 { '-' } else { '+' }, | |
1696 | /// self.0) | |
1697 | /// } else { | |
1698 | /// write!(formatter, "Foo({})", self.0) | |
1699 | /// } | |
1700 | /// } | |
1701 | /// } | |
1702 | /// | |
1703 | /// assert_eq!(&format!("{:+}", Foo(23)), "Foo(+23)"); | |
1704 | /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); | |
1705 | /// ``` | |
1706 | #[stable(feature = "fmt_flags", since = "1.5.0")] | |
1707 | pub fn sign_plus(&self) -> bool { | |
1708 | self.flags & (1 << FlagV1::SignPlus as u32) != 0 | |
1709 | } | |
1710 | ||
1711 | /// Determines if the `-` flag was specified. | |
1712 | /// | |
1713 | /// # Examples | |
1714 | /// | |
1715 | /// ``` | |
1716 | /// use std::fmt; | |
1717 | /// | |
1718 | /// struct Foo(i32); | |
1719 | /// | |
1720 | /// impl fmt::Display for Foo { | |
1721 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1722 | /// if formatter.sign_minus() { | |
1723 | /// // You want a minus sign? Have one! | |
1724 | /// write!(formatter, "-Foo({})", self.0) | |
1725 | /// } else { | |
1726 | /// write!(formatter, "Foo({})", self.0) | |
1727 | /// } | |
1728 | /// } | |
1729 | /// } | |
1730 | /// | |
1731 | /// assert_eq!(&format!("{:-}", Foo(23)), "-Foo(23)"); | |
1732 | /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); | |
1733 | /// ``` | |
1734 | #[stable(feature = "fmt_flags", since = "1.5.0")] | |
1735 | pub fn sign_minus(&self) -> bool { | |
1736 | self.flags & (1 << FlagV1::SignMinus as u32) != 0 | |
1737 | } | |
1738 | ||
1739 | /// Determines if the `#` flag was specified. | |
1740 | /// | |
1741 | /// # Examples | |
1742 | /// | |
1743 | /// ``` | |
1744 | /// use std::fmt; | |
1745 | /// | |
1746 | /// struct Foo(i32); | |
1747 | /// | |
1748 | /// impl fmt::Display for Foo { | |
1749 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1750 | /// if formatter.alternate() { | |
1751 | /// write!(formatter, "Foo({})", self.0) | |
1752 | /// } else { | |
1753 | /// write!(formatter, "{}", self.0) | |
1754 | /// } | |
1755 | /// } | |
1756 | /// } | |
1757 | /// | |
1758 | /// assert_eq!(&format!("{:#}", Foo(23)), "Foo(23)"); | |
1759 | /// assert_eq!(&format!("{}", Foo(23)), "23"); | |
1760 | /// ``` | |
1761 | #[stable(feature = "fmt_flags", since = "1.5.0")] | |
1762 | pub fn alternate(&self) -> bool { | |
1763 | self.flags & (1 << FlagV1::Alternate as u32) != 0 | |
1764 | } | |
1765 | ||
1766 | /// Determines if the `0` flag was specified. | |
1767 | /// | |
1768 | /// # Examples | |
1769 | /// | |
1770 | /// ``` | |
1771 | /// use std::fmt; | |
1772 | /// | |
1773 | /// struct Foo(i32); | |
1774 | /// | |
1775 | /// impl fmt::Display for Foo { | |
1776 | /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
1777 | /// assert!(formatter.sign_aware_zero_pad()); | |
1778 | /// assert_eq!(formatter.width(), Some(4)); | |
1779 | /// // We ignore the formatter's options. | |
1780 | /// write!(formatter, "{}", self.0) | |
1781 | /// } | |
1782 | /// } | |
1783 | /// | |
1784 | /// assert_eq!(&format!("{:04}", Foo(23)), "23"); | |
1785 | /// ``` | |
1786 | #[stable(feature = "fmt_flags", since = "1.5.0")] | |
1787 | pub fn sign_aware_zero_pad(&self) -> bool { | |
1788 | self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0 | |
1789 | } | |
1790 | ||
1791 | // FIXME: Decide what public API we want for these two flags. | |
1792 | // https://github.com/rust-lang/rust/issues/48584 | |
1793 | fn debug_lower_hex(&self) -> bool { | |
1794 | self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0 | |
1795 | } | |
1796 | ||
1797 | fn debug_upper_hex(&self) -> bool { | |
1798 | self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0 | |
1799 | } | |
1800 | ||
1801 | /// Creates a [`DebugStruct`] builder designed to assist with creation of | |
1802 | /// [`fmt::Debug`] implementations for structs. | |
1803 | /// | |
1804 | /// [`fmt::Debug`]: self::Debug | |
1805 | /// | |
1806 | /// # Examples | |
1807 | /// | |
1808 | /// ```rust | |
1809 | /// use std::fmt; | |
1810 | /// use std::net::Ipv4Addr; | |
1811 | /// | |
1812 | /// struct Foo { | |
1813 | /// bar: i32, | |
1814 | /// baz: String, | |
1815 | /// addr: Ipv4Addr, | |
1816 | /// } | |
1817 | /// | |
1818 | /// impl fmt::Debug for Foo { | |
1819 | /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
1820 | /// fmt.debug_struct("Foo") | |
1821 | /// .field("bar", &self.bar) | |
1822 | /// .field("baz", &self.baz) | |
1823 | /// .field("addr", &format_args!("{}", self.addr)) | |
1824 | /// .finish() | |
1825 | /// } | |
1826 | /// } | |
1827 | /// | |
1828 | /// assert_eq!( | |
1829 | /// "Foo { bar: 10, baz: \"Hello World\", addr: 127.0.0.1 }", | |
1830 | /// format!("{:?}", Foo { | |
1831 | /// bar: 10, | |
1832 | /// baz: "Hello World".to_string(), | |
1833 | /// addr: Ipv4Addr::new(127, 0, 0, 1), | |
1834 | /// }) | |
1835 | /// ); | |
1836 | /// ``` | |
1837 | #[stable(feature = "debug_builders", since = "1.2.0")] | |
1838 | pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> { | |
1839 | builders::debug_struct_new(self, name) | |
1840 | } | |
1841 | ||
1842 | /// Creates a `DebugTuple` builder designed to assist with creation of | |
1843 | /// `fmt::Debug` implementations for tuple structs. | |
1844 | /// | |
1845 | /// # Examples | |
1846 | /// | |
1847 | /// ```rust | |
1848 | /// use std::fmt; | |
1849 | /// use std::marker::PhantomData; | |
1850 | /// | |
1851 | /// struct Foo<T>(i32, String, PhantomData<T>); | |
1852 | /// | |
1853 | /// impl<T> fmt::Debug for Foo<T> { | |
1854 | /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
1855 | /// fmt.debug_tuple("Foo") | |
1856 | /// .field(&self.0) | |
1857 | /// .field(&self.1) | |
1858 | /// .field(&format_args!("_")) | |
1859 | /// .finish() | |
1860 | /// } | |
1861 | /// } | |
1862 | /// | |
1863 | /// assert_eq!( | |
1864 | /// "Foo(10, \"Hello\", _)", | |
1865 | /// format!("{:?}", Foo(10, "Hello".to_string(), PhantomData::<u8>)) | |
1866 | /// ); | |
1867 | /// ``` | |
1868 | #[stable(feature = "debug_builders", since = "1.2.0")] | |
1869 | pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> { | |
1870 | builders::debug_tuple_new(self, name) | |
1871 | } | |
1872 | ||
1873 | /// Creates a `DebugList` builder designed to assist with creation of | |
1874 | /// `fmt::Debug` implementations for list-like structures. | |
1875 | /// | |
1876 | /// # Examples | |
1877 | /// | |
1878 | /// ```rust | |
1879 | /// use std::fmt; | |
1880 | /// | |
1881 | /// struct Foo(Vec<i32>); | |
1882 | /// | |
1883 | /// impl fmt::Debug for Foo { | |
1884 | /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
1885 | /// fmt.debug_list().entries(self.0.iter()).finish() | |
1886 | /// } | |
1887 | /// } | |
1888 | /// | |
1889 | /// assert_eq!(format!("{:?}", Foo(vec![10, 11])), "[10, 11]"); | |
1890 | /// ``` | |
1891 | #[stable(feature = "debug_builders", since = "1.2.0")] | |
1892 | pub fn debug_list<'b>(&'b mut self) -> DebugList<'b, 'a> { | |
1893 | builders::debug_list_new(self) | |
1894 | } | |
1895 | ||
1896 | /// Creates a `DebugSet` builder designed to assist with creation of | |
1897 | /// `fmt::Debug` implementations for set-like structures. | |
1898 | /// | |
1899 | /// # Examples | |
1900 | /// | |
1901 | /// ```rust | |
1902 | /// use std::fmt; | |
1903 | /// | |
1904 | /// struct Foo(Vec<i32>); | |
1905 | /// | |
1906 | /// impl fmt::Debug for Foo { | |
1907 | /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
1908 | /// fmt.debug_set().entries(self.0.iter()).finish() | |
1909 | /// } | |
1910 | /// } | |
1911 | /// | |
1912 | /// assert_eq!(format!("{:?}", Foo(vec![10, 11])), "{10, 11}"); | |
1913 | /// ``` | |
1914 | /// | |
1915 | /// [`format_args!`]: crate::format_args | |
1916 | /// | |
1917 | /// In this more complex example, we use [`format_args!`] and `.debug_set()` | |
1918 | /// to build a list of match arms: | |
1919 | /// | |
1920 | /// ```rust | |
1921 | /// use std::fmt; | |
1922 | /// | |
1923 | /// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R)); | |
1924 | /// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V); | |
1925 | /// | |
1926 | /// impl<'a, L, R> fmt::Debug for Arm<'a, L, R> | |
1927 | /// where | |
1928 | /// L: 'a + fmt::Debug, R: 'a + fmt::Debug | |
1929 | /// { | |
1930 | /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
1931 | /// L::fmt(&(self.0).0, fmt)?; | |
1932 | /// fmt.write_str(" => ")?; | |
1933 | /// R::fmt(&(self.0).1, fmt) | |
1934 | /// } | |
1935 | /// } | |
1936 | /// | |
1937 | /// impl<'a, K, V> fmt::Debug for Table<'a, K, V> | |
1938 | /// where | |
1939 | /// K: 'a + fmt::Debug, V: 'a + fmt::Debug | |
1940 | /// { | |
1941 | /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
1942 | /// fmt.debug_set() | |
1943 | /// .entries(self.0.iter().map(Arm)) | |
1944 | /// .entry(&Arm(&(format_args!("_"), &self.1))) | |
1945 | /// .finish() | |
1946 | /// } | |
1947 | /// } | |
1948 | /// ``` | |
1949 | #[stable(feature = "debug_builders", since = "1.2.0")] | |
1950 | pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> { | |
1951 | builders::debug_set_new(self) | |
1952 | } | |
1953 | ||
1954 | /// Creates a `DebugMap` builder designed to assist with creation of | |
1955 | /// `fmt::Debug` implementations for map-like structures. | |
1956 | /// | |
1957 | /// # Examples | |
1958 | /// | |
1959 | /// ```rust | |
1960 | /// use std::fmt; | |
1961 | /// | |
1962 | /// struct Foo(Vec<(String, i32)>); | |
1963 | /// | |
1964 | /// impl fmt::Debug for Foo { | |
1965 | /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
1966 | /// fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish() | |
1967 | /// } | |
1968 | /// } | |
1969 | /// | |
1970 | /// assert_eq!( | |
1971 | /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), | |
1972 | /// r#"{"A": 10, "B": 11}"# | |
1973 | /// ); | |
1974 | /// ``` | |
1975 | #[stable(feature = "debug_builders", since = "1.2.0")] | |
1976 | pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> { | |
1977 | builders::debug_map_new(self) | |
1978 | } | |
1979 | } | |
1980 | ||
1981 | #[stable(since = "1.2.0", feature = "formatter_write")] | |
1982 | impl Write for Formatter<'_> { | |
1983 | fn write_str(&mut self, s: &str) -> Result { | |
1984 | self.buf.write_str(s) | |
1985 | } | |
1986 | ||
1987 | fn write_char(&mut self, c: char) -> Result { | |
1988 | self.buf.write_char(c) | |
1989 | } | |
1990 | ||
1991 | fn write_fmt(&mut self, args: Arguments<'_>) -> Result { | |
1992 | write(self.buf, args) | |
1993 | } | |
1994 | } | |
1995 | ||
1996 | #[stable(feature = "rust1", since = "1.0.0")] | |
1997 | impl Display for Error { | |
1998 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
1999 | Display::fmt("an error occurred when formatting an argument", f) | |
2000 | } | |
2001 | } | |
2002 | ||
2003 | // Implementations of the core formatting traits | |
2004 | ||
2005 | macro_rules! fmt_refs { | |
2006 | ($($tr:ident),*) => { | |
2007 | $( | |
2008 | #[stable(feature = "rust1", since = "1.0.0")] | |
2009 | impl<T: ?Sized + $tr> $tr for &T { | |
2010 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } | |
2011 | } | |
2012 | #[stable(feature = "rust1", since = "1.0.0")] | |
2013 | impl<T: ?Sized + $tr> $tr for &mut T { | |
2014 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } | |
2015 | } | |
2016 | )* | |
2017 | } | |
2018 | } | |
2019 | ||
2020 | fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } | |
2021 | ||
2022 | #[unstable(feature = "never_type", issue = "35121")] | |
2023 | impl Debug for ! { | |
2024 | fn fmt(&self, _: &mut Formatter<'_>) -> Result { | |
2025 | *self | |
2026 | } | |
2027 | } | |
2028 | ||
2029 | #[unstable(feature = "never_type", issue = "35121")] | |
2030 | impl Display for ! { | |
2031 | fn fmt(&self, _: &mut Formatter<'_>) -> Result { | |
2032 | *self | |
2033 | } | |
2034 | } | |
2035 | ||
2036 | #[stable(feature = "rust1", since = "1.0.0")] | |
2037 | impl Debug for bool { | |
2038 | #[inline] | |
2039 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2040 | Display::fmt(self, f) | |
2041 | } | |
2042 | } | |
2043 | ||
2044 | #[stable(feature = "rust1", since = "1.0.0")] | |
2045 | impl Display for bool { | |
2046 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2047 | Display::fmt(if *self { "true" } else { "false" }, f) | |
2048 | } | |
2049 | } | |
2050 | ||
2051 | #[stable(feature = "rust1", since = "1.0.0")] | |
2052 | impl Debug for str { | |
2053 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2054 | f.write_char('"')?; | |
2055 | let mut from = 0; | |
2056 | for (i, c) in self.char_indices() { | |
2057 | let esc = c.escape_debug(); | |
2058 | // If char needs escaping, flush backlog so far and write, else skip | |
2059 | if esc.len() != 1 { | |
2060 | f.write_str(&self[from..i])?; | |
2061 | for c in esc { | |
2062 | f.write_char(c)?; | |
2063 | } | |
2064 | from = i + c.len_utf8(); | |
2065 | } | |
2066 | } | |
2067 | f.write_str(&self[from..])?; | |
2068 | f.write_char('"') | |
2069 | } | |
2070 | } | |
2071 | ||
2072 | #[stable(feature = "rust1", since = "1.0.0")] | |
2073 | impl Display for str { | |
2074 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2075 | f.pad(self) | |
2076 | } | |
2077 | } | |
2078 | ||
2079 | #[stable(feature = "rust1", since = "1.0.0")] | |
2080 | impl Debug for char { | |
2081 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2082 | f.write_char('\'')?; | |
2083 | for c in self.escape_debug() { | |
2084 | f.write_char(c)? | |
2085 | } | |
2086 | f.write_char('\'') | |
2087 | } | |
2088 | } | |
2089 | ||
2090 | #[stable(feature = "rust1", since = "1.0.0")] | |
2091 | impl Display for char { | |
2092 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2093 | if f.width.is_none() && f.precision.is_none() { | |
2094 | f.write_char(*self) | |
2095 | } else { | |
2096 | f.pad(self.encode_utf8(&mut [0; 4])) | |
2097 | } | |
2098 | } | |
2099 | } | |
2100 | ||
2101 | #[stable(feature = "rust1", since = "1.0.0")] | |
2102 | impl<T: ?Sized> Pointer for *const T { | |
2103 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2104 | let old_width = f.width; | |
2105 | let old_flags = f.flags; | |
2106 | ||
2107 | // The alternate flag is already treated by LowerHex as being special- | |
2108 | // it denotes whether to prefix with 0x. We use it to work out whether | |
2109 | // or not to zero extend, and then unconditionally set it to get the | |
2110 | // prefix. | |
2111 | if f.alternate() { | |
2112 | f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32); | |
2113 | ||
2114 | if f.width.is_none() { | |
2115 | f.width = Some((usize::BITS / 4) as usize + 2); | |
2116 | } | |
2117 | } | |
2118 | f.flags |= 1 << (FlagV1::Alternate as u32); | |
2119 | ||
2120 | let ret = LowerHex::fmt(&(*self as *const () as usize), f); | |
2121 | ||
2122 | f.width = old_width; | |
2123 | f.flags = old_flags; | |
2124 | ||
2125 | ret | |
2126 | } | |
2127 | } | |
2128 | ||
2129 | #[stable(feature = "rust1", since = "1.0.0")] | |
2130 | impl<T: ?Sized> Pointer for *mut T { | |
2131 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2132 | Pointer::fmt(&(*self as *const T), f) | |
2133 | } | |
2134 | } | |
2135 | ||
2136 | #[stable(feature = "rust1", since = "1.0.0")] | |
2137 | impl<T: ?Sized> Pointer for &T { | |
2138 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2139 | Pointer::fmt(&(*self as *const T), f) | |
2140 | } | |
2141 | } | |
2142 | ||
2143 | #[stable(feature = "rust1", since = "1.0.0")] | |
2144 | impl<T: ?Sized> Pointer for &mut T { | |
2145 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2146 | Pointer::fmt(&(&**self as *const T), f) | |
2147 | } | |
2148 | } | |
2149 | ||
2150 | // Implementation of Display/Debug for various core types | |
2151 | ||
2152 | #[stable(feature = "rust1", since = "1.0.0")] | |
2153 | impl<T: ?Sized> Debug for *const T { | |
2154 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2155 | Pointer::fmt(self, f) | |
2156 | } | |
2157 | } | |
2158 | #[stable(feature = "rust1", since = "1.0.0")] | |
2159 | impl<T: ?Sized> Debug for *mut T { | |
2160 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2161 | Pointer::fmt(self, f) | |
2162 | } | |
2163 | } | |
2164 | ||
2165 | macro_rules! peel { | |
2166 | ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) | |
2167 | } | |
2168 | ||
2169 | macro_rules! tuple { | |
2170 | () => (); | |
2171 | ( $($name:ident,)+ ) => ( | |
2172 | #[stable(feature = "rust1", since = "1.0.0")] | |
2173 | impl<$($name:Debug),+> Debug for ($($name,)+) where last_type!($($name,)+): ?Sized { | |
2174 | #[allow(non_snake_case, unused_assignments)] | |
2175 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2176 | let mut builder = f.debug_tuple(""); | |
2177 | let ($(ref $name,)+) = *self; | |
2178 | $( | |
2179 | builder.field(&$name); | |
2180 | )+ | |
2181 | ||
2182 | builder.finish() | |
2183 | } | |
2184 | } | |
2185 | peel! { $($name,)+ } | |
2186 | ) | |
2187 | } | |
2188 | ||
2189 | macro_rules! last_type { | |
2190 | ($a:ident,) => { $a }; | |
2191 | ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) }; | |
2192 | } | |
2193 | ||
2194 | tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } | |
2195 | ||
2196 | #[stable(feature = "rust1", since = "1.0.0")] | |
2197 | impl<T: Debug> Debug for [T] { | |
2198 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2199 | f.debug_list().entries(self.iter()).finish() | |
2200 | } | |
2201 | } | |
2202 | ||
2203 | #[stable(feature = "rust1", since = "1.0.0")] | |
2204 | impl Debug for () { | |
2205 | #[inline] | |
2206 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2207 | f.pad("()") | |
2208 | } | |
2209 | } | |
2210 | #[stable(feature = "rust1", since = "1.0.0")] | |
2211 | impl<T: ?Sized> Debug for PhantomData<T> { | |
2212 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2213 | f.pad("PhantomData") | |
2214 | } | |
2215 | } | |
2216 | ||
2217 | #[stable(feature = "rust1", since = "1.0.0")] | |
2218 | impl<T: Copy + Debug> Debug for Cell<T> { | |
2219 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2220 | f.debug_struct("Cell").field("value", &self.get()).finish() | |
2221 | } | |
2222 | } | |
2223 | ||
2224 | #[stable(feature = "rust1", since = "1.0.0")] | |
2225 | impl<T: ?Sized + Debug> Debug for RefCell<T> { | |
2226 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2227 | match self.try_borrow() { | |
2228 | Ok(borrow) => f.debug_struct("RefCell").field("value", &borrow).finish(), | |
2229 | Err(_) => { | |
2230 | // The RefCell is mutably borrowed so we can't look at its value | |
2231 | // here. Show a placeholder instead. | |
2232 | struct BorrowedPlaceholder; | |
2233 | ||
2234 | impl Debug for BorrowedPlaceholder { | |
2235 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2236 | f.write_str("<borrowed>") | |
2237 | } | |
2238 | } | |
2239 | ||
2240 | f.debug_struct("RefCell").field("value", &BorrowedPlaceholder).finish() | |
2241 | } | |
2242 | } | |
2243 | } | |
2244 | } | |
2245 | ||
2246 | #[stable(feature = "rust1", since = "1.0.0")] | |
2247 | impl<T: ?Sized + Debug> Debug for Ref<'_, T> { | |
2248 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2249 | Debug::fmt(&**self, f) | |
2250 | } | |
2251 | } | |
2252 | ||
2253 | #[stable(feature = "rust1", since = "1.0.0")] | |
2254 | impl<T: ?Sized + Debug> Debug for RefMut<'_, T> { | |
2255 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2256 | Debug::fmt(&*(self.deref()), f) | |
2257 | } | |
2258 | } | |
2259 | ||
2260 | #[stable(feature = "core_impl_debug", since = "1.9.0")] | |
2261 | impl<T: ?Sized + Debug> Debug for UnsafeCell<T> { | |
2262 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | |
2263 | f.pad("UnsafeCell") | |
2264 | } | |
2265 | } | |
2266 | ||
2267 | // If you expected tests to be here, look instead at the core/tests/fmt.rs file, | |
2268 | // it's a lot easier than creating all of the rt::Piece structures here. | |
2269 | // There are also tests in the alloc crate, for those that need allocations. |