commit
c1c4f7320e
|
@ -13,5 +13,7 @@ matrix:
|
|||
script:
|
||||
- cargo build --verbose --features "$FEATURES"
|
||||
- cargo test --verbose --features "$FEATURES"
|
||||
- cargo build --verbose --no-default-features --features "$FEATURES"
|
||||
- cargo test --verbose --no-default-features --features "$FEATURES"
|
||||
- if [ "$BUILD_BENCH" == "true" ]; then cargo bench --verbose --no-run --features "$FEATURES"; fi
|
||||
|
||||
|
|
|
@ -11,4 +11,6 @@ readme = "README.md"
|
|||
exclude = ["performance.png"]
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
i128 = []
|
||||
std = []
|
||||
|
|
15
README.md
15
README.md
|
@ -5,7 +5,8 @@ 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
|
||||
[`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
|
||||
[libcore](https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254)
|
||||
but avoids the performance penalty of going through
|
||||
|
@ -32,12 +33,19 @@ println!("{:?}", buf);
|
|||
let mut bytes = [b'\0'; 20];
|
||||
let n = itoa::write(&mut bytes[..], 128u64)?;
|
||||
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
|
||||
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`,
|
||||
|
@ -45,6 +53,9 @@ where `itoa::Integer` is implemented for `i8`, `u8`, `i16`, `u16`, `i32`, `u32`,
|
|||
only available with the nightly compiler when the `i128` feature is enabled for
|
||||
this crate. The return value gives the number of bytes written.
|
||||
|
||||
The `write` function is only available when the `std` feature is enabled
|
||||
(default is enabled).
|
||||
|
||||
## Dependency
|
||||
|
||||
Itoa is available on [crates.io](https://crates.io/crates/itoa). Use the
|
||||
|
|
52
src/lib.rs
52
src/lib.rs
|
@ -8,6 +8,8 @@
|
|||
|
||||
#![doc(html_root_url = "https://docs.rs/itoa/0.3.4")]
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#![cfg_attr(feature = "i128", feature(i128_type, i128))]
|
||||
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless, unreadable_literal))]
|
||||
|
@ -15,15 +17,33 @@
|
|||
#[cfg(feature = "i128")]
|
||||
mod udiv128;
|
||||
|
||||
use std::{io, mem, ptr, slice};
|
||||
#[cfg(feature = "std")]
|
||||
use std::{fmt, io, mem, ptr, slice, str};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use core::{fmt, mem, ptr, slice, str};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[inline]
|
||||
pub fn write<W: io::Write, V: Integer>(wr: W, value: V) -> io::Result<usize> {
|
||||
value.write(wr)
|
||||
}
|
||||
|
||||
pub trait Integer {
|
||||
#[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.
|
||||
mod private {
|
||||
pub trait Sealed {}
|
||||
}
|
||||
|
||||
pub trait Integer: private::Sealed {
|
||||
#[cfg(feature = "std")]
|
||||
fn write<W: io::Write>(self, W) -> io::Result<usize>;
|
||||
|
||||
fn fmt<W: fmt::Write>(self, W) -> fmt::Result;
|
||||
}
|
||||
|
||||
trait IntegerPrivate {
|
||||
|
@ -41,16 +61,31 @@ const MAX_LEN: usize = 40; // i128::MIN (including minus sign)
|
|||
|
||||
// Adaptation of the original implementation at
|
||||
// https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266
|
||||
macro_rules! impl_Integer {
|
||||
($($t:ident),* as $conv_fn:ident) => {$(
|
||||
macro_rules! impl_IntegerCommon {
|
||||
($t:ident) => {
|
||||
impl Integer for $t {
|
||||
#[cfg(feature = "std")]
|
||||
fn write<W: io::Write>(self, mut wr: W) -> io::Result<usize> {
|
||||
let mut buf = unsafe { mem::uninitialized() };
|
||||
let bytes = self.write_to(&mut buf);
|
||||
try!(wr.write_all(bytes));
|
||||
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 {}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_Integer {
|
||||
($($t:ident),* as $conv_fn:ident) => {$(
|
||||
impl_IntegerCommon!($t);
|
||||
|
||||
impl IntegerPrivate for $t {
|
||||
#[allow(unused_comparisons)]
|
||||
|
@ -128,14 +163,7 @@ impl_Integer!(isize, usize as u64);
|
|||
#[cfg(all(feature = "i128"))]
|
||||
macro_rules! impl_Integer128 {
|
||||
($($t:ident),*) => {$(
|
||||
impl Integer for $t {
|
||||
fn write<W: io::Write>(self, mut wr: W) -> io::Result<usize> {
|
||||
let mut buf = unsafe { mem::uninitialized() };
|
||||
let bytes = self.write_to(&mut buf);
|
||||
try!(wr.write_all(bytes));
|
||||
Ok(bytes.len())
|
||||
}
|
||||
}
|
||||
impl_IntegerCommon!($t);
|
||||
|
||||
impl IntegerPrivate for $t {
|
||||
#[allow(unused_comparisons)]
|
||||
|
|
|
@ -17,10 +17,17 @@ macro_rules! test {
|
|||
$(#[$attr])*
|
||||
#[test]
|
||||
fn $name() {
|
||||
#[cfg(feature = "std")]
|
||||
{
|
||||
let mut buf = [b'\0'; 40];
|
||||
let len = itoa::write(&mut buf[..], $value).unwrap();
|
||||
assert_eq!(&buf[0..len], $expected.as_bytes());
|
||||
}
|
||||
|
||||
let mut s = String::new();
|
||||
itoa::fmt(&mut s, $value).unwrap();
|
||||
assert_eq!(s, $expected);
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue