Provide itoa::fmt to write to fmt::Write

Fixes #5.
This commit is contained in:
Mike Hommey 2018-03-17 10:11:33 +09:00
parent 39e80cca43
commit 9f3e867f04
3 changed files with 28 additions and 3 deletions

View File

@ -5,7 +5,8 @@ itoa
[![Latest Version](https://img.shields.io/crates/v/itoa.svg)](https://crates.io/crates/itoa) [![Latest Version](https://img.shields.io/crates/v/itoa.svg)](https://crates.io/crates/itoa)
This crate provides fast functions for printing integer primitives to an This crate provides fast functions for printing integer primitives to an
[`io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html). The [`io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html) or a
[`fmt::Write`](https://doc.rust-lang.org/core/fmt/trait.Write.html). The
implementation comes straight from implementation comes straight from
[libcore](https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254) [libcore](https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254)
but avoids the performance penalty of going through but avoids the performance penalty of going through
@ -32,12 +33,19 @@ println!("{:?}", buf);
let mut bytes = [b'\0'; 20]; let mut bytes = [b'\0'; 20];
let n = itoa::write(&mut bytes[..], 128u64)?; let n = itoa::write(&mut bytes[..], 128u64)?;
println!("{:?}", &bytes[..n]); println!("{:?}", &bytes[..n]);
// write to a String
let mut s = String::new();
itoa::fmt(&mut s, 128u64)?;
println!("{}", s);
``` ```
The function signature is: The function signatures are:
```rust ```rust
fn write<W: io::Write, V: itoa::Integer>(writer: W, value: V) -> io::Result<usize> fn write<W: io::Write, V: itoa::Integer>(writer: W, value: V) -> io::Result<usize>
fn fmt<W: fmt::Write, V: itoa::Integer>(writer: W, value: V) -> fmt::Result
``` ```
where `itoa::Integer` is implemented for `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, where `itoa::Integer` is implemented for `i8`, `u8`, `i16`, `u16`, `i32`, `u32`,

View File

@ -15,13 +15,18 @@
#[cfg(feature = "i128")] #[cfg(feature = "i128")]
mod udiv128; mod udiv128;
use std::{io, mem, ptr, slice}; use std::{fmt, io, mem, ptr, slice, str};
#[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>(wr: W, value: V) -> io::Result<usize> {
value.write(wr) value.write(wr)
} }
#[inline]
pub fn fmt<W: fmt::Write, V: Integer>(wr: W, value: V) -> fmt::Result {
value.fmt(wr)
}
// Seal to prevent downstream implementations of the Integer trait. // Seal to prevent downstream implementations of the Integer trait.
mod private { mod private {
pub trait Sealed {} pub trait Sealed {}
@ -29,6 +34,8 @@ mod private {
pub trait Integer: private::Sealed { pub trait Integer: private::Sealed {
fn write<W: io::Write>(self, W) -> io::Result<usize>; fn write<W: io::Write>(self, W) -> io::Result<usize>;
fn fmt<W: fmt::Write>(self, W) -> fmt::Result;
} }
trait IntegerPrivate { trait IntegerPrivate {
@ -55,6 +62,12 @@ macro_rules! impl_IntegerCommon {
try!(wr.write_all(bytes)); try!(wr.write_all(bytes));
Ok(bytes.len()) Ok(bytes.len())
} }
fn fmt<W: fmt::Write>(self, mut wr: W) -> fmt::Result {
let mut buf = unsafe { mem::uninitialized() };
let bytes = self.write_to(&mut buf);
wr.write_str(unsafe { str::from_utf8_unchecked(bytes) })
}
} }
impl private::Sealed for $t {} impl private::Sealed for $t {}

View File

@ -20,6 +20,10 @@ macro_rules! test {
let mut buf = [b'\0'; 40]; let mut buf = [b'\0'; 40];
let len = itoa::write(&mut buf[..], $value).unwrap(); let len = itoa::write(&mut buf[..], $value).unwrap();
assert_eq!(&buf[0..len], $expected.as_bytes()); assert_eq!(&buf[0..len], $expected.as_bytes());
let mut s = String::new();
itoa::fmt(&mut s, $value).unwrap();
assert_eq!(s, $expected);
} }
)* )*
} }