Skip to main content

perspective_viewer/utils/
number_format.rs

1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
3// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
4// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
5// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
6// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
8// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9// ┃ This file is part of the Perspective library, distributed under the terms ┃
10// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13use std::sync::LazyLock;
14
15use js_sys::Intl;
16use perspective_js::json;
17use perspective_js::utils::global::navigator;
18use wasm_bindgen::JsValue;
19
20struct UnsafeNumberFormat(Intl::NumberFormat);
21
22// JavaScript does not allow threading, but we do not have a non-threadsafe
23// way to conveniently make lazy static caches of JavaScript ref values.
24unsafe impl Send for UnsafeNumberFormat {}
25unsafe impl Sync for UnsafeNumberFormat {}
26
27static NUMBER_FORMAT: LazyLock<UnsafeNumberFormat> = LazyLock::new(|| {
28    let locale = navigator().languages();
29    let opts = json!({});
30    let number_format = Intl::NumberFormat::new(&locale, &opts);
31    UnsafeNumberFormat(number_format)
32});
33
34impl UnsafeNumberFormat {}
35
36/// Trait for the [`u32::to_formatted_string`] method.
37#[extend::ext]
38pub impl u32 {
39    /// Format integers consistenly using the Browser's native `NumberFormat`.
40    fn to_formatted_string(&self) -> String {
41        NUMBER_FORMAT
42            .0
43            .format()
44            .call1(&NUMBER_FORMAT.0, &JsValue::from_f64(*self as f64))
45            .unwrap()
46            .as_string()
47            .unwrap()
48    }
49}