num-format

Crates.io Documentation License

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

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.

```rust use num_format::{Locale, ToFormattedString};

fn main() { let s = 1000000.toformattedstring(&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.

```rust 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.

```rust 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.

```rust use num_format::{Grouping, Locale};

fn main() { let locale = Locale::en; asserteq!(locale.grouping(), Grouping::Standard); asserteq!(locale.minussign(), "-"); asserteq!(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.3", features = ["with-system-locale"] } in your Cargo.toml. Additionally, on Windows (but only on Windows), using SystemLocale requires Clang 3.9 or higher.

```rust 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.

```rust 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

Extra features

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

License

num-format is licensed under either of:

at your option.