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)]
18 use container::Container;
19 use iter::{Iterator, range};
22 use option::{Option, Some, None};
23 use result::{Ok, Err};
25 use slice::{Vector, ImmutableVector};
30 pub use self::num::radix;
31 pub use self::num::Radix;
32 pub use self::num::RadixFmt;
35 ($dst:expr, $($arg:tt)*) => ({
36 format_args!(|args| { $dst.write_fmt(args) }, $($arg)*)
44 pub type Result = result::Result<(), FormatError>;
46 /// The error type which is returned from formatting a message into a stream.
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
51 pub enum FormatError {
52 /// A generic write error occurred during formatting, no other information
53 /// is transmitted via this variant.
57 /// A collection of methods that are required to format a message into a stream.
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.
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
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.
76 /// This function will return an instance of `FormatError` on error.
77 fn write(&mut self, bytes: &[u8]) -> Result;
79 /// Glue for usage of the `write!` macro with implementers of this trait.
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) }
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
89 pub struct Formatter<'a> {
90 /// Flags for formatting (packed version of rt::Flag)
92 /// Character used as 'fill' whenever there is alignment
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>,
101 buf: &'a mut FormatWriter,
102 curarg: slice::Items<'a, Argument<'a>>,
103 args: &'a [Argument<'a>],
106 enum CurrentlyFormatting<'a> {
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,
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 }
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.
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>],
147 impl<'a> Show for Arguments<'a> {
148 fn fmt(&self, fmt: &mut Formatter) -> Result {
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.
157 /// Formats the value using the given formatter.
158 fn fmt(&self, &mut Formatter) -> Result;
161 /// Format trait for the `b` character
163 /// Formats the value using the given formatter.
164 fn fmt(&self, &mut Formatter) -> Result;
167 /// Format trait for the `c` character
169 /// Formats the value using the given formatter.
170 fn fmt(&self, &mut Formatter) -> Result;
173 /// Format trait for the `i` and `d` characters
175 /// Formats the value using the given formatter.
176 fn fmt(&self, &mut Formatter) -> Result;
179 /// Format trait for the `u` character
181 /// Formats the value using the given formatter.
182 fn fmt(&self, &mut Formatter) -> Result;
185 /// Format trait for the `o` character
187 /// Formats the value using the given formatter.
188 fn fmt(&self, &mut Formatter) -> Result;
191 /// Format trait for the `t` character
193 /// Formats the value using the given formatter.
194 fn fmt(&self, &mut Formatter) -> Result;
197 /// Format trait for the `x` character
199 /// Formats the value using the given formatter.
200 fn fmt(&self, &mut Formatter) -> Result;
203 /// Format trait for the `X` character
205 /// Formats the value using the given formatter.
206 fn fmt(&self, &mut Formatter) -> Result;
209 /// Format trait for the `s` character
211 /// Formats the value using the given formatter.
212 fn fmt(&self, &mut Formatter) -> Result;
215 /// Format trait for the `p` character
217 /// Formats the value using the given formatter.
218 fn fmt(&self, &mut Formatter) -> Result;
221 /// Format trait for the `f` character
223 /// Formats the value using the given formatter.
224 fn fmt(&self, &mut Formatter) -> Result;
227 /// Format trait for the `e` character
229 /// Formats the value using the given formatter.
230 fn fmt(&self, &mut Formatter) -> Result;
233 /// Format trait for the `E` character
235 /// Formats the value using the given formatter.
236 fn fmt(&self, &mut Formatter) -> Result;
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; )*) => {
245 pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
251 uniform_fn_call_workaround! {
255 secret_signed, Signed;
256 secret_unsigned, Unsigned;
258 secret_binary, Binary;
259 secret_lower_hex, LowerHex;
260 secret_upper_hex, UpperHex;
261 secret_string, String;
262 secret_pointer, Pointer;
264 secret_lower_exp, LowerExp;
265 secret_upper_exp, UpperExp;
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.
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 {
282 align: rt::AlignUnknown,
285 curarg: args.args.iter(),
287 for piece in args.fmt.iter() {
288 try!(formatter.run(piece, Nothing));
293 impl<'a> Formatter<'a> {
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.
299 fn run(&mut self, piece: &rt::Piece, cur: CurrentlyFormatting) -> Result {
301 rt::String(s) => self.buf.write(s.as_bytes()),
302 rt::CurrentArgument(()) => {
305 Number(n) => secret_show(&radix(n, 10), self),
306 RawString(s) => self.buf.write(s.as_bytes()),
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);
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],
323 // Then actually do some printing
325 None => (value.formatter)(value.value, self),
326 Some(ref method) => self.execute(*method, value)
332 fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> {
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)) }
340 rt::CountIsNextParam => {
341 let v = self.curarg.next().unwrap().value;
342 unsafe { Some(*(v as *any::Void as *uint)) }
347 fn execute(&mut self, method: &rt::Method, arg: Argument) -> Result {
349 // Pluralization is selection upon a numeric value specified as the
351 rt::Plural(offset, ref selectors, ref default) => {
352 // This is validated at compile-time to be a pointer to a
354 let value: &uint = unsafe { mem::transmute(arg.value) };
357 // First, attempt to match against explicit values without the
359 for s in selectors.iter() {
361 rt::Literal(val) if value == val => {
362 return self.runplural(value, s.result);
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,
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,
383 rt::Literal(..) => false
386 return self.runplural(value, s.result);
390 self.runplural(value, *default)
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
397 let value: & &str = unsafe { mem::transmute(arg.value) };
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)));
408 for piece in default.iter() {
409 try!(self.run(piece, RawString(value)));
416 fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) -> Result {
417 for piece in pieces.iter() {
418 try!(self.run(piece, Number(value)));
423 // Helper methods used for padding and processing formatting arguments that
424 // all formatting traits can use.
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.
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
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};
443 let mut width = buf.len();
447 sign = Some('-'); width += 1;
448 } else if self.flags & (1 << (FlagSignPlus as uint)) != 0 {
449 sign = Some('+'); width += 1;
452 let mut prefixed = false;
453 if self.flags & (1 << (FlagAlternate as uint)) != 0 {
454 prefixed = true; width += prefix.len();
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)));
464 if prefixed { f.buf.write(prefix.as_bytes()) }
468 // The `width` field is more of a `min-width` parameter at this point.
470 // If there's no minimum length requirements then we can just
473 try!(write_prefix(self)); self.buf.write(buf)
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)
480 // The sign and prefix goes before the padding if the fill character
482 Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => {
484 try!(write_prefix(self));
485 self.with_padding(min - width, rt::AlignRight, |f| f.buf.write(buf))
487 // Otherwise, the sign and prefix goes after the padding
489 self.with_padding(min - width, rt::AlignRight, |f| {
490 try!(write_prefix(f)); f.buf.write(buf)
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:
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
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());
512 // The `precision` field can be interpreted as a `max-width` for the
513 // string being formatted
514 match self.precision {
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();
521 let nchars = ::cmp::min(max, char_len);
522 return self.buf.write(s.slice_chars(0, nchars).as_bytes());
527 // The `width` field is more of a `min-width` parameter at this point.
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())
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.
540 self.with_padding(width - s.len(), rt::AlignLeft, |me| {
541 me.buf.write(s.as_bytes())
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,
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
557 if align == rt::AlignLeft {
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)));
565 if align == rt::AlignRight {
571 /// Writes some data to the underlying buffer contained within this
573 pub fn write(&mut self, data: &[u8]) -> Result {
577 /// Writes some formatted information into this instance
578 pub fn write_fmt(&mut self, fmt: &Arguments) -> Result {
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> {
590 formatter: mem::transmute(f),
591 value: mem::transmute(t)
597 pub fn format(args: &Arguments) -> ::realstd::string::String {
599 use realstd::str::StrAllocating;
600 use realstd::io::MemWriter;
602 fn mywrite<T: ::realstd::io::Writer>(t: &mut T, b: &[u8]) {
603 use realstd::io::Writer;
607 impl FormatWriter for MemWriter {
608 fn write(&mut self, bytes: &[u8]) -> Result {
609 mywrite(self, bytes);
614 let mut i = MemWriter::new();
615 let _ = write(&mut i, args);
617 let mut result = ::realstd::string::String::new();
618 result.push_str(str::from_utf8(i.get_ref()).unwrap());
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)
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)
636 // Implementations of the core formatting traits
638 impl<T: Show> Show for @T {
639 fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
641 impl<'a, T: Show> Show for &'a T {
642 fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
644 impl<'a, T: Show> Show for &'a mut T {
645 fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
649 fn fmt(&self, f: &mut Formatter) -> Result {
650 secret_string(&(if *self {"true"} else {"false"}), f)
654 impl<'a, T: str::Str> String for T {
655 fn fmt(&self, f: &mut Formatter) -> Result {
656 f.pad(self.as_slice())
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)) };
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)
675 impl<T> Pointer for *mut T {
676 fn fmt(&self, f: &mut Formatter) -> Result {
677 secret_pointer::<*T>(&(*self as *T), f)
680 impl<'a, T> Pointer for &'a T {
681 fn fmt(&self, f: &mut Formatter) -> Result {
682 secret_pointer::<*T>(&(&**self as *T), f)
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)
691 macro_rules! floating(($ty:ident) => {
693 fn fmt(&self, fmt: &mut Formatter) -> Result {
696 let digits = match fmt.precision {
697 Some(i) => float::DigExact(i),
698 None => float::DigMax(6),
700 float::float_to_str_bytes_common(self.abs(),
708 fmt.pad_integral(*self >= 0.0, "", bytes)
713 impl LowerExp for $ty {
714 fn fmt(&self, fmt: &mut Formatter) -> Result {
717 let digits = match fmt.precision {
718 Some(i) => float::DigExact(i),
719 None => float::DigMax(6),
721 float::float_to_str_bytes_common(self.abs(),
729 fmt.pad_integral(*self >= 0.0, "", bytes)
734 impl UpperExp for $ty {
735 fn fmt(&self, fmt: &mut Formatter) -> Result {
738 let digits = match fmt.precision {
739 Some(i) => float::DigExact(i),
740 None => float::DigMax(6),
742 float::float_to_str_bytes_common(self.abs(),
750 fmt.pad_integral(*self >= 0.0, "", bytes)
758 // Implementation of Show for various core types
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))
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)
773 impl<T> Show for *T {
774 fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
776 impl<T> Show for *mut T {
777 fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
780 macro_rules! peel(($name:ident, $($other:ident,)*) => (tuple!($($other,)*)))
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;
793 try!(write!(f, ", "));
795 try!(write!(f, "{}", *$name));
799 try!(write!(f, ","));
808 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
810 impl<'a> Show for &'a any::Any {
811 fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") }
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, "["));
819 let mut is_first = true;
820 for x in self.iter() {
824 try!(write!(f, ", "));
826 try!(write!(f, "{}", *x))
828 if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
829 try!(write!(f, "]"));
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)
841 impl<T: Show> Show for ~[T] {
842 fn fmt(&self, f: &mut Formatter) -> Result {
843 secret_show(&self.as_slice(), f)
848 fn fmt(&self, f: &mut Formatter) -> Result {
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())
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.