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