Skip to content

Commit

Permalink
refactor the whole project, add new feature: std, supported units u…
Browse files Browse the repository at this point in the history
…p to ZiB, and the data type used for storing bytes can be changed to u64 optionally now
  • Loading branch information
magiclen committed May 18, 2020
1 parent 666ced9 commit 74bdea8
Show file tree
Hide file tree
Showing 13 changed files with 1,435 additions and 882 deletions.
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ os:
- osx
- windows

env:
-
- NO_DEFAULT_FEATURES=1
- FEATURES="std"

script:
- if [ "$NO_DEFAULT_FEATURES" = "1" ]; then NO_DEFAULT_FEATURES="--no-default-features"; else NO_DEFAULT_FEATURES=""; fi
- cargo test --verbose $NO_DEFAULT_FEATURES --features "$FEATURES"

matrix:
include:
- rust: stable
Expand Down
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "byte-unit"
version = "3.0.3"
version = "3.1.0"
authors = ["Magic Len <[email protected]>"]
edition = "2018"
repository = "https://github.com/magiclen/byte-unit"
Expand All @@ -13,4 +13,9 @@ license = "MIT"

[badges.travis-ci]
repository = "magiclen/Byte-Unit"
branch = "master"
branch = "master"

[features]
std = []
u128 = []
default = ["u128"]
26 changes: 12 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ Byte Unit

[![Build Status](https://travis-ci.org/magiclen/Byte-Unit.svg?branch=master)](https://travis-ci.org/magiclen/Byte-Unit)

A library for interaction with units of bytes.
A library for interaction with units of bytes. The units are **B** for 1 byte, **KB** for 1000 bytes, **KiB** for 1024 bytes, **MB** for 1000000 bytes, **MiB** for 1048576 bytes, etc, and up to **ZiB** which is 1180591620717411303424 bytes.

The units are **B** for 1 byte, **KB** for 1000 bytes, **KiB** for 1024 bytes, **MB** for 1000000 bytes, **MiB** for 1048576 bytes, etc, and up to **PiB** which is 1125899906842624 bytes.

The data type for storing the size of bytes is `u128`, so don't worry about the overflow problem.
The data type for storing the size of bytes is `u128` by default, but can also be changed to `u64` by disabling the default features (it will also cause the highest supported unit down to **PiB**).

## Usage

Expand All @@ -20,7 +18,7 @@ There are `n_*_bytes` macros can be used. The star `*` means the unit. For examp

let result = n_gb_bytes!(4);

assert_eq!(4000000000u128, result);
assert_eq!(4000000000, result);
```

You may need to assign a primitive type if the `n` is not an integer.
Expand All @@ -30,7 +28,7 @@ You may need to assign a primitive type if the `n` is not an integer.

let result = n_gb_bytes!(2.5, f64);

assert_eq!(2500000000u128, result);
assert_eq!(2500000000, result);
```

### Byte
Expand All @@ -46,7 +44,7 @@ use byte_unit::Byte;

let result = Byte::from_str("50.84 MB").unwrap();

assert_eq!(50840000u128, result.get_bytes());
assert_eq!(50840000, result.get_bytes());
```

You can also use the `from_bytes` and `from_unit` associated functions to create a `Byte` instance.
Expand All @@ -56,9 +54,9 @@ extern crate byte_unit;

use byte_unit::Byte;

let result = Byte::from_bytes(1500000u128);
let result = Byte::from_bytes(1500000);

assert_eq!(1500000u128, result.get_bytes());
assert_eq!(1500000, result.get_bytes());
```

```rust
Expand All @@ -68,7 +66,7 @@ use byte_unit::{Byte, ByteUnit};

let result = Byte::from_unit(1500f64, ByteUnit::KB).unwrap();

assert_eq!(1500000u128, result.get_bytes());
assert_eq!(1500000, result.get_bytes());
```

### AdjustedByte
Expand All @@ -94,7 +92,7 @@ extern crate byte_unit;

use byte_unit::Byte;

let byte = Byte::from_bytes(1500000u128);
let byte = Byte::from_bytes(1500000);

let adjusted_byte = byte.get_appropriate_unit(false);

Expand All @@ -106,14 +104,14 @@ extern crate byte_unit;

use byte_unit::Byte;

let byte = Byte::from_bytes(1500000u128);
let byte = Byte::from_bytes(1500000);

let adjusted_byte = byte.get_appropriate_unit(true);

assert_eq!("1.43 MiB", adjusted_byte.to_string());
```

The number of fractional digits created by the `to_string` method of a `AdjustedByte` instance is always 2.
The number of fractional digits created by the `to_string` method of a `AdjustedByte` instance is always `2`.

To change the number of fractional digits in the formatted string, you can use the `format` method instead.

Expand All @@ -122,7 +120,7 @@ extern crate byte_unit;

use byte_unit::Byte;

let byte = Byte::from_bytes(1500000u128);
let byte = Byte::from_bytes(1500000);

let adjusted_byte = byte.get_appropriate_unit(false);

Expand Down
161 changes: 161 additions & 0 deletions src/adjusted_byte.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
use core::cmp::Ordering;

use alloc::fmt::{self, Display, Formatter};
use alloc::string::String;

use crate::{get_bytes, Byte, ByteUnit};

#[derive(Debug, Clone, Copy)]
/// Generated from the `get_appropriate_unit` and `get_adjusted_unit` methods of a `Byte` object.
pub struct AdjustedByte {
pub(crate) value: f64,
pub(crate) unit: ByteUnit,
}

impl AdjustedByte {
/// Format the `AdjustedByte` object to string.
///
/// # Examples
///
/// ```
/// extern crate byte_unit;
///
/// use byte_unit::{Byte, ByteUnit};
///
/// let byte = Byte::from_unit(1555f64, ByteUnit::KB).unwrap();
///
/// let result = byte.get_appropriate_unit(false).format(3);
///
/// assert_eq!("1.555 MB", result);
/// ```
#[inline]
pub fn format(&self, fractional_digits: usize) -> String {
format!("{:.*} {}", fractional_digits, self.value, self.unit)
}

#[inline]
pub fn get_value(&self) -> f64 {
self.value
}

#[inline]
pub fn get_unit(&self) -> ByteUnit {
self.unit
}

/// Create a new `Byte` object from this `AdjustedByte` object. **Accuracy** should be taken care of.
///
/// ## Examples
///
/// ```
/// extern crate byte_unit;
///
/// use byte_unit::{Byte, ByteUnit};
///
/// let byte = Byte::from_str("123456789123456").unwrap();
/// let adjusted_byte = byte.get_adjusted_unit(ByteUnit::GB);
///
/// assert_eq!(123456.789123456, adjusted_byte.get_value());
///
/// let byte = adjusted_byte.get_byte();
/// let adjusted_byte = byte.get_adjusted_unit(ByteUnit::GB);
///
/// assert_eq!(123456.789123, adjusted_byte.get_value());
/// ```
#[inline]
pub fn get_byte(&self) -> Byte {
let bytes = get_bytes(self.value, self.unit);

Byte::from_bytes(bytes)
}
}

impl Display for AdjustedByte {
#[inline]
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
f.write_fmt(format_args!("{:.2} ", self.value))?;
Display::fmt(&self.unit, f)
}
}

impl PartialEq for AdjustedByte {
/// Deal with the logical numeric equivalent.
///
/// # Examples
///
/// ```
/// extern crate byte_unit;
///
/// use byte_unit::{Byte, ByteUnit};
///
/// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap();
/// let byte2 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap();
///
/// assert_eq!(byte1.get_appropriate_unit(false), byte2.get_appropriate_unit(true));
/// ```
///
/// ```
/// extern crate byte_unit;
///
/// use byte_unit::{Byte, ByteUnit};
///
/// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap();
/// let byte2 = Byte::from_unit(1f64, ByteUnit::MiB).unwrap();
///
/// assert_eq!(byte1.get_appropriate_unit(true), byte2.get_appropriate_unit(false));
/// ```
#[inline]
fn eq(&self, other: &AdjustedByte) -> bool {
let s = self.get_byte();
let o = other.get_byte();

s.eq(&o)
}
}

impl Eq for AdjustedByte {}

impl PartialOrd for AdjustedByte {
#[inline]
fn partial_cmp(&self, other: &AdjustedByte) -> Option<Ordering> {
let s = self.get_byte();
let o = other.get_byte();

s.partial_cmp(&o)
}
}

impl Ord for AdjustedByte {
/// Deal with the logical numeric comparation.
///
/// # Examples
///
/// ```
/// extern crate byte_unit;
///
/// use byte_unit::{Byte, ByteUnit};
///
/// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap();
/// let byte2 = Byte::from_unit(1025f64, ByteUnit::KiB).unwrap();
///
/// assert!(byte1.get_appropriate_unit(false) < byte2.get_appropriate_unit(true));
/// ```
///
/// ```
/// extern crate byte_unit;
///
/// use byte_unit::{Byte, ByteUnit};
///
/// let byte1 = Byte::from_unit(1024f64, ByteUnit::KiB).unwrap();
/// let byte2 = Byte::from_unit(1.01f64, ByteUnit::MiB).unwrap();
///
/// assert!(byte1.get_appropriate_unit(true) < byte2.get_appropriate_unit(false));
/// ```
#[inline]
fn cmp(&self, other: &AdjustedByte) -> Ordering {
let s = self.get_byte();
let o = other.get_byte();

s.cmp(&o)
}
}
Loading

0 comments on commit 74bdea8

Please sign in to comment.