diff --git a/Cargo.toml b/Cargo.toml index e4a5000..dd6ee66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "signifix" -version = "0.7.0" +version = "0.8.0" authors = [ "Rouven Spreckels ", ] description = """ Number Formatter of Fixed Significance with Metric or Binary Prefix""" -documentation = "https://docs.rs/signifix/0.7.0/signifix/" +documentation = "https://docs.rs/signifix" homepage = "https://qu1x.org/signifix" repository = "https://github.com/qu1x/signifix" readme = "README.md" diff --git a/README.md b/README.md index f4c337b..fd074bc 100644 --- a/README.md +++ b/README.md @@ -90,9 +90,9 @@ used by adding `signifix` to the dependencies in your project's ```toml [dependencies] -signifix = "0.7" +signifix = "0.8" -# Optionally enable `i128_type` support. Requires nightly Rust. +# Optionally enable `try_from` and `i128_type` support on nightly Rust. #[dependencies.signifix] #features = ["nightly"] ``` @@ -100,7 +100,9 @@ signifix = "0.7" and this to your crate root: ```rust -#![feature(try_from)] // Until stabilized. Requires nightly Rust. +// Optionally enable `try_from` and `i128_type` support on nightly Rust. +// Required if the `nightly` feature is enabled in your `Cargo.toml`. +//#![feature(try_from, i128_type)] extern crate signifix; ``` @@ -113,7 +115,7 @@ The Signifix notations result in a fixed number of characters preventing jumps to the left or right while making maximum use of their occupied space: ```rust -use std::convert::TryFrom; // Until stabilized. +use signifix::TryFrom; // Until stabilized. use signifix::{metric, binary, Result}; @@ -168,7 +170,7 @@ assert_eq!(binary(1_023.499_999_999_999_95), This is useful to smoothly refresh a transfer rate within a terminal: ```rust -use std::convert::TryFrom; // Until stabilized. +use signifix::TryFrom; // Until stabilized. use std::f64; use std::time::Duration; @@ -218,7 +220,7 @@ Or to monitor a measured quantity like an electrical current including its direction with positive numbers being padded to align with negative ones: ```rust -use std::convert::TryFrom; // Until stabilized. +use signifix::TryFrom; // Until stabilized. use signifix::metric::{Signifix, Result, DEF_MAX_LEN}; @@ -242,7 +244,7 @@ While to visualize a change in file size, a plus sign might be preferred for positive numbers: ```rust -use std::convert::TryFrom; // Until stabilized. +use signifix::TryFrom; // Until stabilized. use signifix::metric::{Signifix, Error, Result}; @@ -263,11 +265,11 @@ The binary prefix instead suits well to visualize quantities being multiples of powers of two, such as memory boundaries due to binary addressing: ```rust -use std::convert::TryFrom; // Until stabilized. +use signifix::TryFrom; // Until stabilized. use signifix::binary::{Signifix, Error, Result}; -let boundary_stat = |used: usize, size: usize| -> Result { +let boundary_stat = |used: u64, size: u64| -> Result { if used == 0 { let size = Signifix::try_from(size)?; return Ok(format!(" 0 B ( 0 %) of {}B", size)); @@ -281,17 +283,17 @@ let boundary_stat = |used: usize, size: usize| -> Result { Ok(format!("{}B ({}) of {}B", used, p100, size)) }; -assert_eq!(boundary_stat(0_000usize.pow(1), 1_024usize.pow(3)), +assert_eq!(boundary_stat(0_000u64.pow(1), 1_024u64.pow(3)), Ok(" 0 B ( 0 %) of 1.000 GiB".into())); -assert_eq!(boundary_stat(1_024usize.pow(2), 1_024usize.pow(3)), +assert_eq!(boundary_stat(1_024u64.pow(2), 1_024u64.pow(3)), Ok("1.000 MiB ( < 1 %) of 1.000 GiB".into())); -assert_eq!(boundary_stat(3_292usize.pow(2), 1_024usize.pow(3)), +assert_eq!(boundary_stat(3_292u64.pow(2), 1_024u64.pow(3)), Ok("10.34 MiB (1.009 %) of 1.000 GiB".into())); -assert_eq!(boundary_stat(8_192usize.pow(2), 1_024usize.pow(3)), +assert_eq!(boundary_stat(8_192u64.pow(2), 1_024u64.pow(3)), Ok("64.00 MiB (6.250 %) of 1.000 GiB".into())); -assert_eq!(boundary_stat(1_000usize.pow(3), 1_024usize.pow(3)), +assert_eq!(boundary_stat(1_000u64.pow(3), 1_024u64.pow(3)), Ok("953.7 MiB (93.13 %) of 1.000 GiB".into())); -assert_eq!(boundary_stat(1_024usize.pow(3), 1_024usize.pow(3)), +assert_eq!(boundary_stat(1_024u64.pow(3), 1_024u64.pow(3)), Ok("1.000 GiB (100.0 %) of 1.000 GiB".into())); ``` @@ -303,7 +305,7 @@ into a locale-sensitive newtype which implements the `Display` trait via the `Signifix::fmt()` method: ```rust -use std::convert::TryFrom; // Until stabilized. +use signifix::TryFrom; // Until stabilized. use signifix::binary::{Signifix, Result}; @@ -347,7 +349,7 @@ Customization can be achieved by extracting information from the `Signifix` type via its methods: ```rust -use std::convert::TryFrom; // Until stabilized. +use signifix::TryFrom; // Until stabilized. use signifix::metric::{Signifix, Result}; diff --git a/RELEASES.md b/RELEASES.md index 4cc586f..f6f0fa4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,10 @@ +# Version 0.8.0 (2017-09-26) + + * Compiles on stable Rust by reimplementing the `try_from` feature. + * Added `nightly` feature enabling `try_from` and `i128_type` support. This + replaces the reimplementation of `try_from`. + * Simplified code by using `binary_search_by()`. + # Version 0.7.0 (2017-07-10) * Added explicit localization support. diff --git a/src/binary.rs b/src/binary.rs index 6e58957..bc1a958 100644 --- a/src/binary.rs +++ b/src/binary.rs @@ -6,7 +6,7 @@ // // DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. -use std::convert::TryFrom; +use super::TryFrom; use std::result; use std::error; diff --git a/src/lib.rs b/src/lib.rs index 1e09909..5ea5b26 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,9 +82,9 @@ //! //! ```toml //! [dependencies] -//! signifix = "0.7" +//! signifix = "0.8" //! -//! # Optionally enable `i128_type` support. Requires nightly Rust. +//! # Optionally enable `try_from` and `i128_type` support on nightly Rust. //! #[dependencies.signifix] //! #features = ["nightly"] //! ``` @@ -92,7 +92,9 @@ //! and this to your crate root: //! //! ``` -//! #![feature(try_from)] // Until stabilized. Requires nightly Rust. +//! // Optionally enable `try_from` and `i128_type` support on nightly Rust. +//! // Required if the `nightly` feature is enabled in your `Cargo.toml`. +//! //#![feature(try_from, i128_type)] //! //! extern crate signifix; //! ``` @@ -105,8 +107,8 @@ //! jumps to the left or right while making maximum use of their occupied space: //! //! ``` -//! # #![feature(try_from)] -//! use std::convert::TryFrom; // Until stabilized. +//! # #![cfg_attr(feature = "nightly", feature(try_from, i128_type))] +//! use signifix::TryFrom; // Until stabilized. //! //! use signifix::{metric, binary, Result}; //! @@ -161,8 +163,8 @@ //! This is useful to smoothly refresh a transfer rate within a terminal: //! //! ``` -//! # #![feature(try_from)] -//! use std::convert::TryFrom; // Until stabilized. +//! # #![cfg_attr(feature = "nightly", feature(try_from, i128_type))] +//! use signifix::TryFrom; // Until stabilized. //! //! use std::f64; //! use std::time::Duration; @@ -212,8 +214,8 @@ //! direction with positive numbers being padded to align with negative ones: //! //! ``` -//! # #![feature(try_from)] -//! use std::convert::TryFrom; // Until stabilized. +//! # #![cfg_attr(feature = "nightly", feature(try_from, i128_type))] +//! use signifix::TryFrom; // Until stabilized. //! //! use signifix::metric::{Signifix, Result, DEF_MAX_LEN}; //! @@ -237,8 +239,8 @@ //! positive numbers: //! //! ``` -//! # #![feature(try_from)] -//! use std::convert::TryFrom; // Until stabilized. +//! # #![cfg_attr(feature = "nightly", feature(try_from, i128_type))] +//! use signifix::TryFrom; // Until stabilized. //! //! use signifix::metric::{Signifix, Error, Result}; //! @@ -259,8 +261,8 @@ //! of powers of two, such as memory boundaries due to binary addressing: //! //! ``` -//! # #![feature(try_from)] -//! use std::convert::TryFrom; // Until stabilized. +//! # #![cfg_attr(feature = "nightly", feature(try_from, i128_type))] +//! use signifix::TryFrom; // Until stabilized. //! //! use signifix::binary::{Signifix, Error, Result}; //! @@ -300,8 +302,8 @@ //! `Signifix::fmt()` method: //! //! ``` -//! # #![feature(try_from)] -//! use std::convert::TryFrom; // Until stabilized. +//! # #![cfg_attr(feature = "nightly", feature(try_from, i128_type))] +//! use signifix::TryFrom; // Until stabilized. //! //! use signifix::binary::{Signifix, Result}; //! @@ -345,8 +347,8 @@ //! type via its methods: //! //! ``` -//! # #![feature(try_from)] -//! use std::convert::TryFrom; // Until stabilized. +//! # #![cfg_attr(feature = "nightly", feature(try_from, i128_type))] +//! use signifix::TryFrom; // Until stabilized. //! //! use signifix::metric::{Signifix, Result}; //! @@ -388,9 +390,7 @@ #![deny(missing_docs)] -#![cfg_attr(feature = "nightly", feature(i128_type))] - -#![feature(try_from)] +#![cfg_attr(feature = "nightly", feature(try_from, i128_type))] use std::result; use std::error; @@ -400,6 +400,39 @@ use std::fmt::{Display, Formatter}; use std::cmp::Ordering; +#[cfg(feature = "nightly")] +pub use std::convert::{TryInto, TryFrom}; + +/// An attempted conversion that consumes `self`, which may or may not be +/// expensive. +#[cfg(not(feature = "nightly"))] +pub trait TryInto: Sized { + /// The type returned in the event of a conversion error. + type Error; + + /// Performs the conversion. + fn try_into(self) -> result::Result; +} + +/// Attempt to construct `Self` via a conversion. +#[cfg(not(feature = "nightly"))] +pub trait TryFrom: Sized { + /// The type returned in the event of a conversion error. + type Error; + + /// Performs the conversion. + fn try_from(value: T) -> result::Result; +} + +#[cfg(not(feature = "nightly"))] +impl TryInto for T where U: TryFrom { + type Error = U::Error; + + fn try_into(self) -> result::Result { + U::try_from(self) + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] struct Signifix { numerator: i16, @@ -425,33 +458,26 @@ impl Signifix { fn significand(&self) -> f64 { self.numerator() as f64 * [1E-00, 1E-01, 1E-02, 1E-03][self.exponent()] } - fn numerator(&self) -> i32 { self.numerator.into() } - fn denominator(&self) -> i32 { [1, 10, 100, 1_000][self.exponent()] } - fn exponent(&self) -> usize { self.exponent.into() } - fn integer(&self) -> i32 { self.numerator() / self.denominator() } - fn fractional(&self) -> i32 { self.numerator().abs() % self.denominator() } - fn parts(&self) -> (i32, i32) { let trunc = self.numerator() / self.denominator(); let fract = self.numerator() - self.denominator() * trunc; (trunc, fract.abs()) } - fn prefix(&self) -> usize { self.prefix.into() } diff --git a/src/metric.rs b/src/metric.rs index 1cf5b30..78b9457 100644 --- a/src/metric.rs +++ b/src/metric.rs @@ -6,7 +6,7 @@ // // DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. -use std::convert::TryFrom; +use super::TryFrom; use std::result; use std::error;