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
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::format::{Format, Locale};
fn main() { let format = Locale::en; asserteq!(format.decimal(), '.');; asserteq!(format.minussign(), "-"); asserteq!(format.separator(), Some(',')) // ... } ```
Environment
The [Environment
] type allows you to access your system's locale settings via the LC_ALL
environment variable.
If you're familiar with C, it pulls system information using the [setlocale
] and [localeconv
] functions in the C
standard library. For more details, see [Environment
].
CustomFormat
Allows for the creation of your own, custom format. For more details, see [CustomFormat
].
Once you have selected a format, you can turn number types into formatted string representations via any of three principle APIs...
ToFormattedString
Using the [ToFormattedString
] trait is the simplist API, just call [to_formatted_string
] on a type that implements
it (all the number types in the standard library implement it) with a desired format. 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 numformat::ToFormattedString; use numformat::format::Locale;
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 number types in the standard library, it is not available
for third party types like [num_bigint::BigInt
] since their maximum size cannot be known in advance.
```rust use numformat::Buffer; use numformat::format::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);
assert_eq!(buf.as_str(), "1,000,000");
} ```
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 it, such as [Vec
], [String
], [File
], etc.).
If you're writing a number type that can use the [Buffer
] API (e.g. any number type in the standard library), there
is no heap allocation. That said, you can also use this API with types where the [Buffer
] API will not work, like
[num_bigint::BigInt
], in which case there will be heap allocations used. This trait is not available
in a no_std
environment.
```rust use numformat::WriteFormatted; use numformat::format::Locale;
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");
} ```
| Available features | What to put in your Cargo.toml
|
| :----------------- | :------------------------------------------------------------ |
| no_std
| num-format = { version = "0.1", default-features = false }
|
| num-bigint
| num-format = { version = "0.1", features = ["num-bigint"] }
|
| serde
| num-format = { version = "0.1", features = ["with-serde"] }
|
num-format is licensed under either of:
at your option.