]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/mod.rs
auto merge of #19941 : alexcrichton/rust/issue-19767, r=brson
[rust.git] / src / libcore / fmt / mod.rs
1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Utilities for formatting and printing strings
12
13 #![allow(unused_variables)]
14
15 use any;
16 use cell::{Cell, Ref, RefMut};
17 use iter::{Iterator, IteratorExt, range};
18 use kinds::{Copy, Sized};
19 use mem;
20 use option::Option;
21 use option::Option::{Some, None};
22 use ops::{Deref, FnOnce};
23 use result::Result::{Ok, Err};
24 use result;
25 use slice::SliceExt;
26 use slice;
27 use str::{StrExt, Utf8Error};
28
29 pub use self::num::radix;
30 pub use self::num::Radix;
31 pub use self::num::RadixFmt;
32
33 mod num;
34 mod float;
35 pub mod rt;
36
37 #[experimental = "core and I/O reconciliation may alter this definition"]
38 /// The type returned by formatter methods.
39 pub type Result = result::Result<(), Error>;
40
41 /// The error type which is returned from formatting a message into a stream.
42 ///
43 /// This type does not support transmission of an error other than that an error
44 /// occurred. Any extra information must be arranged to be transmitted through
45 /// some other means.
46 #[experimental = "core and I/O reconciliation may alter this definition"]
47 #[deriving(Copy)]
48 pub struct Error;
49
50 /// A collection of methods that are required to format a message into a stream.
51 ///
52 /// This trait is the type which this modules requires when formatting
53 /// information. This is similar to the standard library's `io::Writer` trait,
54 /// but it is only intended for use in libcore.
55 ///
56 /// This trait should generally not be implemented by consumers of the standard
57 /// library. The `write!` macro accepts an instance of `io::Writer`, and the
58 /// `io::Writer` trait is favored over implementing this trait.
59 #[experimental = "waiting for core and I/O reconciliation"]
60 pub trait FormatWriter {
61     /// Writes a slice of bytes into this writer, returning whether the write
62     /// succeeded.
63     ///
64     /// This method can only succeed if the entire byte slice was successfully
65     /// written, and this method will not return until all data has been
66     /// written or an error occurs.
67     ///
68     /// # Errors
69     ///
70     /// This function will return an instance of `FormatError` on error.
71     fn write(&mut self, bytes: &[u8]) -> Result;
72
73     // NOTE(stage0): Remove cfg after a snapshot
74     #[cfg(not(stage0))]
75     /// Glue for usage of the `write!` macro with implementers of this trait.
76     ///
77     /// This method should generally not be invoked manually, but rather through
78     /// the `write!` macro itself.
79     fn write_fmt(&mut self, args: Arguments) -> Result { write(self, args) }
80
81     // NOTE(stage0): Remove method after a snapshot
82     #[cfg(stage0)]
83     /// Glue for usage of the `write!` macro with implementers of this trait.
84     ///
85     /// This method should generally not be invoked manually, but rather through
86     /// the `write!` macro itself.
87     fn write_fmt(&mut self, args: &Arguments) -> Result { write(self, args) }
88 }
89
90 /// A struct to represent both where to emit formatting strings to and how they
91 /// should be formatted. A mutable version of this is passed to all formatting
92 /// traits.
93 #[unstable = "name may change and implemented traits are also unstable"]
94 pub struct Formatter<'a> {
95     flags: uint,
96     fill: char,
97     align: rt::Alignment,
98     width: Option<uint>,
99     precision: Option<uint>,
100
101     buf: &'a mut (FormatWriter+'a),
102     curarg: slice::Iter<'a, Argument<'a>>,
103     args: &'a [Argument<'a>],
104 }
105
106 // NB. Argument is essentially an optimized partially applied formatting function,
107 // equivalent to `exists T.(&T, fn(&T, &mut Formatter) -> Result`.
108
109 enum Void {}
110
111 /// This struct represents the generic "argument" which is taken by the Xprintf
112 /// family of functions. It contains a function to format the given value. At
113 /// compile time it is ensured that the function and the value have the correct
114 /// types, and then this struct is used to canonicalize arguments to one type.
115 #[experimental = "implementation detail of the `format_args!` macro"]
116 #[deriving(Copy)]
117 pub struct Argument<'a> {
118     value: &'a Void,
119     formatter: fn(&Void, &mut Formatter) -> Result,
120 }
121
122 impl<'a> Argument<'a> {
123     #[inline(never)]
124     fn show_uint(x: &uint, f: &mut Formatter) -> Result {
125         Show::fmt(x, f)
126     }
127
128     fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter) -> Result) -> Argument<'b> {
129         unsafe {
130             Argument {
131                 formatter: mem::transmute(f),
132                 value: mem::transmute(x)
133             }
134         }
135     }
136
137     fn from_uint(x: &uint) -> Argument {
138         Argument::new(x, Argument::show_uint)
139     }
140
141     fn as_uint(&self) -> Option<uint> {
142         if self.formatter as uint == Argument::show_uint as uint {
143             Some(unsafe { *(self.value as *const _ as *const uint) })
144         } else {
145             None
146         }
147     }
148 }
149
150 impl<'a> Arguments<'a> {
151     /// When using the format_args!() macro, this function is used to generate the
152     /// Arguments structure.
153     #[doc(hidden)] #[inline]
154     #[experimental = "implementation detail of the `format_args!` macro"]
155     pub fn new(pieces: &'a [&'a str],
156                args: &'a [Argument<'a>]) -> Arguments<'a> {
157         Arguments {
158             pieces: pieces,
159             fmt: None,
160             args: args
161         }
162     }
163
164     /// This function is used to specify nonstandard formatting parameters.
165     /// The `pieces` array must be at least as long as `fmt` to construct
166     /// a valid Arguments structure. Also, any `Count` within `fmt` that is
167     /// `CountIsParam` or `CountIsNextParam` has to point to an argument
168     /// created with `argumentuint`. However, failing to do so doesn't cause
169     /// unsafety, but will ignore invalid .
170     #[doc(hidden)] #[inline]
171     #[experimental = "implementation detail of the `format_args!` macro"]
172     pub fn with_placeholders(pieces: &'a [&'a str],
173                              fmt: &'a [rt::Argument<'a>],
174                              args: &'a [Argument<'a>]) -> Arguments<'a> {
175         Arguments {
176             pieces: pieces,
177             fmt: Some(fmt),
178             args: args
179         }
180     }
181 }
182
183 /// This structure represents a safely precompiled version of a format string
184 /// and its arguments. This cannot be generated at runtime because it cannot
185 /// safely be done so, so no constructors are given and the fields are private
186 /// to prevent modification.
187 ///
188 /// The `format_args!` macro will safely create an instance of this structure
189 /// and pass it to a function or closure, passed as the first argument. The
190 /// macro validates the format string at compile-time so usage of the `write`
191 /// and `format` functions can be safely performed.
192 #[stable]
193 #[deriving(Copy)]
194 pub struct Arguments<'a> {
195     // Format string pieces to print.
196     pieces: &'a [&'a str],
197
198     // Placeholder specs, or `None` if all specs are default (as in "{}{}").
199     fmt: Option<&'a [rt::Argument<'a>]>,
200
201     // Dynamic arguments for interpolation, to be interleaved with string
202     // pieces. (Every argument is preceded by a string piece.)
203     args: &'a [Argument<'a>],
204 }
205
206 impl<'a> Show for Arguments<'a> {
207     // NOTE(stage0): Remove cfg after a snapshot
208     #[cfg(not(stage0))]
209     fn fmt(&self, fmt: &mut Formatter) -> Result {
210         write(fmt.buf, *self)
211     }
212
213     // NOTE(stage0): Remove method after a snapshot
214     #[cfg(stage0)]
215     fn fmt(&self, fmt: &mut Formatter) -> Result {
216         write(fmt.buf, self)
217     }
218 }
219
220 /// When a format is not otherwise specified, types are formatted by ascribing
221 /// to this trait. There is not an explicit way of selecting this trait to be
222 /// used for formatting, it is only if no other format is specified.
223 #[unstable = "I/O and core have yet to be reconciled"]
224 pub trait Show for Sized? {
225     /// Formats the value using the given formatter.
226     fn fmt(&self, &mut Formatter) -> Result;
227 }
228
229
230 /// Format trait for the `o` character
231 #[unstable = "I/O and core have yet to be reconciled"]
232 pub trait Octal for Sized? {
233     /// Formats the value using the given formatter.
234     fn fmt(&self, &mut Formatter) -> Result;
235 }
236
237 /// Format trait for the `b` character
238 #[unstable = "I/O and core have yet to be reconciled"]
239 pub trait Binary for Sized? {
240     /// Formats the value using the given formatter.
241     fn fmt(&self, &mut Formatter) -> Result;
242 }
243
244 /// Format trait for the `x` character
245 #[unstable = "I/O and core have yet to be reconciled"]
246 pub trait LowerHex for Sized? {
247     /// Formats the value using the given formatter.
248     fn fmt(&self, &mut Formatter) -> Result;
249 }
250
251 /// Format trait for the `X` character
252 #[unstable = "I/O and core have yet to be reconciled"]
253 pub trait UpperHex for Sized? {
254     /// Formats the value using the given formatter.
255     fn fmt(&self, &mut Formatter) -> Result;
256 }
257
258 /// Format trait for the `p` character
259 #[unstable = "I/O and core have yet to be reconciled"]
260 pub trait Pointer for Sized? {
261     /// Formats the value using the given formatter.
262     fn fmt(&self, &mut Formatter) -> Result;
263 }
264
265 /// Format trait for the `e` character
266 #[unstable = "I/O and core have yet to be reconciled"]
267 pub trait LowerExp for Sized? {
268     /// Formats the value using the given formatter.
269     fn fmt(&self, &mut Formatter) -> Result;
270 }
271
272 /// Format trait for the `E` character
273 #[unstable = "I/O and core have yet to be reconciled"]
274 pub trait UpperExp for Sized? {
275     /// Formats the value using the given formatter.
276     fn fmt(&self, &mut Formatter) -> Result;
277 }
278
279 static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument {
280     position: rt::ArgumentNext,
281     format: rt::FormatSpec {
282         fill: ' ',
283         align: rt::AlignUnknown,
284         flags: 0,
285         precision: rt::CountImplied,
286         width: rt::CountImplied,
287     }
288 };
289
290 // NOTE(stage0): Remove cfg after a snapshot
291 #[cfg(not(stage0))]
292 /// The `write` function takes an output stream, a precompiled format string,
293 /// and a list of arguments. The arguments will be formatted according to the
294 /// specified format string into the output stream provided.
295 ///
296 /// # Arguments
297 ///
298 ///   * output - the buffer to write output to
299 ///   * args - the precompiled arguments generated by `format_args!`
300 #[experimental = "libcore and I/O have yet to be reconciled, and this is an \
301                   implementation detail which should not otherwise be exported"]
302 pub fn write(output: &mut FormatWriter, args: Arguments) -> Result {
303     let mut formatter = Formatter {
304         flags: 0,
305         width: None,
306         precision: None,
307         buf: output,
308         align: rt::AlignUnknown,
309         fill: ' ',
310         args: args.args,
311         curarg: args.args.iter(),
312     };
313
314     let mut pieces = args.pieces.iter();
315
316     match args.fmt {
317         None => {
318             // We can use default formatting parameters for all arguments.
319             for _ in range(0, args.args.len()) {
320                 try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
321                 try!(formatter.run(&DEFAULT_ARGUMENT));
322             }
323         }
324         Some(fmt) => {
325             // Every spec has a corresponding argument that is preceded by
326             // a string piece.
327             for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
328                 try!(formatter.buf.write(piece.as_bytes()));
329                 try!(formatter.run(arg));
330             }
331         }
332     }
333
334     // There can be only one trailing string piece left.
335     match pieces.next() {
336         Some(piece) => {
337             try!(formatter.buf.write(piece.as_bytes()));
338         }
339         None => {}
340     }
341
342     Ok(())
343 }
344
345 // NOTE(stage0): Remove function after a snapshot
346 #[cfg(stage0)]
347 /// The `write` function takes an output stream, a precompiled format string,
348 /// and a list of arguments. The arguments will be formatted according to the
349 /// specified format string into the output stream provided.
350 ///
351 /// # Arguments
352 ///
353 ///   * output - the buffer to write output to
354 ///   * args - the precompiled arguments generated by `format_args!`
355 #[experimental = "libcore and I/O have yet to be reconciled, and this is an \
356                   implementation detail which should not otherwise be exported"]
357 pub fn write(output: &mut FormatWriter, args: &Arguments) -> Result {
358     let mut formatter = Formatter {
359         flags: 0,
360         width: None,
361         precision: None,
362         buf: output,
363         align: rt::AlignUnknown,
364         fill: ' ',
365         args: args.args,
366         curarg: args.args.iter(),
367     };
368
369     let mut pieces = args.pieces.iter();
370
371     match args.fmt {
372         None => {
373             // We can use default formatting parameters for all arguments.
374             for _ in range(0, args.args.len()) {
375                 try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
376                 try!(formatter.run(&DEFAULT_ARGUMENT));
377             }
378         }
379         Some(fmt) => {
380             // Every spec has a corresponding argument that is preceded by
381             // a string piece.
382             for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
383                 try!(formatter.buf.write(piece.as_bytes()));
384                 try!(formatter.run(arg));
385             }
386         }
387     }
388
389     // There can be only one trailing string piece left.
390     match pieces.next() {
391         Some(piece) => {
392             try!(formatter.buf.write(piece.as_bytes()));
393         }
394         None => {}
395     }
396
397     Ok(())
398 }
399
400 impl<'a> Formatter<'a> {
401
402     // First up is the collection of functions used to execute a format string
403     // at runtime. This consumes all of the compile-time statics generated by
404     // the format! syntax extension.
405     fn run(&mut self, arg: &rt::Argument) -> Result {
406         // Fill in the format parameters into the formatter
407         self.fill = arg.format.fill;
408         self.align = arg.format.align;
409         self.flags = arg.format.flags;
410         self.width = self.getcount(&arg.format.width);
411         self.precision = self.getcount(&arg.format.precision);
412
413         // Extract the correct argument
414         let value = match arg.position {
415             rt::ArgumentNext => { *self.curarg.next().unwrap() }
416             rt::ArgumentIs(i) => self.args[i],
417         };
418
419         // Then actually do some printing
420         (value.formatter)(value.value, self)
421     }
422
423     fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> {
424         match *cnt {
425             rt::CountIs(n) => Some(n),
426             rt::CountImplied => None,
427             rt::CountIsParam(i) => {
428                 self.args[i].as_uint()
429             }
430             rt::CountIsNextParam => {
431                 self.curarg.next().and_then(|arg| arg.as_uint())
432             }
433         }
434     }
435
436     // Helper methods used for padding and processing formatting arguments that
437     // all formatting traits can use.
438
439     /// Performs the correct padding for an integer which has already been
440     /// emitted into a byte-array. The byte-array should *not* contain the sign
441     /// for the integer, that will be added by this method.
442     ///
443     /// # Arguments
444     ///
445     /// * is_positive - whether the original integer was positive or not.
446     /// * prefix - if the '#' character (FlagAlternate) is provided, this
447     ///   is the prefix to put in front of the number.
448     /// * buf - the byte array that the number has been formatted into
449     ///
450     /// This function will correctly account for the flags provided as well as
451     /// the minimum width. It will not take precision into account.
452     #[unstable = "definition may change slightly over time"]
453     pub fn pad_integral(&mut self,
454                         is_positive: bool,
455                         prefix: &str,
456                         buf: &[u8])
457                         -> Result {
458         use char::Char;
459         use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
460
461         let mut width = buf.len();
462
463         let mut sign = None;
464         if !is_positive {
465             sign = Some('-'); width += 1;
466         } else if self.flags & (1 << (FlagSignPlus as uint)) != 0 {
467             sign = Some('+'); width += 1;
468         }
469
470         let mut prefixed = false;
471         if self.flags & (1 << (FlagAlternate as uint)) != 0 {
472             prefixed = true; width += prefix.char_len();
473         }
474
475         // Writes the sign if it exists, and then the prefix if it was requested
476         let write_prefix = |f: &mut Formatter| {
477             for c in sign.into_iter() {
478                 let mut b = [0, ..4];
479                 let n = c.encode_utf8(&mut b).unwrap_or(0);
480                 try!(f.buf.write(b[..n]));
481             }
482             if prefixed { f.buf.write(prefix.as_bytes()) }
483             else { Ok(()) }
484         };
485
486         // The `width` field is more of a `min-width` parameter at this point.
487         match self.width {
488             // If there's no minimum length requirements then we can just
489             // write the bytes.
490             None => {
491                 try!(write_prefix(self)); self.buf.write(buf)
492             }
493             // Check if we're over the minimum width, if so then we can also
494             // just write the bytes.
495             Some(min) if width >= min => {
496                 try!(write_prefix(self)); self.buf.write(buf)
497             }
498             // The sign and prefix goes before the padding if the fill character
499             // is zero
500             Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => {
501                 self.fill = '0';
502                 try!(write_prefix(self));
503                 self.with_padding(min - width, rt::AlignRight, |f| f.buf.write(buf))
504             }
505             // Otherwise, the sign and prefix goes after the padding
506             Some(min) => {
507                 self.with_padding(min - width, rt::AlignRight, |f| {
508                     try!(write_prefix(f)); f.buf.write(buf)
509                 })
510             }
511         }
512     }
513
514     /// This function takes a string slice and emits it to the internal buffer
515     /// after applying the relevant formatting flags specified. The flags
516     /// recognized for generic strings are:
517     ///
518     /// * width - the minimum width of what to emit
519     /// * fill/align - what to emit and where to emit it if the string
520     ///                provided needs to be padded
521     /// * precision - the maximum length to emit, the string is truncated if it
522     ///               is longer than this length
523     ///
524     /// Notably this function ignored the `flag` parameters
525     #[unstable = "definition may change slightly over time"]
526     pub fn pad(&mut self, s: &str) -> Result {
527         // Make sure there's a fast path up front
528         if self.width.is_none() && self.precision.is_none() {
529             return self.buf.write(s.as_bytes());
530         }
531         // The `precision` field can be interpreted as a `max-width` for the
532         // string being formatted
533         match self.precision {
534             Some(max) => {
535                 // If there's a maximum width and our string is longer than
536                 // that, then we must always have truncation. This is the only
537                 // case where the maximum length will matter.
538                 let char_len = s.char_len();
539                 if char_len >= max {
540                     let nchars = ::cmp::min(max, char_len);
541                     return self.buf.write(s.slice_chars(0, nchars).as_bytes());
542                 }
543             }
544             None => {}
545         }
546         // The `width` field is more of a `min-width` parameter at this point.
547         match self.width {
548             // If we're under the maximum length, and there's no minimum length
549             // requirements, then we can just emit the string
550             None => self.buf.write(s.as_bytes()),
551             // If we're under the maximum width, check if we're over the minimum
552             // width, if so it's as easy as just emitting the string.
553             Some(width) if s.char_len() >= width => {
554                 self.buf.write(s.as_bytes())
555             }
556             // If we're under both the maximum and the minimum width, then fill
557             // up the minimum width with the specified string + some alignment.
558             Some(width) => {
559                 self.with_padding(width - s.char_len(), rt::AlignLeft, |me| {
560                     me.buf.write(s.as_bytes())
561                 })
562             }
563         }
564     }
565
566     /// Runs a callback, emitting the correct padding either before or
567     /// afterwards depending on whether right or left alignment is requested.
568     fn with_padding<F>(&mut self, padding: uint, default: rt::Alignment, f: F) -> Result where
569         F: FnOnce(&mut Formatter) -> Result,
570     {
571         use char::Char;
572         let align = match self.align {
573             rt::AlignUnknown => default,
574             _ => self.align
575         };
576
577         let (pre_pad, post_pad) = match align {
578             rt::AlignLeft => (0u, padding),
579             rt::AlignRight | rt::AlignUnknown => (padding, 0u),
580             rt::AlignCenter => (padding / 2, (padding + 1) / 2),
581         };
582
583         let mut fill = [0u8, ..4];
584         let len = self.fill.encode_utf8(&mut fill).unwrap_or(0);
585
586         for _ in range(0, pre_pad) {
587             try!(self.buf.write(fill[..len]));
588         }
589
590         try!(f(self));
591
592         for _ in range(0, post_pad) {
593             try!(self.buf.write(fill[..len]));
594         }
595
596         Ok(())
597     }
598
599     /// Writes some data to the underlying buffer contained within this
600     /// formatter.
601     #[unstable = "reconciling core and I/O may alter this definition"]
602     pub fn write(&mut self, data: &[u8]) -> Result {
603         self.buf.write(data)
604     }
605
606     // NOTE(stage0): Remove cfg after a snapshot
607     #[cfg(not(stage0))]
608     /// Writes some formatted information into this instance
609     #[unstable = "reconciling core and I/O may alter this definition"]
610     pub fn write_fmt(&mut self, fmt: Arguments) -> Result {
611         write(self.buf, fmt)
612     }
613
614     // NOTE(stage0): Remove method after a snapshot
615     #[cfg(stage0)]
616     /// Writes some formatted information into this instance
617     #[unstable = "reconciling core and I/O may alter this definition"]
618     pub fn write_fmt(&mut self, fmt: &Arguments) -> Result {
619         write(self.buf, fmt)
620     }
621
622     /// Flags for formatting (packed version of rt::Flag)
623     #[experimental = "return type may change and method was just created"]
624     pub fn flags(&self) -> uint { self.flags }
625
626     /// Character used as 'fill' whenever there is alignment
627     #[unstable = "method was just created"]
628     pub fn fill(&self) -> char { self.fill }
629
630     /// Flag indicating what form of alignment was requested
631     #[unstable = "method was just created"]
632     pub fn align(&self) -> rt::Alignment { self.align }
633
634     /// Optionally specified integer width that the output should be
635     #[unstable = "method was just created"]
636     pub fn width(&self) -> Option<uint> { self.width }
637
638     /// Optionally specified precision for numeric types
639     #[unstable = "method was just created"]
640     pub fn precision(&self) -> Option<uint> { self.precision }
641 }
642
643 impl Show for Error {
644     fn fmt(&self, f: &mut Formatter) -> Result {
645         "an error occurred when formatting an argument".fmt(f)
646     }
647 }
648
649 /// This is a function which calls are emitted to by the compiler itself to
650 /// create the Argument structures that are passed into the `format` function.
651 #[doc(hidden)] #[inline]
652 #[experimental = "implementation detail of the `format_args!` macro"]
653 pub fn argument<'a, T>(f: fn(&T, &mut Formatter) -> Result,
654                        t: &'a T) -> Argument<'a> {
655     Argument::new(t, f)
656 }
657
658 /// When the compiler determines that the type of an argument *must* be a uint
659 /// (such as for width and precision), then it invokes this method.
660 #[doc(hidden)] #[inline]
661 #[experimental = "implementation detail of the `format_args!` macro"]
662 pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
663     Argument::from_uint(s)
664 }
665
666 // Implementations of the core formatting traits
667
668 impl<'a, Sized? T: Show> Show for &'a T {
669     fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
670 }
671 impl<'a, Sized? T: Show> Show for &'a mut T {
672     fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
673 }
674 impl<'a> Show for &'a (Show+'a) {
675     fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
676 }
677
678 impl Show for bool {
679     fn fmt(&self, f: &mut Formatter) -> Result {
680         Show::fmt(if *self { "true" } else { "false" }, f)
681     }
682 }
683
684 impl Show for str {
685     fn fmt(&self, f: &mut Formatter) -> Result {
686         f.pad(self)
687     }
688 }
689
690 impl Show for char {
691     fn fmt(&self, f: &mut Formatter) -> Result {
692         use char::Char;
693
694         let mut utf8 = [0u8, ..4];
695         let amt = self.encode_utf8(&mut utf8).unwrap_or(0);
696         let s: &str = unsafe { mem::transmute(utf8[..amt]) };
697         Show::fmt(s, f)
698     }
699 }
700
701 impl<T> Pointer for *const T {
702     fn fmt(&self, f: &mut Formatter) -> Result {
703         f.flags |= 1 << (rt::FlagAlternate as uint);
704         LowerHex::fmt(&(*self as uint), f)
705     }
706 }
707
708 impl<T> Pointer for *mut T {
709     fn fmt(&self, f: &mut Formatter) -> Result {
710         Pointer::fmt(&(*self as *const T), f)
711     }
712 }
713
714 impl<'a, T> Pointer for &'a T {
715     fn fmt(&self, f: &mut Formatter) -> Result {
716         Pointer::fmt(&(*self as *const T), f)
717     }
718 }
719
720 impl<'a, T> Pointer for &'a mut T {
721     fn fmt(&self, f: &mut Formatter) -> Result {
722         Pointer::fmt(&(&**self as *const T), f)
723     }
724 }
725
726 macro_rules! floating { ($ty:ident) => {
727     impl Show for $ty {
728         fn fmt(&self, fmt: &mut Formatter) -> Result {
729             use num::Float;
730
731             let digits = match fmt.precision {
732                 Some(i) => float::DigExact(i),
733                 None => float::DigMax(6),
734             };
735             float::float_to_str_bytes_common(self.abs(),
736                                              10,
737                                              true,
738                                              float::SignNeg,
739                                              digits,
740                                              float::ExpNone,
741                                              false,
742                                              |bytes| {
743                 fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
744             })
745         }
746     }
747
748     impl LowerExp for $ty {
749         fn fmt(&self, fmt: &mut Formatter) -> Result {
750             use num::Float;
751
752             let digits = match fmt.precision {
753                 Some(i) => float::DigExact(i),
754                 None => float::DigMax(6),
755             };
756             float::float_to_str_bytes_common(self.abs(),
757                                              10,
758                                              true,
759                                              float::SignNeg,
760                                              digits,
761                                              float::ExpDec,
762                                              false,
763                                              |bytes| {
764                 fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
765             })
766         }
767     }
768
769     impl UpperExp for $ty {
770         fn fmt(&self, fmt: &mut Formatter) -> Result {
771             use num::Float;
772
773             let digits = match fmt.precision {
774                 Some(i) => float::DigExact(i),
775                 None => float::DigMax(6),
776             };
777             float::float_to_str_bytes_common(self.abs(),
778                                              10,
779                                              true,
780                                              float::SignNeg,
781                                              digits,
782                                              float::ExpDec,
783                                              true,
784                                              |bytes| {
785                 fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
786             })
787         }
788     }
789 } }
790 floating! { f32 }
791 floating! { f64 }
792
793 // Implementation of Show for various core types
794
795 impl<T> Show for *const T {
796     fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
797 }
798
799 impl<T> Show for *mut T {
800     fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
801 }
802
803 macro_rules! peel {
804     ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* })
805 }
806
807 macro_rules! tuple {
808     () => ();
809     ( $($name:ident,)+ ) => (
810         impl<$($name:Show),*> Show for ($($name,)*) {
811             #[allow(non_snake_case, unused_assignments)]
812             fn fmt(&self, f: &mut Formatter) -> Result {
813                 try!(write!(f, "("));
814                 let ($(ref $name,)*) = *self;
815                 let mut n = 0i;
816                 $(
817                     if n > 0 {
818                         try!(write!(f, ", "));
819                     }
820                     try!(write!(f, "{}", *$name));
821                     n += 1;
822                 )*
823                 if n == 1 {
824                     try!(write!(f, ","));
825                 }
826                 write!(f, ")")
827             }
828         }
829         peel! { $($name,)* }
830     )
831 }
832
833 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
834
835 impl<'a> Show for &'a (any::Any+'a) {
836     fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") }
837 }
838
839 impl<T: Show> Show for [T] {
840     fn fmt(&self, f: &mut Formatter) -> Result {
841         if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
842             try!(write!(f, "["));
843         }
844         let mut is_first = true;
845         for x in self.iter() {
846             if is_first {
847                 is_first = false;
848             } else {
849                 try!(write!(f, ", "));
850             }
851             try!(write!(f, "{}", *x))
852         }
853         if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
854             try!(write!(f, "]"));
855         }
856         Ok(())
857     }
858 }
859
860 impl Show for () {
861     fn fmt(&self, f: &mut Formatter) -> Result {
862         f.pad("()")
863     }
864 }
865
866 impl<T: Copy + Show> Show for Cell<T> {
867     fn fmt(&self, f: &mut Formatter) -> Result {
868         write!(f, "Cell {{ value: {} }}", self.get())
869     }
870 }
871
872 impl<'b, T: Show> Show for Ref<'b, T> {
873     fn fmt(&self, f: &mut Formatter) -> Result {
874         (**self).fmt(f)
875     }
876 }
877
878 impl<'b, T: Show> Show for RefMut<'b, T> {
879     fn fmt(&self, f: &mut Formatter) -> Result {
880         (*(self.deref())).fmt(f)
881     }
882 }
883
884 impl Show for Utf8Error {
885     fn fmt(&self, f: &mut Formatter) -> Result {
886         match *self {
887             Utf8Error::InvalidByte(n) => {
888                 write!(f, "invalid utf-8: invalid byte at index {}", n)
889             }
890             Utf8Error::TooShort => {
891                 write!(f, "invalid utf-8: byte slice too short")
892             }
893         }
894     }
895 }
896
897 // If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
898 // it's a lot easier than creating all of the rt::Piece structures here.