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.
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.
11 //! Utilities for formatting and printing strings
13 #![allow(unused_variable)]
16 use cell::{Cell, Ref, RefMut};
18 use collections::Collection;
19 use iter::{Iterator, range};
22 use option::{Option, Some, None};
24 use result::{Ok, Err};
26 use slice::{Vector, ImmutableVector};
31 pub use self::num::radix;
32 pub use self::num::Radix;
33 pub use self::num::RadixFmt;
39 pub type Result = result::Result<(), FormatError>;
41 /// The error type which is returned from formatting a message into a stream.
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
46 pub enum FormatError {
47 /// A generic write error occurred during formatting, no other information
48 /// is transmitted via this variant.
52 /// A collection of methods that are required to format a message into a stream.
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.
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
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.
71 /// This function will return an instance of `FormatError` on error.
72 fn write(&mut self, bytes: &[u8]) -> Result;
74 /// Glue for usage of the `write!` macro with implementers of this trait.
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) }
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
84 pub struct Formatter<'a> {
85 /// Flags for formatting (packed version of rt::Flag)
87 /// Character used as 'fill' whenever there is alignment
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>,
96 buf: &'a mut FormatWriter,
97 curarg: slice::Items<'a, Argument<'a>>,
98 args: &'a [Argument<'a>],
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,
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 }
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.
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>],
136 impl<'a> Show for Arguments<'a> {
137 fn fmt(&self, fmt: &mut Formatter) -> Result {
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.
146 /// Formats the value using the given formatter.
147 fn fmt(&self, &mut Formatter) -> Result;
150 /// Format trait for the `b` character
152 /// Formats the value using the given formatter.
153 fn fmt(&self, &mut Formatter) -> Result;
156 /// Format trait for the `c` character
158 /// Formats the value using the given formatter.
159 fn fmt(&self, &mut Formatter) -> Result;
162 /// Format trait for the `i` and `d` characters
164 /// Formats the value using the given formatter.
165 fn fmt(&self, &mut Formatter) -> Result;
168 /// Format trait for the `u` character
170 /// Formats the value using the given formatter.
171 fn fmt(&self, &mut Formatter) -> Result;
174 /// Format trait for the `o` character
176 /// Formats the value using the given formatter.
177 fn fmt(&self, &mut Formatter) -> Result;
180 /// Format trait for the `t` character
182 /// Formats the value using the given formatter.
183 fn fmt(&self, &mut Formatter) -> Result;
186 /// Format trait for the `x` character
188 /// Formats the value using the given formatter.
189 fn fmt(&self, &mut Formatter) -> Result;
192 /// Format trait for the `X` character
194 /// Formats the value using the given formatter.
195 fn fmt(&self, &mut Formatter) -> Result;
198 /// Format trait for the `s` character
200 /// Formats the value using the given formatter.
201 fn fmt(&self, &mut Formatter) -> Result;
204 /// Format trait for the `p` character
206 /// Formats the value using the given formatter.
207 fn fmt(&self, &mut Formatter) -> Result;
210 /// Format trait for the `f` character
212 /// Formats the value using the given formatter.
213 fn fmt(&self, &mut Formatter) -> Result;
216 /// Format trait for the `e` character
218 /// Formats the value using the given formatter.
219 fn fmt(&self, &mut Formatter) -> Result;
222 /// Format trait for the `E` character
224 /// Formats the value using the given formatter.
225 fn fmt(&self, &mut Formatter) -> Result;
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; )*) => {
234 pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
240 uniform_fn_call_workaround! {
244 secret_signed, Signed;
245 secret_unsigned, Unsigned;
247 secret_binary, Binary;
248 secret_lower_hex, LowerHex;
249 secret_upper_hex, UpperHex;
250 secret_string, String;
251 secret_pointer, Pointer;
253 secret_lower_exp, LowerExp;
254 secret_upper_exp, UpperExp;
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.
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 {
271 align: rt::AlignUnknown,
274 curarg: args.args.iter(),
276 for piece in args.fmt.iter() {
277 try!(formatter.run(piece));
282 impl<'a> Formatter<'a> {
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.
288 fn run(&mut self, piece: &rt::Piece) -> Result {
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);
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],
305 // Then actually do some printing
306 (value.formatter)(value.value, self)
311 fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> {
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)) }
319 rt::CountIsNextParam => {
320 let v = self.curarg.next().unwrap().value;
321 unsafe { Some(*(v as *any::Void as *uint)) }
326 // Helper methods used for padding and processing formatting arguments that
327 // all formatting traits can use.
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.
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
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};
346 let mut width = buf.len();
350 sign = Some('-'); width += 1;
351 } else if self.flags & (1 << (FlagSignPlus as uint)) != 0 {
352 sign = Some('+'); width += 1;
355 let mut prefixed = false;
356 if self.flags & (1 << (FlagAlternate as uint)) != 0 {
357 prefixed = true; width += prefix.len();
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)));
367 if prefixed { f.buf.write(prefix.as_bytes()) }
371 // The `width` field is more of a `min-width` parameter at this point.
373 // If there's no minimum length requirements then we can just
376 try!(write_prefix(self)); self.buf.write(buf)
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)
383 // The sign and prefix goes before the padding if the fill character
385 Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => {
387 try!(write_prefix(self));
388 self.with_padding(min - width, rt::AlignRight, |f| f.buf.write(buf))
390 // Otherwise, the sign and prefix goes after the padding
392 self.with_padding(min - width, rt::AlignRight, |f| {
393 try!(write_prefix(f)); f.buf.write(buf)
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:
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
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());
415 // The `precision` field can be interpreted as a `max-width` for the
416 // string being formatted
417 match self.precision {
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();
424 let nchars = ::cmp::min(max, char_len);
425 return self.buf.write(s.slice_chars(0, nchars).as_bytes());
430 // The `width` field is more of a `min-width` parameter at this point.
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())
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.
443 self.with_padding(width - s.len(), rt::AlignLeft, |me| {
444 me.buf.write(s.as_bytes())
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,
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
460 if align == rt::AlignLeft {
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)));
468 if align == rt::AlignRight {
474 /// Writes some data to the underlying buffer contained within this
476 pub fn write(&mut self, data: &[u8]) -> Result {
480 /// Writes some formatted information into this instance
481 pub fn write_fmt(&mut self, fmt: &Arguments) -> Result {
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> {
493 formatter: mem::transmute(f),
494 value: mem::transmute(t)
500 pub fn format(args: &Arguments) -> ::realstd::string::String {
502 use realstd::io::MemWriter;
504 fn mywrite<T: ::realstd::io::Writer>(t: &mut T, b: &[u8]) {
505 use realstd::io::Writer;
509 impl FormatWriter for MemWriter {
510 fn write(&mut self, bytes: &[u8]) -> Result {
511 mywrite(self, bytes);
516 let mut i = MemWriter::new();
517 let _ = write(&mut i, args);
519 let mut result = ::realstd::string::String::new();
520 result.push_str(str::from_utf8(i.get_ref()).unwrap());
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)
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)
538 // Implementations of the core formatting traits
540 impl<'a, T: Show> Show for &'a T {
541 fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
543 impl<'a, T: Show> Show for &'a mut T {
544 fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
548 fn fmt(&self, f: &mut Formatter) -> Result {
549 secret_string(&(if *self {"true"} else {"false"}), f)
553 impl<'a, T: str::Str> String for T {
554 fn fmt(&self, f: &mut Formatter) -> Result {
555 f.pad(self.as_slice())
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)) };
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)
574 impl<T> Pointer for *mut T {
575 fn fmt(&self, f: &mut Formatter) -> Result {
576 secret_pointer::<*T>(&(*self as *T), f)
579 impl<'a, T> Pointer for &'a T {
580 fn fmt(&self, f: &mut Formatter) -> Result {
581 secret_pointer::<*T>(&(&**self as *T), f)
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)
590 macro_rules! floating(($ty:ident) => {
592 fn fmt(&self, fmt: &mut Formatter) -> Result {
595 let digits = match fmt.precision {
596 Some(i) => float::DigExact(i),
597 None => float::DigMax(6),
599 float::float_to_str_bytes_common(self.abs(),
607 fmt.pad_integral(*self >= 0.0, "", bytes)
612 impl LowerExp for $ty {
613 fn fmt(&self, fmt: &mut Formatter) -> Result {
616 let digits = match fmt.precision {
617 Some(i) => float::DigExact(i),
618 None => float::DigMax(6),
620 float::float_to_str_bytes_common(self.abs(),
628 fmt.pad_integral(*self >= 0.0, "", bytes)
633 impl UpperExp for $ty {
634 fn fmt(&self, fmt: &mut Formatter) -> Result {
637 let digits = match fmt.precision {
638 Some(i) => float::DigExact(i),
639 None => float::DigMax(6),
641 float::float_to_str_bytes_common(self.abs(),
649 fmt.pad_integral(*self >= 0.0, "", bytes)
657 // Implementation of Show for various core types
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))
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)
672 impl<T> Show for *T {
673 fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
675 impl<T> Show for *mut T {
676 fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
679 macro_rules! peel(($name:ident, $($other:ident,)*) => (tuple!($($other,)*)))
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;
692 try!(write!(f, ", "));
694 try!(write!(f, "{}", *$name));
698 try!(write!(f, ","));
707 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
709 impl<'a> Show for &'a any::Any {
710 fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") }
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, "["));
718 let mut is_first = true;
719 for x in self.iter() {
723 try!(write!(f, ", "));
725 try!(write!(f, "{}", *x))
727 if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
728 try!(write!(f, "]"));
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)
741 fn fmt(&self, f: &mut Formatter) -> Result {
746 impl<T: Copy + Show> Show for Cell<T> {
747 fn fmt(&self, f: &mut Formatter) -> Result {
748 write!(f, "Cell {{ value: {} }}", self.get())
752 impl<'b, T: Show> Show for Ref<'b, T> {
753 fn fmt(&self, f: &mut Formatter) -> Result {
758 impl<'b, T: Show> Show for RefMut<'b, T> {
759 fn fmt(&self, f: &mut Formatter) -> Result {
760 (*(self.deref())).fmt(f)
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.