MCPcopy Index your code
hub / github.com/bcmyers/num-format

github.com/bcmyers/num-format @v0.4.4

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.4.4 ↗ · + Follow
194 symbols 510 edges 47 files 50 documented · 26%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

num-format

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.3", 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.56.0 or greater if compiled with --no-default-features
  • Rust 1.58.0 or greater if compiled with default features
  • 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.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.

Extension points exported contracts — how you extend this code

WriteFormatted (Interface)
A key trait . Gives types in the standard library that implement [`io::Write`] or [`fmt::Write`], such as ` [41 implementers]
num-format/src/write_formatted.rs
Sealed (Interface)
(no doc) [20 implementers]
num-format/src/lib.rs
Format (Interface)
Trait that abstracts over [`CustomFormat`], [`Locale`], and `SystemLocale`. [`CustomFormat`]: struct.CustomFormat.html [3 …
num-format/src/format.rs
ToFormattedString (Interface)
A key trait . Gives numbers the [`to_formatted_string`] method. This trait is sealed; so you may not imple [3 implementers]
num-format/src/to_formatted_string.rs
ToFormattedStr (Interface)
Marker trait for number types that can be formatted without heap allocation (see [`Buffer`]). This trait is sealed; so [2 …
num-format/src/to_formatted_str.rs

Core symbols most depended-on inside this repo

new
called by 226
num-format/src/system_locale/nix.rs
write_formatted
called by 49
num-format/src/buffer.rs
to_string
called by 30
num-format/src/system_locale/nix.rs
as_bytes
called by 15
num-format/src/buffer.rs
len
called by 15
num-format/src/buffer.rs
as_ref
called by 12
num-format/src/buffer.rs
get_locale_info_ex
called by 8
num-format/src/system_locale/windows.rs
separator
called by 6
num-format/src/locale.rs

Shape

Method 96
Function 68
Class 18
Interface 7
Enum 5

Languages

Rust99%
Python1%

Modules by API surface

num-format/src/buffer.rs21 symbols
num-format/src/system_locale.rs16 symbols
num-format/src/error.rs13 symbols
num-format/src/custom_format.rs13 symbols
num-format/src/locale.rs12 symbols
num-format/src/custom_format_builder.rs12 symbols
num-format/src/system_locale/windows.rs10 symbols
num-format/src/system_locale/nix.rs10 symbols
num-format/src/strings.rs7 symbols
num-format/tests/test_unsigned.rs6 symbols
num-format/tests/test_signed.rs6 symbols
num-format/tests/test_non_zero.rs6 symbols

For agents

$ claude mcp add num-format \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact