Crate num_format
source · [−]Expand description
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.2", 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-localefeature 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.2", default-features = false } |
with-num-bigint | num-format = { version = "0.4.2", features = ["with-num-bigint"] } |
with-serde | num-format = { version = "0.4.2", features = ["with-serde"] } |
with-system-locale | num-format = { version = "0.4.2", features = ["with-system-locale"] } |
License
num-format is licensed under either of:
at your option.
Modules
Structs
&str without heap allocation.Format.CustomFormats.Enums
Format.Traits
Buffer).to_formatted_string method.io::Write
or fmt::Write, such as &mut [u8] and &mut String, a write_formatted method for writing
formatted numbers.