human_format-1.0.3/.github/ISSUE_TEMPLATE.md000064400000000000000000000005651323350316000164300ustar0000000000000000## Summary of Issue or Feature _Please include a detailed description of the issue or feature._ _Mockups and examples should be used wherever relevant_ ### Reproduction Steps 1. Include dependency 2. ... ## Logs & Source Code _Please attach all relevant logs & source code_ _If possible, please provide an [MCVE](https://stackoverflow.com/help/mcve)_ human_format-1.0.3/.github/PULL_REQUEST_TEMPLATE.md000064400000000000000000000012251323350316000175160ustar0000000000000000## Overview This PR proposes... _provide a detailed explanation of the PR_ ## Test Cases & Validation Steps ## TODO - [ ] run `cargo test` and have 0 failed or skipped test cases - [ ] run `cargo fmt` and have 0 modified files - [ ] merge `develop` and validate that it no features are broken - [ ] document new public API - [ ] provide new test cases for any new/modified behavior - [ ] adhere to project standards & practices ## Further Enhancements _Here is an opportunity for you to provide some feedback on the PR to take it to the next level. These elements may become new issues in the backlog that may grow into their own PRs!_human_format-1.0.3/.gitignore000064400000000000000000000004751323501130600143510ustar0000000000000000# Generated by Cargo # will have compiled files and executables /target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk human_format-1.0.3/.travis.yml000064400000000000000000000016421323501130600144670ustar0000000000000000sudo: false language: rust cache: cargo: true directories: - $HOME/deps notifications: webhooks: urls: - https://webhooks.gitter.im/e/4fd67aa92c02652d2c36 on_success: always # options: [always|never|change] default: always on_failure: always # options: [always|never|change] default: always on_start: always # options: [always|never|change] default: always matrix: include: - os: linux rust: stable compiler: gcc - os: linux rust: beta compiler: gcc - os: linux rust: nightly compiler: gcc - os: osx rust: stable osx_image: xcode9 compiler: clang - os: osx rust: beta osx_image: xcode9 compiler: clang - os: osx rust: nightly osx_image: xcode9 compiler: clang script: - cargo test --verbose - cargo build --release --verbose --allhuman_format-1.0.3/appveyor.yml000064400000000000000000000034031323501130600147430ustar0000000000000000environment: global: PROJECT_NAME: human_readable matrix: # Stable channel - TARGET: i686-pc-windows-gnu CHANNEL: stable - TARGET: i686-pc-windows-msvc CHANNEL: stable - TARGET: x86_64-pc-windows-gnu CHANNEL: stable - TARGET: x86_64-pc-windows-msvc CHANNEL: stable # Beta channel - TARGET: i686-pc-windows-gnu CHANNEL: beta - TARGET: i686-pc-windows-msvc CHANNEL: beta - TARGET: x86_64-pc-windows-gnu CHANNEL: beta - TARGET: x86_64-pc-windows-msvc CHANNEL: beta # Nightly channel - TARGET: i686-pc-windows-gnu CHANNEL: nightly - TARGET: i686-pc-windows-msvc CHANNEL: nightly - TARGET: x86_64-pc-windows-gnu CHANNEL: nightly - TARGET: x86_64-pc-windows-msvc CHANNEL: nightly # Install Rust and Cargo # (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml) install: - curl -sSf -o rustup-init.exe https://win.rustup.rs - rustup-init.exe --default-host %TARGET% --default-toolchain %CHANNEL% -y - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - rustc -Vv - cargo -V # 'cargo test' takes care of building for us, so disable Appveyor's build stage. This prevents # the "directory does not contain a project or solution file" error. # source: https://github.com/starkat99/appveyor-rust/blob/master/appveyor.yml#L113 build: false # Equivalent to Travis' `script` phase # TODO modify this phase as you see fit test_script: - cargo test --verbose - cargo build --release --verbose --all notifications: - provider: Webhook url: https://webhooks.gitter.im/e/32d2a5e895aa632a5754 method: GET cache: - target - C:\Users\appveyor\.cargo\registryhuman_format-1.0.3/Cargo.toml.orig000064400000000000000000000015061356635567300152750ustar0000000000000000[package] name = "human_format" version = "1.0.3" authors = ["Bob Chatman "] license = "MIT" description = "Rust Port of human-format from node, formatting numbers for us, while the machines are still at bay." homepage = "https://github.com/BobGneu/human-format-rs" repository = "https://github.com/BobGneu/human-format-rs" documentation = "https://docs.rs/human_format" readme = "README.md" license-file = "LICENSE" keywords = ["numbers", "formatting", "filesize", "human", "magnitude"] categories = ["value-formatting", "no-std"] [lib] name = "human_format" path = "src/lib.rs" [badges] travis-ci = { repository = "BobGneu/human-format-rs" } appveyor = { repository = "BobGneu/human-format-rs" } maintenace = { status = "actively-developed" } [dev-dependencies] galvanic-test = "0.1.3"human_format-1.0.3/Cargo.toml0000644000000025030000000000000115520ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "human_format" version = "1.0.3" authors = ["Bob Chatman "] description = "Rust Port of human-format from node, formatting numbers for us, while the machines are still at bay." homepage = "https://github.com/BobGneu/human-format-rs" documentation = "https://docs.rs/human_format" readme = "README.md" keywords = ["numbers", "formatting", "filesize", "human", "magnitude"] categories = ["value-formatting", "no-std"] license = "MIT" license-file = "LICENSE" repository = "https://github.com/BobGneu/human-format-rs" [lib] name = "human_format" path = "src/lib.rs" [dev-dependencies.galvanic-test] version = "0.1.3" [badges.appveyor] repository = "BobGneu/human-format-rs" [badges.maintenace] status = "actively-developed" [badges.travis-ci] repository = "BobGneu/human-format-rs" human_format-1.0.3/changelog.md000064400000000000000000000023151356635567300146560ustar0000000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] ## [1.0.3] - 2019-11-23 ### Fixed - Removed unnecessary logging - [PR#9](https://github.com/BobGneu/human-format-rs/pull/9) by [@jaysonsantos](https://github.com/jaysonsantos) - Corrected binary base to 1024 ## [1.0.2] - 2018-02-01 ### Fixed - Corrected issue with API, expecting owned strings when the common occurance will be references. ## [1.0.1] - 2018-01-28 ### Added - Updated Documentation to improve utility of [docs.rs](https://docs.rs/crate/human_format/) - Added fmt to build scripts ## [1.0.0] - 2018-01-28 Initial Release [unreleased]: https://github.com/BobGneu/human-format-rs/compare/master...develop [1.0.3]: https://github.com/BobGneu/human-format-rs/compare/1.0.2...1.0.3 [1.0.2]: https://github.com/BobGneu/human-format-rs/compare/1.0.1...1.0.2 [1.0.1]: https://github.com/BobGneu/human-format-rs/compare/1.0.0...1.0.1 [1.0.0]: https://github.com/BobGneu/human-format-rs/tree/1.0.0 human_format-1.0.3/LICENSE000064400000000000000000000021011323501130600133520ustar0000000000000000MIT License Copyright (c) 2018 Bob Chatman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. human_format-1.0.3/README.md000064400000000000000000000052001323501130600136270ustar0000000000000000# human-format-rs [![Crates.io](https://img.shields.io/crates/v/human_format.svg)](https://crates.io/crates/human_format) [![Documentation](https://img.shields.io/badge/docs-rs-red.svg)](https://docs.rs/human_format) Rust Port of human-format from node, formatting numbers for us, while the machines are still at bay. | Branch | Linux/MacOS | Windows | | :-- | :--: | :--: | | Master | [![Build Status](https://travis-ci.org/BobGneu/human-format-rs.svg?branch=master)](https://travis-ci.org/BobGneu/human-format-rs) | [![Build status](https://ci.appveyor.com/api/projects/status/jarar20r4wucmmec/branch/master?svg=true)](https://ci.appveyor.com/project/BobGneu/human-format-rs/branch/master) | | Develop | [![Build Status](https://travis-ci.org/BobGneu/human-format-rs.svg?branch=develop)](https://travis-ci.org/BobGneu/human-format-rs) | [![Build status](https://ci.appveyor.com/api/projects/status/jarar20r4wucmmec/branch/develop?svg=true)](https://ci.appveyor.com/project/BobGneu/human-format-rs/branch/develop) | ## What is human_format? The primary purpose for this crate is to format numbers in a customizable fashion based around magnitudes. It is inspired by the [human-format](https://www.npmjs.com/package/human-format) package and the hope is to ultimately provide an idiomatic rust port. ## Usage 1. Add this package as a dependency ```toml [dependencies] human_format = "0.2" ``` 2. Add the crate reference at your crate root ```rust extern crate human_format; ``` 3. Print some human readable strings ## Examples ```rust // 1.00 k Formatter::new() .format(1000 as f64)); // 1.34 k Formatter::new() .with_decimals(2) .format(1337 as f64); // 1.3 k Formatter::new() .with_decimals(1) .format(1337 as f64); // 1.3B Formatter::new() .with_decimals(1) .with_separator("") .format(1337000000 as f64); // 1.00 - k Formatter::new() .with_separator(" - ") .format(1000 as f64); // Define your own scales as you see fit let mut custom_binary_scales = Scales::new(); custom_binary_scales .with_base(1000) .with_suffixes(["".to_owned(),"k".to_owned(), "M".to_owned(), "G".to_owned(), "T".to_owned(), "P".to_owned(), "E".to_owned(), "Z".to_owned(), "Y".to_owned()].to_vec()); // 1.00 kB Formatter::new() .with_scales(custom_binary_scales) .with_units("B") .format(1000 as f64); // 1.00 kiB Formatter::new() .with_scales(Scales::Binary()) .with_units("B") .format(1000 as f64); ``` For more examples please consult [tests/demo.rs](https://github.com/BobGneu/human-format-rs/blob/master/tests/demo.rs) human_format-1.0.3/src/lib.rs000064400000000000000000000144671356635567300143230ustar0000000000000000#![doc(html_root_url = "https://docs.rs/human_format")] //! `human_format` provides facilitates creating a formatted string, converting between numbers that are beyond typical //! needs for humans into a simpler string that conveys the gist of the meaning of the number. //! //! ## Setup //! //! Add the library to your dependencies listing //! //! ```toml //! [dependencies] //! human_format = "0.2" //! ``` //! //! Add the crate reference at your crate root //! //! ```rust //! extern crate human_format; //! ``` //! //! Print some human readable strings //! //! ```rust //! // "1.00 k" //! let tmpStr = human_format::Formatter::new() //! .format(1000.0); //! # assert_eq!(tmpStr, "1.00 k"); //! //! // "1.00 M" //! let tmpStr2 = human_format::Formatter::new() //! .format(1000000.0); //! # assert_eq!(tmpStr2, "1.00 M"); //! //! // "1.00 B" //! let tmpStr3 = human_format::Formatter::new() //! .format(1000000000.0); //! # assert_eq!(tmpStr3, "1.00 B"); //! ``` //! //! If you are so inspired you can even try playing with units and customizing your `Scales` //! //! For more examples you should review the examples on github: [tests/demo.rs](https://github.com/BobGneu/human-format-rs/blob/master/tests/demo.rs) //! #[derive(Debug)] struct ScaledValue { value: f32, suffix: String, } /// Entry point to the lib. Use this to handle your formatting needs. #[derive(Debug)] pub struct Formatter { decimals: usize, separator: String, scales: Scales, forced_units: String, forced_suffix: String, } /// Provide a customized scaling scheme for your own modeling. #[derive(Debug)] pub struct Scales { base: u32, suffixes: Vec, } impl Formatter { /// Initializes a new `Formatter` with default values. pub fn new() -> Self { Formatter { decimals: 2, separator: " ".to_owned(), scales: Scales::SI(), forced_units: "".to_owned(), forced_suffix: "".to_owned(), } } /// Sets the decimals value for formatting the string. pub fn with_decimals(&mut self, decimals: usize) -> &mut Self { self.decimals = decimals; self } /// Sets the separator value for formatting the string. pub fn with_separator(&mut self, separator: &str) -> &mut Self { self.separator = separator.to_owned(); self } /// Sets the scales value. pub fn with_scales(&mut self, scales: Scales) -> &mut Self { self.scales = scales; self } /// Sets the units value. pub fn with_units(&mut self, units: &str) -> &mut Self { self.forced_units = units.to_owned(); self } /// Sets the expected suffix value. pub fn with_suffix(&mut self, suffix: &str) -> &mut Self { self.forced_suffix = suffix.to_owned(); self } /// Formats the number into a string pub fn format(&self, value: f64) -> String { if value < 0.0 { return format!("-{}", self.format(value * -1.0)); } let scaled_value = self.scales.to_scaled_value(value); format!( "{:.width$}{}{}{}", scaled_value.value, self.separator, scaled_value.suffix, self.forced_units, width = self.decimals ) } /// Parse a string back into a float value. pub fn parse(&self, value: &str) -> f64 { let v: Vec<&str> = value.split(&self.separator).collect(); let result = v.get(0).unwrap().parse::().unwrap(); let mut suffix = v.get(1).unwrap().to_string(); let new_len = suffix.len() - self.forced_units.len(); suffix.truncate(new_len); let magnitude_multiplier = self.scales.get_magnitude_multipler(&suffix); (result * magnitude_multiplier) } } impl Scales { /// Instantiates a new `Scales` with SI keys pub fn new() -> Self { Scales::SI() } /// Instantiates a new `Scales` with SI keys pub fn SI() -> Self { Scales { base: 1000, suffixes: vec![ "".to_owned(), "k".to_owned(), "M".to_owned(), "B".to_owned(), "T".to_owned(), "P".to_owned(), "E".to_owned(), "Z".to_owned(), "Y".to_owned(), ], } } /// Instantiates a new `Scales` with Binary keys pub fn Binary() -> Self { Scales { base: 1024, suffixes: vec![ "".to_owned(), "Ki".to_owned(), "Mi".to_owned(), "Gi".to_owned(), "Ti".to_owned(), "Pi".to_owned(), "Ei".to_owned(), "Zi".to_owned(), "Yi".to_owned(), ], } } /// Sets the base for the `Scales` pub fn with_base(&mut self, base: u32) -> &mut Self { self.base = base; self } /// Sets the suffixes listing appropriately pub fn with_suffixes(&mut self, suffixes: Vec<&str>) -> &mut Self { self.suffixes = Vec::new(); for suffix in suffixes { // This should be to_owned to be clear about intent. // https://users.rust-lang.org/t/to-string-vs-to-owned-for-string-literals/1441/6 self.suffixes.push(suffix.to_owned()); } self } fn get_magnitude_multipler(&self, value: &str) -> f64 { for ndx in 0..self.suffixes.len() { if value == self.suffixes[ndx] { return self.base.pow(ndx as u32) as f64; } } return 0.0; } fn to_scaled_value(&self, value: f64) -> ScaledValue { let mut index: usize = 0; let mut _value: f64 = value; loop { if _value < (self.base as f64) { break; } _value /= self.base as f64; index += 1; } ScaledValue { value: (value / self.base.pow((index) as u32) as f64) as f32, suffix: self.suffixes[index].to_owned(), } } } human_format-1.0.3/tests/demo.rs000064400000000000000000000052251356635567300150440ustar0000000000000000#[macro_use] extern crate galvanic_test; extern crate human_format; test_suite! { name demo_examples; use human_format::*; test should_allow_use_of_si_scale_implicitly() { assert_eq!(Formatter::new() .format(1000 as f64), "1.00 k"); } test should_allow_explicit_decimals() { assert_eq!(Formatter::new() .with_decimals(1) .format(1000 as f64), "1.0 k"); } test should_allow_explicit_separator() { assert_eq!(Formatter::new() .with_separator(" - ") .format(1000 as f64), "1.00 - k"); } test should_allow_use_of_si_scale_explicitly() { assert_eq!(Formatter::new() .with_scales(Scales::SI()) .format(1000 as f64), "1.00 k"); } test should_allow_use_of_binary_scale_explicitly() { assert_eq!(Formatter::new() .with_scales(Scales::Binary()) .format(1024 as f64), "1.00 Ki"); } test should_allow_use_of_binary_units_explicitly() { assert_eq!(Formatter::new() .with_scales(Scales::Binary()) .with_units("B") .format(102400 as f64), "100.00 KiB"); } test should_output_10_24MiB() { assert_eq!(Formatter::new() .with_scales(Scales::Binary()) .with_units("B") .format(1024.0 * 1024.0 as f64), "1.00 MiB"); } test should_allow_explicit_suffix_and_unit() { assert_eq!(Formatter::new() .with_suffix("k") .with_units("m") .format(1024 as f64), "1.02 km"); } test should_allow_use_of_explicit_scale() { let mut scales = Scales::new(); scales .with_base(1024) .with_suffixes(vec!["","Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"]); assert_eq!(Formatter::new() .with_scales(scales) .with_units("B") .format(1024 as f64), "1.00 KiB"); } test should_allow_parsing_to_f64() { assert_eq!(Formatter::new() .parse("1.00 k"), 1000.0); } test should_allow_parsing_binary_values_to_f64() { assert_eq!(Formatter::new() .with_scales(Scales::Binary()) .parse("1.00 Ki"), 1024.0); } test should_allow_parsing_binary_values_with_units_to_f64() { assert_eq!(Formatter::new() .with_scales(Scales::Binary()) .with_units("B") .parse("1.00 KiB"), 1024.0); } } human_format-1.0.3/.cargo_vcs_info.json0000644000000001120000000000000135460ustar00{ "git": { "sha1": "db926220a8e752230d984f580a13966ae19cbc7a" } }