diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-13 15:42:53 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-30 09:21:56 -0800 |
| commit | 62273575139a80c2b208a3a27e0c2392b1425be6 (patch) | |
| tree | f9381a041e8ad95efe57ee6f85954a8b063b853f /src/libcore/fmt | |
| parent | 52c74e63dacd49017b19330e0cbecbac0a3fe62e (diff) | |
std: Stabilize the std::fmt module
This commit performs a final stabilization pass over the std::fmt module, marking all necessary APIs as stable. One of the more interesting aspects of this module is that it exposes a good deal of its runtime representation to the outside world in order for `format_args!` to be able to construct the format strings. Instead of hacking the compiler to assume that these items are stable, this commit instead lays out a story for the stabilization and evolution of these APIs. There are three primary details used by the `format_args!` macro: 1. `Arguments` - an opaque package of a "compiled format string". This structure is passed around and the `write` function is the source of truth for transforming a compiled format string into a string at runtime. This must be able to be constructed in stable code. 2. `Argument` - an opaque structure representing an argument to a format string. This is *almost* a trait object as it's just a pointer/function pair, but due to the function originating from one of many traits, it's not actually a trait object. Like `Arguments`, this must be constructed from stable code. 3. `fmt::rt` - this module contains the runtime type definitions primarily for the `rt::Argument` structure. Whenever an argument is formatted with nonstandard flags, a corresponding `rt::Argument` is generated describing how the argument is being formatted. This can be used to construct an `Arguments`. The primary interface to `std::fmt` is the `Arguments` structure, and as such this type name is stabilize as-is today. It is expected for libraries to pass around an `Arguments` structure to represent a pending formatted computation. The remaining portions are largely "cruft" which would rather not be stabilized, but due to the stability checks they must be. As a result, almost all pieces have been renamed to represent that they are "version 1" of the formatting representation. The theory is that at a later date if we change the representation of these types we can add new definitions called "version 2" and corresponding constructors for `Arguments`. One of the other remaining large questions about the fmt module were how the pending I/O reform would affect the signatures of methods in the module. Due to [RFC 526][rfc], however, the writers of fmt are now incompatible with the writers of io, so this question has largely been solved. As a result the interfaces are largely stabilized as-is today. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md Specifically, the following changes were made: * The contents of `fmt::rt` were all moved under `fmt::rt::v1` * `fmt::rt` is stable * `fmt::rt::v1` is stable * `Error` is stable * `Writer` is stable * `Writer::write_str` is stable * `Writer::write_fmt` is stable * `Formatter` is stable * `Argument` has been renamed to `ArgumentV1` and is stable * `ArgumentV1::new` is stable * `ArgumentV1::from_uint` is stable * `Arguments::new_v1` is stable (renamed from `new`) * `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`) * All formatting traits are now stable, as well as the `fmt` method. * `fmt::write` is stable * `fmt::format` is stable * `Formatter::pad_integral` is stable * `Formatter::pad` is stable * `Formatter::write_str` is stable * `Formatter::write_fmt` is stable * Some assorted top level items which were only used by `format_args!` were removed in favor of static functions on `ArgumentV1` as well. * The formatting-flag-accessing methods remain unstable Within the contents of the `fmt::rt::v1` module, the following actions were taken: * Reexports of all enum variants were removed * All prefixes on enum variants were removed * A few miscellaneous enum variants were renamed * Otherwise all structs, fields, and variants were marked stable. In addition to these actions in the `std::fmt` module, many implementations of `Show` and `String` were stabilized as well. In some other modules: * `ToString` is now stable * `ToString::to_string` is now stable * `Vec` no longer implements `fmt::Writer` (this has moved to `String`) This is a breaking change due to all of the changes to the `fmt::rt` module, but this likely will not have much impact on existing programs. Closes #20661 [breaking-change]
Diffstat (limited to 'src/libcore/fmt')
| -rw-r--r-- | src/libcore/fmt/mod.rs | 252 | ||||
| -rw-r--r-- | src/libcore/fmt/rt.rs | 86 | ||||
| -rw-r--r-- | src/libcore/fmt/rt/v1.rs | 94 |
3 files changed, 239 insertions, 193 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 8b7a4c677ac..2ff67ebd550 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -10,7 +10,6 @@ //! Utilities for formatting and printing strings -#![allow(unused_variables)] #![stable(feature = "rust1", since = "1.0.0")] use any; @@ -27,6 +26,7 @@ use result; use slice::SliceExt; use slice; use str::{self, StrExt}; +use self::rt::v1::Alignment; pub use self::num::radix; pub use self::num::Radix; @@ -34,10 +34,15 @@ pub use self::num::RadixFmt; mod num; mod float; -pub mod rt; -#[unstable(feature = "core", - reason = "core and I/O reconciliation may alter this definition")] +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(hidden)] +pub mod rt { + #[cfg(stage0)] pub use self::v1::*; + pub mod v1; +} + +#[stable(feature = "rust1", since = "1.0.0")] /// The type returned by formatter methods. pub type Result = result::Result<(), Error>; @@ -46,8 +51,7 @@ pub type Result = result::Result<(), Error>; /// This type does not support transmission of an error other than that an error /// occurred. Any extra information must be arranged to be transmitted through /// some other means. -#[unstable(feature = "core", - reason = "core and I/O reconciliation may alter this definition")] +#[stable(feature = "rust1", since = "1.0.0")] #[derive(Copy, Debug)] pub struct Error; @@ -60,8 +64,7 @@ pub struct Error; /// This trait should generally not be implemented by consumers of the standard /// library. The `write!` macro accepts an instance of `io::Writer`, and the /// `io::Writer` trait is favored over implementing this trait. -#[unstable(feature = "core", - reason = "waiting for core and I/O reconciliation")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait Writer { /// Writes a slice of bytes into this writer, returning whether the write /// succeeded. @@ -73,12 +76,14 @@ pub trait Writer { /// # Errors /// /// This function will return an instance of `FormatError` on error. + #[stable(feature = "rust1", since = "1.0.0")] fn write_str(&mut self, s: &str) -> Result; /// Glue for usage of the `write!` macro with implementers of this trait. /// /// This method should generally not be invoked manually, but rather through /// the `write!` macro itself. + #[stable(feature = "rust1", since = "1.0.0")] fn write_fmt(&mut self, args: Arguments) -> Result { // This Adapter is needed to allow `self` (of type `&mut // Self`) to be cast to a FormatWriter (below) without @@ -104,18 +109,17 @@ pub trait Writer { /// A struct to represent both where to emit formatting strings to and how they /// should be formatted. A mutable version of this is passed to all formatting /// traits. -#[unstable(feature = "core", - reason = "name may change and implemented traits are also unstable")] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Formatter<'a> { flags: uint, fill: char, - align: rt::Alignment, + align: rt::v1::Alignment, width: Option<uint>, precision: Option<uint>, buf: &'a mut (Writer+'a), - curarg: slice::Iter<'a, Argument<'a>>, - args: &'a [Argument<'a>], + curarg: slice::Iter<'a, ArgumentV1<'a>>, + args: &'a [ArgumentV1<'a>], } // NB. Argument is essentially an optimized partially applied formatting function, @@ -127,35 +131,40 @@ enum Void {} /// family of functions. It contains a function to format the given value. At /// compile time it is ensured that the function and the value have the correct /// types, and then this struct is used to canonicalize arguments to one type. -#[unstable(feature = "core", - reason = "implementation detail of the `format_args!` macro")] #[derive(Copy)] -pub struct Argument<'a> { +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(hidden)] +pub struct ArgumentV1<'a> { value: &'a Void, formatter: fn(&Void, &mut Formatter) -> Result, } -impl<'a> Argument<'a> { +impl<'a> ArgumentV1<'a> { #[inline(never)] fn show_uint(x: &uint, f: &mut Formatter) -> Result { Display::fmt(x, f) } - fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter) -> Result) -> Argument<'b> { + #[doc(hidden)] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new<'b, T>(x: &'b T, + f: fn(&T, &mut Formatter) -> Result) -> ArgumentV1<'b> { unsafe { - Argument { + ArgumentV1 { formatter: mem::transmute(f), value: mem::transmute(x) } } } - fn from_uint(x: &uint) -> Argument { - Argument::new(x, Argument::show_uint) + #[doc(hidden)] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn from_uint(x: &uint) -> ArgumentV1 { + ArgumentV1::new(x, ArgumentV1::show_uint) } fn as_uint(&self) -> Option<uint> { - if self.formatter as uint == Argument::show_uint as uint { + if self.formatter as uint == ArgumentV1::show_uint as uint { Some(unsafe { *(self.value as *const _ as *const uint) }) } else { None @@ -163,14 +172,32 @@ impl<'a> Argument<'a> { } } +// flags available in the v1 format of format_args +#[derive(Copy)] +#[allow(dead_code)] // SignMinus isn't currently used +enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, } + impl<'a> Arguments<'a> { /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. #[doc(hidden)] #[inline] - #[unstable(feature = "core", - reason = "implementation detail of the `format_args!` macro")] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new_v1(pieces: &'a [&'a str], + args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { + Arguments { + pieces: pieces, + fmt: None, + args: args + } + } + + /// When using the format_args!() macro, this function is used to generate the + /// Arguments structure. + #[doc(hidden)] #[inline] + #[cfg(stage0)] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(pieces: &'a [&'a str], - args: &'a [Argument<'a>]) -> Arguments<'a> { + args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { Arguments { pieces: pieces, fmt: None, @@ -185,11 +212,28 @@ impl<'a> Arguments<'a> { /// created with `argumentuint`. However, failing to do so doesn't cause /// unsafety, but will ignore invalid . #[doc(hidden)] #[inline] - #[unstable(feature = "core", - reason = "implementation detail of the `format_args!` macro")] + #[cfg(stage0)] + #[stable(feature = "rust1", since = "1.0.0")] pub fn with_placeholders(pieces: &'a [&'a str], - fmt: &'a [rt::Argument], - args: &'a [Argument<'a>]) -> Arguments<'a> { + fmt: &'a [rt::v1::Argument], + args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { + Arguments { + pieces: pieces, + fmt: Some(fmt), + args: args + } + } + /// This function is used to specify nonstandard formatting parameters. + /// The `pieces` array must be at least as long as `fmt` to construct + /// a valid Arguments structure. Also, any `Count` within `fmt` that is + /// `CountIsParam` or `CountIsNextParam` has to point to an argument + /// created with `argumentuint`. However, failing to do so doesn't cause + /// unsafety, but will ignore invalid . + #[doc(hidden)] #[inline] + #[cfg(not(stage0))] + pub fn new_v1_formatted(pieces: &'a [&'a str], + args: &'a [ArgumentV1<'a>], + fmt: &'a [rt::v1::Argument]) -> Arguments<'a> { Arguments { pieces: pieces, fmt: Some(fmt), @@ -214,11 +258,11 @@ pub struct Arguments<'a> { pieces: &'a [&'a str], // Placeholder specs, or `None` if all specs are default (as in "{}{}"). - fmt: Option<&'a [rt::Argument]>, + fmt: Option<&'a [rt::v1::Argument]>, // Dynamic arguments for interpolation, to be interleaved with string // pieces. (Every argument is preceded by a string piece.) - args: &'a [Argument<'a>], + args: &'a [ArgumentV1<'a>], } #[stable(feature = "rust1", since = "1.0.0")] @@ -237,20 +281,20 @@ impl<'a> Display for Arguments<'a> { /// Format trait for the `:?` format. Useful for debugging, all types /// should implement this. -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] #[deprecated(since = "1.0.0", reason = "renamed to Debug")] +#[unstable(feature = "old_fmt")] pub trait Show { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `:?` format. Useful for debugging, all types /// should implement this. -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] -#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \ - crate, add `#[derive(Debug)]` or manually implement it"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ + defined in your crate, add `#[derive(Debug)]` or \ + manually implement it"] #[lang = "debug_trait"] pub trait Debug { /// Formats the value using the given formatter. @@ -264,19 +308,20 @@ impl<T: Show + ?Sized> Debug for T { /// When a value can be semantically expressed as a String, this trait may be /// used. It corresponds to the default format, `{}`. -#[unstable(feature = "core")] #[deprecated(since = "1.0.0", reason = "renamed to Display")] +#[unstable(feature = "old_fmt")] pub trait String { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// When a value can be semantically expressed as a String, this trait may be /// used. It corresponds to the default format, `{}`. -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] -#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default formatter; try using \ - `:?` instead if you are using a format string"] +#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \ + formatter; try using `:?` instead if you are using \ + a format string"] +#[stable(feature = "rust1", since = "1.0.0")] pub trait Display { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; @@ -288,58 +333,58 @@ impl<T: String + ?Sized> Display for T { } /// Format trait for the `o` character -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait Octal { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `b` character -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait Binary { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `x` character -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait LowerHex { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `X` character -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait UpperHex { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `p` character -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait Pointer { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `e` character -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait LowerExp { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `E` character -#[unstable(feature = "core", - reason = "I/O and core have yet to be reconciled")] +#[stable(feature = "rust1", since = "1.0.0")] pub trait UpperExp { /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, &mut Formatter) -> Result; } @@ -351,16 +396,14 @@ pub trait UpperExp { /// /// * output - the buffer to write output to /// * args - the precompiled arguments generated by `format_args!` -#[unstable(feature = "core", - reason = "libcore and I/O have yet to be reconciled, and this is an \ - implementation detail which should not otherwise be exported")] +#[stable(feature = "rust1", since = "1.0.0")] pub fn write(output: &mut Writer, args: Arguments) -> Result { let mut formatter = Formatter { flags: 0, width: None, precision: None, buf: output, - align: rt::AlignUnknown, + align: Alignment::Unknown, fill: ' ', args: args.args, curarg: args.args.iter(), @@ -402,7 +445,7 @@ impl<'a> Formatter<'a> { // First up is the collection of functions used to execute a format string // at runtime. This consumes all of the compile-time statics generated by // the format! syntax extension. - fn run(&mut self, arg: &rt::Argument) -> Result { + fn run(&mut self, arg: &rt::v1::Argument) -> Result { // Fill in the format parameters into the formatter self.fill = arg.format.fill; self.align = arg.format.align; @@ -412,22 +455,22 @@ impl<'a> Formatter<'a> { // Extract the correct argument let value = match arg.position { - rt::ArgumentNext => { *self.curarg.next().unwrap() } - rt::ArgumentIs(i) => self.args[i], + rt::v1::Position::Next => { *self.curarg.next().unwrap() } + rt::v1::Position::At(i) => self.args[i], }; // Then actually do some printing (value.formatter)(value.value, self) } - fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> { + fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<uint> { match *cnt { - rt::CountIs(n) => Some(n), - rt::CountImplied => None, - rt::CountIsParam(i) => { + rt::v1::Count::Is(n) => Some(n), + rt::v1::Count::Implied => None, + rt::v1::Count::Param(i) => { self.args[i].as_uint() } - rt::CountIsNextParam => { + rt::v1::Count::NextParam => { self.curarg.next().and_then(|arg| arg.as_uint()) } } @@ -437,8 +480,8 @@ impl<'a> Formatter<'a> { // all formatting traits can use. /// Performs the correct padding for an integer which has already been - /// emitted into a byte-array. The byte-array should *not* contain the sign - /// for the integer, that will be added by this method. + /// emitted into a str. The str should *not* contain the sign for the + /// integer, that will be added by this method. /// /// # Arguments /// @@ -449,27 +492,25 @@ impl<'a> Formatter<'a> { /// /// This function will correctly account for the flags provided as well as /// the minimum width. It will not take precision into account. - #[unstable(feature = "core", - reason = "definition may change slightly over time")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn pad_integral(&mut self, is_positive: bool, prefix: &str, buf: &str) -> Result { use char::CharExt; - use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad}; let mut width = buf.len(); let mut sign = None; if !is_positive { sign = Some('-'); width += 1; - } else if self.flags & (1 << (FlagSignPlus as uint)) != 0 { + } else if self.flags & (1 << (FlagV1::SignPlus as uint)) != 0 { sign = Some('+'); width += 1; } let mut prefixed = false; - if self.flags & (1 << (FlagAlternate as uint)) != 0 { + if self.flags & (1 << (FlagV1::Alternate as uint)) != 0 { prefixed = true; width += prefix.char_len(); } @@ -499,16 +540,16 @@ impl<'a> Formatter<'a> { } // The sign and prefix goes before the padding if the fill character // is zero - Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => { + Some(min) if self.flags & (1 << (FlagV1::SignAwareZeroPad as uint)) != 0 => { self.fill = '0'; try!(write_prefix(self)); - self.with_padding(min - width, rt::AlignRight, |f| { + self.with_padding(min - width, Alignment::Right, |f| { f.buf.write_str(buf) }) } // Otherwise, the sign and prefix goes after the padding Some(min) => { - self.with_padding(min - width, rt::AlignRight, |f| { + self.with_padding(min - width, Alignment::Right, |f| { try!(write_prefix(f)); f.buf.write_str(buf) }) } @@ -526,8 +567,7 @@ impl<'a> Formatter<'a> { /// is longer than this length /// /// Notably this function ignored the `flag` parameters - #[unstable(feature = "core", - reason = "definition may change slightly over time")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn pad(&mut self, s: &str) -> Result { // Make sure there's a fast path up front if self.width.is_none() && self.precision.is_none() { @@ -561,7 +601,7 @@ impl<'a> Formatter<'a> { // If we're under both the maximum and the minimum width, then fill // up the minimum width with the specified string + some alignment. Some(width) => { - self.with_padding(width - s.char_len(), rt::AlignLeft, |me| { + self.with_padding(width - s.char_len(), Alignment::Left, |me| { me.buf.write_str(s) }) } @@ -570,19 +610,20 @@ impl<'a> Formatter<'a> { /// Runs a callback, emitting the correct padding either before or /// afterwards depending on whether right or left alignment is requested. - fn with_padding<F>(&mut self, padding: uint, default: rt::Alignment, f: F) -> Result where - F: FnOnce(&mut Formatter) -> Result, + fn with_padding<F>(&mut self, padding: uint, default: Alignment, + f: F) -> Result + where F: FnOnce(&mut Formatter) -> Result, { use char::CharExt; let align = match self.align { - rt::AlignUnknown => default, + Alignment::Unknown => default, _ => self.align }; let (pre_pad, post_pad) = match align { - rt::AlignLeft => (0, padding), - rt::AlignRight | rt::AlignUnknown => (padding, 0), - rt::AlignCenter => (padding / 2, (padding + 1) / 2), + Alignment::Left => (0, padding), + Alignment::Right | Alignment::Unknown => (padding, 0), + Alignment::Center => (padding / 2, (padding + 1) / 2), }; let mut fill = [0u8; 4]; @@ -604,23 +645,20 @@ impl<'a> Formatter<'a> { /// Writes some data to the underlying buffer contained within this /// formatter. - #[unstable(feature = "core", - reason = "reconciling core and I/O may alter this definition")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn write_str(&mut self, data: &str) -> Result { self.buf.write_str(data) } /// Writes some formatted information into this instance - #[unstable(feature = "core", - reason = "reconciling core and I/O may alter this definition")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn write_fmt(&mut self, fmt: Arguments) -> Result { write(self.buf, fmt) } /// Flags for formatting (packed version of rt::Flag) - #[unstable(feature = "core", - reason = "return type may change and method was just created")] - pub fn flags(&self) -> uint { self.flags } + #[stable(feature = "rust1", since = "1.0.0")] + pub fn flags(&self) -> usize { self.flags } /// Character used as 'fill' whenever there is alignment #[unstable(feature = "core", reason = "method was just created")] @@ -628,7 +666,7 @@ impl<'a> Formatter<'a> { /// Flag indicating what form of alignment was requested #[unstable(feature = "core", reason = "method was just created")] - pub fn align(&self) -> rt::Alignment { self.align } + pub fn align(&self) -> Alignment { self.align } /// Optionally specified integer width that the output should be #[unstable(feature = "core", reason = "method was just created")] @@ -649,20 +687,20 @@ impl Display for Error { /// This is a function which calls are emitted to by the compiler itself to /// create the Argument structures that are passed into the `format` function. #[doc(hidden)] #[inline] -#[unstable(feature = "core", - reason = "implementation detail of the `format_args!` macro")] +#[cfg(stage0)] +#[stable(feature = "rust1", since = "1.0.0")] pub fn argument<'a, T>(f: fn(&T, &mut Formatter) -> Result, - t: &'a T) -> Argument<'a> { - Argument::new(t, f) + t: &'a T) -> ArgumentV1<'a> { + ArgumentV1::new(t, f) } /// When the compiler determines that the type of an argument *must* be a uint /// (such as for width and precision), then it invokes this method. #[doc(hidden)] #[inline] -#[unstable(feature = "core", - reason = "implementation detail of the `format_args!` macro")] -pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { - Argument::from_uint(s) +#[cfg(stage0)] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn argumentuint<'a>(s: &'a uint) -> ArgumentV1<'a> { + ArgumentV1::from_uint(s) } // Implementations of the core formatting traits @@ -741,9 +779,9 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl<T> Pointer for *const T { fn fmt(&self, f: &mut Formatter) -> Result { - f.flags |= 1 << (rt::FlagAlternate as uint); + f.flags |= 1 << (FlagV1::Alternate as uint); let ret = LowerHex::fmt(&(*self as uint), f); - f.flags &= !(1 << (rt::FlagAlternate as uint)); + f.flags &= !(1 << (FlagV1::Alternate as uint)); ret } } @@ -899,7 +937,7 @@ impl<'a> Debug for &'a (any::Any+'a) { #[stable(feature = "rust1", since = "1.0.0")] impl<T: Debug> Debug for [T] { fn fmt(&self, f: &mut Formatter) -> Result { - if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + if f.flags & (1 << (FlagV1::Alternate as uint)) == 0 { try!(write!(f, "[")); } let mut is_first = true; @@ -911,7 +949,7 @@ impl<T: Debug> Debug for [T] { } try!(write!(f, "{:?}", *x)) } - if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + if f.flags & (1 << (FlagV1::Alternate as uint)) == 0 { try!(write!(f, "]")); } Ok(()) diff --git a/src/libcore/fmt/rt.rs b/src/libcore/fmt/rt.rs deleted file mode 100644 index 0b2c1efbc5d..00000000000 --- a/src/libcore/fmt/rt.rs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! This is an internal module used by the ifmt! runtime. These structures are -//! emitted to static arrays to precompile format strings ahead of time. -//! -//! These definitions are similar to their `ct` equivalents, but differ in that -//! these can be statically allocated and are slightly optimized for the runtime - -#![unstable(feature = "core", - reason = "implementation detail of the `format_args!` macro")] - -pub use self::Alignment::*; -pub use self::Count::*; -pub use self::Position::*; -pub use self::Flag::*; - -#[doc(hidden)] -#[derive(Copy)] -pub struct Argument { - pub position: Position, - pub format: FormatSpec, -} - -#[doc(hidden)] -#[derive(Copy)] -pub struct FormatSpec { - pub fill: char, - pub align: Alignment, - pub flags: uint, - pub precision: Count, - pub width: Count, -} - -/// Possible alignments that can be requested as part of a formatting directive. -#[derive(Copy, PartialEq)] -pub enum Alignment { - /// Indication that contents should be left-aligned. - AlignLeft, - /// Indication that contents should be right-aligned. - AlignRight, - /// Indication that contents should be center-aligned. - AlignCenter, - /// No alignment was requested. - AlignUnknown, -} - -#[doc(hidden)] -#[derive(Copy)] -pub enum Count { - CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied, -} - -#[doc(hidden)] -#[derive(Copy)] -pub enum Position { - ArgumentNext, ArgumentIs(uint) -} - -/// Flags which can be passed to formatting via a directive. -/// -/// These flags are discovered through the `flags` field of the `Formatter` -/// structure. The flag in that structure is a union of these flags into a -/// `uint` where each flag's discriminant is the corresponding bit. -#[derive(Copy)] -pub enum Flag { - /// A flag which enables number formatting to always print the sign of a - /// number. - FlagSignPlus, - /// Currently not a used flag - FlagSignMinus, - /// Indicates that the "alternate formatting" for a type should be used. - /// - /// The meaning of this flag is type-specific. - FlagAlternate, - /// Indicates that padding should be done with a `0` character as well as - /// being aware of the sign to be printed. - FlagSignAwareZeroPad, -} diff --git a/src/libcore/fmt/rt/v1.rs b/src/libcore/fmt/rt/v1.rs new file mode 100644 index 00000000000..f0c82759b70 --- /dev/null +++ b/src/libcore/fmt/rt/v1.rs @@ -0,0 +1,94 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This is an internal module used by the ifmt! runtime. These structures are +//! emitted to static arrays to precompile format strings ahead of time. +//! +//! These definitions are similar to their `ct` equivalents, but differ in that +//! these can be statically allocated and are slightly optimized for the runtime + +#![stable(feature = "rust1", since = "1.0.0")] + +#[cfg(stage0)] pub use self::Position::*; + +#[cfg(stage0)] pub use self::Alignment::Left as AlignLeft; +#[cfg(stage0)] pub use self::Alignment::Right as AlignRight; +#[cfg(stage0)] pub use self::Alignment::Center as AlignCenter; +#[cfg(stage0)] pub use self::Alignment::Unknown as AlignUnknown; +#[cfg(stage0)] pub use self::Count::Is as CountIs; +#[cfg(stage0)] pub use self::Count::Implied as CountImplied; +#[cfg(stage0)] pub use self::Count::Param as CountIsParam; +#[cfg(stage0)] pub use self::Count::NextParam as CountIsNextParam; +#[cfg(stage0)] pub use self::Position::Next as ArgumentNext; +#[cfg(stage0)] pub use self::Position::At as ArgumentIs; + +#[derive(Copy)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Argument { + #[stable(feature = "rust1", since = "1.0.0")] + pub position: Position, + #[stable(feature = "rust1", since = "1.0.0")] + pub format: FormatSpec, +} + +#[derive(Copy)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct FormatSpec { + #[stable(feature = "rust1", since = "1.0.0")] + pub fill: char, + #[stable(feature = "rust1", since = "1.0.0")] + pub align: Alignment, + #[stable(feature = "rust1", since = "1.0.0")] + pub flags: uint, + #[stable(feature = "rust1", since = "1.0.0")] + pub precision: Count, + #[stable(feature = "rust1", since = "1.0.0")] + pub width: Count, +} + +/// Possible alignments that can be requested as part of a formatting directive. +#[derive(Copy, PartialEq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Alignment { + /// Indication that contents should be left-aligned. + #[stable(feature = "rust1", since = "1.0.0")] + Left, + /// Indication that contents should be right-aligned. + #[stable(feature = "rust1", since = "1.0.0")] + Right, + /// Indication that contents should be center-aligned. + #[stable(feature = "rust1", since = "1.0.0")] + Center, + /// No alignment was requested. + #[stable(feature = "rust1", since = "1.0.0")] + Unknown, +} + +#[derive(Copy)] +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Count { + #[stable(feature = "rust1", since = "1.0.0")] + Is(usize), + #[stable(feature = "rust1", since = "1.0.0")] + Param(usize), + #[stable(feature = "rust1", since = "1.0.0")] + NextParam, + #[stable(feature = "rust1", since = "1.0.0")] + Implied, +} + +#[derive(Copy)] +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Position { + #[stable(feature = "rust1", since = "1.0.0")] + Next, + #[stable(feature = "rust1", since = "1.0.0")] + At(usize) +} |
