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