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