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