Skip to content
This repository has been archived by the owner on Apr 19, 2022. It is now read-only.

Commit

Permalink
no_std support for formatting (#43)
Browse files Browse the repository at this point in the history
* adds no std support

* typos

* overflow issue

* buffer fix

* Fixes quickcheck

* typo

* Removes extra cast

* Returns `From` trait (it's better to create a separate PR). Adds fmt tests

* Fixes tests

* Fixes naming issue

* Fixes formatting
  • Loading branch information
Pzixel authored and debris committed Aug 3, 2018
1 parent 75521ae commit 91f6c7a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! Efficient large, fixed-size big integers and hashes.
#![cfg_attr(not(feature="std"), no_std)]
#![cfg_attr(all(not(feature="std"), test), feature(alloc))]

extern crate byteorder;

Expand All @@ -35,5 +36,9 @@ extern crate core;
#[macro_use]
extern crate quickcheck;

#[cfg(all(not(feature = "std"), test))]
#[macro_use]
extern crate alloc;

pub mod uint;
pub use ::uint::*;
52 changes: 44 additions & 8 deletions src/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ macro_rules! construct_uint {
pub struct $name(pub [u64; $n_words]);

impl $name {
pub const MAX: $name = $name([u64::max_value(); $n_words]);

/// Convert from a decimal string.
pub fn from_dec_str(value: &str) -> Result<Self, FromDecStrErr> {
if !value.bytes().all(|b| b >= 48 && b <= 57) {
Expand Down Expand Up @@ -910,34 +912,39 @@ macro_rules! construct_uint {
}
}

#[cfg(feature="std")]
impl ::core::fmt::Debug for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Display::fmt(self, f)
}
}

#[cfg(feature="std")]
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
if self.is_zero() {
return write!(f, "0");
}

let mut s = String::new();
let mut buf = [0_u8; $n_words*20];
let mut i = buf.len() - 1;
let mut current = *self;
let ten = $name::from(10);

while !current.is_zero() {
s = format!("{}{}", (current % ten).low_u32(), s);
loop {
let digit = (current % ten).low_u64() as u8;
buf[i] = digit + b'0';
current = current / ten;
if current.is_zero() {
break;
}
i -= 1;
}

write!(f, "{}", s)
// sequence of `'0'..'9'` chars is guaranteed to be a valid UTF8 string
let s = unsafe {::core::str::from_utf8_unchecked(&buf[i..])};
f.write_str(s)
}
}

#[cfg(feature="std")]
impl ::core::fmt::LowerHex for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let &$name(ref data) = self;
Expand Down Expand Up @@ -1172,9 +1179,38 @@ impl From<U512> for [u8; 64] {
known_heap_size!(0, U128, U256);

#[cfg(test)]
#[cfg(feature="std")]
mod tests {
use uint::{U128, U256, U512};

#[test]
pub fn display_u128() {
let expected = "340282366920938463463374607431768211455";
let value = U128::MAX;
assert_eq!(format!("{}", value), expected);
assert_eq!(format!("{:?}", value), expected);
}

#[test]
pub fn display_u256() {
let expected = "115792089237316195423570985008687907853269984665640564039457584007913129639935";
let value = U256::MAX;
assert_eq!(format!("{}", value), expected);
assert_eq!(format!("{:?}", value), expected);
}

#[test]
pub fn display_u512() {
let expected = "13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095";
let value = U512::MAX;
assert_eq!(format!("{}", value), expected);
assert_eq!(format!("{:?}", value), expected);
}
}

#[cfg(test)]
#[cfg(feature="std")]
mod std_tests {
use uint::{U128, U256, U512};
use std::str::FromStr;
use super::FromDecStrErr;
use std::u64::MAX;
Expand Down

0 comments on commit 91f6c7a

Please sign in to comment.