Skip to content

Commit

Permalink
Support no_std
Browse files Browse the repository at this point in the history
Fixes #3.
  • Loading branch information
glandium committed Mar 16, 2018
1 parent 13d1f09 commit 1c13f60
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 11 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ readme = "README.md"
exclude = ["performance.png"]

[features]
default = ["use_std"]
i128 = []
use_std = []
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ 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
implementation comes straight from
[`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) when the
`use_std` feature is disabled. 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
[`fmt::Formatter`](https://doc.rust-lang.org/std/fmt/struct.Formatter.html).
Expand Down
43 changes: 34 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,49 @@

#![doc(html_root_url = "https://docs.rs/itoa/0.3.4")]

#![cfg_attr(not(feature = "use_std"), no_std)]

#![cfg_attr(feature = "i128", feature(i128_type, i128))]

#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless, unreadable_literal))]

#[cfg(feature = "i128")]
mod udiv128;

use std::{io, mem, ptr, slice};
#[cfg(feature = "use_std")]
mod compat {
pub use std::{io, mem, ptr, slice};
pub use io::Write;
pub type Result = io::Result<usize>;

#[inline]
pub fn write_compat<W: Write>(wr: &mut W, bytes: &[u8]) -> Result {
try!(wr.write_all(bytes));
Ok(bytes.len())
}
}

#[cfg(not(feature = "use_std"))]
mod compat {
pub use core::{fmt, mem, ptr, slice, str};
pub use self::fmt::Write;
pub type Result = self::fmt::Result;

#[inline]
pub fn write_compat<W: Write>(wr: &mut W, bytes: &[u8]) -> Result {
wr.write_str(unsafe { str::from_utf8_unchecked(bytes) })
}
}

use compat::*;

#[inline]
pub fn write<W: io::Write, V: Integer>(wr: W, value: V) -> io::Result<usize> {
pub fn write<W: Write, V: Integer>(wr: W, value: V) -> Result {
value.write(wr)
}

pub trait Integer {
fn write<W: io::Write>(self, W) -> io::Result<usize>;
fn write<W: Write>(self, W) -> Result;
}

trait IntegerPrivate {
Expand All @@ -44,11 +71,10 @@ const MAX_LEN: usize = 40; // i128::MIN (including minus sign)
macro_rules! impl_Integer {
($($t:ident),* as $conv_fn:ident) => {$(
impl Integer for $t {
fn write<W: io::Write>(self, mut wr: W) -> io::Result<usize> {
fn write<W: Write>(self, mut wr: W) -> Result {
let mut buf = unsafe { mem::uninitialized() };
let bytes = self.write_to(&mut buf);
try!(wr.write_all(bytes));
Ok(bytes.len())
write_compat(&mut wr, bytes)
}
}

Expand Down Expand Up @@ -129,11 +155,10 @@ impl_Integer!(isize, usize as u64);
macro_rules! impl_Integer128 {
($($t:ident),*) => {$(
impl Integer for $t {
fn write<W: io::Write>(self, mut wr: W) -> io::Result<usize> {
fn write<W: Write>(self, mut wr: W) -> Result {
let mut buf = unsafe { mem::uninitialized() };
let bytes = self.write_to(&mut buf);
try!(wr.write_all(bytes));
Ok(bytes.len())
write_compat(&mut wr, bytes)
}
}

Expand Down

0 comments on commit 1c13f60

Please sign in to comment.