Giter Site home page Giter Site logo

wumms / num-format Goto Github PK

View Code? Open in Web Editor NEW

This project forked from bcmyers/num-format

0.0 1.0 0.0 367 KB

A Rust crate for producing string representations of numbers, formatted according to international standards

License: Apache License 2.0

Rust 99.45% C++ 0.01% Shell 0.45% Python 0.09%

num-format's Introduction

num-format

Build Status Crates.io Documentation License

A Rust crate for producing string representations of numbers, formatted according to international standards, e.g.

  • "1,000,000" for US English
  • "10,00,000" for Indian English
  • "1 000 000" for French French

Creating a string representation

num-format offers three principal APIs...

ToFormattedString

The ToFormattedString trait is the simplist of the three APIs. Just call to_formatted_string on a type that implements it (all the integer types in the standard library implement it) while providing a desired format (see picking a format below). That said, using ToFormattedString will always heap allocate; so it is the slowest of the three APIs and cannot be used in a no_std environment.

use num_format::{Locale, ToFormattedString};

fn main() {
    let s = 1000000.to_formatted_string(&Locale::en);
    assert_eq!(&s, "1,000,000");
}

Buffer

Using the Buffer type is the fastest API, as it does not heap allocate. Instead, the formatted representation is written into a stack-allocated buffer. As such, you can use it in a no_std environment.

Although this API is available for all the integer types in the standard library, it is not available for types like num_bigint::BigInt whose maximum size cannot be known in advance.

use num_format::{Buffer, Locale};

fn main() {
    // Create a stack-allocated buffer...
    let mut buf = Buffer::default();

    // Write "1,000,000" into the buffer...
    buf.write_formatted(&1000000, &Locale::en);

    // Get a view into the buffer as a &str...
    let s = buf.as_str();

    // Do what you want with the &str...
    assert_eq!("1,000,000", s);
}

WriteFormatted

The WriteFormatted trait is in between the other two APIs. You can write a formatted representation into any type that implements WriteFormatted (all the types in the standard library that implement io::Write or fmt::Write implement WriteFormatted, such as Vec, String, File, etc.).

If you're writing a number type that can use the Buffer API, there is no heap allocation. That said, the io::Write and fmt::Write machinery adds a bit of overhead; so it's faster to use the Buffer type directly. This trait is not available in a no_std environment.

use num_format::{Locale, WriteFormatted};

fn main() {
    // Create a writer...
    let mut writer = String::new(); // Could also be Vec::new(), File::open(...), ...

    // Write "1,000,000" into the writer...
    writer.write_formatted(&1000000, &Locale::en);

    assert_eq!(&writer, "1,000,000");
}

Picking a format

Formatting options (e.g. which thousands separator to use, what the minus sign looks like, etc.) are represented by the Format trait. This crate offers three concrete implementations of the Format trait...

Locale

The Locale type is a programatically generated enum representing formatting standards from the Common Locale Data Repository, which is maintained by the Unicode Consortium and used by Apple in macOS and iOS, by LibreOffice, by IBM in AIX, among others.

use num_format::{Grouping, Locale};

fn main() {
    let locale = Locale::en;
    assert_eq!(locale.grouping(), Grouping::Standard);
    assert_eq!(locale.minus_sign(), "-");
    assert_eq!(locale.name(), "en");
    assert_eq!(locale.separator(), ",");

    let locale2 = Locale::from_name("en").unwrap();
    assert_eq!(locale, locale2);

    let available = Locale::available_names();
    println!("All of the locale names available in the Unicode database are...");
    println!("{:#?}", available);
}

SystemLocale (available behind feature flag with-system-locale)

The SystemLocale type is another type that implements Format. It allows you to access your OS's locale information. It has a very similar API to Locale and should work on all major operating systems (i.e. macOS, linux, the BSDs, and Windows).

Since this type requires several dependencies (especially on Windows), it is behind a feature flag. To use it, include num-format = { version = "0.4", features = ["with-system-locale"] } in your Cargo.toml. Additionally, on Windows (but only on Windows), using SystemLocale requires Clang 3.9 or higher.

use num_format::SystemLocale;

fn main() {
    let locale = SystemLocale::default().unwrap();
    println!("My system's default locale is...");
    println!("{:#?}", &locale);

    let available = SystemLocale::available_names().unwrap();
    println!("My available locale names are...");
    println!("{:#?}", available);

    match SystemLocale::from_name("en_US") {
        Ok(_) => println!("My system has the 'en_US' locale."),
        Err(_) => println!("The 'en_US' locale is not included with my system."),
    }
}

CustomFormat

CustomFormat is the third and final type that implements Format. You can use it to build your own custom formats.

use num_format::{Buffer, Error, CustomFormat, Grouping};

fn main() -> Result<(), Error> {
    let format = CustomFormat::builder()
        .grouping(Grouping::Indian)
        .minus_sign("๐Ÿ™Œ")
        .separator("๐Ÿ˜€")
        .build()?;

    let mut buf = Buffer::new();
    buf.write_formatted(&(-1000000), &format);
    assert_eq!("๐Ÿ™Œ10๐Ÿ˜€00๐Ÿ˜€000", buf.as_str());

    Ok(())
}

Requirements

  • Rust 1.31 or greater
  • If you're using the with-system-locale feature and you're on Windows, Clang 3.9 or higher is also required. See here for installation instructions.

Extra features

Available features What to put in your Cargo.toml
no_std num-format = { version = "0.4", default-features = false }
with-num-bigint num-format = { version = "0.4", features = ["with-num-bigint"] }
with-serde num-format = { version = "0.4", features = ["with-serde"] }
with-system-locale num-format = { version = "0.4", features = ["with-system-locale"] }

License

num-format is licensed under either of:

at your option.

num-format's People

Contributors

bcmyers avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.