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