use option::Option;
use option::Option::{Some, None};
use ops::{Deref, FnOnce};
-use result::Result::{Ok, Err};
+use result::Result::Ok;
use result;
use slice::SliceExt;
use slice;
-use str::{StrExt, Utf8Error};
+use str::{self, StrExt, Utf8Error};
+
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::Err;
pub use self::num::radix;
pub use self::num::Radix;
/// occurred. Any extra information must be arranged to be transmitted through
/// some other means.
#[experimental = "core and I/O reconciliation may alter this definition"]
-#[deriving(Copy)]
+#[derive(Copy)]
pub struct Error;
/// A collection of methods that are required to format a message into a stream.
/// library. The `write!` macro accepts an instance of `io::Writer`, and the
/// `io::Writer` trait is favored over implementing this trait.
#[experimental = "waiting for core and I/O reconciliation"]
-pub trait FormatWriter {
+pub trait Writer {
/// Writes a slice of bytes into this writer, returning whether the write
/// succeeded.
///
/// # Errors
///
/// This function will return an instance of `FormatError` on error.
- fn write(&mut self, bytes: &[u8]) -> Result;
+ fn write_str(&mut self, s: &str) -> Result;
- // NOTE(stage0): Remove cfg after a snapshot
- #[cfg(not(stage0))]
/// 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.
- fn write_fmt(&mut self, args: Arguments) -> Result { write(self, args) }
+ 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
+ // requiring a `Sized` bound.
+ struct Adapter<'a,T: ?Sized +'a>(&'a mut T);
+
+ impl<'a, T: ?Sized> Writer for Adapter<'a, T>
+ where T: Writer
+ {
+ fn write_str(&mut self, s: &str) -> Result {
+ self.0.write_str(s)
+ }
- // NOTE(stage0): Remove method after a snapshot
- #[cfg(stage0)]
- /// 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.
- fn write_fmt(&mut self, args: &Arguments) -> Result { write(self, args) }
+ fn write_fmt(&mut self, args: Arguments) -> Result {
+ self.0.write_fmt(args)
+ }
+ }
+
+ write(&mut Adapter(self), args)
+ }
}
/// A struct to represent both where to emit formatting strings to and how they
width: Option<uint>,
precision: Option<uint>,
- buf: &'a mut (FormatWriter+'a),
+ buf: &'a mut (Writer+'a),
curarg: slice::Iter<'a, Argument<'a>>,
args: &'a [Argument<'a>],
}
/// 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.
#[experimental = "implementation detail of the `format_args!` macro"]
-#[deriving(Copy)]
+#[derive(Copy)]
pub struct Argument<'a> {
value: &'a Void,
formatter: fn(&Void, &mut Formatter) -> Result,
/// macro validates the format string at compile-time so usage of the `write`
/// and `format` functions can be safely performed.
#[stable]
-#[deriving(Copy)]
+#[derive(Copy)]
pub struct Arguments<'a> {
// Format string pieces to print.
pieces: &'a [&'a str],
}
impl<'a> Show for Arguments<'a> {
- // NOTE(stage0): Remove cfg after a snapshot
- #[cfg(not(stage0))]
fn fmt(&self, fmt: &mut Formatter) -> Result {
write(fmt.buf, *self)
}
-
- // NOTE(stage0): Remove method after a snapshot
- #[cfg(stage0)]
- fn fmt(&self, fmt: &mut Formatter) -> Result {
- write(fmt.buf, self)
- }
}
/// When a format is not otherwise specified, types are formatted by ascribing
/// to this trait. There is not an explicit way of selecting this trait to be
/// used for formatting, it is only if no other format is specified.
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait Show for Sized? {
+pub trait Show {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `o` character
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait Octal for Sized? {
+pub trait Octal {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `b` character
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait Binary for Sized? {
+pub trait Binary {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `x` character
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait LowerHex for Sized? {
+pub trait LowerHex {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `X` character
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait UpperHex for Sized? {
+pub trait UpperHex {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `p` character
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait Pointer for Sized? {
+pub trait Pointer {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `e` character
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait LowerExp for Sized? {
+pub trait LowerExp {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `E` character
#[unstable = "I/O and core have yet to be reconciled"]
-pub trait UpperExp for Sized? {
+pub trait UpperExp {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
-static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument {
- position: rt::ArgumentNext,
- format: rt::FormatSpec {
- fill: ' ',
- align: rt::AlignUnknown,
- flags: 0,
- precision: rt::CountImplied,
- width: rt::CountImplied,
- }
-};
-
-// NOTE(stage0): Remove cfg after a snapshot
-#[cfg(not(stage0))]
/// The `write` function takes an output stream, a precompiled format string,
/// and a list of arguments. The arguments will be formatted according to the
/// specified format string into the output stream provided.
/// * args - the precompiled arguments generated by `format_args!`
#[experimental = "libcore and I/O have yet to be reconciled, and this is an \
implementation detail which should not otherwise be exported"]
-pub fn write(output: &mut FormatWriter, args: Arguments) -> Result {
+pub fn write(output: &mut Writer, args: Arguments) -> Result {
let mut formatter = Formatter {
flags: 0,
width: None,
match args.fmt {
None => {
// We can use default formatting parameters for all arguments.
- for _ in range(0, args.args.len()) {
- try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
- try!(formatter.run(&DEFAULT_ARGUMENT));
+ for (arg, piece) in args.args.iter().zip(pieces.by_ref()) {
+ try!(formatter.buf.write_str(*piece));
+ try!((arg.formatter)(arg.value, &mut formatter));
}
}
Some(fmt) => {
// Every spec has a corresponding argument that is preceded by
// a string piece.
for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
- try!(formatter.buf.write(piece.as_bytes()));
+ try!(formatter.buf.write_str(*piece));
try!(formatter.run(arg));
}
}
// There can be only one trailing string piece left.
match pieces.next() {
Some(piece) => {
- try!(formatter.buf.write(piece.as_bytes()));
- }
- None => {}
- }
-
- Ok(())
-}
-
-// NOTE(stage0): Remove function after a snapshot
-#[cfg(stage0)]
-/// The `write` function takes an output stream, a precompiled format string,
-/// and a list of arguments. The arguments will be formatted according to the
-/// specified format string into the output stream provided.
-///
-/// # Arguments
-///
-/// * output - the buffer to write output to
-/// * args - the precompiled arguments generated by `format_args!`
-#[experimental = "libcore and I/O have yet to be reconciled, and this is an \
- implementation detail which should not otherwise be exported"]
-pub fn write(output: &mut FormatWriter, args: &Arguments) -> Result {
- let mut formatter = Formatter {
- flags: 0,
- width: None,
- precision: None,
- buf: output,
- align: rt::AlignUnknown,
- fill: ' ',
- args: args.args,
- curarg: args.args.iter(),
- };
-
- let mut pieces = args.pieces.iter();
-
- match args.fmt {
- None => {
- // We can use default formatting parameters for all arguments.
- for _ in range(0, args.args.len()) {
- try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
- try!(formatter.run(&DEFAULT_ARGUMENT));
- }
- }
- Some(fmt) => {
- // Every spec has a corresponding argument that is preceded by
- // a string piece.
- for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
- try!(formatter.buf.write(piece.as_bytes()));
- try!(formatter.run(arg));
- }
- }
- }
-
- // There can be only one trailing string piece left.
- match pieces.next() {
- Some(piece) => {
- try!(formatter.buf.write(piece.as_bytes()));
+ try!(formatter.buf.write_str(*piece));
}
None => {}
}
pub fn pad_integral(&mut self,
is_positive: bool,
prefix: &str,
- buf: &[u8])
+ buf: &str)
-> Result {
- use char::Char;
+ use char::CharExt;
use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
let mut width = buf.len();
}
// Writes the sign if it exists, and then the prefix if it was requested
- let write_prefix = |f: &mut Formatter| {
+ let write_prefix = |&: f: &mut Formatter| {
for c in sign.into_iter() {
- let mut b = [0, ..4];
+ let mut b = [0; 4];
let n = c.encode_utf8(&mut b).unwrap_or(0);
- try!(f.buf.write(b[..n]));
+ let b = unsafe { str::from_utf8_unchecked(b[0..n]) };
+ try!(f.buf.write_str(b));
}
- if prefixed { f.buf.write(prefix.as_bytes()) }
+ if prefixed { f.buf.write_str(prefix) }
else { Ok(()) }
};
// If there's no minimum length requirements then we can just
// write the bytes.
None => {
- try!(write_prefix(self)); self.buf.write(buf)
+ try!(write_prefix(self)); self.buf.write_str(buf)
}
// Check if we're over the minimum width, if so then we can also
// just write the bytes.
Some(min) if width >= min => {
- try!(write_prefix(self)); self.buf.write(buf)
+ try!(write_prefix(self)); self.buf.write_str(buf)
}
// The sign and prefix goes before the padding if the fill character
// is zero
Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => {
self.fill = '0';
try!(write_prefix(self));
- self.with_padding(min - width, rt::AlignRight, |f| f.buf.write(buf))
+ self.with_padding(min - width, rt::AlignRight, |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| {
- try!(write_prefix(f)); f.buf.write(buf)
+ try!(write_prefix(f)); f.buf.write_str(buf)
})
}
}
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() {
- return self.buf.write(s.as_bytes());
+ return self.buf.write_str(s);
}
// The `precision` field can be interpreted as a `max-width` for the
// string being formatted
let char_len = s.char_len();
if char_len >= max {
let nchars = ::cmp::min(max, char_len);
- return self.buf.write(s.slice_chars(0, nchars).as_bytes());
+ return self.buf.write_str(s.slice_chars(0, nchars));
}
}
None => {}
match self.width {
// If we're under the maximum length, and there's no minimum length
// requirements, then we can just emit the string
- None => self.buf.write(s.as_bytes()),
+ None => self.buf.write_str(s),
// If we're under the maximum width, check if we're over the minimum
// width, if so it's as easy as just emitting the string.
Some(width) if s.char_len() >= width => {
- self.buf.write(s.as_bytes())
+ self.buf.write_str(s)
}
// 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| {
- me.buf.write(s.as_bytes())
+ me.buf.write_str(s)
})
}
}
fn with_padding<F>(&mut self, padding: uint, default: rt::Alignment, f: F) -> Result where
F: FnOnce(&mut Formatter) -> Result,
{
- use char::Char;
+ use char::CharExt;
let align = match self.align {
rt::AlignUnknown => default,
_ => self.align
rt::AlignCenter => (padding / 2, (padding + 1) / 2),
};
- let mut fill = [0u8, ..4];
+ let mut fill = [0u8; 4];
let len = self.fill.encode_utf8(&mut fill).unwrap_or(0);
+ let fill = unsafe { str::from_utf8_unchecked(fill[..len]) };
for _ in range(0, pre_pad) {
- try!(self.buf.write(fill[..len]));
+ try!(self.buf.write_str(fill));
}
try!(f(self));
for _ in range(0, post_pad) {
- try!(self.buf.write(fill[..len]));
+ try!(self.buf.write_str(fill));
}
Ok(())
/// Writes some data to the underlying buffer contained within this
/// formatter.
#[unstable = "reconciling core and I/O may alter this definition"]
- pub fn write(&mut self, data: &[u8]) -> Result {
- self.buf.write(data)
+ pub fn write_str(&mut self, data: &str) -> Result {
+ self.buf.write_str(data)
}
- // NOTE(stage0): Remove cfg after a snapshot
- #[cfg(not(stage0))]
/// Writes some formatted information into this instance
#[unstable = "reconciling core and I/O may alter this definition"]
pub fn write_fmt(&mut self, fmt: Arguments) -> Result {
write(self.buf, fmt)
}
- // NOTE(stage0): Remove method after a snapshot
- #[cfg(stage0)]
- /// Writes some formatted information into this instance
- #[unstable = "reconciling core and I/O may alter this definition"]
- pub fn write_fmt(&mut self, fmt: &Arguments) -> Result {
- write(self.buf, fmt)
- }
-
/// Flags for formatting (packed version of rt::Flag)
#[experimental = "return type may change and method was just created"]
pub fn flags(&self) -> uint { self.flags }
// Implementations of the core formatting traits
-impl<'a, Sized? T: Show> Show for &'a T {
+impl<'a, T: ?Sized + Show> Show for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
}
-impl<'a, Sized? T: Show> Show for &'a mut T {
+impl<'a, T: ?Sized + Show> Show for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
}
-impl<'a> Show for &'a (Show+'a) {
- fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
-}
impl Show for bool {
fn fmt(&self, f: &mut Formatter) -> Result {
impl Show for char {
fn fmt(&self, f: &mut Formatter) -> Result {
- use char::Char;
+ use char::CharExt;
- let mut utf8 = [0u8, ..4];
+ let mut utf8 = [0u8; 4];
let amt = self.encode_utf8(&mut utf8).unwrap_or(0);
let s: &str = unsafe { mem::transmute(utf8[..amt]) };
Show::fmt(s, f)
impl<T> Pointer for *const T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.flags |= 1 << (rt::FlagAlternate as uint);
- LowerHex::fmt(&(*self as uint), f)
+ let ret = LowerHex::fmt(&(*self as uint), f);
+ f.flags &= !(1 << (rt::FlagAlternate as uint));
+ ret
}
}