// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Utilities for formatting and printing strings
+//! Utilities for formatting and printing strings.
#![stable(feature = "rust1", since = "1.0.0")]
use prelude::v1::*;
-use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
+use cell::{UnsafeCell, Cell, RefCell, Ref, RefMut, BorrowState};
use marker::PhantomData;
use mem;
use num::flt2dec;
use result;
use slice;
use str;
-use self::rt::v1::Alignment;
-
-#[unstable(feature = "fmt_radix", issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[allow(deprecated)]
-pub use self::num::radix;
-#[unstable(feature = "fmt_radix", issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[allow(deprecated)]
-pub use self::num::Radix;
-#[unstable(feature = "fmt_radix", issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[allow(deprecated)]
-pub use self::num::RadixFmt;
+
+#[unstable(feature = "fmt_flags_align", issue = "27726")]
+/// Possible alignments returned by `Formatter::align`
+#[derive(Debug)]
+pub enum Alignment {
+ /// Indication that contents should be left-aligned.
+ Left,
+ /// Indication that contents should be right-aligned.
+ Right,
+ /// Indication that contents should be center-aligned.
+ Center,
+ /// No alignment was requested.
+ Unknown,
+}
+
#[stable(feature = "debug_builders", since = "1.2.0")]
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};
/// This function will return an instance of `Error` on error.
#[stable(feature = "fmt_write_char", since = "1.1.0")]
fn write_char(&mut self, c: char) -> Result {
- let mut utf_8 = [0u8; 4];
- let bytes_written = c.encode_utf8(&mut utf_8).unwrap_or(0);
- self.write_str(unsafe { str::from_utf8_unchecked(&utf_8[..bytes_written]) })
+ self.write_str(unsafe {
+ str::from_utf8_unchecked(c.encode_utf8().as_slice())
+ })
}
/// Glue for usage of the `write!` macro with implementors of this trait.
/// 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.
+#[allow(missing_debug_implementations)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Formatter<'a> {
flags: u32,
/// 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.
#[derive(Copy)]
+#[allow(missing_debug_implementations)]
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
issue = "0")]
#[doc(hidden)]
width: None,
precision: None,
buf: output,
- align: Alignment::Unknown,
+ align: rt::v1::Alignment::Unknown,
fill: ' ',
args: args.args,
curarg: args.args.iter(),
None => {
// We can use default formatting parameters for all arguments.
for (arg, piece) in args.args.iter().zip(pieces.by_ref()) {
- try!(formatter.buf.write_str(*piece));
- try!((arg.formatter)(arg.value, &mut formatter));
+ formatter.buf.write_str(*piece)?;
+ (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_str(*piece));
- try!(formatter.run(arg));
+ formatter.buf.write_str(*piece)?;
+ formatter.run(arg)?;
}
}
}
// There can be only one trailing string piece left.
match pieces.next() {
Some(piece) => {
- try!(formatter.buf.write_str(*piece));
+ formatter.buf.write_str(*piece)?;
}
None => {}
}
// Writes the sign if it exists, and then the prefix if it was requested
let write_prefix = |f: &mut Formatter| {
if let Some(c) = sign {
- let mut b = [0; 4];
- let n = c.encode_utf8(&mut b).unwrap_or(0);
- let b = unsafe { str::from_utf8_unchecked(&b[..n]) };
- try!(f.buf.write_str(b));
+ f.buf.write_str(unsafe {
+ str::from_utf8_unchecked(c.encode_utf8().as_slice())
+ })?;
}
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_str(buf)
+ 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_str(buf)
+ 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.sign_aware_zero_pad() => {
self.fill = '0';
- try!(write_prefix(self));
- self.with_padding(min - width, Alignment::Right, |f| {
+ write_prefix(self)?;
+ self.with_padding(min - width, rt::v1::Alignment::Right, |f| {
f.buf.write_str(buf)
})
}
// Otherwise, the sign and prefix goes after the padding
Some(min) => {
- self.with_padding(min - width, Alignment::Right, |f| {
- try!(write_prefix(f)); f.buf.write_str(buf)
+ self.with_padding(min - width, rt::v1::Alignment::Right, |f| {
+ write_prefix(f)?; f.buf.write_str(buf)
})
}
}
// 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.chars().count(), Alignment::Left, |me| {
+ let align = rt::v1::Alignment::Left;
+ self.with_padding(width - s.chars().count(), align, |me| {
me.buf.write_str(s)
})
}
/// 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: usize, default: Alignment,
+ fn with_padding<F>(&mut self, padding: usize, default: rt::v1::Alignment,
f: F) -> Result
where F: FnOnce(&mut Formatter) -> Result,
{
use char::CharExt;
let align = match self.align {
- Alignment::Unknown => default,
+ rt::v1::Alignment::Unknown => default,
_ => self.align
};
let (pre_pad, post_pad) = match align {
- Alignment::Left => (0, padding),
- Alignment::Right | Alignment::Unknown => (padding, 0),
- Alignment::Center => (padding / 2, (padding + 1) / 2),
+ rt::v1::Alignment::Left => (0, padding),
+ rt::v1::Alignment::Right |
+ rt::v1::Alignment::Unknown => (padding, 0),
+ rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2),
};
- let mut fill = [0; 4];
- let len = self.fill.encode_utf8(&mut fill).unwrap_or(0);
- let fill = unsafe { str::from_utf8_unchecked(&fill[..len]) };
+ let fill = self.fill.encode_utf8();
+ let fill = unsafe {
+ str::from_utf8_unchecked(fill.as_slice())
+ };
for _ in 0..pre_pad {
- try!(self.buf.write_str(fill));
+ self.buf.write_str(fill)?;
}
- try!(f(self));
+ f(self)?;
for _ in 0..post_pad {
- try!(self.buf.write_str(fill));
+ self.buf.write_str(fill)?;
}
Ok(())
if self.sign_aware_zero_pad() {
// a sign always goes first
let sign = unsafe { str::from_utf8_unchecked(formatted.sign) };
- try!(self.buf.write_str(sign));
+ self.buf.write_str(sign)?;
// remove the sign from the formatted parts
formatted.sign = b"";
width = if width < sign.len() { 0 } else { width - sign.len() };
- align = Alignment::Right;
+ align = rt::v1::Alignment::Right;
self.fill = '0';
}
}
if !formatted.sign.is_empty() {
- try!(write_bytes(self.buf, formatted.sign));
+ write_bytes(self.buf, formatted.sign)?;
}
for part in formatted.parts {
match *part {
const ZEROES: &'static str = // 64 zeroes
"0000000000000000000000000000000000000000000000000000000000000000";
while nzeroes > ZEROES.len() {
- try!(self.buf.write_str(ZEROES));
+ self.buf.write_str(ZEROES)?;
nzeroes -= ZEROES.len();
}
if nzeroes > 0 {
- try!(self.buf.write_str(&ZEROES[..nzeroes]));
+ self.buf.write_str(&ZEROES[..nzeroes])?;
}
}
flt2dec::Part::Num(mut v) => {
*c = b'0' + (v % 10) as u8;
v /= 10;
}
- try!(write_bytes(self.buf, &s[..len]));
+ write_bytes(self.buf, &s[..len])?;
}
flt2dec::Part::Copy(buf) => {
- try!(write_bytes(self.buf, buf));
+ write_bytes(self.buf, buf)?;
}
}
}
/// Flag indicating what form of alignment was requested
#[unstable(feature = "fmt_flags_align", reason = "method was just created",
issue = "27726")]
- pub fn align(&self) -> Alignment { self.align }
+ pub fn align(&self) -> Alignment {
+ match self.align {
+ rt::v1::Alignment::Left => Alignment::Left,
+ rt::v1::Alignment::Right => Alignment::Right,
+ rt::v1::Alignment::Center => Alignment::Center,
+ rt::v1::Alignment::Unknown => Alignment::Unknown,
+ }
+ }
/// Optionally specified integer width that the output should be
#[stable(feature = "fmt_flags", since = "1.5.0")]
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for str {
fn fmt(&self, f: &mut Formatter) -> Result {
- try!(f.write_char('"'));
+ f.write_char('"')?;
let mut from = 0;
for (i, c) in self.char_indices() {
let esc = c.escape_default();
// If char needs escaping, flush backlog so far and write, else skip
if esc.size_hint() != (1, Some(1)) {
- try!(f.write_str(&self[from..i]));
+ f.write_str(&self[from..i])?;
for c in esc {
- try!(f.write_char(c));
+ f.write_char(c)?;
}
from = i + c.len_utf8();
}
}
- try!(f.write_str(&self[from..]));
+ f.write_str(&self[from..])?;
f.write_char('"')
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for char {
fn fmt(&self, f: &mut Formatter) -> Result {
- try!(f.write_char('\''));
+ f.write_char('\'')?;
for c in self.escape_default() {
- try!(f.write_char(c))
+ f.write_char(c)?
}
f.write_char('\'')
}
if f.width.is_none() && f.precision.is_none() {
f.write_char(*self)
} else {
- let mut utf8 = [0; 4];
- let amt = self.encode_utf8(&mut utf8).unwrap_or(0);
- let s: &str = unsafe { str::from_utf8_unchecked(&utf8[..amt]) };
- f.pad(s)
+ f.pad(unsafe {
+ str::from_utf8_unchecked(self.encode_utf8().as_slice())
+ })
}
}
}
fn fmt(&self, f: &mut Formatter) -> Result {
let mut builder = f.debug_tuple("");
let ($(ref $name,)*) = *self;
- let mut n = 0;
$(
builder.field($name);
- n += 1;
)*
- if n == 1 {
- try!(write!(builder.formatter(), ","));
- }
-
builder.finish()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Copy + Debug> Debug for Cell<T> {
fn fmt(&self, f: &mut Formatter) -> Result {
- write!(f, "Cell {{ value: {:?} }}", self.get())
+ f.debug_struct("Cell")
+ .field("value", &self.get())
+ .finish()
}
}
fn fmt(&self, f: &mut Formatter) -> Result {
match self.borrow_state() {
BorrowState::Unused | BorrowState::Reading => {
- write!(f, "RefCell {{ value: {:?} }}", self.borrow())
+ f.debug_struct("RefCell")
+ .field("value", &self.borrow())
+ .finish()
+ }
+ BorrowState::Writing => {
+ f.debug_struct("RefCell")
+ .field("value", &"<borrowed>")
+ .finish()
}
- BorrowState::Writing => write!(f, "RefCell {{ <borrowed> }}"),
}
}
}
}
}
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: ?Sized + Debug> Debug for UnsafeCell<T> {
+ fn fmt(&self, f: &mut Formatter) -> Result {
+ f.pad("UnsafeCell")
+ }
+}
+
// If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
// it's a lot easier than creating all of the rt::Piece structures here.