parent
058439f12f
commit
658f09f9c2
68
src/lib.rs
68
src/lib.rs
|
@ -26,14 +26,44 @@ use core::{fmt, mem, ptr, slice, str};
|
||||||
/// Write integer to an `io::Write`.
|
/// Write integer to an `io::Write`.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn write<W: io::Write, V: Integer>(wr: W, value: V) -> io::Result<usize> {
|
pub fn write<W: io::Write, V: Integer>(mut wr: W, value: V) -> io::Result<usize> {
|
||||||
value.write(wr)
|
let mut buf = Buffer::new();
|
||||||
|
let s = buf.format(value);
|
||||||
|
try!(wr.write_all(s.as_bytes()));
|
||||||
|
Ok(s.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write integer to an `fmt::Write`.
|
/// Write integer to an `fmt::Write`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fmt<W: fmt::Write, V: Integer>(wr: W, value: V) -> fmt::Result {
|
pub fn fmt<W: fmt::Write, V: Integer>(mut wr: W, value: V) -> fmt::Result {
|
||||||
value.fmt(wr)
|
let mut buf = Buffer::new();
|
||||||
|
wr.write_str(buf.format(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A safe API for formatting integers to text.
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Buffer {
|
||||||
|
bytes: [u8; I128_MAX_LEN],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Buffer {
|
||||||
|
fn default() -> Buffer {
|
||||||
|
Buffer::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Buffer {
|
||||||
|
/// This is a cheap operation; you don't need to worry about reusing buffers
|
||||||
|
/// for efficiency.
|
||||||
|
pub fn new() -> Buffer {
|
||||||
|
Buffer { bytes: unsafe { mem::uninitialized() } }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Print an integer into this buffer and return a reference to its string representation
|
||||||
|
/// within the buffer
|
||||||
|
pub fn format<I: Integer>(&mut self, i: I) -> &str {
|
||||||
|
i.write(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seal to prevent downstream implementations of the Integer trait.
|
// Seal to prevent downstream implementations of the Integer trait.
|
||||||
|
@ -47,12 +77,7 @@ mod private {
|
||||||
pub trait Integer: private::Sealed {
|
pub trait Integer: private::Sealed {
|
||||||
// Not public API.
|
// Not public API.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(feature = "std")]
|
fn write<'a>(self, buf: &'a mut Buffer) -> &'a str;
|
||||||
fn write<W: io::Write>(self, W) -> io::Result<usize>;
|
|
||||||
|
|
||||||
// Not public API.
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn fmt<W: fmt::Write>(self, W) -> fmt::Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait IntegerPrivate<B> {
|
trait IntegerPrivate<B> {
|
||||||
|
@ -71,20 +96,16 @@ const DEC_DIGITS_LUT: &'static[u8] =
|
||||||
macro_rules! impl_IntegerCommon {
|
macro_rules! impl_IntegerCommon {
|
||||||
($max_len:expr, $t:ident) => {
|
($max_len:expr, $t:ident) => {
|
||||||
impl Integer for $t {
|
impl Integer for $t {
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write<W: io::Write>(self, mut wr: W) -> io::Result<usize> {
|
fn write<'a>(self, buf: &'a mut Buffer) -> &'a str {
|
||||||
let mut buf: [u8; $max_len] = unsafe { mem::uninitialized() };
|
unsafe {
|
||||||
let bytes = self.write_to(&mut buf);
|
debug_assert!($max_len <= I128_MAX_LEN);
|
||||||
try!(wr.write_all(bytes));
|
let buf = mem::transmute::<&mut [u8; I128_MAX_LEN], &mut [u8; $max_len]>(
|
||||||
Ok(bytes.len())
|
&mut buf.bytes
|
||||||
}
|
);
|
||||||
|
let bytes = self.write_to(buf);
|
||||||
#[inline]
|
str::from_utf8_unchecked(bytes)
|
||||||
fn fmt<W: fmt::Write>(self, mut wr: W) -> fmt::Result {
|
}
|
||||||
let mut buf: [u8; $max_len] = unsafe { mem::uninitialized() };
|
|
||||||
let bytes = self.write_to(&mut buf);
|
|
||||||
wr.write_str(unsafe { str::from_utf8_unchecked(bytes) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +275,6 @@ macro_rules! impl_Integer128 {
|
||||||
|
|
||||||
#[cfg(all(feature = "i128"))]
|
#[cfg(all(feature = "i128"))]
|
||||||
const U128_MAX_LEN: usize = 39;
|
const U128_MAX_LEN: usize = 39;
|
||||||
#[cfg(all(feature = "i128"))]
|
|
||||||
const I128_MAX_LEN: usize = 40;
|
const I128_MAX_LEN: usize = 40;
|
||||||
|
|
||||||
#[cfg(all(feature = "i128"))]
|
#[cfg(all(feature = "i128"))]
|
||||||
|
|
Loading…
Reference in New Issue