num-format-0.4.0/Cargo.toml.orig010064400007650000024000000035751343310555500147240ustar0000000000000000[package] name = "num-format" version = "0.4.0" # Remember to keep html_root_url in lib.rs in sync! authors = ["Brian Myers "] categories = ["encoding", "internationalization", "localization", "no-std", "value-formatting"] description = "A Rust crate for producing string-representations of numbers, formatted according to international standards" documentation = "https://docs.rs/num-format" edition = "2018" homepage = "https://github.com/bcmyers/num-format" keywords = ["comma", "internationalization", "number", "separator", "thousands"] license = "MIT/Apache-2.0" publish = true readme = "README.md" repository = "https://github.com/bcmyers/num-format" [badges] maintenance = { status = "actively-developed" } travis-ci = { repository = "bcmyers/num-format", branch = "master" } [dependencies] arrayvec = { version = "0.4", default-features = false } itoa = { version = "0.4", default-features = false, features = ["i128"] } lazy_static = { version = "1.2", optional = true } num-bigint = { version = "0.2", optional = true } serde = { version = "1.0", default-features = false, optional = true } [target.'cfg(unix)'.dependencies] cfg-if = { version = "0.1", optional = true } encoding_rs = { version = "0.8", optional = true } libc = { version = "0.2", optional = true } [target.'cfg(windows)'.dependencies] num-format-windows = { version = "0.3", optional = true } widestring = { version = "0.4", optional = true } winapi = { version = "0.3", features = ["winnls"], optional = true } [features] default = ["std"] std = ["arrayvec/default", "itoa/default", "itoa/i128"] with-serde = ["arrayvec/serde-1", "serde/derive"] with-system-locale = ["cfg-if", "encoding_rs", "lazy_static", "libc", "num-format-windows", "std", "widestring", "winapi/winnls"] with-num-bigint = ["num-bigint", "std"] [dev-dependencies] cfg-if = "0.1" lazy_static = "1.2" rand = "0.6" serde_json = "1.0" num-format-0.4.0/Cargo.toml0000644000000050520000000000000111610ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "num-format" version = "0.4.0" authors = ["Brian Myers "] publish = true description = "A Rust crate for producing string-representations of numbers, formatted according to international standards" homepage = "https://github.com/bcmyers/num-format" documentation = "https://docs.rs/num-format" readme = "README.md" keywords = ["comma", "internationalization", "number", "separator", "thousands"] categories = ["encoding", "internationalization", "localization", "no-std", "value-formatting"] license = "MIT/Apache-2.0" repository = "https://github.com/bcmyers/num-format" [dependencies.arrayvec] version = "0.4" default-features = false [dependencies.itoa] version = "0.4" features = ["i128"] default-features = false [dependencies.lazy_static] version = "1.2" optional = true [dependencies.num-bigint] version = "0.2" optional = true [dependencies.serde] version = "1.0" optional = true default-features = false [dev-dependencies.cfg-if] version = "0.1" [dev-dependencies.lazy_static] version = "1.2" [dev-dependencies.rand] version = "0.6" [dev-dependencies.serde_json] version = "1.0" [features] default = ["std"] std = ["arrayvec/default", "itoa/default", "itoa/i128"] with-num-bigint = ["num-bigint", "std"] with-serde = ["arrayvec/serde-1", "serde/derive"] with-system-locale = ["cfg-if", "encoding_rs", "lazy_static", "libc", "num-format-windows", "std", "widestring", "winapi/winnls"] [target."cfg(unix)".dependencies.cfg-if] version = "0.1" optional = true [target."cfg(unix)".dependencies.encoding_rs] version = "0.8" optional = true [target."cfg(unix)".dependencies.libc] version = "0.2" optional = true [target."cfg(windows)".dependencies.num-format-windows] version = "0.3" optional = true [target."cfg(windows)".dependencies.widestring] version = "0.4" optional = true [target."cfg(windows)".dependencies.winapi] version = "0.3" features = ["winnls"] optional = true [badges.maintenance] status = "actively-developed" [badges.travis-ci] branch = "master" repository = "bcmyers/num-format" num-format-0.4.0/LICENSE-APACHE010064400007650000024000000251171343304455300137550ustar0000000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2018 Brian Myers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. num-format-0.4.0/LICENSE-MIT010064400007650000024000000020541343304455300134600ustar0000000000000000MIT License Copyright (c) 2018 Brian Myers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. num-format-0.4.0/README.md010064400007650000024000000200071343310603000132660ustar0000000000000000# num-format [![Build Status](https://travis-ci.org/bcmyers/num-format.svg?branch=master)](https://travis-ci.org/bcmyers/num-format) [![Crates.io](https://img.shields.io/crates/v/num-format.svg)](https://crates.io/crates/num-format) [![Documentation](https://docs.rs/num-format/badge.svg)](https://docs.rs/num-format/) ![License](https://img.shields.io/crates/l/num_format.svg) 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. ```rust 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. ```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; 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", 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 * Rust 1.31 or greater * If you're using the `with-system-locale` feature **and** you're on Windows, Clang 3.9 or higher is also required. See [here](https://rust-lang.github.io/rust-bindgen/requirements.html) for installation instructions. ## Extra features | Available features | What to put in your `Cargo.toml` | | :------------------- | :-------------------------------------------------------------------- | | `no_std` | `num-format = { version = "0.4", default-features = false }` | | `with-num-bigint` | `num-format = { version = "0.4", features = ["with-num-bigint"] }` | | `with-serde` | `num-format = { version = "0.4", features = ["with-serde"] }` | | `with-system-locale` | `num-format = { version = "0.4", features = ["with-system-locale"] }` | ## License **num-format** is licensed under either of: - [The Apache License, Version 2.0], or - [The MIT license] at your option. [bindgen]: https://crates.io/crates/bindgen [`Buffer`]: https://docs.rs/num-format/0.4.0/num_format/struct.Buffer.html [Common Locale Data Repository]: https://en.wikipedia.org/wiki/Common_Locale_Data_Repository [`CustomFormat`]: https://docs.rs/num-format/0.4.0/num_format/struct.CustomFormat.html [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html [`fmt::Write`]: https://doc.rust-lang.org/std/fmt/fn.write.html [`Format`]: https://docs.rs/num-format/0.4.0/num_format/trait.Format.html [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html [`Locale`]: https://docs.rs/num-format/0.4.0/num_format/enum.Locale.html [`num_bigint::BigInt`]: https://docs.rs/num-bigint/0.2.2/num_bigint/struct.BigInt.html [picking a format]: #picking-a-format [`String`]: https://doc.rust-lang.org/std/string/struct.String.html [The Apache License, Version 2.0]: http://www.apache.org/licenses/LICENSE-2.0 [The MIT license]: http://opensource.org/licenses/MIT [`ToFormattedString`]: https://docs.rs/num-format/0.4.0/num_format/trait.ToFormattedString.html [`to_formatted_string`]: https://docs.rs/num-format/0.4.0/num_format/trait.ToFormattedString.html#method.to_formatted_string [Unicode Consortium]: https://en.wikipedia.org/wiki/Unicode_Consortium [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html [`WriteFormatted`]: https://docs.rs/num-format/0.4.0/num_format/trait.WriteFormatted.html num-format-0.4.0/README.tpl010064400007650000024000000000301343304455300134720ustar0000000000000000# {{crate}} {{readme}} num-format-0.4.0/src/buffer.rs010064400007650000024000000145271343305750000144360ustar0000000000000000use core::borrow::Borrow; use core::fmt; use core::mem; use core::ops::Deref; use core::str; use crate::constants::MAX_BUF_LEN; use crate::format::Format; use crate::to_formatted_str::ToFormattedStr; /// A key type. Represents a stack-allocated buffer you can use to get a /// formatted `&str` without heap allocation. /// /// # Example /// ``` /// 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); /// } /// ``` #[derive(Copy, Clone)] pub struct Buffer { pub(crate) inner: [u8; MAX_BUF_LEN], pub(crate) pos: usize, pub(crate) end: usize, } impl Buffer { /// Constructs a new, stack-allocated buffer. #[inline(always)] pub fn new() -> Buffer { Buffer { inner: unsafe { mem::uninitialized() }, pos: MAX_BUF_LEN, end: MAX_BUF_LEN, } } /// Returns a `&[u8]` view into the buffer. #[inline(always)] pub fn as_bytes(&self) -> &[u8] { &self.inner[self.pos..self.end] } /// Returns a `&str` view into the buffer. #[inline(always)] pub fn as_str(&self) -> &str { unsafe { str::from_utf8_unchecked(self.as_bytes()) } } /// Returns `true` if the buffer is empty; `false` otherwise. #[inline(always)] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Returns the length (in bytes) of the buffer. #[inline(always)] pub fn len(&self) -> usize { self.end - self.pos } /// Writes the provided number into the buffer using the provided format. #[inline(always)] pub fn write_formatted(&mut self, n: &N, format: &F) -> usize where F: Format, N: ToFormattedStr, { n.read_to_buffer(self, format) } #[inline(always)] pub(crate) fn as_mut_ptr(&mut self) -> *mut u8 { self.inner.as_mut_ptr() } #[inline(always)] pub(crate) fn write_with_itoa(&mut self, n: N) -> usize { let mut itoa_buf = itoa::Buffer::new(); let s = itoa_buf.format(n); let s_len = s.len(); self.pos = MAX_BUF_LEN - s_len; self.end = MAX_BUF_LEN; let dst = &mut self.inner[self.pos..self.end]; dst.copy_from_slice(s.as_bytes()); s_len } } impl AsRef for Buffer { #[inline(always)] fn as_ref(&self) -> &str { self.as_str() } } impl Borrow for Buffer { #[inline(always)] fn borrow(&self) -> &str { self.as_str() } } impl fmt::Debug for Buffer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.as_str()) } } impl Default for Buffer { /// Same as the [`new`] method. /// /// [`new`]: struct.Buffer.html#method.new #[inline(always)] fn default() -> Buffer { Buffer::new() } } impl Deref for Buffer { type Target = str; #[inline(always)] fn deref(&self) -> &Self::Target { self.as_str() } } impl fmt::Display for Buffer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.as_str()) } } #[cfg(feature = "with-serde")] mod serialization { use serde::{de, ser}; use super::*; impl ser::Serialize for Buffer { fn serialize(&self, serializer: S) -> Result where S: ser::Serializer, { serializer.serialize_bytes(self.as_bytes()) } } impl<'de> de::Deserialize<'de> for Buffer { fn deserialize(deserializer: D) -> Result where D: de::Deserializer<'de>, { struct BufferVisitor; impl<'de> de::Visitor<'de> for BufferVisitor { type Value = Buffer; fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "bytes of maximum length {}", MAX_BUF_LEN) } fn visit_seq(self, mut seq: V) -> Result where V: de::SeqAccess<'de>, { let mut inner: [u8; MAX_BUF_LEN] = unsafe { mem::uninitialized() }; let mut index = 0; while let Some(value) = seq.next_element()? { if index < MAX_BUF_LEN { inner[index] = value; index += 1; } else { return Err(de::Error::invalid_length(index, &self)); } } Ok(Buffer { inner, pos: 0, end: index, }) } } deserializer.deserialize_bytes(BufferVisitor) } } #[cfg(test)] mod tests { use arrayvec::ArrayString; use crate::constants::MAX_BUF_LEN; use crate::{Buffer, Locale}; #[test] fn test_buffer_serialization() { let mut buf = Buffer::new(); let _ = buf.write_formatted(&1_000, &Locale::en); let s = serde_json::to_string(&buf).unwrap(); assert_eq!(&s, "[49,44,48,48,48]"); } #[test] fn test_buffer_deserialization() { // should pass let buf: Buffer = serde_json::from_str("[49,44,48,48,48]").unwrap(); assert_eq!(0, buf.pos); assert_eq!(5, buf.end); assert_eq!(&[49, 44, 48, 48, 48], buf.as_bytes()); assert_eq!("1,000", buf.as_str()); // should fail let mut should_fail = ArrayString::<[u8; 1024]>::new(); should_fail.push_str("[0"); for _ in 0..MAX_BUF_LEN { should_fail.push_str(",0"); } should_fail.push(']'); let result: Result = serde_json::from_str(&should_fail); if result.is_ok() { panic!("was somehow able to deserialize bytes that were too long") } } } } num-format-0.4.0/src/constants.rs010064400007650000024000000013131343304455300151720ustar0000000000000000use crate::strings::{MAX_MIN_LEN, MAX_SEP_LEN}; // Want this to be as large as the largest possible string representation of any type // that implements ToFormattedStr, which is currently i128's Grouping::Indian representation. // The max len of an i128 formatted string is ... // 39 digits + 18 separators (each potentially 8 bytes) + 1 minus sign (potentially 8 bytes) pub(crate) const MAX_BUF_LEN: usize = 39 + 18 * MAX_SEP_LEN + MAX_MIN_LEN; pub(crate) const TABLE: &[u8] = b"\ 0001020304050607080910111213141516171819\ 2021222324252627282930313233343536373839\ 4041424344454647484950515253545556575859\ 6061626364656667686970717273747576777879\ 8081828384858687888990919293949596979899"; num-format-0.4.0/src/custom_format.rs010064400007650000024000000121271343306076200160450ustar0000000000000000use crate::strings::{ DecString, DecimalStr, InfString, InfinityStr, MinString, MinusSignStr, NanStr, NanString, PlusSignStr, PlusString, SepString, SeparatorStr, }; use crate::{CustomFormatBuilder, Format, Grouping, Locale}; /// Type for representing your own custom formats. Implements [`Format`]. /// /// # Example /// ```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(()) /// } /// ``` /// /// [`Format`]: trait.Format.html #[derive(Clone, Debug, Eq, PartialEq, Hash)] #[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] pub struct CustomFormat { pub(crate) dec: DecString, pub(crate) grp: Grouping, pub(crate) inf: InfString, pub(crate) min: MinString, pub(crate) nan: NanString, pub(crate) plus: PlusString, pub(crate) sep: SepString, } impl CustomFormat { /// Constructs a [`CustomFormatBuilder`]. /// /// [`CustomFormatBuilder`]: struct.CustomFormatBuilder.html pub fn builder() -> CustomFormatBuilder { CustomFormatBuilder::new() } /// Turns `self` into a [`CustomFormatBuilder`]. /// /// [`CustomFormatBuilder`]: struct.CustomFormatBuilder.html pub fn into_builder(self) -> CustomFormatBuilder { self.into() } /// Returns this format's representation of decimal points. pub fn decimal(&self) -> &str { &self.dec } /// Returns this format's [`Grouping`], which governs how digits are separated (see [`Grouping`]). /// /// [`Grouping`]: enum.Grouping.html pub fn grouping(&self) -> Grouping { self.grp } /// Returns this format's representation of infinity. pub fn infinity(&self) -> &str { &self.inf } /// Returns this format's representation of minus signs. pub fn minus_sign(&self) -> &str { &self.min } /// Returns this format's representation of NaN. pub fn nan(&self) -> &str { &self.nan } /// Returns this format's representation of plus signs. pub fn plus_sign(&self) -> &str { &self.plus } /// Returns this format's representation of separators. pub fn separator(&self) -> &str { &self.sep } } impl Default for CustomFormat { /// Returns a `CustomFormat` with settings equal to `Locale::en`. fn default() -> Self { Locale::en.into() } } impl Format for CustomFormat { #[inline(always)] fn decimal(&self) -> DecimalStr<'_> { DecimalStr::new(self.decimal()).unwrap() } #[inline(always)] fn grouping(&self) -> Grouping { self.grouping() } #[inline(always)] fn infinity(&self) -> InfinityStr<'_> { InfinityStr::new(self.infinity()).unwrap() } #[inline(always)] fn minus_sign(&self) -> MinusSignStr<'_> { MinusSignStr::new(self.minus_sign()).unwrap() } #[inline(always)] fn nan(&self) -> NanStr<'_> { NanStr::new(self.nan()).unwrap() } #[inline(always)] fn plus_sign(&self) -> PlusSignStr<'_> { PlusSignStr::new(self.plus_sign()).unwrap() } #[inline(always)] fn separator(&self) -> SeparatorStr<'_> { SeparatorStr::new(self.separator()).unwrap() } } impl From for CustomFormat { fn from(locale: Locale) -> Self { Self { dec: DecString::new(locale.decimal()).unwrap(), grp: locale.grouping(), inf: InfString::new(locale.infinity()).unwrap(), min: MinString::new(locale.minus_sign()).unwrap(), nan: NanString::new(locale.nan()).unwrap(), plus: PlusString::new(locale.plus_sign()).unwrap(), sep: SepString::new(locale.separator()).unwrap(), } } } #[cfg(all(feature = "with-system-locale", any(unix, windows)))] mod system { use super::*; use crate::SystemLocale; impl From for CustomFormat { fn from(locale: SystemLocale) -> Self { Self { dec: DecString::new(locale.decimal()).unwrap(), grp: locale.grouping(), inf: InfString::new(locale.infinity()).unwrap(), min: MinString::new(locale.minus_sign()).unwrap(), nan: NanString::new(locale.nan()).unwrap(), plus: PlusString::new(locale.plus_sign()).unwrap(), sep: SepString::new(locale.separator()).unwrap(), } } } } #[cfg(all(test, feature = "with-serde"))] mod tests { use super::*; #[test] fn test_serialization() { let locale = CustomFormat::builder().build().unwrap(); let s = serde_json::to_string(&locale).unwrap(); let expected = r#"{"dec":".","grp":"Standard","inf":"∞","min":"-","nan":"NaN","plus":"+","sep":","}"#; assert_eq!(expected, &s); } } num-format-0.4.0/src/custom_format_builder.rs010064400007650000024000000105601343306100300175370ustar0000000000000000use crate::custom_format::CustomFormat; use crate::error::Error; use crate::format::Format; use crate::grouping::Grouping; use crate::locale::Locale; use crate::strings::{DecString, InfString, MinString, NanString, PlusString, SepString}; /// Type for building [`CustomFormat`]s. /// /// [`CustomFormat`]: struct.CustomFormat.html #[derive(Clone, Debug, Eq, PartialEq, Hash)] #[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] pub struct CustomFormatBuilder { dec: Result, grp: Grouping, inf: Result, min: Result, nan: Result, plus: Result, sep: Result, } impl CustomFormatBuilder { pub(crate) fn new() -> Self { Self { dec: DecString::new(Locale::en.decimal()), grp: Locale::en.grouping(), inf: InfString::new(Locale::en.infinity()), min: MinString::new(Locale::en.minus_sign()), nan: NanString::new(Locale::en.nan()), plus: PlusString::new(Locale::en.plus_sign()), sep: SepString::new(Locale::en.separator()), } } /// Construct a [`CustomFormat`]. /// /// # Errors /// /// Return an error if: /// - The "decimal" is longer than 8 bytes /// - The "infinity sign" is longer than 128 bytes /// - The "minus sign" is longer than 8 bytes /// - The "nan symbol" is longer than 64 bytes /// - The "plus sign" is longer than 8 bytes /// - The "separator" is longer than 8 bytes /// /// [`CustomFormat`]: struct.CustomFormat.html pub fn build(self) -> Result { Ok(CustomFormat { dec: self.dec?, grp: self.grp, inf: self.inf?, min: self.min?, nan: self.nan?, plus: self.plus?, sep: self.sep?, }) } /// Sets the character used to represent decimal points. pub fn decimal(mut self, s: S) -> Self where S: AsRef, { self.dec = DecString::new(s); self } /// Sets all fields based on the provided format. pub fn format(mut self, value: &F) -> Self where F: Format, { self.dec = DecString::new(value.decimal()); self.grp = value.grouping(); self.inf = InfString::new(value.infinity()); self.min = MinString::new(value.minus_sign()); self.nan = NanString::new(value.nan()); self.plus = PlusString::new(value.plus_sign()); self.sep = SepString::new(value.separator()); self } /// Sets the [`Grouping`] used to separate digits. /// /// [`Grouping`]: enum.Grouping.html pub fn grouping(mut self, value: Grouping) -> Self { self.grp = value; self } /// Sets the string representation of infinity. pub fn infinity(mut self, s: S) -> Self where S: AsRef, { self.inf = InfString::new(s); self } /// Sets the string representation of a minus sign. pub fn minus_sign(mut self, s: S) -> Self where S: AsRef, { self.min = MinString::new(s); self } /// Sets the string representation of NaN. pub fn nan(mut self, s: S) -> Self where S: AsRef, { self.nan = NanString::new(s); self } /// Sets the string representation of a plus sign. pub fn plus_sign(mut self, s: S) -> Self where S: AsRef, { self.plus = PlusString::new(s); self } /// Sets the string representation of a thousands separator. pub fn separator(mut self, s: S) -> Self where S: AsRef, { self.sep = SepString::new(s); self } } impl From for CustomFormatBuilder { fn from(format: CustomFormat) -> Self { CustomFormat::builder().format(&format) } } impl From for CustomFormatBuilder { fn from(locale: Locale) -> Self { CustomFormat::builder().format(&locale) } } #[cfg(all(feature = "with-system-locale", any(unix, windows)))] mod standard { use super::*; use crate::system_locale::SystemLocale; impl From for CustomFormatBuilder { fn from(locale: SystemLocale) -> Self { CustomFormat::builder().format(&locale) } } } num-format-0.4.0/src/error.rs010064400007650000024000000062451343306070000143100ustar0000000000000000use core::fmt; use crate::error_kind::ErrorKind; #[cfg(not(feature = "std"))] use crate::strings::ErrString; #[derive(Clone, Debug, Eq, PartialEq, Hash)] #[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] /// This crate's error type. pub struct Error { kind: ErrorKind, } impl Error { /// Constructs a new [`Error`] with kind [`ErrorKind::Other`]. /// /// [`Error`]: struct.Error.html /// [`ErrorKind::Other`]: enum.ErrorKind.html#variant.Other pub fn new(message: S) -> Error where S: AsRef, { #[cfg(feature = "std")] return Error { kind: ErrorKind::Other(message.as_ref().into()), }; #[cfg(not(feature = "std"))] return Error { kind: ErrorKind::Other(ErrString::truncated(message).into()), }; } /// Returns the [`ErrorKind`]. /// /// [`ErrorKind`]: enum.ErrorKind.html pub fn kind(&self) -> &ErrorKind { &self.kind } } impl Error { pub(crate) fn capacity(len: usize, cap: usize) -> Error { Error { kind: ErrorKind::Capacity { len, cap }, } } #[cfg(all(feature = "with-system-locale", any(unix, windows)))] pub(crate) fn interior_nul_byte(locale_name: S) -> Error where S: Into, { Error { kind: ErrorKind::InteriorNulByte(locale_name.into()), } } pub(crate) fn parse_locale(input: S) -> Error where S: AsRef, { #[cfg(feature = "std")] return Error { kind: ErrorKind::ParseLocale(input.as_ref().into()), }; #[cfg(not(feature = "std"))] return Error { kind: ErrorKind::ParseLocale(ErrString::truncated(input.as_ref()).into()), }; } #[cfg(all(feature = "with-system-locale", any(unix, windows)))] pub(crate) fn system_invalid_return(function_name: S, message: T) -> Error where S: Into, T: Into, { Error { kind: ErrorKind::SystemInvalidReturn { function_name: function_name.into(), message: message.into(), }, } } #[cfg(all(feature = "with-system-locale", unix))] pub(crate) fn system_unsupported_encoding(encoding_name: S) -> Error where S: Into, { Error { kind: ErrorKind::SystemUnsupportedEncoding(encoding_name.into()), } } #[cfg(all(feature = "with-system-locale", any(unix, windows)))] pub(crate) fn system_unsupported_grouping(bytes: B) -> Error where B: Into>, { Error { kind: ErrorKind::SystemUnsupportedGrouping(bytes.into()), } } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.kind) } } impl From for Error { fn from(kind: ErrorKind) -> Error { Error { kind } } } #[cfg(feature = "std")] mod standard { use super::*; impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } } num-format-0.4.0/src/error_kind.rs010064400007650000024000000070011343306074200153120ustar0000000000000000use core::fmt; #[cfg(not(feature = "std"))] use arrayvec::ArrayString; #[cfg(not(feature = "std"))] use crate::strings::MAX_ERR_LEN; /// This crate's error kind. #[derive(Clone, Debug, Eq, PartialEq, Hash)] #[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] pub enum ErrorKind { /// Input exceeds buffer capacity. Capacity { /// Length of the input in bytes. len: usize, /// Capacity of the buffer in bytes. cap: usize, }, #[cfg(all(feature = "with-system-locale", any(unix, windows)))] /// Locale name contains an interior nul byte, which is not allowed. InteriorNulByte(String), #[cfg(feature = "std")] /// Other miscellaneous error. Other(String), #[cfg(not(feature = "std"))] /// Other miscellaneous error. Other(ArrayString<[u8; MAX_ERR_LEN]>), #[cfg(feature = "std")] /// Failed to parse input into a valid locale. ParseLocale(String), #[cfg(not(feature = "std"))] /// Failed to parse input into a valid locale. ParseLocale(ArrayString<[u8; MAX_ERR_LEN]>), #[cfg(all(feature = "with-system-locale", any(unix, windows)))] /// Call to C standard library or Windows API unexpectedly returned invalid data. SystemInvalidReturn { /// The name of the C standard library or Windows API function called. function_name: String, /// Details about the invalid data returned. message: String, }, #[cfg(all(feature = "with-system-locale", unix))] /// Attempted to use a system locale that relies on an encoding that is not currently supported /// by num-format. SystemUnsupportedEncoding(String), #[cfg(all(feature = "with-system-locale", any(unix, windows)))] /// The operating system returned grouping data that is currently unsuppported by num-format. SystemUnsupportedGrouping(Vec), } impl fmt::Display for ErrorKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::ErrorKind::*; match self { Capacity { len, cap } => write!( f, "Attempted to write input of length {} bytes into a buffer with \ capacity {} bytes.", len, cap ), #[cfg(all(feature = "with-system-locale", any(unix, windows)))] InteriorNulByte(ref locale_name) => write!( f, "Locale name {} contains an interior nul byte, which is not allowed.", locale_name ), Other(ref message) => write!(f, "{}", message), ParseLocale(ref input) => write!(f, "Failed to parse {} into a valid locale.", input), #[cfg(all(feature = "with-system-locale", any(unix, windows)))] SystemInvalidReturn { message, .. } => write!(f, "{}", message), #[cfg(all(feature = "with-system-locale", unix))] SystemUnsupportedEncoding(ref encoding_name) => write!( f, "Attempted to use a system locale that relies on an encoding that is not \ currently supported by num-format. The unsupported encoding is {}.", encoding_name ), #[cfg(all(feature = "with-system-locale", any(unix, windows)))] SystemUnsupportedGrouping(ref bytes) => write!( f, "The operating system returned grouping data of {:?}, which is not currently \ suppported by num-format.", bytes ), } } } num-format-0.4.0/src/format.rs010064400007650000024000000021551343304455300144530ustar0000000000000000use crate::strings::{DecimalStr, InfinityStr, MinusSignStr, NanStr, PlusSignStr, SeparatorStr}; use crate::Grouping; /// Trait that abstracts over [`CustomFormat`], [`Locale`], and [`SystemLocale`]. /// /// [`CustomFormat`]: struct.CustomFormat.html /// [`Locale`]: enum.Locale.html /// [`SystemLocale`]: struct.SystemLocale.html pub trait Format { /// Returns the string representation of a decimal point. fn decimal(&self) -> DecimalStr<'_>; /// Returns the [`Grouping`] to use for separating digits. (see [`Grouping`]) /// /// [`Grouping`]: enum.Grouping.html fn grouping(&self) -> Grouping; /// Returns the string representation of an infinity symbol. fn infinity(&self) -> InfinityStr<'_>; /// Returns the string representation of a minus sign. fn minus_sign(&self) -> MinusSignStr<'_>; /// Returns the string representation of NaN. fn nan(&self) -> NanStr<'_>; /// Returns the string representation of a plus sign. fn plus_sign(&self) -> PlusSignStr<'_>; /// Returns the string representation of a thousands separator. fn separator(&self) -> SeparatorStr<'_>; } num-format-0.4.0/src/grouping.rs010064400007650000024000000010101343304455300150020ustar0000000000000000/// Type for specifying how digits are grouped together (e.g. 1,000,000 vs. 10,00,000 vs. 1000000). #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] pub enum Grouping { /// Digits are separated into groups of three (e.g. 10,000,000) Standard, /// The first three digits are grouped together and all digits after that are /// separated into groups of two (e.g. 1,00,00,000) Indian, /// No grouping (e.g. 10000000) Posix, } num-format-0.4.0/src/impls.rs010064400007650000024000000001021343306064400142740ustar0000000000000000mod integers; #[cfg(feature = "with-num-bigint")] mod num_bigint; num-format-0.4.0/src/impls/integers.rs010064400007650000024000000137731343306114100161270ustar0000000000000000#![allow(trivial_numeric_casts)] use core::marker::PhantomData; use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; use core::ptr; use crate::buffer::Buffer; use crate::constants::{MAX_BUF_LEN, TABLE}; use crate::format::Format; use crate::grouping::Grouping; use crate::sealed::Sealed; use crate::to_formatted_str::ToFormattedStr; // unsigned integers impl ToFormattedStr for u8 { #[doc(hidden)] #[inline(always)] fn read_to_buffer<'a, F>(&self, buf: &'a mut Buffer, _: &F) -> usize where F: Format, { buf.write_with_itoa(*self) } } macro_rules! impl_unsigned { ($type:ty) => { impl ToFormattedStr for $type { #[doc(hidden)] #[inline(always)] fn read_to_buffer<'a, F>(&self, buf: &'a mut Buffer, format: &F) -> usize where F: Format, { let n = *self as u128; run_core_algorithm(n, buf, format) } } }; } impl_unsigned!(u16); impl_unsigned!(u32); impl_unsigned!(usize); impl_unsigned!(u64); impl_unsigned!(u128); impl Sealed for u8 {} impl Sealed for u16 {} impl Sealed for u32 {} impl Sealed for usize {} impl Sealed for u64 {} impl Sealed for u128 {} // signed integers macro_rules! impl_signed { ($type:ty) => { impl ToFormattedStr for $type { #[doc(hidden)] #[inline(always)] fn read_to_buffer<'a, F>(&self, buf: &'a mut Buffer, format: &F) -> usize where F: Format, { if self.is_negative() { let n = (!(*self as u128)).wrapping_add(1); // make positive by adding 1 to the 2s complement let c = run_core_algorithm(n, buf, format); let minus_sign = format.minus_sign().into_str(); let min_len = minus_sign.len(); buf.pos -= min_len; for (i, byte) in minus_sign.as_bytes().iter().enumerate() { buf.inner[buf.pos + i] = *byte; } c + min_len } else { let n = *self as u128; let c = run_core_algorithm(n, buf, format); c } } } }; } impl_signed!(i8); impl_signed!(i16); impl_signed!(i32); impl_signed!(isize); impl_signed!(i64); impl_signed!(i128); impl Sealed for i8 {} impl Sealed for i16 {} impl Sealed for i32 {} impl Sealed for isize {} impl Sealed for i64 {} impl Sealed for i128 {} // non-zero unsigned integers impl ToFormattedStr for NonZeroU8 { #[doc(hidden)] #[inline(always)] fn read_to_buffer<'a, F>(&self, buf: &'a mut Buffer, _: &F) -> usize where F: Format, { buf.write_with_itoa(self.get()) } } macro_rules! impl_non_zero { ($type:ty) => { impl ToFormattedStr for $type { #[doc(hidden)] #[inline(always)] fn read_to_buffer<'a, F>(&self, buf: &'a mut Buffer, format: &F) -> usize where F: Format, { let n = self.get() as u128; run_core_algorithm(n, buf, format) } } }; } impl_non_zero!(NonZeroU16); impl_non_zero!(NonZeroU32); impl_non_zero!(NonZeroUsize); impl_non_zero!(NonZeroU64); impl_non_zero!(NonZeroU128); impl Sealed for NonZeroU8 {} impl Sealed for NonZeroU16 {} impl Sealed for NonZeroU32 {} impl Sealed for NonZeroUsize {} impl Sealed for NonZeroU64 {} impl Sealed for NonZeroU128 {} // helper functions #[inline(always)] fn run_core_algorithm(mut n: u128, buf: &mut Buffer, format: &F) -> usize where F: Format, { // Bail out early if we can just use itoa // (i.e. if we don't have a separator) let separator = format.separator().into_str(); let grouping = format.grouping(); if separator.is_empty() || grouping == Grouping::Posix { return buf.write_with_itoa(n); } // Reset our position to the end of the buffer buf.pos = MAX_BUF_LEN; buf.end = MAX_BUF_LEN; // Collect separator information let mut sep = Sep { ptr: separator.as_bytes().as_ptr(), len: separator.len(), pos: MAX_BUF_LEN as isize - 4, step: match grouping { Grouping::Standard => 4isize, Grouping::Indian => 3isize, Grouping::Posix => unreachable!(), }, phantom: PhantomData, }; // Start the main algorithm while n >= 10_000 { let remainder = n % 10_000; let table_index = ((remainder % 100) << 1) as isize; write_two_bytes(buf, &mut sep, table_index); let table_index = ((remainder / 100) << 1) as isize; write_two_bytes(buf, &mut sep, table_index); n /= 10_000; } let mut n = n as isize; while n >= 100 { let table_index = (n % 100) << 1; write_two_bytes(buf, &mut sep, table_index); n /= 100; } if n >= 10 { let table_index = n << 1; write_two_bytes(buf, &mut sep, table_index); } else { let table_index = n << 1; write_one_byte(buf, &mut sep, table_index + 1); } buf.end - buf.pos } struct Sep<'a> { ptr: *const u8, len: usize, pos: isize, step: isize, phantom: PhantomData<&'a ()>, } #[inline(always)] fn write_one_byte(buf: &mut Buffer, sep: &mut Sep, table_index: isize) { buf.pos -= 1; if sep.pos == (buf.pos as isize) { buf.pos -= sep.len - 1; unsafe { ptr::copy_nonoverlapping(sep.ptr, buf.as_mut_ptr().add(buf.pos), sep.len) } sep.pos -= sep.step + (sep.len as isize - 1); buf.pos -= 1; } unsafe { ptr::copy_nonoverlapping( TABLE.as_ptr().offset(table_index), buf.as_mut_ptr().add(buf.pos), 1, ) }; } #[inline(always)] fn write_two_bytes(buf: &mut Buffer, sep: &mut Sep, table_index: isize) { write_one_byte(buf, sep, table_index + 1); write_one_byte(buf, sep, table_index); } num-format-0.4.0/src/impls/num_bigint.rs010064400007650000024000000157671343306114300164510ustar0000000000000000#![cfg(feature = "with-num-bigint")] use std::fmt; use std::io; use std::ops::Neg; use num_bigint::{BigInt, BigUint, Sign}; use crate::sealed::Sealed; use crate::{Format, Grouping, ToFormattedString}; impl ToFormattedString for BigInt { #[inline(always)] fn read_to_io_writer(&self, mut w: W, format: &F) -> Result where F: Format, W: io::Write, { match self.sign() { Sign::Minus => { let minus_sign = format.minus_sign().into_str(); w.write_all(minus_sign.as_bytes())?; let s = self.neg().to_string(); let c = io_algorithm(s, w, format)?; Ok(c + minus_sign.len()) } Sign::NoSign | Sign::Plus => { let s = self.to_string(); let c = io_algorithm(s, w, format)?; Ok(c) } } } #[inline(always)] fn read_to_fmt_writer(&self, mut w: W, format: &F) -> Result where F: Format, W: fmt::Write, { match self.sign() { Sign::Minus => { let minus_sign = format.minus_sign().into_str(); w.write_str(minus_sign)?; let s = self.neg().to_string(); let c = fmt_algorithm(s, w, format)?; Ok(c + minus_sign.len()) } Sign::NoSign | Sign::Plus => { let s = self.to_string(); let c = fmt_algorithm(s, w, format)?; Ok(c) } } } } impl ToFormattedString for BigUint { #[inline(always)] fn read_to_io_writer(&self, w: W, format: &F) -> Result where F: Format, W: io::Write, { let s = self.to_string(); let c = io_algorithm(s, w, format)?; Ok(c) } #[inline(always)] fn read_to_fmt_writer(&self, w: W, format: &F) -> Result where F: Format, W: fmt::Write, { let s = self.to_string(); let c = fmt_algorithm(s, w, format)?; Ok(c) } } impl Sealed for BigInt {} impl Sealed for BigUint {} #[inline(always)] fn io_algorithm(s: String, mut w: W, format: &F) -> Result where W: io::Write, F: Format, { let separator = format.separator().into_str(); let grouping = format.grouping(); if separator.is_empty() || grouping == Grouping::Posix { w.write_all(s.as_bytes())?; return Ok(s.len()); } let mut sep_next = match s.len() { s_len if s_len < 4 => { w.write_all(s.as_bytes())?; return Ok(s_len); } s_len => match grouping { Grouping::Standard => match s_len % 3 { 0 => 3, 2 => 2, 1 => 1, _ => unreachable!(), }, Grouping::Indian => match s_len % 2 { 0 => 1, 1 => 2, _ => unreachable!(), }, Grouping::Posix => unreachable!(), }, }; let sep_bytes = separator.as_bytes(); let sep_len = separator.len(); let sep_step = match grouping { Grouping::Standard => 4, Grouping::Indian => 3, Grouping::Posix => unreachable!(), }; let mut bytes_written = 0; let mut digits_remaining = s.len(); let mut iter = s.as_bytes().iter(); while let Some(digit) = iter.next() { if bytes_written == sep_next { w.write_all(sep_bytes)?; bytes_written += sep_len; if digits_remaining > 3 { sep_next += sep_len + sep_step - 1; } } w.write_all(&[*digit])?; bytes_written += 1; digits_remaining -= 1; } Ok(bytes_written) } #[inline(always)] fn fmt_algorithm(s: String, mut w: W, format: &F) -> Result where W: fmt::Write, F: Format, { let separator = format.separator().into_str(); let grouping = format.grouping(); if separator.is_empty() || grouping == Grouping::Posix { w.write_str(&s)?; return Ok(s.len()); } let mut sep_next = match s.len() { s_len if s_len < 4 => { w.write_str(&s)?; return Ok(s_len); } s_len => match grouping { Grouping::Standard => match s_len % 3 { 0 => 3, 2 => 2, 1 => 1, _ => unreachable!(), }, Grouping::Indian => match s_len % 2 { 0 => 1, 1 => 2, _ => unreachable!(), }, Grouping::Posix => unreachable!(), }, }; let sep_len = separator.len(); let sep_no_chars = separator.chars().count(); let sep_step = match grouping { Grouping::Standard => 4, Grouping::Indian => 3, Grouping::Posix => unreachable!(), }; let mut bytes_written = 0; let mut chars_written = 0; let mut digits_remaining = s.len(); let mut iter = s.chars(); while let Some(c) = iter.next() { if chars_written == sep_next { w.write_str(separator)?; bytes_written += sep_len; chars_written += sep_no_chars; if digits_remaining > 3 { sep_next += sep_step + sep_no_chars - 1; } } w.write_char(c)?; bytes_written += 1; chars_written += 1; digits_remaining -= 1; } Ok(bytes_written) } #[cfg(test)] mod tests { use super::*; use crate::custom_format::CustomFormat; use crate::write_formatted::WriteFormatted; #[test] fn test_num_bigint_count() { let n = BigInt::new(Sign::Minus, vec![1_000_000_000]); let format = CustomFormat::builder() .minus_sign("𠜱") .separator("𠜱") .build() .unwrap(); { let mut vec = Vec::new(); let c = vec.write_formatted(&n, &format).unwrap(); let s = String::from_utf8(vec).unwrap(); assert_eq!(&s, "𠜱1𠜱000𠜱000𠜱000"); assert_eq!(c, 26); } { let mut s = String::new(); let c = s.write_formatted(&n, &format).unwrap(); assert_eq!(&s, "𠜱1𠜱000𠜱000𠜱000"); assert_eq!(c, 26); } let format = format .into_builder() .grouping(Grouping::Indian) .build() .unwrap(); { let mut vec = Vec::new(); let c = vec.write_formatted(&n, &format).unwrap(); let s = String::from_utf8(vec).unwrap(); assert_eq!(&s, "𠜱1𠜱00𠜱00𠜱00𠜱000"); assert_eq!(c, 30); } { let mut s = String::new(); let c = s.write_formatted(&n, &format).unwrap(); assert_eq!(&s, "𠜱1𠜱00𠜱00𠜱00𠜱000"); assert_eq!(c, 30); } } } num-format-0.4.0/src/lib.rs010064400007650000024000000244531343311636700137410ustar0000000000000000/*! [![Build Status](https://travis-ci.org/bcmyers/num-format.svg?branch=master)](https://travis-ci.org/bcmyers/num-format) [![Crates.io](https://img.shields.io/crates/v/num-format.svg)](https://crates.io/crates/num-format) [![Documentation](https://docs.rs/num-format/badge.svg)](https://docs.rs/num-format/) ![License](https://img.shields.io/crates/l/num_format.svg) 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. ```rust # use cfg_if::cfg_if; cfg_if! { if #[cfg(feature = "std")] { use num_format::{Locale, ToFormattedString}; fn main() { let s = 1000000.to_formatted_string(&Locale::en); assert_eq!(&s, "1,000,000"); } # } else { fn main() {} } } ``` ### `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 cfg_if::cfg_if; cfg_if! { if #[cfg(feature = "std")] { 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"); } # } else { fn main() {} } } ``` # 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; 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", features = ["with-system-locale"] }` in your `Cargo.toml`. Additionally, on Windows (but **only** on Windows), using `SystemLocale` requires Clang 3.9 or higher. ```rust # #[cfg(all(feature = "with-system-locale", any(unix, windows)))] use num_format::SystemLocale; # #[cfg(all(feature = "with-system-locale", any(unix, windows)))] 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."), } } # #[cfg(not(all(feature = "with-system-locale", any(unix, windows))))] # fn main() {} ``` ### `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 * Rust 1.31 or greater * If you're using the `with-system-locale` feature **and** you're on Windows, Clang 3.9 or higher is also required. See [here](https://rust-lang.github.io/rust-bindgen/requirements.html) for installation instructions. # Extra features | Available features | What to put in your `Cargo.toml` | | :------------------- | :-------------------------------------------------------------------- | | `no_std` | `num-format = { version = "0.4", default-features = false }` | | `with-num-bigint` | `num-format = { version = "0.4", features = ["with-num-bigint"] }` | | `with-serde` | `num-format = { version = "0.4", features = ["with-serde"] }` | | `with-system-locale` | `num-format = { version = "0.4", features = ["with-system-locale"] }` | # License **num-format** is licensed under either of: - [The Apache License, Version 2.0], or - [The MIT license] at your option. [bindgen]: https://crates.io/crates/bindgen [`Buffer`]: https://docs.rs/num-format/0.4.0/num_format/struct.Buffer.html [Common Locale Data Repository]: https://en.wikipedia.org/wiki/Common_Locale_Data_Repository [`CustomFormat`]: https://docs.rs/num-format/0.4.0/num_format/struct.CustomFormat.html [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html [`fmt::Write`]: https://doc.rust-lang.org/std/fmt/fn.write.html [`Format`]: https://docs.rs/num-format/0.4.0/num_format/trait.Format.html [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html [`Locale`]: https://docs.rs/num-format/0.4.0/num_format/enum.Locale.html [`num_bigint::BigInt`]: https://docs.rs/num-bigint/0.2.2/num_bigint/struct.BigInt.html [picking a format]: #picking-a-format [`String`]: https://doc.rust-lang.org/std/string/struct.String.html [The Apache License, Version 2.0]: http://www.apache.org/licenses/LICENSE-2.0 [The MIT license]: http://opensource.org/licenses/MIT [`ToFormattedString`]: https://docs.rs/num-format/0.4.0/num_format/trait.ToFormattedString.html [`to_formatted_string`]: https://docs.rs/num-format/0.4.0/num_format/trait.ToFormattedString.html#method.to_formatted_string [Unicode Consortium]: https://en.wikipedia.org/wiki/Unicode_Consortium [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html [`WriteFormatted`]: https://docs.rs/num-format/0.4.0/num_format/trait.WriteFormatted.html */ #![cfg_attr(not(feature = "std"), no_std)] #![deny( dead_code, deprecated, // missing_copy_implementations, missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts, unused_extern_crates, unused_imports, unused_macros, unused_mut, unused_results, unused_parens, unused_unsafe, unused_variables )] #![doc(html_root_url = "https://docs.rs/num-format/0.4.0")] #[cfg(all(feature = "with-system-locale", unix))] #[macro_use] extern crate cfg_if; #[cfg(all(feature = "with-system-locale", any(unix, windows)))] #[macro_use] extern crate lazy_static; #[cfg(feature = "with-serde")] #[macro_use] extern crate serde; mod buffer; mod constants; mod custom_format; mod custom_format_builder; mod error; mod error_kind; mod format; mod grouping; mod impls; mod locale; mod strings; #[cfg(all(feature = "with-system-locale", any(unix, windows)))] mod system_locale; mod to_formatted_str; #[cfg(feature = "std")] mod to_formatted_string; #[cfg(feature = "std")] mod write_formatted; pub use self::buffer::Buffer; pub use self::custom_format::CustomFormat; pub use self::custom_format_builder::CustomFormatBuilder; pub use self::error::Error; pub use self::error_kind::ErrorKind; pub use self::format::Format; pub use self::grouping::Grouping; pub use self::locale::Locale; #[cfg(all(feature = "with-system-locale", any(unix, windows)))] pub use self::system_locale::SystemLocale; pub use self::to_formatted_str::ToFormattedStr; #[cfg(feature = "std")] pub use self::to_formatted_string::ToFormattedString; #[cfg(feature = "std")] pub use self::write_formatted::WriteFormatted; mod sealed { pub trait Sealed {} } pub mod utils { //! Utility types needed if you want to implement [`Format`] on your own type. //! //! [`Format`]: trait.Format.html pub use crate::strings::{ DecimalStr, InfinityStr, MinusSignStr, NanStr, PlusSignStr, SeparatorStr, }; } num-format-0.4.0/src/locale.rs010064400007650000024000004470241343306637400144370ustar0000000000000000#![doc = r"Note: This module was autogenerated by num-format-dev."] use crate::error::Error; use crate::format::Format; use crate::grouping::Grouping; use crate::strings::{DecimalStr, InfinityStr, MinusSignStr, NanStr, PlusSignStr, SeparatorStr}; use core::str::FromStr; const AVAILABLE_NAMES: [&'static str; 538usize] = [ "af", "af-NA", "agq", "ak", "am", "ar", "ar-AE", "ar-BH", "ar-DJ", "ar-DZ", "ar-EG", "ar-EH", "ar-ER", "ar-IL", "ar-IQ", "ar-JO", "ar-KM", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-MR", "ar-OM", "ar-PS", "ar-QA", "ar-SA", "ar-SD", "ar-SO", "ar-SS", "ar-SY", "ar-TD", "ar-TN", "ar-YE", "as", "asa", "ast", "az", "az-Cyrl", "az-Latn", "bas", "be", "bem", "bez", "bg", "bm", "bn", "bn-IN", "bo", "bo-IN", "br", "brx", "bs", "bs-Cyrl", "bs-Latn", "ca", "ca-AD", "ca-ES-VALENCIA", "ca-FR", "ca-IT", "ccp", "ccp-IN", "ce", "cgg", "chr", "ckb", "ckb-IR", "cs", "cu", "cy", "da", "da-GL", "dav", "de", "de-AT", "de-BE", "de-CH", "de-IT", "de-LI", "de-LU", "dje", "dsb", "dua", "dyo", "dz", "ebu", "ee", "ee-TG", "el", "el-CY", "en", "en-001", "en-150", "en-AG", "en-AI", "en-AS", "en-AT", "en-AU", "en-BB", "en-BE", "en-BI", "en-BM", "en-BS", "en-BW", "en-BZ", "en-CA", "en-CC", "en-CH", "en-CK", "en-CM", "en-CX", "en-CY", "en-DE", "en-DG", "en-DK", "en-DM", "en-ER", "en-FI", "en-FJ", "en-FK", "en-FM", "en-GB", "en-GD", "en-GG", "en-GH", "en-GI", "en-GM", "en-GU", "en-GY", "en-HK", "en-IE", "en-IL", "en-IM", "en-IN", "en-IO", "en-JE", "en-JM", "en-KE", "en-KI", "en-KN", "en-KY", "en-LC", "en-LR", "en-LS", "en-MG", "en-MH", "en-MO", "en-MP", "en-MS", "en-MT", "en-MU", "en-MW", "en-MY", "en-NA", "en-NF", "en-NG", "en-NL", "en-NR", "en-NU", "en-NZ", "en-PG", "en-PH", "en-PK", "en-PN", "en-PR", "en-PW", "en-RW", "en-SB", "en-SC", "en-SD", "en-SE", "en-SG", "en-SH", "en-SI", "en-SL", "en-SS", "en-SX", "en-SZ", "en-TC", "en-TK", "en-TO", "en-TT", "en-TV", "en-TZ", "en-UG", "en-UM", "en-US-POSIX", "en-VC", "en-VG", "en-VI", "en-VU", "en-WS", "en-ZA", "en-ZM", "en-ZW", "eo", "es", "es-419", "es-AR", "es-BO", "es-BR", "es-BZ", "es-CL", "es-CO", "es-CR", "es-CU", "es-DO", "es-EA", "es-EC", "es-GQ", "es-GT", "es-HN", "es-IC", "es-MX", "es-NI", "es-PA", "es-PE", "es-PH", "es-PR", "es-PY", "es-SV", "es-US", "es-UY", "es-VE", "et", "eu", "ewo", "fa", "fa-AF", "ff", "ff-Latn", "ff-Latn-BF", "ff-Latn-CM", "ff-Latn-GH", "ff-Latn-GM", "ff-Latn-GN", "ff-Latn-GW", "ff-Latn-LR", "ff-Latn-MR", "ff-Latn-NE", "ff-Latn-NG", "ff-Latn-SL", "fi", "fil", "fo", "fo-DK", "fr", "fr-BE", "fr-BF", "fr-BI", "fr-BJ", "fr-BL", "fr-CA", "fr-CD", "fr-CF", "fr-CG", "fr-CH", "fr-CI", "fr-CM", "fr-DJ", "fr-DZ", "fr-GA", "fr-GF", "fr-GN", "fr-GP", "fr-GQ", "fr-HT", "fr-KM", "fr-LU", "fr-MA", "fr-MC", "fr-MF", "fr-MG", "fr-ML", "fr-MQ", "fr-MR", "fr-MU", "fr-NC", "fr-NE", "fr-PF", "fr-PM", "fr-RE", "fr-RW", "fr-SC", "fr-SN", "fr-SY", "fr-TD", "fr-TG", "fr-TN", "fr-VU", "fr-WF", "fr-YT", "fur", "fy", "ga", "gd", "gl", "gsw", "gsw-FR", "gsw-LI", "gu", "guz", "gv", "ha", "ha-GH", "ha-NE", "haw", "he", "hi", "hr", "hr-BA", "hsb", "hu", "hy", "ia", "id", "ig", "ii", "is", "it", "it-CH", "it-SM", "it-VA", "ja", "jgo", "jmc", "jv", "ka", "kab", "kam", "kde", "kea", "khq", "ki", "kk", "kkj", "kl", "kln", "km", "kn", "ko", "ko-KP", "kok", "ks", "ksb", "ksf", "ksh", "ku", "kw", "ky", "lag", "lb", "lg", "lkt", "ln", "ln-AO", "ln-CF", "ln-CG", "lo", "lrc", "lrc-IQ", "lt", "lu", "luo", "luy", "lv", "mas", "mas-TZ", "mer", "mfe", "mg", "mgh", "mgo", "mi", "mk", "ml", "mn", "mr", "ms", "ms-BN", "ms-SG", "mt", "mua", "my", "mzn", "naq", "nb", "nb-SJ", "nd", "nds", "nds-NL", "ne", "ne-IN", "nl", "nl-AW", "nl-BE", "nl-BQ", "nl-CW", "nl-SR", "nl-SX", "nmg", "nn", "nnh", "nus", "nyn", "om", "om-KE", "or", "os", "os-RU", "pa", "pa-Arab", "pa-Guru", "pl", "prg", "ps", "pt", "pt-AO", "pt-CH", "pt-CV", "pt-GQ", "pt-GW", "pt-LU", "pt-MO", "pt-MZ", "pt-PT", "pt-ST", "pt-TL", "qu", "qu-BO", "qu-EC", "rm", "rn", "ro", "ro-MD", "rof", "root", "ru", "ru-BY", "ru-KG", "ru-KZ", "ru-MD", "ru-UA", "rw", "rwk", "sah", "saq", "sbp", "sd", "se", "se-FI", "se-SE", "seh", "ses", "sg", "shi", "shi-Latn", "shi-Tfng", "si", "sk", "sl", "smn", "sn", "so", "so-DJ", "so-ET", "so-KE", "sq", "sq-MK", "sq-XK", "sr", "sr-Cyrl", "sr-Cyrl-BA", "sr-Cyrl-ME", "sr-Cyrl-XK", "sr-Latn", "sr-Latn-BA", "sr-Latn-ME", "sr-Latn-XK", "sv", "sv-AX", "sv-FI", "sw", "sw-CD", "sw-KE", "sw-UG", "ta", "ta-LK", "ta-MY", "ta-SG", "te", "teo", "teo-KE", "tg", "th", "ti", "ti-ER", "tk", "to", "tr", "tr-CY", "tt", "twq", "tzm", "ug", "uk", "ur", "ur-IN", "uz", "uz-Arab", "uz-Cyrl", "uz-Latn", "vai", "vai-Latn", "vai-Vaii", "vi", "vo", "vun", "wae", "wo", "xh", "xog", "yav", "yi", "yo", "yo-BJ", "yue", "yue-Hans", "yue-Hant", "zgh", "zh", "zh-Hans", "zh-Hans-HK", "zh-Hans-MO", "zh-Hans-SG", "zh-Hant", "zh-Hant-HK", "zh-Hant-MO", "zu", ]; #[doc = r"A key type. Represents formats from the [Unicode Consortium]'s"] #[doc = r"[Common Locale Data Repository (CLDR)]. Implements [`Format`]."] #[doc = r""] #[doc = r"# Example"] #[doc = r"```"] #[doc = r"use num_format::{Buffer, Locale};"] #[doc = r""] #[doc = r"fn main() {"] #[doc = r" // Using the French format from the Unicode Common Locale Data Repository..."] #[doc = r" let mut buf = Buffer::new();"] #[doc = r" buf.write_formatted(&(-1000000), &Locale::fr);"] #[doc = r#" assert_eq!("-1\u{202f}000\u{202f}000", buf.as_str());"#] #[doc = r""] #[doc = r" // Note:"] #[doc = r#" // U+202F is the "NARROW NO-BREAK SPACE" code point."#] #[doc = r" // When displayed to the screen, it looks like a space."] #[doc = r"}"] #[doc = r"```"] #[doc = r""] #[doc = r" [`Format`]: trait.Format.html"] #[doc = r" [Common Locale Data Repository (CLDR)]: https://en.wikipedia.org/wiki/Common_Locale_Data_Repository"] #[doc = r" [Unicode Consortium]: https://en.wikipedia.org/wiki/Unicode_Consortium"] #[allow(non_camel_case_types, missing_docs)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] pub enum Locale { af, af_NA, agq, ak, am, ar, ar_AE, ar_BH, ar_DJ, ar_DZ, ar_EG, ar_EH, ar_ER, ar_IL, ar_IQ, ar_JO, ar_KM, ar_KW, ar_LB, ar_LY, ar_MA, ar_MR, ar_OM, ar_PS, ar_QA, ar_SA, ar_SD, ar_SO, ar_SS, ar_SY, ar_TD, ar_TN, ar_YE, as_, asa, ast, az, az_Cyrl, az_Latn, bas, be, bem, bez, bg, bm, bn, bn_IN, bo, bo_IN, br, brx, bs, bs_Cyrl, bs_Latn, ca, ca_AD, ca_ES_VALENCIA, ca_FR, ca_IT, ccp, ccp_IN, ce, cgg, chr, ckb, ckb_IR, cs, cu, cy, da, da_GL, dav, de, de_AT, de_BE, de_CH, de_IT, de_LI, de_LU, dje, dsb, dua, dyo, dz, ebu, ee, ee_TG, el, el_CY, en, en_001, en_150, en_AG, en_AI, en_AS, en_AT, en_AU, en_BB, en_BE, en_BI, en_BM, en_BS, en_BW, en_BZ, en_CA, en_CC, en_CH, en_CK, en_CM, en_CX, en_CY, en_DE, en_DG, en_DK, en_DM, en_ER, en_FI, en_FJ, en_FK, en_FM, en_GB, en_GD, en_GG, en_GH, en_GI, en_GM, en_GU, en_GY, en_HK, en_IE, en_IL, en_IM, en_IN, en_IO, en_JE, en_JM, en_KE, en_KI, en_KN, en_KY, en_LC, en_LR, en_LS, en_MG, en_MH, en_MO, en_MP, en_MS, en_MT, en_MU, en_MW, en_MY, en_NA, en_NF, en_NG, en_NL, en_NR, en_NU, en_NZ, en_PG, en_PH, en_PK, en_PN, en_PR, en_PW, en_RW, en_SB, en_SC, en_SD, en_SE, en_SG, en_SH, en_SI, en_SL, en_SS, en_SX, en_SZ, en_TC, en_TK, en_TO, en_TT, en_TV, en_TZ, en_UG, en_UM, en_US_POSIX, en_VC, en_VG, en_VI, en_VU, en_WS, en_ZA, en_ZM, en_ZW, eo, es, es_419, es_AR, es_BO, es_BR, es_BZ, es_CL, es_CO, es_CR, es_CU, es_DO, es_EA, es_EC, es_GQ, es_GT, es_HN, es_IC, es_MX, es_NI, es_PA, es_PE, es_PH, es_PR, es_PY, es_SV, es_US, es_UY, es_VE, et, eu, ewo, fa, fa_AF, ff, ff_Latn, ff_Latn_BF, ff_Latn_CM, ff_Latn_GH, ff_Latn_GM, ff_Latn_GN, ff_Latn_GW, ff_Latn_LR, ff_Latn_MR, ff_Latn_NE, ff_Latn_NG, ff_Latn_SL, fi, fil, fo, fo_DK, fr, fr_BE, fr_BF, fr_BI, fr_BJ, fr_BL, fr_CA, fr_CD, fr_CF, fr_CG, fr_CH, fr_CI, fr_CM, fr_DJ, fr_DZ, fr_GA, fr_GF, fr_GN, fr_GP, fr_GQ, fr_HT, fr_KM, fr_LU, fr_MA, fr_MC, fr_MF, fr_MG, fr_ML, fr_MQ, fr_MR, fr_MU, fr_NC, fr_NE, fr_PF, fr_PM, fr_RE, fr_RW, fr_SC, fr_SN, fr_SY, fr_TD, fr_TG, fr_TN, fr_VU, fr_WF, fr_YT, fur, fy, ga, gd, gl, gsw, gsw_FR, gsw_LI, gu, guz, gv, ha, ha_GH, ha_NE, haw, he, hi, hr, hr_BA, hsb, hu, hy, ia, id, ig, ii, is, it, it_CH, it_SM, it_VA, ja, jgo, jmc, jv, ka, kab, kam, kde, kea, khq, ki, kk, kkj, kl, kln, km, kn, ko, ko_KP, kok, ks, ksb, ksf, ksh, ku, kw, ky, lag, lb, lg, lkt, ln, ln_AO, ln_CF, ln_CG, lo, lrc, lrc_IQ, lt, lu, luo, luy, lv, mas, mas_TZ, mer, mfe, mg, mgh, mgo, mi, mk, ml, mn, mr, ms, ms_BN, ms_SG, mt, mua, my, mzn, naq, nb, nb_SJ, nd, nds, nds_NL, ne, ne_IN, nl, nl_AW, nl_BE, nl_BQ, nl_CW, nl_SR, nl_SX, nmg, nn, nnh, nus, nyn, om, om_KE, or, os, os_RU, pa, pa_Arab, pa_Guru, pl, prg, ps, pt, pt_AO, pt_CH, pt_CV, pt_GQ, pt_GW, pt_LU, pt_MO, pt_MZ, pt_PT, pt_ST, pt_TL, qu, qu_BO, qu_EC, rm, rn, ro, ro_MD, rof, root, ru, ru_BY, ru_KG, ru_KZ, ru_MD, ru_UA, rw, rwk, sah, saq, sbp, sd, se, se_FI, se_SE, seh, ses, sg, shi, shi_Latn, shi_Tfng, si, sk, sl, smn, sn, so, so_DJ, so_ET, so_KE, sq, sq_MK, sq_XK, sr, sr_Cyrl, sr_Cyrl_BA, sr_Cyrl_ME, sr_Cyrl_XK, sr_Latn, sr_Latn_BA, sr_Latn_ME, sr_Latn_XK, sv, sv_AX, sv_FI, sw, sw_CD, sw_KE, sw_UG, ta, ta_LK, ta_MY, ta_SG, te, teo, teo_KE, tg, th, ti, ti_ER, tk, to, tr, tr_CY, tt, twq, tzm, ug, uk, ur, ur_IN, uz, uz_Arab, uz_Cyrl, uz_Latn, vai, vai_Latn, vai_Vaii, vi, vo, vun, wae, wo, xh, xog, yav, yi, yo, yo_BJ, yue, yue_Hans, yue_Hant, zgh, zh, zh_Hans, zh_Hans_HK, zh_Hans_MO, zh_Hans_SG, zh_Hant, zh_Hant_HK, zh_Hant_MO, zu, } impl Locale { #[doc = r" Constructs a [`Locale`] from its name. For a list of available names, see"] #[doc = r" [`available_names`]."] #[doc = r""] #[doc = r" # Errors"] #[doc = r""] #[doc = r" Returns an error if the name provided cannot be"] #[doc = r" parsed into a [`Locale`]."] #[doc = r""] #[doc = r" [`available_names`]: enum.Locale.html#method.available_names"] #[doc = r" [`Locale`]: enum.Locale.html"] pub fn from_name(name: S) -> Result where S: AsRef, { let name = name.as_ref(); name.parse::() } #[doc = r" Returns a static slice of all available names."] pub fn available_names() -> &'static [&'static str] { &AVAILABLE_NAMES } #[doc = r" Returns the locale's decimal representation."] pub fn decimal(&self) -> &'static str { use self::Locale::*; match self { af => ",", af_NA => ",", agq => ",", ak => ".", am => ".", ar => "\u{66b}", ar_AE => "\u{66b}", ar_BH => "\u{66b}", ar_DJ => "\u{66b}", ar_DZ => ",", ar_EG => "\u{66b}", ar_EH => ".", ar_ER => "\u{66b}", ar_IL => "\u{66b}", ar_IQ => "\u{66b}", ar_JO => "\u{66b}", ar_KM => "\u{66b}", ar_KW => "\u{66b}", ar_LB => "\u{66b}", ar_LY => ",", ar_MA => ",", ar_MR => "\u{66b}", ar_OM => "\u{66b}", ar_PS => "\u{66b}", ar_QA => "\u{66b}", ar_SA => "\u{66b}", ar_SD => "\u{66b}", ar_SO => "\u{66b}", ar_SS => "\u{66b}", ar_SY => "\u{66b}", ar_TD => "\u{66b}", ar_TN => ",", ar_YE => "\u{66b}", as_ => ".", asa => ".", ast => ",", az => ",", az_Cyrl => ",", az_Latn => ",", bas => ",", be => ",", bem => ".", bez => ".", bg => ",", bm => ".", bn => ".", bn_IN => ".", bo => ".", bo_IN => ".", br => ",", brx => ".", bs => ",", bs_Cyrl => ",", bs_Latn => ",", ca => ",", ca_AD => ",", ca_ES_VALENCIA => ",", ca_FR => ",", ca_IT => ",", ccp => ".", ccp_IN => ".", ce => ".", cgg => ".", chr => ".", ckb => "\u{66b}", ckb_IR => "\u{66b}", cs => ",", cu => ".", cy => ".", da => ",", da_GL => ",", dav => ".", de => ",", de_AT => ",", de_BE => ",", de_CH => ".", de_IT => ",", de_LI => ".", de_LU => ",", dje => ".", dsb => ",", dua => ",", dyo => ",", dz => ".", ebu => ".", ee => ".", ee_TG => ".", el => ",", el_CY => ",", en => ".", en_001 => ".", en_150 => ",", en_AG => ".", en_AI => ".", en_AS => ".", en_AT => ",", en_AU => ".", en_BB => ".", en_BE => ",", en_BI => ".", en_BM => ".", en_BS => ".", en_BW => ".", en_BZ => ".", en_CA => ".", en_CC => ".", en_CH => ",", en_CK => ".", en_CM => ".", en_CX => ".", en_CY => ".", en_DE => ",", en_DG => ".", en_DK => ",", en_DM => ".", en_ER => ".", en_FI => ",", en_FJ => ".", en_FK => ".", en_FM => ".", en_GB => ".", en_GD => ".", en_GG => ".", en_GH => ".", en_GI => ".", en_GM => ".", en_GU => ".", en_GY => ".", en_HK => ".", en_IE => ".", en_IL => ".", en_IM => ".", en_IN => ".", en_IO => ".", en_JE => ".", en_JM => ".", en_KE => ".", en_KI => ".", en_KN => ".", en_KY => ".", en_LC => ".", en_LR => ".", en_LS => ".", en_MG => ".", en_MH => ".", en_MO => ".", en_MP => ".", en_MS => ".", en_MT => ".", en_MU => ".", en_MW => ".", en_MY => ".", en_NA => ".", en_NF => ".", en_NG => ".", en_NL => ",", en_NR => ".", en_NU => ".", en_NZ => ".", en_PG => ".", en_PH => ".", en_PK => ".", en_PN => ".", en_PR => ".", en_PW => ".", en_RW => ".", en_SB => ".", en_SC => ".", en_SD => ".", en_SE => ",", en_SG => ".", en_SH => ".", en_SI => ",", en_SL => ".", en_SS => ".", en_SX => ".", en_SZ => ".", en_TC => ".", en_TK => ".", en_TO => ".", en_TT => ".", en_TV => ".", en_TZ => ".", en_UG => ".", en_UM => ".", en_US_POSIX => ".", en_VC => ".", en_VG => ".", en_VI => ".", en_VU => ".", en_WS => ".", en_ZA => ",", en_ZM => ".", en_ZW => ".", eo => ",", es => ",", es_419 => ".", es_AR => ",", es_BO => ",", es_BR => ".", es_BZ => ".", es_CL => ",", es_CO => ",", es_CR => ",", es_CU => ".", es_DO => ".", es_EA => ",", es_EC => ",", es_GQ => ",", es_GT => ".", es_HN => ".", es_IC => ",", es_MX => ".", es_NI => ".", es_PA => ".", es_PE => ".", es_PH => ",", es_PR => ".", es_PY => ",", es_SV => ".", es_US => ".", es_UY => ",", es_VE => ",", et => ",", eu => ",", ewo => ",", fa => "\u{66b}", fa_AF => "\u{66b}", ff => ",", ff_Latn => ",", ff_Latn_BF => ",", ff_Latn_CM => ",", ff_Latn_GH => ",", ff_Latn_GM => ",", ff_Latn_GN => ",", ff_Latn_GW => ",", ff_Latn_LR => ",", ff_Latn_MR => ",", ff_Latn_NE => ",", ff_Latn_NG => ",", ff_Latn_SL => ",", fi => ",", fil => ".", fo => ",", fo_DK => ",", fr => ",", fr_BE => ",", fr_BF => ",", fr_BI => ",", fr_BJ => ",", fr_BL => ",", fr_CA => ",", fr_CD => ",", fr_CF => ",", fr_CG => ",", fr_CH => ",", fr_CI => ",", fr_CM => ",", fr_DJ => ",", fr_DZ => ",", fr_GA => ",", fr_GF => ",", fr_GN => ",", fr_GP => ",", fr_GQ => ",", fr_HT => ",", fr_KM => ",", fr_LU => ",", fr_MA => ",", fr_MC => ",", fr_MF => ",", fr_MG => ",", fr_ML => ",", fr_MQ => ",", fr_MR => ",", fr_MU => ",", fr_NC => ",", fr_NE => ",", fr_PF => ",", fr_PM => ",", fr_RE => ",", fr_RW => ",", fr_SC => ",", fr_SN => ",", fr_SY => ",", fr_TD => ",", fr_TG => ",", fr_TN => ",", fr_VU => ",", fr_WF => ",", fr_YT => ",", fur => ",", fy => ",", ga => ".", gd => ".", gl => ",", gsw => ".", gsw_FR => ".", gsw_LI => ".", gu => ".", guz => ".", gv => ".", ha => ".", ha_GH => ".", ha_NE => ".", haw => ".", he => ".", hi => ".", hr => ",", hr_BA => ",", hsb => ",", hu => ",", hy => ",", ia => ",", id => ",", ig => ".", ii => ".", is => ",", it => ",", it_CH => ".", it_SM => ",", it_VA => ",", ja => ".", jgo => ",", jmc => ".", jv => ",", ka => ",", kab => ",", kam => ".", kde => ".", kea => ",", khq => ".", ki => ".", kk => ",", kkj => ",", kl => ",", kln => ".", km => ",", kn => ".", ko => ".", ko_KP => ".", kok => ".", ks => "\u{66b}", ksb => ".", ksf => ",", ksh => ",", ku => ",", kw => ".", ky => ",", lag => ".", lb => ",", lg => ".", lkt => ".", ln => ",", ln_AO => ",", ln_CF => ",", ln_CG => ",", lo => ",", lrc => "\u{66b}", lrc_IQ => "\u{66b}", lt => ",", lu => ",", luo => ".", luy => ".", lv => ",", mas => ".", mas_TZ => ".", mer => ".", mfe => ".", mg => ".", mgh => ",", mgo => ".", mi => ".", mk => ",", ml => ".", mn => ".", mr => ".", ms => ".", ms_BN => ",", ms_SG => ".", mt => ".", mua => ",", my => ".", mzn => "\u{66b}", naq => ".", nb => ",", nb_SJ => ",", nd => ".", nds => ".", nds_NL => ".", ne => ".", ne_IN => ".", nl => ",", nl_AW => ",", nl_BE => ",", nl_BQ => ",", nl_CW => ",", nl_SR => ",", nl_SX => ",", nmg => ",", nn => ",", nnh => ",", nus => ".", nyn => ".", om => ".", om_KE => ".", or => ".", os => ",", os_RU => ",", pa => ".", pa_Arab => "\u{66b}", pa_Guru => ".", pl => ",", prg => ".", ps => "\u{66b}", pt => ",", pt_AO => ",", pt_CH => ",", pt_CV => ",", pt_GQ => ",", pt_GW => ",", pt_LU => ",", pt_MO => ",", pt_MZ => ",", pt_PT => ",", pt_ST => ",", pt_TL => ",", qu => ".", qu_BO => ",", qu_EC => ".", rm => ".", rn => ",", ro => ",", ro_MD => ",", rof => ".", root => ".", ru => ",", ru_BY => ",", ru_KG => ",", ru_KZ => ",", ru_MD => ",", ru_UA => ",", rw => ",", rwk => ".", sah => ",", saq => ".", sbp => ".", sd => "\u{66b}", se => ",", se_FI => ",", se_SE => ",", seh => ",", ses => ".", sg => ",", shi => ",", shi_Latn => ",", shi_Tfng => ",", si => ".", sk => ",", sl => ",", smn => ",", sn => ".", so => ".", so_DJ => ".", so_ET => ".", so_KE => ".", sq => ",", sq_MK => ",", sq_XK => ",", sr => ",", sr_Cyrl => ",", sr_Cyrl_BA => ",", sr_Cyrl_ME => ",", sr_Cyrl_XK => ",", sr_Latn => ",", sr_Latn_BA => ",", sr_Latn_ME => ",", sr_Latn_XK => ",", sv => ",", sv_AX => ",", sv_FI => ",", sw => ".", sw_CD => ",", sw_KE => ".", sw_UG => ".", ta => ".", ta_LK => ".", ta_MY => ".", ta_SG => ".", te => ".", teo => ".", teo_KE => ".", tg => ",", th => ".", ti => ".", ti_ER => ".", tk => ",", to => ".", tr => ",", tr_CY => ",", tt => ",", twq => ".", tzm => ",", ug => ".", uk => ",", ur => ".", ur_IN => "\u{66b}", uz => ",", uz_Arab => "\u{66b}", uz_Cyrl => ",", uz_Latn => ",", vai => ".", vai_Latn => ".", vai_Vaii => ".", vi => ",", vo => ".", vun => ".", wae => ",", wo => ",", xh => ".", xog => ".", yav => ",", yi => ".", yo => ".", yo_BJ => ".", yue => ".", yue_Hans => ".", yue_Hant => ".", zgh => ",", zh => ".", zh_Hans => ".", zh_Hans_HK => ".", zh_Hans_MO => ".", zh_Hans_SG => ".", zh_Hant => ".", zh_Hant_HK => ".", zh_Hant_MO => ".", zu => ".", } } #[doc = r" Returns the locale's [`Grouping`]."] #[doc = r""] #[doc = r" [`Grouping`]: enum.Grouping.html"] pub fn grouping(&self) -> Grouping { use self::Grouping::*; use self::Locale::*; match self { af => Standard, af_NA => Standard, agq => Standard, ak => Standard, am => Standard, ar => Standard, ar_AE => Standard, ar_BH => Standard, ar_DJ => Standard, ar_DZ => Standard, ar_EG => Standard, ar_EH => Standard, ar_ER => Standard, ar_IL => Standard, ar_IQ => Standard, ar_JO => Standard, ar_KM => Standard, ar_KW => Standard, ar_LB => Standard, ar_LY => Standard, ar_MA => Standard, ar_MR => Standard, ar_OM => Standard, ar_PS => Standard, ar_QA => Standard, ar_SA => Standard, ar_SD => Standard, ar_SO => Standard, ar_SS => Standard, ar_SY => Standard, ar_TD => Standard, ar_TN => Standard, ar_YE => Standard, as_ => Indian, asa => Standard, ast => Standard, az => Standard, az_Cyrl => Standard, az_Latn => Standard, bas => Standard, be => Standard, bem => Standard, bez => Standard, bg => Standard, bm => Standard, bn => Indian, bn_IN => Indian, bo => Standard, bo_IN => Standard, br => Standard, brx => Indian, bs => Standard, bs_Cyrl => Standard, bs_Latn => Standard, ca => Standard, ca_AD => Standard, ca_ES_VALENCIA => Standard, ca_FR => Standard, ca_IT => Standard, ccp => Indian, ccp_IN => Indian, ce => Standard, cgg => Standard, chr => Standard, ckb => Standard, ckb_IR => Standard, cs => Standard, cu => Standard, cy => Standard, da => Standard, da_GL => Standard, dav => Standard, de => Standard, de_AT => Standard, de_BE => Standard, de_CH => Standard, de_IT => Standard, de_LI => Standard, de_LU => Standard, dje => Standard, dsb => Standard, dua => Standard, dyo => Standard, dz => Indian, ebu => Standard, ee => Standard, ee_TG => Standard, el => Standard, el_CY => Standard, en => Standard, en_001 => Standard, en_150 => Standard, en_AG => Standard, en_AI => Standard, en_AS => Standard, en_AT => Standard, en_AU => Standard, en_BB => Standard, en_BE => Standard, en_BI => Standard, en_BM => Standard, en_BS => Standard, en_BW => Standard, en_BZ => Standard, en_CA => Standard, en_CC => Standard, en_CH => Standard, en_CK => Standard, en_CM => Standard, en_CX => Standard, en_CY => Standard, en_DE => Standard, en_DG => Standard, en_DK => Standard, en_DM => Standard, en_ER => Standard, en_FI => Standard, en_FJ => Standard, en_FK => Standard, en_FM => Standard, en_GB => Standard, en_GD => Standard, en_GG => Standard, en_GH => Standard, en_GI => Standard, en_GM => Standard, en_GU => Standard, en_GY => Standard, en_HK => Standard, en_IE => Standard, en_IL => Standard, en_IM => Standard, en_IN => Indian, en_IO => Standard, en_JE => Standard, en_JM => Standard, en_KE => Standard, en_KI => Standard, en_KN => Standard, en_KY => Standard, en_LC => Standard, en_LR => Standard, en_LS => Standard, en_MG => Standard, en_MH => Standard, en_MO => Standard, en_MP => Standard, en_MS => Standard, en_MT => Standard, en_MU => Standard, en_MW => Standard, en_MY => Standard, en_NA => Standard, en_NF => Standard, en_NG => Standard, en_NL => Standard, en_NR => Standard, en_NU => Standard, en_NZ => Standard, en_PG => Standard, en_PH => Standard, en_PK => Standard, en_PN => Standard, en_PR => Standard, en_PW => Standard, en_RW => Standard, en_SB => Standard, en_SC => Standard, en_SD => Standard, en_SE => Standard, en_SG => Standard, en_SH => Standard, en_SI => Standard, en_SL => Standard, en_SS => Standard, en_SX => Standard, en_SZ => Standard, en_TC => Standard, en_TK => Standard, en_TO => Standard, en_TT => Standard, en_TV => Standard, en_TZ => Standard, en_UG => Standard, en_UM => Standard, en_US_POSIX => Posix, en_VC => Standard, en_VG => Standard, en_VI => Standard, en_VU => Standard, en_WS => Standard, en_ZA => Standard, en_ZM => Standard, en_ZW => Standard, eo => Standard, es => Standard, es_419 => Standard, es_AR => Standard, es_BO => Standard, es_BR => Standard, es_BZ => Standard, es_CL => Standard, es_CO => Standard, es_CR => Standard, es_CU => Standard, es_DO => Standard, es_EA => Standard, es_EC => Standard, es_GQ => Standard, es_GT => Standard, es_HN => Standard, es_IC => Standard, es_MX => Standard, es_NI => Standard, es_PA => Standard, es_PE => Standard, es_PH => Standard, es_PR => Standard, es_PY => Standard, es_SV => Standard, es_US => Standard, es_UY => Standard, es_VE => Standard, et => Standard, eu => Standard, ewo => Standard, fa => Standard, fa_AF => Standard, ff => Standard, ff_Latn => Standard, ff_Latn_BF => Standard, ff_Latn_CM => Standard, ff_Latn_GH => Standard, ff_Latn_GM => Standard, ff_Latn_GN => Standard, ff_Latn_GW => Standard, ff_Latn_LR => Standard, ff_Latn_MR => Standard, ff_Latn_NE => Standard, ff_Latn_NG => Standard, ff_Latn_SL => Standard, fi => Standard, fil => Standard, fo => Standard, fo_DK => Standard, fr => Standard, fr_BE => Standard, fr_BF => Standard, fr_BI => Standard, fr_BJ => Standard, fr_BL => Standard, fr_CA => Standard, fr_CD => Standard, fr_CF => Standard, fr_CG => Standard, fr_CH => Standard, fr_CI => Standard, fr_CM => Standard, fr_DJ => Standard, fr_DZ => Standard, fr_GA => Standard, fr_GF => Standard, fr_GN => Standard, fr_GP => Standard, fr_GQ => Standard, fr_HT => Standard, fr_KM => Standard, fr_LU => Standard, fr_MA => Standard, fr_MC => Standard, fr_MF => Standard, fr_MG => Standard, fr_ML => Standard, fr_MQ => Standard, fr_MR => Standard, fr_MU => Standard, fr_NC => Standard, fr_NE => Standard, fr_PF => Standard, fr_PM => Standard, fr_RE => Standard, fr_RW => Standard, fr_SC => Standard, fr_SN => Standard, fr_SY => Standard, fr_TD => Standard, fr_TG => Standard, fr_TN => Standard, fr_VU => Standard, fr_WF => Standard, fr_YT => Standard, fur => Standard, fy => Standard, ga => Standard, gd => Standard, gl => Standard, gsw => Standard, gsw_FR => Standard, gsw_LI => Standard, gu => Indian, guz => Standard, gv => Standard, ha => Standard, ha_GH => Standard, ha_NE => Standard, haw => Standard, he => Standard, hi => Indian, hr => Standard, hr_BA => Standard, hsb => Standard, hu => Standard, hy => Standard, ia => Standard, id => Standard, ig => Standard, ii => Standard, is => Standard, it => Standard, it_CH => Standard, it_SM => Standard, it_VA => Standard, ja => Standard, jgo => Standard, jmc => Standard, jv => Standard, ka => Standard, kab => Standard, kam => Standard, kde => Standard, kea => Standard, khq => Standard, ki => Standard, kk => Standard, kkj => Standard, kl => Standard, kln => Standard, km => Standard, kn => Standard, ko => Standard, ko_KP => Standard, kok => Indian, ks => Indian, ksb => Standard, ksf => Standard, ksh => Standard, ku => Standard, kw => Standard, ky => Standard, lag => Standard, lb => Standard, lg => Standard, lkt => Standard, ln => Standard, ln_AO => Standard, ln_CF => Standard, ln_CG => Standard, lo => Standard, lrc => Standard, lrc_IQ => Standard, lt => Standard, lu => Standard, luo => Standard, luy => Standard, lv => Standard, mas => Standard, mas_TZ => Standard, mer => Standard, mfe => Standard, mg => Standard, mgh => Standard, mgo => Standard, mi => Standard, mk => Standard, ml => Indian, mn => Standard, mr => Indian, ms => Standard, ms_BN => Standard, ms_SG => Standard, mt => Standard, mua => Standard, my => Standard, mzn => Standard, naq => Standard, nb => Standard, nb_SJ => Standard, nd => Standard, nds => Standard, nds_NL => Standard, ne => Standard, ne_IN => Standard, nl => Standard, nl_AW => Standard, nl_BE => Standard, nl_BQ => Standard, nl_CW => Standard, nl_SR => Standard, nl_SX => Standard, nmg => Standard, nn => Standard, nnh => Standard, nus => Standard, nyn => Standard, om => Standard, om_KE => Standard, or => Indian, os => Standard, os_RU => Standard, pa => Indian, pa_Arab => Standard, pa_Guru => Indian, pl => Standard, prg => Standard, ps => Standard, pt => Standard, pt_AO => Standard, pt_CH => Standard, pt_CV => Standard, pt_GQ => Standard, pt_GW => Standard, pt_LU => Standard, pt_MO => Standard, pt_MZ => Standard, pt_PT => Standard, pt_ST => Standard, pt_TL => Standard, qu => Standard, qu_BO => Standard, qu_EC => Standard, rm => Standard, rn => Standard, ro => Standard, ro_MD => Standard, rof => Standard, root => Standard, ru => Standard, ru_BY => Standard, ru_KG => Standard, ru_KZ => Standard, ru_MD => Standard, ru_UA => Standard, rw => Standard, rwk => Standard, sah => Standard, saq => Standard, sbp => Standard, sd => Standard, se => Standard, se_FI => Standard, se_SE => Standard, seh => Standard, ses => Standard, sg => Standard, shi => Standard, shi_Latn => Standard, shi_Tfng => Standard, si => Standard, sk => Standard, sl => Standard, smn => Standard, sn => Standard, so => Standard, so_DJ => Standard, so_ET => Standard, so_KE => Standard, sq => Standard, sq_MK => Standard, sq_XK => Standard, sr => Standard, sr_Cyrl => Standard, sr_Cyrl_BA => Standard, sr_Cyrl_ME => Standard, sr_Cyrl_XK => Standard, sr_Latn => Standard, sr_Latn_BA => Standard, sr_Latn_ME => Standard, sr_Latn_XK => Standard, sv => Standard, sv_AX => Standard, sv_FI => Standard, sw => Standard, sw_CD => Standard, sw_KE => Standard, sw_UG => Standard, ta => Indian, ta_LK => Indian, ta_MY => Standard, ta_SG => Standard, te => Indian, teo => Standard, teo_KE => Standard, tg => Standard, th => Standard, ti => Standard, ti_ER => Standard, tk => Standard, to => Standard, tr => Standard, tr_CY => Standard, tt => Standard, twq => Standard, tzm => Standard, ug => Standard, uk => Standard, ur => Standard, ur_IN => Standard, uz => Standard, uz_Arab => Standard, uz_Cyrl => Standard, uz_Latn => Standard, vai => Standard, vai_Latn => Standard, vai_Vaii => Standard, vi => Standard, vo => Standard, vun => Standard, wae => Standard, wo => Standard, xh => Standard, xog => Standard, yav => Standard, yi => Standard, yo => Standard, yo_BJ => Standard, yue => Standard, yue_Hans => Standard, yue_Hant => Standard, zgh => Standard, zh => Standard, zh_Hans => Standard, zh_Hans_HK => Standard, zh_Hans_MO => Standard, zh_Hans_SG => Standard, zh_Hant => Standard, zh_Hant_HK => Standard, zh_Hant_MO => Standard, zu => Standard, } } #[doc = r" Returns the locale's infinity representation."] pub fn infinity(&self) -> &'static str { use self::Locale::*; match self { af => "\u{221e}", af_NA => "\u{221e}", agq => "\u{221e}", ak => "\u{221e}", am => "\u{221e}", ar => "\u{221e}", ar_AE => "\u{221e}", ar_BH => "\u{221e}", ar_DJ => "\u{221e}", ar_DZ => "\u{221e}", ar_EG => "\u{221e}", ar_EH => "\u{221e}", ar_ER => "\u{221e}", ar_IL => "\u{221e}", ar_IQ => "\u{221e}", ar_JO => "\u{221e}", ar_KM => "\u{221e}", ar_KW => "\u{221e}", ar_LB => "\u{221e}", ar_LY => "\u{221e}", ar_MA => "\u{221e}", ar_MR => "\u{221e}", ar_OM => "\u{221e}", ar_PS => "\u{221e}", ar_QA => "\u{221e}", ar_SA => "\u{221e}", ar_SD => "\u{221e}", ar_SO => "\u{221e}", ar_SS => "\u{221e}", ar_SY => "\u{221e}", ar_TD => "\u{221e}", ar_TN => "\u{221e}", ar_YE => "\u{221e}", as_ => "\u{221e}", asa => "\u{221e}", ast => "\u{221e}", az => "\u{221e}", az_Cyrl => "\u{221e}", az_Latn => "\u{221e}", bas => "\u{221e}", be => "\u{221e}", bem => "\u{221e}", bez => "\u{221e}", bg => "\u{221e}", bm => "\u{221e}", bn => "\u{221e}", bn_IN => "\u{221e}", bo => "\u{221e}", bo_IN => "\u{221e}", br => "\u{221e}", brx => "\u{221e}", bs => "\u{221e}", bs_Cyrl => "\u{221e}", bs_Latn => "\u{221e}", ca => "\u{221e}", ca_AD => "\u{221e}", ca_ES_VALENCIA => "\u{221e}", ca_FR => "\u{221e}", ca_IT => "\u{221e}", ccp => "\u{221e}", ccp_IN => "\u{221e}", ce => "\u{221e}", cgg => "\u{221e}", chr => "\u{221e}", ckb => "\u{221e}", ckb_IR => "\u{221e}", cs => "\u{221e}", cu => "\u{221e}", cy => "\u{221e}", da => "\u{221e}", da_GL => "\u{221e}", dav => "\u{221e}", de => "\u{221e}", de_AT => "\u{221e}", de_BE => "\u{221e}", de_CH => "\u{221e}", de_IT => "\u{221e}", de_LI => "\u{221e}", de_LU => "\u{221e}", dje => "\u{221e}", dsb => "\u{221e}", dua => "\u{221e}", dyo => "\u{221e}", dz => "\u{f42}\u{fb2}\u{f44}\u{f66}\u{f0b}\u{f58}\u{f7a}\u{f51}", ebu => "\u{221e}", ee => "\u{221e}", ee_TG => "\u{221e}", el => "\u{221e}", el_CY => "\u{221e}", en => "\u{221e}", en_001 => "\u{221e}", en_150 => "\u{221e}", en_AG => "\u{221e}", en_AI => "\u{221e}", en_AS => "\u{221e}", en_AT => "\u{221e}", en_AU => "\u{221e}", en_BB => "\u{221e}", en_BE => "\u{221e}", en_BI => "\u{221e}", en_BM => "\u{221e}", en_BS => "\u{221e}", en_BW => "\u{221e}", en_BZ => "\u{221e}", en_CA => "\u{221e}", en_CC => "\u{221e}", en_CH => "\u{221e}", en_CK => "\u{221e}", en_CM => "\u{221e}", en_CX => "\u{221e}", en_CY => "\u{221e}", en_DE => "\u{221e}", en_DG => "\u{221e}", en_DK => "\u{221e}", en_DM => "\u{221e}", en_ER => "\u{221e}", en_FI => "\u{221e}", en_FJ => "\u{221e}", en_FK => "\u{221e}", en_FM => "\u{221e}", en_GB => "\u{221e}", en_GD => "\u{221e}", en_GG => "\u{221e}", en_GH => "\u{221e}", en_GI => "\u{221e}", en_GM => "\u{221e}", en_GU => "\u{221e}", en_GY => "\u{221e}", en_HK => "\u{221e}", en_IE => "\u{221e}", en_IL => "\u{221e}", en_IM => "\u{221e}", en_IN => "\u{221e}", en_IO => "\u{221e}", en_JE => "\u{221e}", en_JM => "\u{221e}", en_KE => "\u{221e}", en_KI => "\u{221e}", en_KN => "\u{221e}", en_KY => "\u{221e}", en_LC => "\u{221e}", en_LR => "\u{221e}", en_LS => "\u{221e}", en_MG => "\u{221e}", en_MH => "\u{221e}", en_MO => "\u{221e}", en_MP => "\u{221e}", en_MS => "\u{221e}", en_MT => "\u{221e}", en_MU => "\u{221e}", en_MW => "\u{221e}", en_MY => "\u{221e}", en_NA => "\u{221e}", en_NF => "\u{221e}", en_NG => "\u{221e}", en_NL => "\u{221e}", en_NR => "\u{221e}", en_NU => "\u{221e}", en_NZ => "\u{221e}", en_PG => "\u{221e}", en_PH => "\u{221e}", en_PK => "\u{221e}", en_PN => "\u{221e}", en_PR => "\u{221e}", en_PW => "\u{221e}", en_RW => "\u{221e}", en_SB => "\u{221e}", en_SC => "\u{221e}", en_SD => "\u{221e}", en_SE => "\u{221e}", en_SG => "\u{221e}", en_SH => "\u{221e}", en_SI => "\u{221e}", en_SL => "\u{221e}", en_SS => "\u{221e}", en_SX => "\u{221e}", en_SZ => "\u{221e}", en_TC => "\u{221e}", en_TK => "\u{221e}", en_TO => "\u{221e}", en_TT => "\u{221e}", en_TV => "\u{221e}", en_TZ => "\u{221e}", en_UG => "\u{221e}", en_UM => "\u{221e}", en_US_POSIX => "INF", en_VC => "\u{221e}", en_VG => "\u{221e}", en_VI => "\u{221e}", en_VU => "\u{221e}", en_WS => "\u{221e}", en_ZA => "\u{221e}", en_ZM => "\u{221e}", en_ZW => "\u{221e}", eo => "\u{221e}", es => "\u{221e}", es_419 => "\u{221e}", es_AR => "\u{221e}", es_BO => "\u{221e}", es_BR => "\u{221e}", es_BZ => "\u{221e}", es_CL => "\u{221e}", es_CO => "\u{221e}", es_CR => "\u{221e}", es_CU => "\u{221e}", es_DO => "\u{221e}", es_EA => "\u{221e}", es_EC => "\u{221e}", es_GQ => "\u{221e}", es_GT => "\u{221e}", es_HN => "\u{221e}", es_IC => "\u{221e}", es_MX => "\u{221e}", es_NI => "\u{221e}", es_PA => "\u{221e}", es_PE => "\u{221e}", es_PH => "\u{221e}", es_PR => "\u{221e}", es_PY => "\u{221e}", es_SV => "\u{221e}", es_US => "\u{221e}", es_UY => "\u{221e}", es_VE => "\u{221e}", et => "\u{221e}", eu => "\u{221e}", ewo => "\u{221e}", fa => "\u{221e}", fa_AF => "\u{221e}", ff => "\u{221e}", ff_Latn => "\u{221e}", ff_Latn_BF => "\u{221e}", ff_Latn_CM => "\u{221e}", ff_Latn_GH => "\u{221e}", ff_Latn_GM => "\u{221e}", ff_Latn_GN => "\u{221e}", ff_Latn_GW => "\u{221e}", ff_Latn_LR => "\u{221e}", ff_Latn_MR => "\u{221e}", ff_Latn_NE => "\u{221e}", ff_Latn_NG => "\u{221e}", ff_Latn_SL => "\u{221e}", fi => "\u{221e}", fil => "\u{221e}", fo => "\u{221e}", fo_DK => "\u{221e}", fr => "\u{221e}", fr_BE => "\u{221e}", fr_BF => "\u{221e}", fr_BI => "\u{221e}", fr_BJ => "\u{221e}", fr_BL => "\u{221e}", fr_CA => "\u{221e}", fr_CD => "\u{221e}", fr_CF => "\u{221e}", fr_CG => "\u{221e}", fr_CH => "\u{221e}", fr_CI => "\u{221e}", fr_CM => "\u{221e}", fr_DJ => "\u{221e}", fr_DZ => "\u{221e}", fr_GA => "\u{221e}", fr_GF => "\u{221e}", fr_GN => "\u{221e}", fr_GP => "\u{221e}", fr_GQ => "\u{221e}", fr_HT => "\u{221e}", fr_KM => "\u{221e}", fr_LU => "\u{221e}", fr_MA => "\u{221e}", fr_MC => "\u{221e}", fr_MF => "\u{221e}", fr_MG => "\u{221e}", fr_ML => "\u{221e}", fr_MQ => "\u{221e}", fr_MR => "\u{221e}", fr_MU => "\u{221e}", fr_NC => "\u{221e}", fr_NE => "\u{221e}", fr_PF => "\u{221e}", fr_PM => "\u{221e}", fr_RE => "\u{221e}", fr_RW => "\u{221e}", fr_SC => "\u{221e}", fr_SN => "\u{221e}", fr_SY => "\u{221e}", fr_TD => "\u{221e}", fr_TG => "\u{221e}", fr_TN => "\u{221e}", fr_VU => "\u{221e}", fr_WF => "\u{221e}", fr_YT => "\u{221e}", fur => "\u{221e}", fy => "\u{221e}", ga => "\u{221e}", gd => "\u{221e}", gl => "\u{221e}", gsw => "\u{221e}", gsw_FR => "\u{221e}", gsw_LI => "\u{221e}", gu => "\u{221e}", guz => "\u{221e}", gv => "\u{221e}", ha => "\u{221e}", ha_GH => "\u{221e}", ha_NE => "\u{221e}", haw => "\u{221e}", he => "\u{221e}", hi => "\u{221e}", hr => "\u{221e}", hr_BA => "\u{221e}", hsb => "\u{221e}", hu => "\u{221e}", hy => "\u{221e}", ia => "\u{221e}", id => "\u{221e}", ig => "\u{221e}", ii => "\u{221e}", is => "\u{221e}", it => "\u{221e}", it_CH => "\u{221e}", it_SM => "\u{221e}", it_VA => "\u{221e}", ja => "\u{221e}", jgo => "\u{221e}", jmc => "\u{221e}", jv => "\u{221e}", ka => "\u{221e}", kab => "\u{221e}", kam => "\u{221e}", kde => "\u{221e}", kea => "\u{221e}", khq => "\u{221e}", ki => "\u{221e}", kk => "\u{221e}", kkj => "\u{221e}", kl => "\u{221e}", kln => "\u{221e}", km => "\u{221e}", kn => "\u{221e}", ko => "\u{221e}", ko_KP => "\u{221e}", kok => "\u{221e}", ks => "\u{221e}", ksb => "\u{221e}", ksf => "\u{221e}", ksh => "\u{221e}", ku => "\u{221e}", kw => "\u{221e}", ky => "\u{221e}", lag => "\u{221e}", lb => "\u{221e}", lg => "\u{221e}", lkt => "\u{221e}", ln => "\u{221e}", ln_AO => "\u{221e}", ln_CF => "\u{221e}", ln_CG => "\u{221e}", lo => "\u{221e}", lrc => "\u{221e}", lrc_IQ => "\u{221e}", lt => "\u{221e}", lu => "\u{221e}", luo => "\u{221e}", luy => "\u{221e}", lv => "\u{221e}", mas => "\u{221e}", mas_TZ => "\u{221e}", mer => "\u{221e}", mfe => "\u{221e}", mg => "\u{221e}", mgh => "\u{221e}", mgo => "\u{221e}", mi => "\u{221e}", mk => "\u{221e}", ml => "\u{221e}", mn => "\u{221e}", mr => "\u{221e}", ms => "\u{221e}", ms_BN => "\u{221e}", ms_SG => "\u{221e}", mt => "\u{221e}", mua => "\u{221e}", my => "\u{221e}", mzn => "\u{221e}", naq => "\u{221e}", nb => "\u{221e}", nb_SJ => "\u{221e}", nd => "\u{221e}", nds => "\u{221e}", nds_NL => "\u{221e}", ne => "\u{221e}", ne_IN => "\u{221e}", nl => "\u{221e}", nl_AW => "\u{221e}", nl_BE => "\u{221e}", nl_BQ => "\u{221e}", nl_CW => "\u{221e}", nl_SR => "\u{221e}", nl_SX => "\u{221e}", nmg => "\u{221e}", nn => "\u{221e}", nnh => "\u{221e}", nus => "\u{221e}", nyn => "\u{221e}", om => "\u{221e}", om_KE => "\u{221e}", or => "\u{221e}", os => "\u{221e}", os_RU => "\u{221e}", pa => "\u{221e}", pa_Arab => "\u{221e}", pa_Guru => "\u{221e}", pl => "\u{221e}", prg => "\u{221e}", ps => "\u{221e}", pt => "\u{221e}", pt_AO => "\u{221e}", pt_CH => "\u{221e}", pt_CV => "\u{221e}", pt_GQ => "\u{221e}", pt_GW => "\u{221e}", pt_LU => "\u{221e}", pt_MO => "\u{221e}", pt_MZ => "\u{221e}", pt_PT => "\u{221e}", pt_ST => "\u{221e}", pt_TL => "\u{221e}", qu => "\u{221e}", qu_BO => "\u{221e}", qu_EC => "\u{221e}", rm => "\u{221e}", rn => "\u{221e}", ro => "\u{221e}", ro_MD => "\u{221e}", rof => "\u{221e}", root => "\u{221e}", ru => "\u{221e}", ru_BY => "\u{221e}", ru_KG => "\u{221e}", ru_KZ => "\u{221e}", ru_MD => "\u{221e}", ru_UA => "\u{221e}", rw => "\u{221e}", rwk => "\u{221e}", sah => "\u{221e}", saq => "\u{221e}", sbp => "\u{221e}", sd => "\u{221e}", se => "\u{221e}", se_FI => "\u{221e}", se_SE => "\u{221e}", seh => "\u{221e}", ses => "\u{221e}", sg => "\u{221e}", shi => "\u{221e}", shi_Latn => "\u{221e}", shi_Tfng => "\u{221e}", si => "\u{221e}", sk => "\u{221e}", sl => "\u{221e}", smn => "\u{221e}", sn => "\u{221e}", so => "\u{221e}", so_DJ => "\u{221e}", so_ET => "\u{221e}", so_KE => "\u{221e}", sq => "\u{221e}", sq_MK => "\u{221e}", sq_XK => "\u{221e}", sr => "\u{221e}", sr_Cyrl => "\u{221e}", sr_Cyrl_BA => "\u{221e}", sr_Cyrl_ME => "\u{221e}", sr_Cyrl_XK => "\u{221e}", sr_Latn => "\u{221e}", sr_Latn_BA => "\u{221e}", sr_Latn_ME => "\u{221e}", sr_Latn_XK => "\u{221e}", sv => "\u{221e}", sv_AX => "\u{221e}", sv_FI => "\u{221e}", sw => "\u{221e}", sw_CD => "\u{221e}", sw_KE => "\u{221e}", sw_UG => "\u{221e}", ta => "\u{221e}", ta_LK => "\u{221e}", ta_MY => "\u{221e}", ta_SG => "\u{221e}", te => "\u{221e}", teo => "\u{221e}", teo_KE => "\u{221e}", tg => "\u{221e}", th => "\u{221e}", ti => "\u{221e}", ti_ER => "\u{221e}", tk => "\u{221e}", to => "\u{221e}", tr => "\u{221e}", tr_CY => "\u{221e}", tt => "\u{221e}", twq => "\u{221e}", tzm => "\u{221e}", ug => "\u{221e}", uk => "\u{221e}", ur => "\u{221e}", ur_IN => "\u{221e}", uz => "\u{221e}", uz_Arab => "\u{221e}", uz_Cyrl => "\u{221e}", uz_Latn => "\u{221e}", vai => "\u{221e}", vai_Latn => "\u{221e}", vai_Vaii => "\u{221e}", vi => "\u{221e}", vo => "\u{221e}", vun => "\u{221e}", wae => "\u{221e}", wo => "\u{221e}", xh => "\u{221e}", xog => "\u{221e}", yav => "\u{221e}", yi => "\u{221e}", yo => "\u{221e}", yo_BJ => "\u{221e}", yue => "\u{221e}", yue_Hans => "\u{221e}", yue_Hant => "\u{221e}", zgh => "\u{221e}", zh => "\u{221e}", zh_Hans => "\u{221e}", zh_Hans_HK => "\u{221e}", zh_Hans_MO => "\u{221e}", zh_Hans_SG => "\u{221e}", zh_Hant => "\u{221e}", zh_Hant_HK => "\u{221e}", zh_Hant_MO => "\u{221e}", zu => "\u{221e}", } } #[doc = r" Returns the locale's minus sign representation."] pub fn minus_sign(&self) -> &'static str { use self::Locale::*; match self { af => "-", af_NA => "-", agq => "-", ak => "-", am => "-", ar => "\u{61c}-", ar_AE => "\u{61c}-", ar_BH => "\u{61c}-", ar_DJ => "\u{61c}-", ar_DZ => "\u{200e}-", ar_EG => "\u{61c}-", ar_EH => "\u{200e}-", ar_ER => "\u{61c}-", ar_IL => "\u{61c}-", ar_IQ => "\u{61c}-", ar_JO => "\u{61c}-", ar_KM => "\u{61c}-", ar_KW => "\u{61c}-", ar_LB => "\u{61c}-", ar_LY => "\u{200e}-", ar_MA => "\u{200e}-", ar_MR => "\u{61c}-", ar_OM => "\u{61c}-", ar_PS => "\u{61c}-", ar_QA => "\u{61c}-", ar_SA => "\u{61c}-", ar_SD => "\u{61c}-", ar_SO => "\u{61c}-", ar_SS => "\u{61c}-", ar_SY => "\u{61c}-", ar_TD => "\u{61c}-", ar_TN => "\u{200e}-", ar_YE => "\u{61c}-", as_ => "-", asa => "-", ast => "-", az => "-", az_Cyrl => "-", az_Latn => "-", bas => "-", be => "-", bem => "-", bez => "-", bg => "-", bm => "-", bn => "-", bn_IN => "-", bo => "-", bo_IN => "-", br => "-", brx => "-", bs => "-", bs_Cyrl => "-", bs_Latn => "-", ca => "-", ca_AD => "-", ca_ES_VALENCIA => "-", ca_FR => "-", ca_IT => "-", ccp => "-", ccp_IN => "-", ce => "-", cgg => "-", chr => "-", ckb => "\u{200f}-", ckb_IR => "\u{200f}-", cs => "-", cu => "-", cy => "-", da => "-", da_GL => "-", dav => "-", de => "-", de_AT => "-", de_BE => "-", de_CH => "-", de_IT => "-", de_LI => "-", de_LU => "-", dje => "-", dsb => "-", dua => "-", dyo => "-", dz => "-", ebu => "-", ee => "-", ee_TG => "-", el => "-", el_CY => "-", en => "-", en_001 => "-", en_150 => "-", en_AG => "-", en_AI => "-", en_AS => "-", en_AT => "-", en_AU => "-", en_BB => "-", en_BE => "-", en_BI => "-", en_BM => "-", en_BS => "-", en_BW => "-", en_BZ => "-", en_CA => "-", en_CC => "-", en_CH => "-", en_CK => "-", en_CM => "-", en_CX => "-", en_CY => "-", en_DE => "-", en_DG => "-", en_DK => "-", en_DM => "-", en_ER => "-", en_FI => "-", en_FJ => "-", en_FK => "-", en_FM => "-", en_GB => "-", en_GD => "-", en_GG => "-", en_GH => "-", en_GI => "-", en_GM => "-", en_GU => "-", en_GY => "-", en_HK => "-", en_IE => "-", en_IL => "-", en_IM => "-", en_IN => "-", en_IO => "-", en_JE => "-", en_JM => "-", en_KE => "-", en_KI => "-", en_KN => "-", en_KY => "-", en_LC => "-", en_LR => "-", en_LS => "-", en_MG => "-", en_MH => "-", en_MO => "-", en_MP => "-", en_MS => "-", en_MT => "-", en_MU => "-", en_MW => "-", en_MY => "-", en_NA => "-", en_NF => "-", en_NG => "-", en_NL => "-", en_NR => "-", en_NU => "-", en_NZ => "-", en_PG => "-", en_PH => "-", en_PK => "-", en_PN => "-", en_PR => "-", en_PW => "-", en_RW => "-", en_SB => "-", en_SC => "-", en_SD => "-", en_SE => "-", en_SG => "-", en_SH => "-", en_SI => "-", en_SL => "-", en_SS => "-", en_SX => "-", en_SZ => "-", en_TC => "-", en_TK => "-", en_TO => "-", en_TT => "-", en_TV => "-", en_TZ => "-", en_UG => "-", en_UM => "-", en_US_POSIX => "-", en_VC => "-", en_VG => "-", en_VI => "-", en_VU => "-", en_WS => "-", en_ZA => "-", en_ZM => "-", en_ZW => "-", eo => "-", es => "-", es_419 => "-", es_AR => "-", es_BO => "-", es_BR => "-", es_BZ => "-", es_CL => "-", es_CO => "-", es_CR => "-", es_CU => "-", es_DO => "-", es_EA => "-", es_EC => "-", es_GQ => "-", es_GT => "-", es_HN => "-", es_IC => "-", es_MX => "-", es_NI => "-", es_PA => "-", es_PE => "-", es_PH => "-", es_PR => "-", es_PY => "-", es_SV => "-", es_US => "-", es_UY => "-", es_VE => "-", et => "\u{2212}", eu => "\u{2212}", ewo => "-", fa => "\u{200e}\u{2212}", fa_AF => "\u{200e}\u{2212}", ff => "-", ff_Latn => "-", ff_Latn_BF => "-", ff_Latn_CM => "-", ff_Latn_GH => "-", ff_Latn_GM => "-", ff_Latn_GN => "-", ff_Latn_GW => "-", ff_Latn_LR => "-", ff_Latn_MR => "-", ff_Latn_NE => "-", ff_Latn_NG => "-", ff_Latn_SL => "-", fi => "\u{2212}", fil => "-", fo => "\u{2212}", fo_DK => "\u{2212}", fr => "-", fr_BE => "-", fr_BF => "-", fr_BI => "-", fr_BJ => "-", fr_BL => "-", fr_CA => "-", fr_CD => "-", fr_CF => "-", fr_CG => "-", fr_CH => "-", fr_CI => "-", fr_CM => "-", fr_DJ => "-", fr_DZ => "-", fr_GA => "-", fr_GF => "-", fr_GN => "-", fr_GP => "-", fr_GQ => "-", fr_HT => "-", fr_KM => "-", fr_LU => "-", fr_MA => "-", fr_MC => "-", fr_MF => "-", fr_MG => "-", fr_ML => "-", fr_MQ => "-", fr_MR => "-", fr_MU => "-", fr_NC => "-", fr_NE => "-", fr_PF => "-", fr_PM => "-", fr_RE => "-", fr_RW => "-", fr_SC => "-", fr_SN => "-", fr_SY => "-", fr_TD => "-", fr_TG => "-", fr_TN => "-", fr_VU => "-", fr_WF => "-", fr_YT => "-", fur => "-", fy => "-", ga => "-", gd => "-", gl => "-", gsw => "\u{2212}", gsw_FR => "\u{2212}", gsw_LI => "\u{2212}", gu => "-", guz => "-", gv => "-", ha => "-", ha_GH => "-", ha_NE => "-", haw => "-", he => "\u{200e}-", hi => "-", hr => "-", hr_BA => "-", hsb => "-", hu => "-", hy => "-", ia => "-", id => "-", ig => "-", ii => "-", is => "-", it => "-", it_CH => "-", it_SM => "-", it_VA => "-", ja => "-", jgo => "-", jmc => "-", jv => "-", ka => "-", kab => "-", kam => "-", kde => "-", kea => "-", khq => "-", ki => "-", kk => "-", kkj => "-", kl => "-", kln => "-", km => "-", kn => "-", ko => "-", ko_KP => "-", kok => "-", ks => "\u{200e}-\u{200e}", ksb => "-", ksf => "-", ksh => "\u{2212}", ku => "-", kw => "-", ky => "-", lag => "-", lb => "-", lg => "-", lkt => "-", ln => "-", ln_AO => "-", ln_CF => "-", ln_CG => "-", lo => "-", lrc => "\u{200e}-\u{200e}", lrc_IQ => "\u{200e}-\u{200e}", lt => "\u{2212}", lu => "-", luo => "-", luy => "-", lv => "-", mas => "-", mas_TZ => "-", mer => "-", mfe => "-", mg => "-", mgh => "-", mgo => "-", mi => "-", mk => "-", ml => "-", mn => "-", mr => "-", ms => "-", ms_BN => "-", ms_SG => "-", mt => "-", mua => "-", my => "-", mzn => "\u{200e}-\u{200e}", naq => "-", nb => "\u{2212}", nb_SJ => "\u{2212}", nd => "-", nds => "-", nds_NL => "-", ne => "-", ne_IN => "-", nl => "-", nl_AW => "-", nl_BE => "-", nl_BQ => "-", nl_CW => "-", nl_SR => "-", nl_SX => "-", nmg => "-", nn => "\u{2212}", nnh => "-", nus => "-", nyn => "-", om => "-", om_KE => "-", or => "-", os => "-", os_RU => "-", pa => "-", pa_Arab => "\u{200e}-\u{200e}", pa_Guru => "-", pl => "-", prg => "-", ps => "\u{200e}-\u{200e}", pt => "-", pt_AO => "-", pt_CH => "-", pt_CV => "-", pt_GQ => "-", pt_GW => "-", pt_LU => "-", pt_MO => "-", pt_MZ => "-", pt_PT => "-", pt_ST => "-", pt_TL => "-", qu => "-", qu_BO => "-", qu_EC => "-", rm => "\u{2212}", rn => "-", ro => "-", ro_MD => "-", rof => "-", root => "-", ru => "-", ru_BY => "-", ru_KG => "-", ru_KZ => "-", ru_MD => "-", ru_UA => "-", rw => "-", rwk => "-", sah => "-", saq => "-", sbp => "-", sd => "\u{61c}-", se => "\u{2212}", se_FI => "\u{2212}", se_SE => "\u{2212}", seh => "-", ses => "-", sg => "-", shi => "-", shi_Latn => "-", shi_Tfng => "-", si => "-", sk => "-", sl => "\u{2212}", smn => "-", sn => "-", so => "-", so_DJ => "-", so_ET => "-", so_KE => "-", sq => "-", sq_MK => "-", sq_XK => "-", sr => "-", sr_Cyrl => "-", sr_Cyrl_BA => "-", sr_Cyrl_ME => "-", sr_Cyrl_XK => "-", sr_Latn => "-", sr_Latn_BA => "-", sr_Latn_ME => "-", sr_Latn_XK => "-", sv => "\u{2212}", sv_AX => "\u{2212}", sv_FI => "\u{2212}", sw => "-", sw_CD => "-", sw_KE => "-", sw_UG => "-", ta => "-", ta_LK => "-", ta_MY => "-", ta_SG => "-", te => "-", teo => "-", teo_KE => "-", tg => "-", th => "-", ti => "-", ti_ER => "-", tk => "-", to => "-", tr => "-", tr_CY => "-", tt => "-", twq => "-", tzm => "-", ug => "-", uk => "-", ur => "\u{200e}-", ur_IN => "\u{200e}-\u{200e}", uz => "-", uz_Arab => "\u{200e}-\u{200e}", uz_Cyrl => "-", uz_Latn => "-", vai => "-", vai_Latn => "-", vai_Vaii => "-", vi => "-", vo => "-", vun => "-", wae => "-", wo => "-", xh => "-", xog => "-", yav => "-", yi => "-", yo => "-", yo_BJ => "-", yue => "-", yue_Hans => "-", yue_Hant => "-", zgh => "-", zh => "-", zh_Hans => "-", zh_Hans_HK => "-", zh_Hans_MO => "-", zh_Hans_SG => "-", zh_Hant => "-", zh_Hant_HK => "-", zh_Hant_MO => "-", zu => "-", } } #[doc = r" Returns the locale's name."] pub fn name(&self) -> &'static str { use self::Locale::*; match self { af => "af", af_NA => "af-NA", agq => "agq", ak => "ak", am => "am", ar => "ar", ar_AE => "ar-AE", ar_BH => "ar-BH", ar_DJ => "ar-DJ", ar_DZ => "ar-DZ", ar_EG => "ar-EG", ar_EH => "ar-EH", ar_ER => "ar-ER", ar_IL => "ar-IL", ar_IQ => "ar-IQ", ar_JO => "ar-JO", ar_KM => "ar-KM", ar_KW => "ar-KW", ar_LB => "ar-LB", ar_LY => "ar-LY", ar_MA => "ar-MA", ar_MR => "ar-MR", ar_OM => "ar-OM", ar_PS => "ar-PS", ar_QA => "ar-QA", ar_SA => "ar-SA", ar_SD => "ar-SD", ar_SO => "ar-SO", ar_SS => "ar-SS", ar_SY => "ar-SY", ar_TD => "ar-TD", ar_TN => "ar-TN", ar_YE => "ar-YE", as_ => "as", asa => "asa", ast => "ast", az => "az", az_Cyrl => "az-Cyrl", az_Latn => "az-Latn", bas => "bas", be => "be", bem => "bem", bez => "bez", bg => "bg", bm => "bm", bn => "bn", bn_IN => "bn-IN", bo => "bo", bo_IN => "bo-IN", br => "br", brx => "brx", bs => "bs", bs_Cyrl => "bs-Cyrl", bs_Latn => "bs-Latn", ca => "ca", ca_AD => "ca-AD", ca_ES_VALENCIA => "ca-ES-VALENCIA", ca_FR => "ca-FR", ca_IT => "ca-IT", ccp => "ccp", ccp_IN => "ccp-IN", ce => "ce", cgg => "cgg", chr => "chr", ckb => "ckb", ckb_IR => "ckb-IR", cs => "cs", cu => "cu", cy => "cy", da => "da", da_GL => "da-GL", dav => "dav", de => "de", de_AT => "de-AT", de_BE => "de-BE", de_CH => "de-CH", de_IT => "de-IT", de_LI => "de-LI", de_LU => "de-LU", dje => "dje", dsb => "dsb", dua => "dua", dyo => "dyo", dz => "dz", ebu => "ebu", ee => "ee", ee_TG => "ee-TG", el => "el", el_CY => "el-CY", en => "en", en_001 => "en-001", en_150 => "en-150", en_AG => "en-AG", en_AI => "en-AI", en_AS => "en-AS", en_AT => "en-AT", en_AU => "en-AU", en_BB => "en-BB", en_BE => "en-BE", en_BI => "en-BI", en_BM => "en-BM", en_BS => "en-BS", en_BW => "en-BW", en_BZ => "en-BZ", en_CA => "en-CA", en_CC => "en-CC", en_CH => "en-CH", en_CK => "en-CK", en_CM => "en-CM", en_CX => "en-CX", en_CY => "en-CY", en_DE => "en-DE", en_DG => "en-DG", en_DK => "en-DK", en_DM => "en-DM", en_ER => "en-ER", en_FI => "en-FI", en_FJ => "en-FJ", en_FK => "en-FK", en_FM => "en-FM", en_GB => "en-GB", en_GD => "en-GD", en_GG => "en-GG", en_GH => "en-GH", en_GI => "en-GI", en_GM => "en-GM", en_GU => "en-GU", en_GY => "en-GY", en_HK => "en-HK", en_IE => "en-IE", en_IL => "en-IL", en_IM => "en-IM", en_IN => "en-IN", en_IO => "en-IO", en_JE => "en-JE", en_JM => "en-JM", en_KE => "en-KE", en_KI => "en-KI", en_KN => "en-KN", en_KY => "en-KY", en_LC => "en-LC", en_LR => "en-LR", en_LS => "en-LS", en_MG => "en-MG", en_MH => "en-MH", en_MO => "en-MO", en_MP => "en-MP", en_MS => "en-MS", en_MT => "en-MT", en_MU => "en-MU", en_MW => "en-MW", en_MY => "en-MY", en_NA => "en-NA", en_NF => "en-NF", en_NG => "en-NG", en_NL => "en-NL", en_NR => "en-NR", en_NU => "en-NU", en_NZ => "en-NZ", en_PG => "en-PG", en_PH => "en-PH", en_PK => "en-PK", en_PN => "en-PN", en_PR => "en-PR", en_PW => "en-PW", en_RW => "en-RW", en_SB => "en-SB", en_SC => "en-SC", en_SD => "en-SD", en_SE => "en-SE", en_SG => "en-SG", en_SH => "en-SH", en_SI => "en-SI", en_SL => "en-SL", en_SS => "en-SS", en_SX => "en-SX", en_SZ => "en-SZ", en_TC => "en-TC", en_TK => "en-TK", en_TO => "en-TO", en_TT => "en-TT", en_TV => "en-TV", en_TZ => "en-TZ", en_UG => "en-UG", en_UM => "en-UM", en_US_POSIX => "en-US-POSIX", en_VC => "en-VC", en_VG => "en-VG", en_VI => "en-VI", en_VU => "en-VU", en_WS => "en-WS", en_ZA => "en-ZA", en_ZM => "en-ZM", en_ZW => "en-ZW", eo => "eo", es => "es", es_419 => "es-419", es_AR => "es-AR", es_BO => "es-BO", es_BR => "es-BR", es_BZ => "es-BZ", es_CL => "es-CL", es_CO => "es-CO", es_CR => "es-CR", es_CU => "es-CU", es_DO => "es-DO", es_EA => "es-EA", es_EC => "es-EC", es_GQ => "es-GQ", es_GT => "es-GT", es_HN => "es-HN", es_IC => "es-IC", es_MX => "es-MX", es_NI => "es-NI", es_PA => "es-PA", es_PE => "es-PE", es_PH => "es-PH", es_PR => "es-PR", es_PY => "es-PY", es_SV => "es-SV", es_US => "es-US", es_UY => "es-UY", es_VE => "es-VE", et => "et", eu => "eu", ewo => "ewo", fa => "fa", fa_AF => "fa-AF", ff => "ff", ff_Latn => "ff-Latn", ff_Latn_BF => "ff-Latn-BF", ff_Latn_CM => "ff-Latn-CM", ff_Latn_GH => "ff-Latn-GH", ff_Latn_GM => "ff-Latn-GM", ff_Latn_GN => "ff-Latn-GN", ff_Latn_GW => "ff-Latn-GW", ff_Latn_LR => "ff-Latn-LR", ff_Latn_MR => "ff-Latn-MR", ff_Latn_NE => "ff-Latn-NE", ff_Latn_NG => "ff-Latn-NG", ff_Latn_SL => "ff-Latn-SL", fi => "fi", fil => "fil", fo => "fo", fo_DK => "fo-DK", fr => "fr", fr_BE => "fr-BE", fr_BF => "fr-BF", fr_BI => "fr-BI", fr_BJ => "fr-BJ", fr_BL => "fr-BL", fr_CA => "fr-CA", fr_CD => "fr-CD", fr_CF => "fr-CF", fr_CG => "fr-CG", fr_CH => "fr-CH", fr_CI => "fr-CI", fr_CM => "fr-CM", fr_DJ => "fr-DJ", fr_DZ => "fr-DZ", fr_GA => "fr-GA", fr_GF => "fr-GF", fr_GN => "fr-GN", fr_GP => "fr-GP", fr_GQ => "fr-GQ", fr_HT => "fr-HT", fr_KM => "fr-KM", fr_LU => "fr-LU", fr_MA => "fr-MA", fr_MC => "fr-MC", fr_MF => "fr-MF", fr_MG => "fr-MG", fr_ML => "fr-ML", fr_MQ => "fr-MQ", fr_MR => "fr-MR", fr_MU => "fr-MU", fr_NC => "fr-NC", fr_NE => "fr-NE", fr_PF => "fr-PF", fr_PM => "fr-PM", fr_RE => "fr-RE", fr_RW => "fr-RW", fr_SC => "fr-SC", fr_SN => "fr-SN", fr_SY => "fr-SY", fr_TD => "fr-TD", fr_TG => "fr-TG", fr_TN => "fr-TN", fr_VU => "fr-VU", fr_WF => "fr-WF", fr_YT => "fr-YT", fur => "fur", fy => "fy", ga => "ga", gd => "gd", gl => "gl", gsw => "gsw", gsw_FR => "gsw-FR", gsw_LI => "gsw-LI", gu => "gu", guz => "guz", gv => "gv", ha => "ha", ha_GH => "ha-GH", ha_NE => "ha-NE", haw => "haw", he => "he", hi => "hi", hr => "hr", hr_BA => "hr-BA", hsb => "hsb", hu => "hu", hy => "hy", ia => "ia", id => "id", ig => "ig", ii => "ii", is => "is", it => "it", it_CH => "it-CH", it_SM => "it-SM", it_VA => "it-VA", ja => "ja", jgo => "jgo", jmc => "jmc", jv => "jv", ka => "ka", kab => "kab", kam => "kam", kde => "kde", kea => "kea", khq => "khq", ki => "ki", kk => "kk", kkj => "kkj", kl => "kl", kln => "kln", km => "km", kn => "kn", ko => "ko", ko_KP => "ko-KP", kok => "kok", ks => "ks", ksb => "ksb", ksf => "ksf", ksh => "ksh", ku => "ku", kw => "kw", ky => "ky", lag => "lag", lb => "lb", lg => "lg", lkt => "lkt", ln => "ln", ln_AO => "ln-AO", ln_CF => "ln-CF", ln_CG => "ln-CG", lo => "lo", lrc => "lrc", lrc_IQ => "lrc-IQ", lt => "lt", lu => "lu", luo => "luo", luy => "luy", lv => "lv", mas => "mas", mas_TZ => "mas-TZ", mer => "mer", mfe => "mfe", mg => "mg", mgh => "mgh", mgo => "mgo", mi => "mi", mk => "mk", ml => "ml", mn => "mn", mr => "mr", ms => "ms", ms_BN => "ms-BN", ms_SG => "ms-SG", mt => "mt", mua => "mua", my => "my", mzn => "mzn", naq => "naq", nb => "nb", nb_SJ => "nb-SJ", nd => "nd", nds => "nds", nds_NL => "nds-NL", ne => "ne", ne_IN => "ne-IN", nl => "nl", nl_AW => "nl-AW", nl_BE => "nl-BE", nl_BQ => "nl-BQ", nl_CW => "nl-CW", nl_SR => "nl-SR", nl_SX => "nl-SX", nmg => "nmg", nn => "nn", nnh => "nnh", nus => "nus", nyn => "nyn", om => "om", om_KE => "om-KE", or => "or", os => "os", os_RU => "os-RU", pa => "pa", pa_Arab => "pa-Arab", pa_Guru => "pa-Guru", pl => "pl", prg => "prg", ps => "ps", pt => "pt", pt_AO => "pt-AO", pt_CH => "pt-CH", pt_CV => "pt-CV", pt_GQ => "pt-GQ", pt_GW => "pt-GW", pt_LU => "pt-LU", pt_MO => "pt-MO", pt_MZ => "pt-MZ", pt_PT => "pt-PT", pt_ST => "pt-ST", pt_TL => "pt-TL", qu => "qu", qu_BO => "qu-BO", qu_EC => "qu-EC", rm => "rm", rn => "rn", ro => "ro", ro_MD => "ro-MD", rof => "rof", root => "root", ru => "ru", ru_BY => "ru-BY", ru_KG => "ru-KG", ru_KZ => "ru-KZ", ru_MD => "ru-MD", ru_UA => "ru-UA", rw => "rw", rwk => "rwk", sah => "sah", saq => "saq", sbp => "sbp", sd => "sd", se => "se", se_FI => "se-FI", se_SE => "se-SE", seh => "seh", ses => "ses", sg => "sg", shi => "shi", shi_Latn => "shi-Latn", shi_Tfng => "shi-Tfng", si => "si", sk => "sk", sl => "sl", smn => "smn", sn => "sn", so => "so", so_DJ => "so-DJ", so_ET => "so-ET", so_KE => "so-KE", sq => "sq", sq_MK => "sq-MK", sq_XK => "sq-XK", sr => "sr", sr_Cyrl => "sr-Cyrl", sr_Cyrl_BA => "sr-Cyrl-BA", sr_Cyrl_ME => "sr-Cyrl-ME", sr_Cyrl_XK => "sr-Cyrl-XK", sr_Latn => "sr-Latn", sr_Latn_BA => "sr-Latn-BA", sr_Latn_ME => "sr-Latn-ME", sr_Latn_XK => "sr-Latn-XK", sv => "sv", sv_AX => "sv-AX", sv_FI => "sv-FI", sw => "sw", sw_CD => "sw-CD", sw_KE => "sw-KE", sw_UG => "sw-UG", ta => "ta", ta_LK => "ta-LK", ta_MY => "ta-MY", ta_SG => "ta-SG", te => "te", teo => "teo", teo_KE => "teo-KE", tg => "tg", th => "th", ti => "ti", ti_ER => "ti-ER", tk => "tk", to => "to", tr => "tr", tr_CY => "tr-CY", tt => "tt", twq => "twq", tzm => "tzm", ug => "ug", uk => "uk", ur => "ur", ur_IN => "ur-IN", uz => "uz", uz_Arab => "uz-Arab", uz_Cyrl => "uz-Cyrl", uz_Latn => "uz-Latn", vai => "vai", vai_Latn => "vai-Latn", vai_Vaii => "vai-Vaii", vi => "vi", vo => "vo", vun => "vun", wae => "wae", wo => "wo", xh => "xh", xog => "xog", yav => "yav", yi => "yi", yo => "yo", yo_BJ => "yo-BJ", yue => "yue", yue_Hans => "yue-Hans", yue_Hant => "yue-Hant", zgh => "zgh", zh => "zh", zh_Hans => "zh-Hans", zh_Hans_HK => "zh-Hans-HK", zh_Hans_MO => "zh-Hans-MO", zh_Hans_SG => "zh-Hans-SG", zh_Hant => "zh-Hant", zh_Hant_HK => "zh-Hant-HK", zh_Hant_MO => "zh-Hant-MO", zu => "zu", } } #[doc = r" Returns the locale's NaN representation."] pub fn nan(&self) -> &'static str { use self::Locale::*; match self { af => "NaN" , af_NA => "NaN" , agq => "NaN" , ak => "NaN" , am => "NaN" , ar => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_AE => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_BH => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_DJ => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_DZ => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}\u{64b}\u{627}" , ar_EG => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_EH => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}\u{64b}\u{627}" , ar_ER => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_IL => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_IQ => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_JO => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_KM => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_KW => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_LB => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_LY => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}\u{64b}\u{627}" , ar_MA => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}\u{64b}\u{627}" , ar_MR => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_OM => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_PS => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_QA => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_SA => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_SD => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_SO => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_SS => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_SY => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_TD => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , ar_TN => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}\u{64b}\u{627}" , ar_YE => "\u{644}\u{64a}\u{633}\u{a0}\u{631}\u{642}\u{645}" , as_ => "NaN" , asa => "NaN" , ast => "ND" , az => "NaN" , az_Cyrl => "NaN" , az_Latn => "NaN" , bas => "NaN" , be => "NaN" , bem => "NaN" , bez => "NaN" , bg => "NaN" , bm => "NaN" , bn => "NaN" , bn_IN => "NaN" , bo => "NaN" , bo_IN => "NaN" , br => "NaN" , brx => "NaN" , bs => "NaN" , bs_Cyrl => "NaN" , bs_Latn => "NaN" , ca => "NaN" , ca_AD => "NaN" , ca_ES_VALENCIA => "NaN" , ca_FR => "NaN" , ca_IT => "NaN" , ccp => "NaN" , ccp_IN => "NaN" , ce => "\u{422}\u{435}\u{440}\u{445}\u{44c}\u{430}\u{448}\u{a0}\u{434}\u{430}\u{446}" , cgg => "NaN" , chr => "NaN" , ckb => "NaN" , ckb_IR => "NaN" , cs => "NaN" , cu => "NaN" , cy => "NaN" , da => "NaN" , da_GL => "NaN" , dav => "NaN" , de => "NaN" , de_AT => "NaN" , de_BE => "NaN" , de_CH => "NaN" , de_IT => "NaN" , de_LI => "NaN" , de_LU => "NaN" , dje => "NaN" , dsb => "NaN" , dua => "NaN" , dyo => "NaN" , dz => "\u{f68}\u{f44}\u{f0b}\u{f58}\u{f51}" , ebu => "NaN" , ee => "mnn" , ee_TG => "mnn" , el => "NaN" , el_CY => "NaN" , en => "NaN" , en_001 => "NaN" , en_150 => "NaN" , en_AG => "NaN" , en_AI => "NaN" , en_AS => "NaN" , en_AT => "NaN" , en_AU => "NaN" , en_BB => "NaN" , en_BE => "NaN" , en_BI => "NaN" , en_BM => "NaN" , en_BS => "NaN" , en_BW => "NaN" , en_BZ => "NaN" , en_CA => "NaN" , en_CC => "NaN" , en_CH => "NaN" , en_CK => "NaN" , en_CM => "NaN" , en_CX => "NaN" , en_CY => "NaN" , en_DE => "NaN" , en_DG => "NaN" , en_DK => "NaN" , en_DM => "NaN" , en_ER => "NaN" , en_FI => "NaN" , en_FJ => "NaN" , en_FK => "NaN" , en_FM => "NaN" , en_GB => "NaN" , en_GD => "NaN" , en_GG => "NaN" , en_GH => "NaN" , en_GI => "NaN" , en_GM => "NaN" , en_GU => "NaN" , en_GY => "NaN" , en_HK => "NaN" , en_IE => "NaN" , en_IL => "NaN" , en_IM => "NaN" , en_IN => "NaN" , en_IO => "NaN" , en_JE => "NaN" , en_JM => "NaN" , en_KE => "NaN" , en_KI => "NaN" , en_KN => "NaN" , en_KY => "NaN" , en_LC => "NaN" , en_LR => "NaN" , en_LS => "NaN" , en_MG => "NaN" , en_MH => "NaN" , en_MO => "NaN" , en_MP => "NaN" , en_MS => "NaN" , en_MT => "NaN" , en_MU => "NaN" , en_MW => "NaN" , en_MY => "NaN" , en_NA => "NaN" , en_NF => "NaN" , en_NG => "NaN" , en_NL => "NaN" , en_NR => "NaN" , en_NU => "NaN" , en_NZ => "NaN" , en_PG => "NaN" , en_PH => "NaN" , en_PK => "NaN" , en_PN => "NaN" , en_PR => "NaN" , en_PW => "NaN" , en_RW => "NaN" , en_SB => "NaN" , en_SC => "NaN" , en_SD => "NaN" , en_SE => "NaN" , en_SG => "NaN" , en_SH => "NaN" , en_SI => "NaN" , en_SL => "NaN" , en_SS => "NaN" , en_SX => "NaN" , en_SZ => "NaN" , en_TC => "NaN" , en_TK => "NaN" , en_TO => "NaN" , en_TT => "NaN" , en_TV => "NaN" , en_TZ => "NaN" , en_UG => "NaN" , en_UM => "NaN" , en_US_POSIX => "NaN" , en_VC => "NaN" , en_VG => "NaN" , en_VI => "NaN" , en_VU => "NaN" , en_WS => "NaN" , en_ZA => "NaN" , en_ZM => "NaN" , en_ZW => "NaN" , eo => "NaN" , es => "NaN" , es_419 => "NaN" , es_AR => "NaN" , es_BO => "NaN" , es_BR => "NaN" , es_BZ => "NaN" , es_CL => "NaN" , es_CO => "NaN" , es_CR => "NaN" , es_CU => "NaN" , es_DO => "NaN" , es_EA => "NaN" , es_EC => "NaN" , es_GQ => "NaN" , es_GT => "NaN" , es_HN => "NaN" , es_IC => "NaN" , es_MX => "NaN" , es_NI => "NaN" , es_PA => "NaN" , es_PE => "NaN" , es_PH => "NaN" , es_PR => "NaN" , es_PY => "NaN" , es_SV => "NaN" , es_US => "NaN" , es_UY => "NaN" , es_VE => "NaN" , et => "NaN" , eu => "NaN" , ewo => "NaN" , fa => "\u{646}\u{627}\u{639}\u{62f}\u{62f}" , fa_AF => "\u{646}\u{627}\u{639}\u{62f}\u{62f}" , ff => "NaN" , ff_Latn => "NaN" , ff_Latn_BF => "NaN" , ff_Latn_CM => "NaN" , ff_Latn_GH => "NaN" , ff_Latn_GM => "NaN" , ff_Latn_GN => "NaN" , ff_Latn_GW => "NaN" , ff_Latn_LR => "NaN" , ff_Latn_MR => "NaN" , ff_Latn_NE => "NaN" , ff_Latn_NG => "NaN" , ff_Latn_SL => "NaN" , fi => "ep\u{e4}luku" , fil => "NaN" , fo => "NaN" , fo_DK => "NaN" , fr => "NaN" , fr_BE => "NaN" , fr_BF => "NaN" , fr_BI => "NaN" , fr_BJ => "NaN" , fr_BL => "NaN" , fr_CA => "NaN" , fr_CD => "NaN" , fr_CF => "NaN" , fr_CG => "NaN" , fr_CH => "NaN" , fr_CI => "NaN" , fr_CM => "NaN" , fr_DJ => "NaN" , fr_DZ => "NaN" , fr_GA => "NaN" , fr_GF => "NaN" , fr_GN => "NaN" , fr_GP => "NaN" , fr_GQ => "NaN" , fr_HT => "NaN" , fr_KM => "NaN" , fr_LU => "NaN" , fr_MA => "NaN" , fr_MC => "NaN" , fr_MF => "NaN" , fr_MG => "NaN" , fr_ML => "NaN" , fr_MQ => "NaN" , fr_MR => "NaN" , fr_MU => "NaN" , fr_NC => "NaN" , fr_NE => "NaN" , fr_PF => "NaN" , fr_PM => "NaN" , fr_RE => "NaN" , fr_RW => "NaN" , fr_SC => "NaN" , fr_SN => "NaN" , fr_SY => "NaN" , fr_TD => "NaN" , fr_TG => "NaN" , fr_TN => "NaN" , fr_VU => "NaN" , fr_WF => "NaN" , fr_YT => "NaN" , fur => "NaN" , fy => "NaN" , ga => "NaN" , gd => "NaN" , gl => "NaN" , gsw => "NaN" , gsw_FR => "NaN" , gsw_LI => "NaN" , gu => "NaN" , guz => "NaN" , gv => "NaN" , ha => "NaN" , ha_GH => "NaN" , ha_NE => "NaN" , haw => "NaN" , he => "NaN" , hi => "NaN" , hr => "NaN" , hr_BA => "NaN" , hsb => "NaN" , hu => "NaN" , hy => "\u{548}\u{579}\u{539}" , ia => "NaN" , id => "NaN" , ig => "NaN" , ii => "NaN" , is => "NaN" , it => "NaN" , it_CH => "NaN" , it_SM => "NaN" , it_VA => "NaN" , ja => "NaN" , jgo => "NaN" , jmc => "NaN" , jv => "NaN" , ka => "\u{10d0}\u{10e0}\u{a0}\u{10d0}\u{10e0}\u{10d8}\u{10e1}\u{a0}\u{10e0}\u{10d8}\u{10ea}\u{10ee}\u{10d5}\u{10d8}" , kab => "NaN" , kam => "NaN" , kde => "NaN" , kea => "NaN" , khq => "NaN" , ki => "NaN" , kk => "\u{441}\u{430}\u{43d}\u{a0}\u{435}\u{43c}\u{435}\u{441}" , kkj => "NaN" , kl => "NaN" , kln => "NaN" , km => "NaN" , kn => "NaN" , ko => "NaN" , ko_KP => "NaN" , kok => "NaN" , ks => "NaN" , ksb => "NaN" , ksf => "NaN" , ksh => "\u{a4}\u{a4}\u{a4}" , ku => "NaN" , kw => "NaN" , ky => "\u{441}\u{430}\u{43d}\u{a0}\u{44d}\u{43c}\u{435}\u{441}" , lag => "NaN" , lb => "NaN" , lg => "NaN" , lkt => "NaN" , ln => "NaN" , ln_AO => "NaN" , ln_CF => "NaN" , ln_CG => "NaN" , lo => "\u{e9a}\u{ecd}\u{ec8}\u{200b}\u{ec1}\u{ea1}\u{ec8}\u{e99}\u{200b}\u{ec2}\u{e95}\u{200b}\u{ec0}\u{ea5}\u{e81}" , lrc => "NaN" , lrc_IQ => "NaN" , lt => "NaN" , lu => "NaN" , luo => "NaN" , luy => "NaN" , lv => "NS" , mas => "NaN" , mas_TZ => "NaN" , mer => "NaN" , mfe => "NaN" , mg => "NaN" , mgh => "NaN" , mgo => "NaN" , mi => "NaN" , mk => "NaN" , ml => "NaN" , mn => "NaN" , mr => "NaN" , ms => "NaN" , ms_BN => "NaN" , ms_SG => "NaN" , mt => "NaN" , mua => "NaN" , my => "\u{1002}\u{100f}\u{1014}\u{103a}\u{1038}\u{1019}\u{101f}\u{102f}\u{1010}\u{103a}\u{101e}\u{1031}\u{102c}" , mzn => "NaN" , naq => "NaN" , nb => "NaN" , nb_SJ => "NaN" , nd => "NaN" , nds => "NaN" , nds_NL => "NaN" , ne => "NaN" , ne_IN => "NaN" , nl => "NaN" , nl_AW => "NaN" , nl_BE => "NaN" , nl_BQ => "NaN" , nl_CW => "NaN" , nl_SR => "NaN" , nl_SX => "NaN" , nmg => "NaN" , nn => "NaN" , nnh => "NaN" , nus => "NaN" , nyn => "NaN" , om => "NaN" , om_KE => "NaN" , or => "NaN" , os => "\u{41d}\u{41d}" , os_RU => "\u{41d}\u{41d}" , pa => "NaN" , pa_Arab => "NaN" , pa_Guru => "NaN" , pl => "NaN" , prg => "NaN" , ps => "NaN" , pt => "NaN" , pt_AO => "NaN" , pt_CH => "NaN" , pt_CV => "NaN" , pt_GQ => "NaN" , pt_GW => "NaN" , pt_LU => "NaN" , pt_MO => "NaN" , pt_MZ => "NaN" , pt_PT => "NaN" , pt_ST => "NaN" , pt_TL => "NaN" , qu => "NaN" , qu_BO => "NaN" , qu_EC => "NaN" , rm => "NaN" , rn => "NaN" , ro => "NaN" , ro_MD => "NaN" , rof => "NaN" , root => "NaN" , ru => "\u{43d}\u{435}\u{a0}\u{447}\u{438}\u{441}\u{43b}\u{43e}" , ru_BY => "\u{43d}\u{435}\u{a0}\u{447}\u{438}\u{441}\u{43b}\u{43e}" , ru_KG => "\u{43d}\u{435}\u{a0}\u{447}\u{438}\u{441}\u{43b}\u{43e}" , ru_KZ => "\u{43d}\u{435}\u{a0}\u{447}\u{438}\u{441}\u{43b}\u{43e}" , ru_MD => "\u{43d}\u{435}\u{a0}\u{447}\u{438}\u{441}\u{43b}\u{43e}" , ru_UA => "\u{43d}\u{435}\u{a0}\u{447}\u{438}\u{441}\u{43b}\u{43e}" , rw => "NaN" , rwk => "NaN" , sah => "\u{447}\u{44b}\u{44b}\u{4bb}\u{44b}\u{43b}\u{430}\u{a0}\u{431}\u{443}\u{43e}\u{442}\u{430}\u{445}" , saq => "NaN" , sbp => "NaN" , sd => "NaN" , se => "\u{a4}\u{a4}\u{a4}" , se_FI => "\u{a4}\u{a4}\u{a4}" , se_SE => "\u{a4}\u{a4}\u{a4}" , seh => "NaN" , ses => "NaN" , sg => "NaN" , shi => "NaN" , shi_Latn => "NaN" , shi_Tfng => "NaN" , si => "NaN" , sk => "NaN" , sl => "NaN" , smn => "epiloho" , sn => "NaN" , so => "NaN" , so_DJ => "NaN" , so_ET => "NaN" , so_KE => "NaN" , sq => "NaN" , sq_MK => "NaN" , sq_XK => "NaN" , sr => "NaN" , sr_Cyrl => "NaN" , sr_Cyrl_BA => "NaN" , sr_Cyrl_ME => "NaN" , sr_Cyrl_XK => "NaN" , sr_Latn => "NaN" , sr_Latn_BA => "NaN" , sr_Latn_ME => "NaN" , sr_Latn_XK => "NaN" , sv => "\u{a4}\u{a4}\u{a4}" , sv_AX => "\u{a4}\u{a4}\u{a4}" , sv_FI => "\u{a4}\u{a4}\u{a4}" , sw => "NaN" , sw_CD => "NaN" , sw_KE => "NaN" , sw_UG => "NaN" , ta => "NaN" , ta_LK => "NaN" , ta_MY => "NaN" , ta_SG => "NaN" , te => "NaN" , teo => "NaN" , teo_KE => "NaN" , tg => "NaN" , th => "NaN" , ti => "NaN" , ti_ER => "NaN" , tk => "san\u{a0}d\u{e4}l" , to => "TF" , tr => "NaN" , tr_CY => "NaN" , tt => "NaN" , twq => "NaN" , tzm => "NaN" , ug => "NaN" , uk => "NaN" , ur => "NaN" , ur_IN => "NaN" , uz => "son\u{a0}emas" , uz_Arab => "NaN" , uz_Cyrl => "\u{4b3}\u{430}\u{49b}\u{438}\u{49b}\u{438}\u{439}\u{a0}\u{441}\u{43e}\u{43d}\u{a0}\u{44d}\u{43c}\u{430}\u{441}" , uz_Latn => "son\u{a0}emas" , vai => "NaN" , vai_Latn => "NaN" , vai_Vaii => "NaN" , vi => "NaN" , vo => "NaN" , vun => "NaN" , wae => "NaN" , wo => "NaN" , xh => "NaN" , xog => "NaN" , yav => "NaN" , yi => "NaN" , yo => "NaN" , yo_BJ => "NaN" , yue => "\u{975e}\u{6578}\u{503c}" , yue_Hans => "\u{975e}\u{6570}\u{503c}" , yue_Hant => "\u{975e}\u{6578}\u{503c}" , zgh => "NaN" , zh => "NaN" , zh_Hans => "NaN" , zh_Hans_HK => "NaN" , zh_Hans_MO => "NaN" , zh_Hans_SG => "NaN" , zh_Hant => "\u{975e}\u{6578}\u{503c}" , zh_Hant_HK => "\u{975e}\u{6578}\u{503c}" , zh_Hant_MO => "\u{975e}\u{6578}\u{503c}" , zu => "NaN" , } } #[doc = r" Returns the locale's plus sign representation."] pub fn plus_sign(&self) -> &'static str { use self::Locale::*; match self { af => "+", af_NA => "+", agq => "+", ak => "+", am => "+", ar => "\u{61c}+", ar_AE => "\u{61c}+", ar_BH => "\u{61c}+", ar_DJ => "\u{61c}+", ar_DZ => "\u{200e}+", ar_EG => "\u{61c}+", ar_EH => "\u{200e}+", ar_ER => "\u{61c}+", ar_IL => "\u{61c}+", ar_IQ => "\u{61c}+", ar_JO => "\u{61c}+", ar_KM => "\u{61c}+", ar_KW => "\u{61c}+", ar_LB => "\u{61c}+", ar_LY => "\u{200e}+", ar_MA => "\u{200e}+", ar_MR => "\u{61c}+", ar_OM => "\u{61c}+", ar_PS => "\u{61c}+", ar_QA => "\u{61c}+", ar_SA => "\u{61c}+", ar_SD => "\u{61c}+", ar_SO => "\u{61c}+", ar_SS => "\u{61c}+", ar_SY => "\u{61c}+", ar_TD => "\u{61c}+", ar_TN => "\u{200e}+", ar_YE => "\u{61c}+", as_ => "+", asa => "+", ast => "+", az => "+", az_Cyrl => "+", az_Latn => "+", bas => "+", be => "+", bem => "+", bez => "+", bg => "+", bm => "+", bn => "+", bn_IN => "+", bo => "+", bo_IN => "+", br => "+", brx => "+", bs => "+", bs_Cyrl => "+", bs_Latn => "+", ca => "+", ca_AD => "+", ca_ES_VALENCIA => "+", ca_FR => "+", ca_IT => "+", ccp => "+", ccp_IN => "+", ce => "+", cgg => "+", chr => "+", ckb => "\u{200f}+", ckb_IR => "\u{200f}+", cs => "+", cu => "+", cy => "+", da => "+", da_GL => "+", dav => "+", de => "+", de_AT => "+", de_BE => "+", de_CH => "+", de_IT => "+", de_LI => "+", de_LU => "+", dje => "+", dsb => "+", dua => "+", dyo => "+", dz => "+", ebu => "+", ee => "+", ee_TG => "+", el => "+", el_CY => "+", en => "+", en_001 => "+", en_150 => "+", en_AG => "+", en_AI => "+", en_AS => "+", en_AT => "+", en_AU => "+", en_BB => "+", en_BE => "+", en_BI => "+", en_BM => "+", en_BS => "+", en_BW => "+", en_BZ => "+", en_CA => "+", en_CC => "+", en_CH => "+", en_CK => "+", en_CM => "+", en_CX => "+", en_CY => "+", en_DE => "+", en_DG => "+", en_DK => "+", en_DM => "+", en_ER => "+", en_FI => "+", en_FJ => "+", en_FK => "+", en_FM => "+", en_GB => "+", en_GD => "+", en_GG => "+", en_GH => "+", en_GI => "+", en_GM => "+", en_GU => "+", en_GY => "+", en_HK => "+", en_IE => "+", en_IL => "+", en_IM => "+", en_IN => "+", en_IO => "+", en_JE => "+", en_JM => "+", en_KE => "+", en_KI => "+", en_KN => "+", en_KY => "+", en_LC => "+", en_LR => "+", en_LS => "+", en_MG => "+", en_MH => "+", en_MO => "+", en_MP => "+", en_MS => "+", en_MT => "+", en_MU => "+", en_MW => "+", en_MY => "+", en_NA => "+", en_NF => "+", en_NG => "+", en_NL => "+", en_NR => "+", en_NU => "+", en_NZ => "+", en_PG => "+", en_PH => "+", en_PK => "+", en_PN => "+", en_PR => "+", en_PW => "+", en_RW => "+", en_SB => "+", en_SC => "+", en_SD => "+", en_SE => "+", en_SG => "+", en_SH => "+", en_SI => "+", en_SL => "+", en_SS => "+", en_SX => "+", en_SZ => "+", en_TC => "+", en_TK => "+", en_TO => "+", en_TT => "+", en_TV => "+", en_TZ => "+", en_UG => "+", en_UM => "+", en_US_POSIX => "+", en_VC => "+", en_VG => "+", en_VI => "+", en_VU => "+", en_WS => "+", en_ZA => "+", en_ZM => "+", en_ZW => "+", eo => "+", es => "+", es_419 => "+", es_AR => "+", es_BO => "+", es_BR => "+", es_BZ => "+", es_CL => "+", es_CO => "+", es_CR => "+", es_CU => "+", es_DO => "+", es_EA => "+", es_EC => "+", es_GQ => "+", es_GT => "+", es_HN => "+", es_IC => "+", es_MX => "+", es_NI => "+", es_PA => "+", es_PE => "+", es_PH => "+", es_PR => "+", es_PY => "+", es_SV => "+", es_US => "+", es_UY => "+", es_VE => "+", et => "+", eu => "+", ewo => "+", fa => "\u{200e}+", fa_AF => "\u{200e}+", ff => "+", ff_Latn => "+", ff_Latn_BF => "+", ff_Latn_CM => "+", ff_Latn_GH => "+", ff_Latn_GM => "+", ff_Latn_GN => "+", ff_Latn_GW => "+", ff_Latn_LR => "+", ff_Latn_MR => "+", ff_Latn_NE => "+", ff_Latn_NG => "+", ff_Latn_SL => "+", fi => "+", fil => "+", fo => "+", fo_DK => "+", fr => "+", fr_BE => "+", fr_BF => "+", fr_BI => "+", fr_BJ => "+", fr_BL => "+", fr_CA => "+", fr_CD => "+", fr_CF => "+", fr_CG => "+", fr_CH => "+", fr_CI => "+", fr_CM => "+", fr_DJ => "+", fr_DZ => "+", fr_GA => "+", fr_GF => "+", fr_GN => "+", fr_GP => "+", fr_GQ => "+", fr_HT => "+", fr_KM => "+", fr_LU => "+", fr_MA => "+", fr_MC => "+", fr_MF => "+", fr_MG => "+", fr_ML => "+", fr_MQ => "+", fr_MR => "+", fr_MU => "+", fr_NC => "+", fr_NE => "+", fr_PF => "+", fr_PM => "+", fr_RE => "+", fr_RW => "+", fr_SC => "+", fr_SN => "+", fr_SY => "+", fr_TD => "+", fr_TG => "+", fr_TN => "+", fr_VU => "+", fr_WF => "+", fr_YT => "+", fur => "+", fy => "+", ga => "+", gd => "+", gl => "+", gsw => "+", gsw_FR => "+", gsw_LI => "+", gu => "+", guz => "+", gv => "+", ha => "+", ha_GH => "+", ha_NE => "+", haw => "+", he => "\u{200e}+", hi => "+", hr => "+", hr_BA => "+", hsb => "+", hu => "+", hy => "+", ia => "+", id => "+", ig => "+", ii => "+", is => "+", it => "+", it_CH => "+", it_SM => "+", it_VA => "+", ja => "+", jgo => "+", jmc => "+", jv => "+", ka => "+", kab => "+", kam => "+", kde => "+", kea => "+", khq => "+", ki => "+", kk => "+", kkj => "+", kl => "+", kln => "+", km => "+", kn => "+", ko => "+", ko_KP => "+", kok => "+", ks => "\u{200e}+\u{200e}", ksb => "+", ksf => "+", ksh => "+", ku => "+", kw => "+", ky => "+", lag => "+", lb => "+", lg => "+", lkt => "+", ln => "+", ln_AO => "+", ln_CF => "+", ln_CG => "+", lo => "+", lrc => "\u{200e}+\u{200e}", lrc_IQ => "\u{200e}+\u{200e}", lt => "+", lu => "+", luo => "+", luy => "+", lv => "+", mas => "+", mas_TZ => "+", mer => "+", mfe => "+", mg => "+", mgh => "+", mgo => "+", mi => "+", mk => "+", ml => "+", mn => "+", mr => "+", ms => "+", ms_BN => "+", ms_SG => "+", mt => "+", mua => "+", my => "+", mzn => "\u{200e}+\u{200e}", naq => "+", nb => "+", nb_SJ => "+", nd => "+", nds => "+", nds_NL => "+", ne => "+", ne_IN => "+", nl => "+", nl_AW => "+", nl_BE => "+", nl_BQ => "+", nl_CW => "+", nl_SR => "+", nl_SX => "+", nmg => "+", nn => "+", nnh => "+", nus => "+", nyn => "+", om => "+", om_KE => "+", or => "+", os => "+", os_RU => "+", pa => "+", pa_Arab => "\u{200e}+\u{200e}", pa_Guru => "+", pl => "+", prg => "+", ps => "\u{200e}+\u{200e}", pt => "+", pt_AO => "+", pt_CH => "+", pt_CV => "+", pt_GQ => "+", pt_GW => "+", pt_LU => "+", pt_MO => "+", pt_MZ => "+", pt_PT => "+", pt_ST => "+", pt_TL => "+", qu => "+", qu_BO => "+", qu_EC => "+", rm => "+", rn => "+", ro => "+", ro_MD => "+", rof => "+", root => "+", ru => "+", ru_BY => "+", ru_KG => "+", ru_KZ => "+", ru_MD => "+", ru_UA => "+", rw => "+", rwk => "+", sah => "+", saq => "+", sbp => "+", sd => "\u{61c}+", se => "+", se_FI => "+", se_SE => "+", seh => "+", ses => "+", sg => "+", shi => "+", shi_Latn => "+", shi_Tfng => "+", si => "+", sk => "+", sl => "+", smn => "+", sn => "+", so => "+", so_DJ => "+", so_ET => "+", so_KE => "+", sq => "+", sq_MK => "+", sq_XK => "+", sr => "+", sr_Cyrl => "+", sr_Cyrl_BA => "+", sr_Cyrl_ME => "+", sr_Cyrl_XK => "+", sr_Latn => "+", sr_Latn_BA => "+", sr_Latn_ME => "+", sr_Latn_XK => "+", sv => "+", sv_AX => "+", sv_FI => "+", sw => "+", sw_CD => "+", sw_KE => "+", sw_UG => "+", ta => "+", ta_LK => "+", ta_MY => "+", ta_SG => "+", te => "+", teo => "+", teo_KE => "+", tg => "+", th => "+", ti => "+", ti_ER => "+", tk => "+", to => "+", tr => "+", tr_CY => "+", tt => "+", twq => "+", tzm => "+", ug => "+", uk => "+", ur => "\u{200e}+", ur_IN => "\u{200e}+\u{200e}", uz => "+", uz_Arab => "\u{200e}+\u{200e}", uz_Cyrl => "+", uz_Latn => "+", vai => "+", vai_Latn => "+", vai_Vaii => "+", vi => "+", vo => "+", vun => "+", wae => "+", wo => "+", xh => "+", xog => "+", yav => "+", yi => "+", yo => "+", yo_BJ => "+", yue => "+", yue_Hans => "+", yue_Hant => "+", zgh => "+", zh => "+", zh_Hans => "+", zh_Hans_HK => "+", zh_Hans_MO => "+", zh_Hans_SG => "+", zh_Hant => "+", zh_Hant_HK => "+", zh_Hant_MO => "+", zu => "+", } } #[doc = r" Returns the locale's separator representation, if any."] pub fn separator(&self) -> &'static str { use self::Locale::*; match self { af => "\u{a0}", af_NA => "\u{a0}", agq => "\u{a0}", ak => ",", am => ",", ar => "\u{66c}", ar_AE => "\u{66c}", ar_BH => "\u{66c}", ar_DJ => "\u{66c}", ar_DZ => ".", ar_EG => "\u{66c}", ar_EH => ",", ar_ER => "\u{66c}", ar_IL => "\u{66c}", ar_IQ => "\u{66c}", ar_JO => "\u{66c}", ar_KM => "\u{66c}", ar_KW => "\u{66c}", ar_LB => "\u{66c}", ar_LY => ".", ar_MA => ".", ar_MR => "\u{66c}", ar_OM => "\u{66c}", ar_PS => "\u{66c}", ar_QA => "\u{66c}", ar_SA => "\u{66c}", ar_SD => "\u{66c}", ar_SO => "\u{66c}", ar_SS => "\u{66c}", ar_SY => "\u{66c}", ar_TD => "\u{66c}", ar_TN => ".", ar_YE => "\u{66c}", as_ => ",", asa => ",", ast => ".", az => ".", az_Cyrl => ".", az_Latn => ".", bas => "\u{a0}", be => "\u{a0}", bem => ",", bez => ",", bg => "\u{a0}", bm => ",", bn => ",", bn_IN => ",", bo => ",", bo_IN => ",", br => "\u{a0}", brx => ",", bs => ".", bs_Cyrl => ".", bs_Latn => ".", ca => ".", ca_AD => ".", ca_ES_VALENCIA => ".", ca_FR => ".", ca_IT => ".", ccp => ",", ccp_IN => ",", ce => ",", cgg => ",", chr => ",", ckb => "\u{66c}", ckb_IR => "\u{66c}", cs => "\u{a0}", cu => ",", cy => ",", da => ".", da_GL => ".", dav => ",", de => ".", de_AT => "\u{a0}", de_BE => ".", de_CH => "\u{2019}", de_IT => ".", de_LI => "\u{2019}", de_LU => ".", dje => "\u{a0}", dsb => ".", dua => "\u{a0}", dyo => "\u{a0}", dz => ",", ebu => ",", ee => ",", ee_TG => ",", el => ".", el_CY => ".", en => ",", en_001 => ",", en_150 => ".", en_AG => ",", en_AI => ",", en_AS => ",", en_AT => ".", en_AU => ",", en_BB => ",", en_BE => ".", en_BI => ",", en_BM => ",", en_BS => ",", en_BW => ",", en_BZ => ",", en_CA => ",", en_CC => ",", en_CH => ".", en_CK => ",", en_CM => ",", en_CX => ",", en_CY => ",", en_DE => ".", en_DG => ",", en_DK => ".", en_DM => ",", en_ER => ",", en_FI => "\u{a0}", en_FJ => ",", en_FK => ",", en_FM => ",", en_GB => ",", en_GD => ",", en_GG => ",", en_GH => ",", en_GI => ",", en_GM => ",", en_GU => ",", en_GY => ",", en_HK => ",", en_IE => ",", en_IL => ",", en_IM => ",", en_IN => ",", en_IO => ",", en_JE => ",", en_JM => ",", en_KE => ",", en_KI => ",", en_KN => ",", en_KY => ",", en_LC => ",", en_LR => ",", en_LS => ",", en_MG => ",", en_MH => ",", en_MO => ",", en_MP => ",", en_MS => ",", en_MT => ",", en_MU => ",", en_MW => ",", en_MY => ",", en_NA => ",", en_NF => ",", en_NG => ",", en_NL => ".", en_NR => ",", en_NU => ",", en_NZ => ",", en_PG => ",", en_PH => ",", en_PK => ",", en_PN => ",", en_PR => ",", en_PW => ",", en_RW => ",", en_SB => ",", en_SC => ",", en_SD => ",", en_SE => "\u{a0}", en_SG => ",", en_SH => ",", en_SI => ".", en_SL => ",", en_SS => ",", en_SX => ",", en_SZ => ",", en_TC => ",", en_TK => ",", en_TO => ",", en_TT => ",", en_TV => ",", en_TZ => ",", en_UG => ",", en_UM => ",", en_US_POSIX => ",", en_VC => ",", en_VG => ",", en_VI => ",", en_VU => ",", en_WS => ",", en_ZA => "\u{a0}", en_ZM => ",", en_ZW => ",", eo => "\u{a0}", es => ".", es_419 => ",", es_AR => ".", es_BO => ".", es_BR => ",", es_BZ => ",", es_CL => ".", es_CO => ".", es_CR => "\u{a0}", es_CU => ",", es_DO => ",", es_EA => ".", es_EC => ".", es_GQ => ".", es_GT => ",", es_HN => ",", es_IC => ".", es_MX => ",", es_NI => ",", es_PA => ",", es_PE => ",", es_PH => ".", es_PR => ",", es_PY => ".", es_SV => ",", es_US => ",", es_UY => ".", es_VE => ".", et => "\u{a0}", eu => ".", ewo => "\u{a0}", fa => "\u{66c}", fa_AF => "\u{66c}", ff => "\u{a0}", ff_Latn => "\u{a0}", ff_Latn_BF => "\u{a0}", ff_Latn_CM => "\u{a0}", ff_Latn_GH => "\u{a0}", ff_Latn_GM => "\u{a0}", ff_Latn_GN => "\u{a0}", ff_Latn_GW => "\u{a0}", ff_Latn_LR => "\u{a0}", ff_Latn_MR => "\u{a0}", ff_Latn_NE => "\u{a0}", ff_Latn_NG => "\u{a0}", ff_Latn_SL => "\u{a0}", fi => "\u{a0}", fil => ",", fo => ".", fo_DK => ".", fr => "\u{202f}", fr_BE => "\u{202f}", fr_BF => "\u{202f}", fr_BI => "\u{202f}", fr_BJ => "\u{202f}", fr_BL => "\u{202f}", fr_CA => "\u{a0}", fr_CD => "\u{202f}", fr_CF => "\u{202f}", fr_CG => "\u{202f}", fr_CH => "\u{202f}", fr_CI => "\u{202f}", fr_CM => "\u{202f}", fr_DJ => "\u{202f}", fr_DZ => "\u{202f}", fr_GA => "\u{202f}", fr_GF => "\u{202f}", fr_GN => "\u{202f}", fr_GP => "\u{202f}", fr_GQ => "\u{202f}", fr_HT => "\u{202f}", fr_KM => "\u{202f}", fr_LU => ".", fr_MA => ".", fr_MC => "\u{202f}", fr_MF => "\u{202f}", fr_MG => "\u{202f}", fr_ML => "\u{202f}", fr_MQ => "\u{202f}", fr_MR => "\u{202f}", fr_MU => "\u{202f}", fr_NC => "\u{202f}", fr_NE => "\u{202f}", fr_PF => "\u{202f}", fr_PM => "\u{202f}", fr_RE => "\u{202f}", fr_RW => "\u{202f}", fr_SC => "\u{202f}", fr_SN => "\u{202f}", fr_SY => "\u{202f}", fr_TD => "\u{202f}", fr_TG => "\u{202f}", fr_TN => "\u{202f}", fr_VU => "\u{202f}", fr_WF => "\u{202f}", fr_YT => "\u{202f}", fur => ".", fy => ".", ga => ",", gd => ",", gl => ".", gsw => "\u{2019}", gsw_FR => "\u{2019}", gsw_LI => "\u{2019}", gu => ",", guz => ",", gv => ",", ha => ",", ha_GH => ",", ha_NE => ",", haw => ",", he => ",", hi => ",", hr => ".", hr_BA => ".", hsb => ".", hu => "\u{a0}", hy => "\u{a0}", ia => ".", id => ".", ig => ",", ii => ",", is => ".", it => ".", it_CH => "\u{2019}", it_SM => ".", it_VA => ".", ja => ",", jgo => ".", jmc => ",", jv => ".", ka => "\u{a0}", kab => "\u{a0}", kam => ",", kde => ",", kea => "\u{a0}", khq => "\u{a0}", ki => ",", kk => "\u{a0}", kkj => ".", kl => ".", kln => ",", km => ".", kn => ",", ko => ",", ko_KP => ",", kok => ",", ks => "\u{66c}", ksb => ",", ksf => "\u{a0}", ksh => "\u{a0}", ku => ".", kw => ",", ky => "\u{a0}", lag => ",", lb => ".", lg => ",", lkt => ",", ln => ".", ln_AO => ".", ln_CF => ".", ln_CG => ".", lo => ".", lrc => "\u{66c}", lrc_IQ => "\u{66c}", lt => "\u{a0}", lu => ".", luo => ",", luy => ",", lv => "\u{a0}", mas => ",", mas_TZ => ",", mer => ",", mfe => "\u{a0}", mg => ",", mgh => ".", mgo => ",", mi => ",", mk => ".", ml => ",", mn => ",", mr => ",", ms => ",", ms_BN => ".", ms_SG => ",", mt => ",", mua => ".", my => ",", mzn => "\u{66c}", naq => ",", nb => "\u{a0}", nb_SJ => "\u{a0}", nd => ",", nds => ",", nds_NL => ",", ne => ",", ne_IN => ",", nl => ".", nl_AW => ".", nl_BE => ".", nl_BQ => ".", nl_CW => ".", nl_SR => ".", nl_SX => ".", nmg => "\u{a0}", nn => "\u{a0}", nnh => ".", nus => ",", nyn => ",", om => ",", om_KE => ",", or => ",", os => "\u{a0}", os_RU => "\u{a0}", pa => ",", pa_Arab => "\u{66c}", pa_Guru => ",", pl => "\u{a0}", prg => ",", ps => "\u{66c}", pt => ".", pt_AO => "\u{a0}", pt_CH => "\u{a0}", pt_CV => "\u{a0}", pt_GQ => "\u{a0}", pt_GW => "\u{a0}", pt_LU => "\u{a0}", pt_MO => "\u{a0}", pt_MZ => "\u{a0}", pt_PT => "\u{a0}", pt_ST => "\u{a0}", pt_TL => "\u{a0}", qu => ",", qu_BO => ".", qu_EC => ",", rm => "\u{2019}", rn => ".", ro => ".", ro_MD => ".", rof => ",", root => ",", ru => "\u{a0}", ru_BY => "\u{a0}", ru_KG => "\u{a0}", ru_KZ => "\u{a0}", ru_MD => "\u{a0}", ru_UA => "\u{a0}", rw => ".", rwk => ",", sah => "\u{a0}", saq => ",", sbp => ",", sd => "\u{66c}", se => "\u{a0}", se_FI => "\u{a0}", se_SE => "\u{a0}", seh => ".", ses => "\u{a0}", sg => ".", shi => "\u{a0}", shi_Latn => "\u{a0}", shi_Tfng => "\u{a0}", si => ",", sk => "\u{a0}", sl => ".", smn => "\u{a0}", sn => ",", so => ",", so_DJ => ",", so_ET => ",", so_KE => ",", sq => "\u{a0}", sq_MK => "\u{a0}", sq_XK => "\u{a0}", sr => ".", sr_Cyrl => ".", sr_Cyrl_BA => ".", sr_Cyrl_ME => ".", sr_Cyrl_XK => ".", sr_Latn => ".", sr_Latn_BA => ".", sr_Latn_ME => ".", sr_Latn_XK => ".", sv => "\u{a0}", sv_AX => "\u{a0}", sv_FI => "\u{a0}", sw => ",", sw_CD => ".", sw_KE => ",", sw_UG => ",", ta => ",", ta_LK => ",", ta_MY => ",", ta_SG => ",", te => ",", teo => ",", teo_KE => ",", tg => "\u{a0}", th => ",", ti => ",", ti_ER => ",", tk => "\u{a0}", to => ",", tr => ".", tr_CY => ".", tt => "\u{a0}", twq => "\u{a0}", tzm => "\u{a0}", ug => ",", uk => "\u{a0}", ur => ",", ur_IN => "\u{66c}", uz => "\u{a0}", uz_Arab => "\u{66c}", uz_Cyrl => "\u{a0}", uz_Latn => "\u{a0}", vai => ",", vai_Latn => ",", vai_Vaii => ",", vi => ".", vo => ",", vun => ",", wae => "\u{2019}", wo => ".", xh => "\u{a0}", xog => ",", yav => "\u{a0}", yi => ",", yo => ",", yo_BJ => ",", yue => ",", yue_Hans => ",", yue_Hant => ",", zgh => "\u{a0}", zh => ",", zh_Hans => ",", zh_Hans_HK => ",", zh_Hans_MO => ",", zh_Hans_SG => ",", zh_Hant => ",", zh_Hant_HK => ",", zh_Hant_MO => ",", zu => ",", } } } impl Format for Locale { #[inline(always)] fn decimal(&self) -> DecimalStr<'_> { DecimalStr::new(self.decimal()).unwrap() } #[inline(always)] fn grouping(&self) -> Grouping { self.grouping() } #[inline(always)] fn infinity(&self) -> InfinityStr<'_> { InfinityStr::new(self.infinity()).unwrap() } #[inline(always)] fn minus_sign(&self) -> MinusSignStr<'_> { MinusSignStr::new(self.minus_sign()).unwrap() } #[inline(always)] fn nan(&self) -> NanStr<'_> { NanStr::new(self.nan()).unwrap() } #[inline(always)] fn plus_sign(&self) -> PlusSignStr<'_> { PlusSignStr::new(self.plus_sign()).unwrap() } #[inline(always)] fn separator(&self) -> SeparatorStr<'_> { SeparatorStr::new(self.separator()).unwrap() } } impl FromStr for Locale { type Err = Error; #[doc = r" Same as [`from_name`]."] #[doc = r""] #[doc = r" [`from_name`]: enum.Locale.html#method.from_name"] fn from_str(s: &str) -> Result { use self::Locale::*; let locale = match s { "af" => af, "af-NA" => af_NA, "agq" => agq, "ak" => ak, "am" => am, "ar" => ar, "ar-AE" => ar_AE, "ar-BH" => ar_BH, "ar-DJ" => ar_DJ, "ar-DZ" => ar_DZ, "ar-EG" => ar_EG, "ar-EH" => ar_EH, "ar-ER" => ar_ER, "ar-IL" => ar_IL, "ar-IQ" => ar_IQ, "ar-JO" => ar_JO, "ar-KM" => ar_KM, "ar-KW" => ar_KW, "ar-LB" => ar_LB, "ar-LY" => ar_LY, "ar-MA" => ar_MA, "ar-MR" => ar_MR, "ar-OM" => ar_OM, "ar-PS" => ar_PS, "ar-QA" => ar_QA, "ar-SA" => ar_SA, "ar-SD" => ar_SD, "ar-SO" => ar_SO, "ar-SS" => ar_SS, "ar-SY" => ar_SY, "ar-TD" => ar_TD, "ar-TN" => ar_TN, "ar-YE" => ar_YE, "as" => as_, "asa" => asa, "ast" => ast, "az" => az, "az-Cyrl" => az_Cyrl, "az-Latn" => az_Latn, "bas" => bas, "be" => be, "bem" => bem, "bez" => bez, "bg" => bg, "bm" => bm, "bn" => bn, "bn-IN" => bn_IN, "bo" => bo, "bo-IN" => bo_IN, "br" => br, "brx" => brx, "bs" => bs, "bs-Cyrl" => bs_Cyrl, "bs-Latn" => bs_Latn, "ca" => ca, "ca-AD" => ca_AD, "ca-ES-VALENCIA" => ca_ES_VALENCIA, "ca-FR" => ca_FR, "ca-IT" => ca_IT, "ccp" => ccp, "ccp-IN" => ccp_IN, "ce" => ce, "cgg" => cgg, "chr" => chr, "ckb" => ckb, "ckb-IR" => ckb_IR, "cs" => cs, "cu" => cu, "cy" => cy, "da" => da, "da-GL" => da_GL, "dav" => dav, "de" => de, "de-AT" => de_AT, "de-BE" => de_BE, "de-CH" => de_CH, "de-IT" => de_IT, "de-LI" => de_LI, "de-LU" => de_LU, "dje" => dje, "dsb" => dsb, "dua" => dua, "dyo" => dyo, "dz" => dz, "ebu" => ebu, "ee" => ee, "ee-TG" => ee_TG, "el" => el, "el-CY" => el_CY, "en" => en, "en-001" => en_001, "en-150" => en_150, "en-AG" => en_AG, "en-AI" => en_AI, "en-AS" => en_AS, "en-AT" => en_AT, "en-AU" => en_AU, "en-BB" => en_BB, "en-BE" => en_BE, "en-BI" => en_BI, "en-BM" => en_BM, "en-BS" => en_BS, "en-BW" => en_BW, "en-BZ" => en_BZ, "en-CA" => en_CA, "en-CC" => en_CC, "en-CH" => en_CH, "en-CK" => en_CK, "en-CM" => en_CM, "en-CX" => en_CX, "en-CY" => en_CY, "en-DE" => en_DE, "en-DG" => en_DG, "en-DK" => en_DK, "en-DM" => en_DM, "en-ER" => en_ER, "en-FI" => en_FI, "en-FJ" => en_FJ, "en-FK" => en_FK, "en-FM" => en_FM, "en-GB" => en_GB, "en-GD" => en_GD, "en-GG" => en_GG, "en-GH" => en_GH, "en-GI" => en_GI, "en-GM" => en_GM, "en-GU" => en_GU, "en-GY" => en_GY, "en-HK" => en_HK, "en-IE" => en_IE, "en-IL" => en_IL, "en-IM" => en_IM, "en-IN" => en_IN, "en-IO" => en_IO, "en-JE" => en_JE, "en-JM" => en_JM, "en-KE" => en_KE, "en-KI" => en_KI, "en-KN" => en_KN, "en-KY" => en_KY, "en-LC" => en_LC, "en-LR" => en_LR, "en-LS" => en_LS, "en-MG" => en_MG, "en-MH" => en_MH, "en-MO" => en_MO, "en-MP" => en_MP, "en-MS" => en_MS, "en-MT" => en_MT, "en-MU" => en_MU, "en-MW" => en_MW, "en-MY" => en_MY, "en-NA" => en_NA, "en-NF" => en_NF, "en-NG" => en_NG, "en-NL" => en_NL, "en-NR" => en_NR, "en-NU" => en_NU, "en-NZ" => en_NZ, "en-PG" => en_PG, "en-PH" => en_PH, "en-PK" => en_PK, "en-PN" => en_PN, "en-PR" => en_PR, "en-PW" => en_PW, "en-RW" => en_RW, "en-SB" => en_SB, "en-SC" => en_SC, "en-SD" => en_SD, "en-SE" => en_SE, "en-SG" => en_SG, "en-SH" => en_SH, "en-SI" => en_SI, "en-SL" => en_SL, "en-SS" => en_SS, "en-SX" => en_SX, "en-SZ" => en_SZ, "en-TC" => en_TC, "en-TK" => en_TK, "en-TO" => en_TO, "en-TT" => en_TT, "en-TV" => en_TV, "en-TZ" => en_TZ, "en-UG" => en_UG, "en-UM" => en_UM, "en-US-POSIX" => en_US_POSIX, "en-VC" => en_VC, "en-VG" => en_VG, "en-VI" => en_VI, "en-VU" => en_VU, "en-WS" => en_WS, "en-ZA" => en_ZA, "en-ZM" => en_ZM, "en-ZW" => en_ZW, "eo" => eo, "es" => es, "es-419" => es_419, "es-AR" => es_AR, "es-BO" => es_BO, "es-BR" => es_BR, "es-BZ" => es_BZ, "es-CL" => es_CL, "es-CO" => es_CO, "es-CR" => es_CR, "es-CU" => es_CU, "es-DO" => es_DO, "es-EA" => es_EA, "es-EC" => es_EC, "es-GQ" => es_GQ, "es-GT" => es_GT, "es-HN" => es_HN, "es-IC" => es_IC, "es-MX" => es_MX, "es-NI" => es_NI, "es-PA" => es_PA, "es-PE" => es_PE, "es-PH" => es_PH, "es-PR" => es_PR, "es-PY" => es_PY, "es-SV" => es_SV, "es-US" => es_US, "es-UY" => es_UY, "es-VE" => es_VE, "et" => et, "eu" => eu, "ewo" => ewo, "fa" => fa, "fa-AF" => fa_AF, "ff" => ff, "ff-Latn" => ff_Latn, "ff-Latn-BF" => ff_Latn_BF, "ff-Latn-CM" => ff_Latn_CM, "ff-Latn-GH" => ff_Latn_GH, "ff-Latn-GM" => ff_Latn_GM, "ff-Latn-GN" => ff_Latn_GN, "ff-Latn-GW" => ff_Latn_GW, "ff-Latn-LR" => ff_Latn_LR, "ff-Latn-MR" => ff_Latn_MR, "ff-Latn-NE" => ff_Latn_NE, "ff-Latn-NG" => ff_Latn_NG, "ff-Latn-SL" => ff_Latn_SL, "fi" => fi, "fil" => fil, "fo" => fo, "fo-DK" => fo_DK, "fr" => fr, "fr-BE" => fr_BE, "fr-BF" => fr_BF, "fr-BI" => fr_BI, "fr-BJ" => fr_BJ, "fr-BL" => fr_BL, "fr-CA" => fr_CA, "fr-CD" => fr_CD, "fr-CF" => fr_CF, "fr-CG" => fr_CG, "fr-CH" => fr_CH, "fr-CI" => fr_CI, "fr-CM" => fr_CM, "fr-DJ" => fr_DJ, "fr-DZ" => fr_DZ, "fr-GA" => fr_GA, "fr-GF" => fr_GF, "fr-GN" => fr_GN, "fr-GP" => fr_GP, "fr-GQ" => fr_GQ, "fr-HT" => fr_HT, "fr-KM" => fr_KM, "fr-LU" => fr_LU, "fr-MA" => fr_MA, "fr-MC" => fr_MC, "fr-MF" => fr_MF, "fr-MG" => fr_MG, "fr-ML" => fr_ML, "fr-MQ" => fr_MQ, "fr-MR" => fr_MR, "fr-MU" => fr_MU, "fr-NC" => fr_NC, "fr-NE" => fr_NE, "fr-PF" => fr_PF, "fr-PM" => fr_PM, "fr-RE" => fr_RE, "fr-RW" => fr_RW, "fr-SC" => fr_SC, "fr-SN" => fr_SN, "fr-SY" => fr_SY, "fr-TD" => fr_TD, "fr-TG" => fr_TG, "fr-TN" => fr_TN, "fr-VU" => fr_VU, "fr-WF" => fr_WF, "fr-YT" => fr_YT, "fur" => fur, "fy" => fy, "ga" => ga, "gd" => gd, "gl" => gl, "gsw" => gsw, "gsw-FR" => gsw_FR, "gsw-LI" => gsw_LI, "gu" => gu, "guz" => guz, "gv" => gv, "ha" => ha, "ha-GH" => ha_GH, "ha-NE" => ha_NE, "haw" => haw, "he" => he, "hi" => hi, "hr" => hr, "hr-BA" => hr_BA, "hsb" => hsb, "hu" => hu, "hy" => hy, "ia" => ia, "id" => id, "ig" => ig, "ii" => ii, "is" => is, "it" => it, "it-CH" => it_CH, "it-SM" => it_SM, "it-VA" => it_VA, "ja" => ja, "jgo" => jgo, "jmc" => jmc, "jv" => jv, "ka" => ka, "kab" => kab, "kam" => kam, "kde" => kde, "kea" => kea, "khq" => khq, "ki" => ki, "kk" => kk, "kkj" => kkj, "kl" => kl, "kln" => kln, "km" => km, "kn" => kn, "ko" => ko, "ko-KP" => ko_KP, "kok" => kok, "ks" => ks, "ksb" => ksb, "ksf" => ksf, "ksh" => ksh, "ku" => ku, "kw" => kw, "ky" => ky, "lag" => lag, "lb" => lb, "lg" => lg, "lkt" => lkt, "ln" => ln, "ln-AO" => ln_AO, "ln-CF" => ln_CF, "ln-CG" => ln_CG, "lo" => lo, "lrc" => lrc, "lrc-IQ" => lrc_IQ, "lt" => lt, "lu" => lu, "luo" => luo, "luy" => luy, "lv" => lv, "mas" => mas, "mas-TZ" => mas_TZ, "mer" => mer, "mfe" => mfe, "mg" => mg, "mgh" => mgh, "mgo" => mgo, "mi" => mi, "mk" => mk, "ml" => ml, "mn" => mn, "mr" => mr, "ms" => ms, "ms-BN" => ms_BN, "ms-SG" => ms_SG, "mt" => mt, "mua" => mua, "my" => my, "mzn" => mzn, "naq" => naq, "nb" => nb, "nb-SJ" => nb_SJ, "nd" => nd, "nds" => nds, "nds-NL" => nds_NL, "ne" => ne, "ne-IN" => ne_IN, "nl" => nl, "nl-AW" => nl_AW, "nl-BE" => nl_BE, "nl-BQ" => nl_BQ, "nl-CW" => nl_CW, "nl-SR" => nl_SR, "nl-SX" => nl_SX, "nmg" => nmg, "nn" => nn, "nnh" => nnh, "nus" => nus, "nyn" => nyn, "om" => om, "om-KE" => om_KE, "or" => or, "os" => os, "os-RU" => os_RU, "pa" => pa, "pa-Arab" => pa_Arab, "pa-Guru" => pa_Guru, "pl" => pl, "prg" => prg, "ps" => ps, "pt" => pt, "pt-AO" => pt_AO, "pt-CH" => pt_CH, "pt-CV" => pt_CV, "pt-GQ" => pt_GQ, "pt-GW" => pt_GW, "pt-LU" => pt_LU, "pt-MO" => pt_MO, "pt-MZ" => pt_MZ, "pt-PT" => pt_PT, "pt-ST" => pt_ST, "pt-TL" => pt_TL, "qu" => qu, "qu-BO" => qu_BO, "qu-EC" => qu_EC, "rm" => rm, "rn" => rn, "ro" => ro, "ro-MD" => ro_MD, "rof" => rof, "root" => root, "ru" => ru, "ru-BY" => ru_BY, "ru-KG" => ru_KG, "ru-KZ" => ru_KZ, "ru-MD" => ru_MD, "ru-UA" => ru_UA, "rw" => rw, "rwk" => rwk, "sah" => sah, "saq" => saq, "sbp" => sbp, "sd" => sd, "se" => se, "se-FI" => se_FI, "se-SE" => se_SE, "seh" => seh, "ses" => ses, "sg" => sg, "shi" => shi, "shi-Latn" => shi_Latn, "shi-Tfng" => shi_Tfng, "si" => si, "sk" => sk, "sl" => sl, "smn" => smn, "sn" => sn, "so" => so, "so-DJ" => so_DJ, "so-ET" => so_ET, "so-KE" => so_KE, "sq" => sq, "sq-MK" => sq_MK, "sq-XK" => sq_XK, "sr" => sr, "sr-Cyrl" => sr_Cyrl, "sr-Cyrl-BA" => sr_Cyrl_BA, "sr-Cyrl-ME" => sr_Cyrl_ME, "sr-Cyrl-XK" => sr_Cyrl_XK, "sr-Latn" => sr_Latn, "sr-Latn-BA" => sr_Latn_BA, "sr-Latn-ME" => sr_Latn_ME, "sr-Latn-XK" => sr_Latn_XK, "sv" => sv, "sv-AX" => sv_AX, "sv-FI" => sv_FI, "sw" => sw, "sw-CD" => sw_CD, "sw-KE" => sw_KE, "sw-UG" => sw_UG, "ta" => ta, "ta-LK" => ta_LK, "ta-MY" => ta_MY, "ta-SG" => ta_SG, "te" => te, "teo" => teo, "teo-KE" => teo_KE, "tg" => tg, "th" => th, "ti" => ti, "ti-ER" => ti_ER, "tk" => tk, "to" => to, "tr" => tr, "tr-CY" => tr_CY, "tt" => tt, "twq" => twq, "tzm" => tzm, "ug" => ug, "uk" => uk, "ur" => ur, "ur-IN" => ur_IN, "uz" => uz, "uz-Arab" => uz_Arab, "uz-Cyrl" => uz_Cyrl, "uz-Latn" => uz_Latn, "vai" => vai, "vai-Latn" => vai_Latn, "vai-Vaii" => vai_Vaii, "vi" => vi, "vo" => vo, "vun" => vun, "wae" => wae, "wo" => wo, "xh" => xh, "xog" => xog, "yav" => yav, "yi" => yi, "yo" => yo, "yo-BJ" => yo_BJ, "yue" => yue, "yue-Hans" => yue_Hans, "yue-Hant" => yue_Hant, "zgh" => zgh, "zh" => zh, "zh-Hans" => zh_Hans, "zh-Hans-HK" => zh_Hans_HK, "zh-Hans-MO" => zh_Hans_MO, "zh-Hans-SG" => zh_Hans_SG, "zh-Hant" => zh_Hant, "zh-Hant-HK" => zh_Hant_HK, "zh-Hant-MO" => zh_Hant_MO, "zu" => zu, _ => return Err(Error::parse_locale(s)), }; Ok(locale) } } num-format-0.4.0/src/strings.rs010064400007650000024000000210441343310555200146470ustar0000000000000000use core::fmt; use core::ops::Deref; use arrayvec::ArrayString; const MAX_DEC_LEN: usize = 8; pub(crate) const MAX_ERR_LEN: usize = 256; const MAX_INF_LEN: usize = 128; pub(crate) const MAX_MIN_LEN: usize = 8; const MAX_NAN_LEN: usize = 64; const MAX_PLUS_LEN: usize = 8; pub(crate) const MAX_SEP_LEN: usize = 8; #[cfg(feature = "with-serde")] use serde::{de, ser}; use crate::error::Error; /// Simple wrapper type for a `&str` to make sure its length is less than the maximum for /// a decimal (8 bytes). #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct DecimalStr<'a>(&'a str); impl<'a> DecimalStr<'a> { /// Constructs an [`DecimalStr`], ensuring that the length is less than the maximum for /// a decimal (8 bytes). /// /// # Errors /// /// Returns an error if the provided `&str`'s length is more than 8 bytes. /// /// [`DecimalStr`]: struct.DecimalStr.html pub fn new(s: &'a str) -> Result, Error> { Self::_new(s) } } /// Simple wrapper type for a `&str` to make sure its length is less than the maximum for /// an infinity symbol (128 bytes). #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct InfinityStr<'a>(&'a str); impl<'a> InfinityStr<'a> { /// Constructs an [`InfinityStr`], ensuring that the length is less than the maximum for /// an infinity symbol (128 bytes). /// /// # Errors /// /// Returns an error if the provided `&str`'s length is more than 128 bytes. /// /// [`InfinityStr`]: struct.InfinityStr.html pub fn new(s: &'a str) -> Result, Error> { Self::_new(s) } } /// Simple wrapper type for a `&str` to make sure its length is less than the maximum for /// a minus sign (8 bytes). #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct MinusSignStr<'a>(&'a str); impl<'a> MinusSignStr<'a> { /// Constructs a [`MinusSignStr`], ensuring that the length is less than the maximum for /// a minus sign (8 bytes). /// /// # Errors /// /// Returns an error if the provided `&str`'s length is more than 7 bytes. /// /// [`MinusSignStr`]: struct.MinusSignStr.html pub fn new(s: &'a str) -> Result, Error> { Self::_new(s) } } /// Simple wrapper type for a `&str` to make sure its length is less than the maximum for /// a nan symbol (64 bytes). #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct NanStr<'a>(&'a str); impl<'a> NanStr<'a> { /// Constructs an [`NanStr`], ensuring that the length is less than the maximum for /// a nan symbol (64 bytes). /// /// # Errors /// /// Returns an error if the provided `&str`'s length is more than 64 bytes. /// /// [`NanStr`]: struct.NanStr.html pub fn new(s: &'a str) -> Result, Error> { Self::_new(s) } } /// Simple wrapper type for a `&str` to make sure its length is less than the maximum for /// a plus sign (8 bytes). #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct PlusSignStr<'a>(&'a str); impl<'a> PlusSignStr<'a> { /// Constructs an [`PlusSignStr`], ensuring that the length is less than the maximum for /// a plus sign (8 bytes). /// /// # Errors /// /// Returns an error if the provided `&str`'s length is more than 8 bytes. /// /// [`PlusSignStr`]: struct.PlusSignStr.html pub fn new(s: &'a str) -> Result, Error> { Self::_new(s) } } /// Simple wrapper type for a `&str` to make sure its length is less than the maximum for /// a separator (8 bytes). #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct SeparatorStr<'a>(&'a str); impl<'a> SeparatorStr<'a> { /// Constructs an [`SeparatorStr`], ensuring that the length is less than the maximum for /// a separator (8 bytes). /// /// # Errors /// /// Returns an error if the provided `&str`'s length is more than 8 bytes. /// /// [`SeparatorStr`]: struct.SeparatorStr.html pub fn new(s: &'a str) -> Result, Error> { Self::_new(s) } } macro_rules! create_impls { ( $name:ident, $max_len:expr ) => { impl<'a> $name<'a> { #[inline(always)] /// Allows recovery of the initial / wrapped `&str`. pub fn into_str(self) -> &'a str { self.0 } #[inline(always)] fn _new(s: &'a str) -> Result<$name<'a>, Error> { let len = s.len(); if len > $max_len { return Err(Error::capacity(len, $max_len)); } Ok($name(s)) } } impl<'a> AsRef for $name<'a> { #[inline(always)] fn as_ref(&self) -> &str { self.0 } } impl<'a> fmt::Debug for $name<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } impl<'a> fmt::Display for $name<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) } } }; } create_impls!(DecimalStr, MAX_DEC_LEN); create_impls!(InfinityStr, MAX_INF_LEN); create_impls!(MinusSignStr, MAX_MIN_LEN); create_impls!(NanStr, MAX_NAN_LEN); create_impls!(PlusSignStr, MAX_PLUS_LEN); create_impls!(SeparatorStr, MAX_SEP_LEN); macro_rules! create_string { ( $name:ident, $visitor:ident, $max_len:expr ) => { #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] pub(crate) struct $name(ArrayString<[u8; $max_len]>); impl $name { #[allow(dead_code)] pub(crate) fn new(s: S) -> Result where S: AsRef, { let s = s.as_ref(); let a = ArrayString::from(s).map_err(|_| Error::capacity(s.len(), $max_len))?; Ok($name(a)) } #[allow(dead_code)] pub(crate) fn truncated(s: S) -> Self where S: AsRef, { let s = s.as_ref(); let s = if s.len() > $max_len { &s[0..$max_len] } else { s }; $name(ArrayString::from(s).unwrap()) } #[allow(dead_code)] #[inline(always)] pub(crate) fn capacity() -> usize { $max_len } } impl Deref for $name { type Target = str; #[inline(always)] fn deref(&self) -> &str { self.0.deref() } } impl fmt::Display for $name { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) } } impl From<$name> for ArrayString<[u8; $max_len]> { fn from(s: $name) -> Self { s.0 } } #[cfg(feature = "with-serde")] impl ser::Serialize for $name { fn serialize(&self, serializer: S) -> Result where S: ser::Serializer, { serializer.serialize_str(self.0.as_str()) } } #[cfg(feature = "with-serde")] struct $visitor; #[cfg(feature = "with-serde")] impl<'de> de::Visitor<'de> for $visitor { type Value = $name; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "a string containing at most {} bytes", $max_len) } fn visit_str(self, s: &str) -> Result where E: de::Error, { $name::new(s).map_err(|_| de::Error::invalid_value(de::Unexpected::Str(s), &self)) } } #[cfg(feature = "with-serde")] impl<'de> de::Deserialize<'de> for $name { fn deserialize(deserializer: D) -> Result where D: de::Deserializer<'de>, { deserializer.deserialize_str($visitor) } } }; } create_string!(DecString, DecVisitor, MAX_DEC_LEN); create_string!(ErrString, ErrVisitor, MAX_ERR_LEN); create_string!(InfString, InfVisitor, MAX_INF_LEN); create_string!(MinString, MinVisitor, MAX_MIN_LEN); create_string!(NanString, NanVisitor, MAX_NAN_LEN); create_string!(PlusString, PlusVisitor, MAX_PLUS_LEN); create_string!(SepString, SepVisitor, MAX_SEP_LEN); num-format-0.4.0/src/system_locale.rs010064400007650000024000000173121343307204100160200ustar0000000000000000#![cfg(all(feature = "with-system-locale", any(unix, windows)))] mod unix; mod windows; use std::collections::HashSet; use crate::error::Error; use crate::format::Format; use crate::grouping::Grouping; use crate::strings::{ DecString, DecimalStr, InfString, InfinityStr, MinString, MinusSignStr, NanStr, NanString, PlusSignStr, PlusString, SepString, SeparatorStr, }; /// A key type. Represents formats obtained from your operating system. Implements /// [`Format`]. /// /// # Example /// ```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."), /// } /// } /// ``` /// /// [`Format`]: trait.Format.html #[derive(Clone, Debug, Eq, PartialEq, Hash)] #[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] pub struct SystemLocale { pub(crate) dec: DecString, pub(crate) grp: Grouping, pub(crate) inf: InfString, pub(crate) min: MinString, pub(crate) name: String, pub(crate) nan: NanString, pub(crate) plus: PlusString, pub(crate) sep: SepString, } impl SystemLocale { /// Same as [`default`]. /// /// [`default`]: struct.SystemLocale.html#method.default pub fn new() -> Result { SystemLocale::default() } /// Constucts a [`SystemLocale`] based on your operating system's default locale. /// /// * **Unix-based systems (including macOS)**: The default locale is controlled by "locale /// category environment variables," such as `LANG`, `LC_MONETARY`, `LC_NUMERIC`, and /// `LC_ALL`. For more information, see /// [here](https://www.gnu.org/software/libc/manual/html_node/Locale-Categories.html#Locale-Categories). /// * **Windows**: The default locale is controlled by the regional and language options portion /// of the Control Panel. For more information, see /// [here](https://docs.microsoft.com/en-us/windows/desktop/intl/locales-and-languages). /// /// # Errors /// /// Returns an error if the operating system returned something unexpected (such as a null /// pointer). /// /// [`SystemLocale`]: struct.SystemLocale.html pub fn default() -> Result { #[cfg(unix)] return self::unix::new(None); #[cfg(windows)] return self::windows::new(None); #[cfg(not(any(unix, windows)))] unreachable!() } /// Constucts a [`SystemLocale`] from the provided locale name. For a list of locale names /// available on your system, see [`available_names`]. /// /// # Errors /// /// Returns an error if the name provided could not be parsed into a [`SystemLocale`] or if the /// operating system returned something unexpected (such as a null pointer). /// /// [`available_names`]: struct.SystemLocale.html#method.available_names /// [`SystemLocale`]: struct.SystemLocale.html pub fn from_name(name: S) -> Result where S: Into, { #[cfg(unix)] return self::unix::new(Some(name.into())); #[cfg(windows)] return self::windows::new(Some(name.into())); #[cfg(not(any(unix, windows)))] unreachable!() } /// Returns a set of the locale names available on your operating system. /// /// * **Unix-based systems (including macOS)**: The underlying implementation uses the /// [`locale`] command. /// * **Windows**: The underlying implementation uses the [`EnumSystemLocalesEx`] function. /// # Errors /// /// Returns an error if the operating system returned something unexpected (such as a null /// pointer). /// /// [`EnumSystemLocalesEx`]: https://docs.microsoft.com/en-us/windows/desktop/api/winnls/nf-winnls-enumsystemlocalesex /// [`locale`]: http://man7.org/linux/man-pages/man1/locale.1.html pub fn available_names() -> Result, Error> { #[cfg(unix)] return Ok(self::unix::available_names()); #[cfg(windows)] return self::windows::available_names(); #[cfg(not(any(unix, windows)))] unreachable!() } /// Returns this locale's string representation of a decimal point. pub fn decimal(&self) -> &str { &self.dec } /// Returns this locale's [`Grouping`], which governs how digits are separated /// (see [`Grouping`]). /// /// [`Grouping`]: enum.Grouping.html pub fn grouping(&self) -> Grouping { self.grp } /// Returns this locale's string representation of infinity. pub fn infinity(&self) -> &str { &self.inf } /// Returns this locale's string representation of a minus sign. pub fn minus_sign(&self) -> &str { &self.min } /// Returns this locale's name. pub fn name(&self) -> &str { &self.name } /// Returns this locale's string representation of NaN. pub fn nan(&self) -> &str { &self.nan } /// Returns this locale's string representation of a plus sign. pub fn plus_sign(&self) -> &str { &self.plus } /// Returns this locale's string representation of a thousands separator. pub fn separator(&self) -> &str { &self.sep } #[cfg(unix)] /// Unix-based operating systems (including macOS) do not provide information on how to /// represent infinity symbols; so num-format uses `"∞"` (U+221E) as a default. This /// method allows you to change that default. /// /// # Errors /// /// Returns an error the provided string is longer than 128 bytes. pub fn set_infinity(&mut self, s: S) -> Result<(), Error> where S: AsRef, { self.inf = InfString::new(s)?; Ok(()) } #[cfg(unix)] /// Unix-based operating systems (including macOS) do not provide information on how to /// represent NaN; so num-format uses `"NaN"` as a default. This method allows you to change /// that default. /// /// # Errors /// /// Returns an error the provided string is longer than 64 bytes. pub fn set_nan(&mut self, s: S) -> Result<(), Error> where S: AsRef, { self.nan = NanString::new(s)?; Ok(()) } } impl std::str::FromStr for SystemLocale { type Err = Error; /// Same as [`from_name`]. /// /// [`from_name`]: struct.SystemLocale.html#method.from_name fn from_str(s: &str) -> Result { SystemLocale::from_name(s) } } impl Format for SystemLocale { #[inline(always)] fn decimal(&self) -> DecimalStr<'_> { DecimalStr::new(self.decimal()).unwrap() } #[inline(always)] fn grouping(&self) -> Grouping { self.grouping() } #[inline(always)] fn infinity(&self) -> InfinityStr<'_> { InfinityStr::new(self.infinity()).unwrap() } #[inline(always)] fn minus_sign(&self) -> MinusSignStr<'_> { MinusSignStr::new(self.minus_sign()).unwrap() } #[inline(always)] fn nan(&self) -> NanStr<'_> { NanStr::new(self.nan()).unwrap() } #[inline(always)] fn plus_sign(&self) -> PlusSignStr<'_> { PlusSignStr::new(self.plus_sign()).unwrap() } #[inline(always)] fn separator(&self) -> SeparatorStr<'_> { SeparatorStr::new(self.separator()).unwrap() } } num-format-0.4.0/src/system_locale/unix.rs010064400007650000024000000150531343306110700170040ustar0000000000000000#![cfg(all(feature = "with-system-locale", unix))] mod bsd; mod encoding; mod linux; pub(crate) use self::encoding::{Encoding, UTF_8}; cfg_if! { if #[cfg(any( target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "openbsd", target_os = "netbsd" ))] { use self::bsd::{get_encoding, get_lconv, get_name}; } else { use self::linux::{get_encoding, get_lconv, get_name}; } } use std::collections::HashSet; use std::ffi::{CStr, CString}; use std::process::Command; use std::ptr::{self, NonNull}; use libc::{c_char, c_int, c_void}; use crate::error::Error; use crate::grouping::Grouping; use crate::locale::Locale; use crate::strings::{DecString, InfString, MinString, NanString, PlusString, SepString}; use crate::system_locale::SystemLocale; extern "C" { pub fn freelocale(locale: *const c_void); pub fn newlocale(mask: c_int, name: *const c_char, base: *const c_void) -> *const c_void; pub fn uselocale(locale: *const c_void) -> *const c_void; } pub(crate) fn available_names() -> HashSet { let inner = |bin| { let output = Command::new(bin).arg("-a").output().ok()?; if !output.status.success() { return None; } let stdout = std::str::from_utf8(&output.stdout).ok()?; let set = stdout .lines() .map(|s| s.trim().to_string()) .collect::>(); Some(set) }; if let Some(set) = inner("locale") { return set; } HashSet::default() } pub(crate) fn new(maybe_name: Option) -> Result { // create a new locale object let new = new_locale(&maybe_name)?; let inner = || { // use the new locale object, while saving the initial one let initial = use_locale(new)?; // get the encoding let encoding = get_encoding(new)?; // get the lconv let lconv = get_lconv(new, encoding)?; // get the name let mut name = match maybe_name { Some(name) => name, None => get_name(new, encoding)?, }; if &name == "POSIX" { name = "C".to_string(); } // reset to the initial locale object let _ = use_locale(initial); let system_locale = SystemLocale { dec: lconv.dec, grp: lconv.grp, inf: InfString::new(Locale::en.infinity()).unwrap(), min: lconv.min, name, nan: NanString::new(Locale::en.nan()).unwrap(), plus: lconv.plus, sep: lconv.sep, }; Ok(system_locale) }; let output = inner(); // free the new locale object free_locale(new); output } fn free_locale(locale: *const c_void) { unsafe { freelocale(locale) }; } fn new_locale(name: &Option) -> Result<*const c_void, Error> { let name_cstring = match name { Some(ref name) => { CString::new(name.as_bytes()).map_err(|_| Error::interior_nul_byte(name.to_string()))? } None => CString::new("").unwrap(), }; let mask = libc::LC_CTYPE_MASK | libc::LC_MONETARY_MASK | libc::LC_NUMERIC_MASK; let new_locale = unsafe { newlocale(mask, name_cstring.as_ptr(), ptr::null()) }; if new_locale.is_null() { match name { Some(name) => return Err(Error::parse_locale(name)), None => { return Err(Error::system_invalid_return( "newlocale", "newlocale unexpectedly returned a null pointer.", )); } } } Ok(new_locale) } fn use_locale(locale: *const c_void) -> Result<*const c_void, Error> { let old_locale = unsafe { uselocale(locale) }; if old_locale.is_null() { return Err(Error::system_invalid_return( "uselocale", "uselocale unexpectedly returned a null pointer.", )); } Ok(old_locale) } pub(crate) struct Lconv { pub(crate) dec: DecString, pub(crate) grp: Grouping, pub(crate) min: MinString, pub(crate) plus: PlusString, pub(crate) sep: SepString, } impl Lconv { pub(crate) fn new(lconv: &libc::lconv, encoding: Encoding) -> Result { let dec = { let s = StaticCString::new(lconv.decimal_point, encoding, "lconv.decimal_point")? .to_string()?; DecString::new(&s)? }; let grp = StaticCString::new(lconv.grouping, encoding, "lconv.grouping")?.to_grouping()?; let min = { let s = StaticCString::new(lconv.negative_sign, encoding, "lconv.negative_sign")? .to_string()?; MinString::new(&s)? }; let plus = { let s = StaticCString::new(lconv.positive_sign, encoding, "lconv.positive_sign")? .to_string()?; PlusString::new(&s)? }; let sep = { let s = StaticCString::new(lconv.thousands_sep, encoding, "lconv.thousands_sep")? .to_string()?; SepString::new(&s)? }; Ok(Lconv { dec, grp, min, plus, sep, }) } } /// Invariants: nul terminated, static lifetime pub(crate) struct StaticCString { encoding: Encoding, non_null: NonNull, } impl StaticCString { pub(crate) fn new( ptr: *const std::os::raw::c_char, encoding: Encoding, function_name: &str, ) -> Result { let non_null = NonNull::new(ptr as *mut c_char).ok_or_else(|| { Error::system_invalid_return( function_name, format!("{} unexpectedly returned a null pointer.", function_name), ) })?; Ok(StaticCString { encoding, non_null }) } pub(crate) fn to_grouping(&self) -> Result { let ptr = self.non_null.as_ptr(); let cstr = unsafe { CStr::from_ptr(ptr) }; let bytes = cstr.to_bytes(); let grouping = match bytes { [3, 2] | [2, 3] => Grouping::Indian, [] | [127] => Grouping::Posix, [3] | [3, 3] => Grouping::Standard, _ => return Err(Error::system_unsupported_grouping(bytes)), }; Ok(grouping) } pub(crate) fn to_string(&self) -> Result { let ptr = self.non_null.as_ptr(); let cstr = unsafe { CStr::from_ptr(ptr) }; let bytes = cstr.to_bytes(); self.encoding.decode(bytes) } } num-format-0.4.0/src/system_locale/unix/bsd.rs010064400007650000024000000035401343306630000175520ustar0000000000000000#![cfg(all( feature = "with-system-locale", unix, any( target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "openbsd", target_os = "netbsd" ) ))] use libc::{c_char, c_int, c_void}; use crate::error::Error; use crate::system_locale::unix::{Encoding, Lconv, StaticCString, UTF_8}; extern "C" { fn localeconv_l(locale: *const c_void) -> *const libc::lconv; fn nl_langinfo_l(item: libc::nl_item, locale: *const c_void) -> *const c_char; fn querylocale(mask: c_int, locale: *const c_void) -> *const c_char; } pub(crate) fn get_encoding(locale: *const c_void) -> Result { let encoding_ptr = unsafe { nl_langinfo_l(libc::CODESET, locale) }; let encoding_static_c_string = StaticCString::new(encoding_ptr, *UTF_8, "nl_langinfo_l")?; let encoding_string = encoding_static_c_string.to_string()?; let encoding = Encoding::from_bytes(encoding_string.as_bytes())?; Ok(encoding) } pub(crate) fn get_lconv(locale: *const c_void, encoding: Encoding) -> Result { let lconv_ptr = unsafe { localeconv_l(locale) }; if lconv_ptr.is_null() { return Err(Error::system_invalid_return( "localeconv_l", "localeconv_l unexpectedly returned a null pointer.", )); } let lconv: &libc::lconv = unsafe { lconv_ptr.as_ref() }.unwrap(); let lconv = Lconv::new(lconv, encoding)?; Ok(lconv) } pub(crate) fn get_name(locale: *const c_void, encoding: Encoding) -> Result { let mask = libc::LC_CTYPE_MASK | libc::LC_MONETARY_MASK | libc::LC_NUMERIC_MASK; let name_ptr = unsafe { querylocale(mask, locale) }; let name_static_c_string = StaticCString::new(name_ptr, encoding, "querylocale")?; let name = name_static_c_string.to_string()?; Ok(name) } num-format-0.4.0/src/system_locale/unix/encoding.rs010064400007650000024000000047031343306114600205750ustar0000000000000000#![cfg(all(feature = "with-system-locale", unix))] use crate::error::Error; lazy_static! { pub(crate) static ref UTF_8: Encoding = Encoding::from_bytes(b"UTF-8").unwrap(); } // See https://docs.rs/encoding_rs/0.8.16/encoding_rs/ static LATIN_1: &'static encoding_rs::Encoding = encoding_rs::WINDOWS_1252; #[derive(Copy, Clone, Debug)] pub(crate) struct Encoding(&'static encoding_rs::Encoding); impl Encoding { pub(crate) fn decode<'a>(&self, bytes: &'a [u8]) -> Result { let (cow, _encoding, is_err) = self.0.decode(bytes); if is_err { return Err(Error::system_invalid_return( "nl_langinfo", format!( "nl_langinfo unexpectedly returned data that could not be decoded \ using the proscribed encoding {}. the invalid data was {:?}.", self.name(), bytes ), )); } Ok(cow.into()) } pub(crate) fn name(&self) -> &'static str { self.0.name() } } impl Encoding { pub(crate) fn from_bytes(bytes: &[u8]) -> Result { if let Some(encoding) = encoding_rs::Encoding::for_label_no_replacement(bytes) { return Ok(Encoding(encoding)); } // Helpful: https://github.com/servo/libparserutils/blob/master/build/Aliases let encoding = match bytes { // Assume empty bytes means use LATIN-1 ... b"" => LATIN_1, // Is this correct? // Naming issues... b"Big5HKSCS" => encoding_rs::BIG5, b"CP949" => encoding_rs::EUC_KR, // See https://en.wikipedia.org/wiki/GB_18030 and // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.nlsgdrf/ibm-eucCN.htm b"eucCN" => encoding_rs::GB18030, b"eucJP" => encoding_rs::EUC_JP, b"eucKR" => encoding_rs::EUC_KR, // These are not correct, but seem to only // use LATIN-1 characters for number formatting ... b"ARMSCII-8" => LATIN_1, b"CP1131" => LATIN_1, b"ISCII-DEV" => LATIN_1, b"PT154" => LATIN_1, // If all of the above fail, return an error ... _ => { let name = String::from_utf8_lossy(bytes); return Err(Error::system_unsupported_encoding(name)); } }; Ok(Encoding(encoding)) } } num-format-0.4.0/src/system_locale/unix/linux.rs010064400007650000024000000034071343306630000201430ustar0000000000000000#![cfg(all( feature = "with-system-locale", unix, not(any( target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "openbsd", target_os = "netbsd" )) ))] use std::env; use libc::{c_char, c_void}; use crate::error::Error; use crate::system_locale::unix::{Encoding, Lconv, StaticCString, UTF_8}; extern "C" { fn localeconv() -> *const libc::lconv; fn nl_langinfo(item: libc::nl_item) -> *const c_char; } pub(crate) fn get_encoding(_locale: *const c_void) -> Result { let encoding_ptr = unsafe { nl_langinfo(libc::CODESET) }; let encoding_static_c_string = StaticCString::new(encoding_ptr, *UTF_8, "nl_langinfo")?; let encoding_string = encoding_static_c_string.to_string()?; let encoding = Encoding::from_bytes(encoding_string.as_bytes())?; Ok(encoding) } pub(crate) fn get_lconv(_locale: *const c_void, encoding: Encoding) -> Result { let lconv_ptr = unsafe { localeconv() }; if lconv_ptr.is_null() { return Err(Error::system_invalid_return( "localeconv_l", "localeconv_l unexpectedly returned a null pointer.", )); } let lconv: &libc::lconv = unsafe { lconv_ptr.as_ref() }.unwrap(); let lconv = Lconv::new(lconv, encoding)?; Ok(lconv) } pub(crate) fn get_name(_locale: *const c_void, _encoding: Encoding) -> Result { if let Ok(name) = env::var("LC_ALL") { return Ok(name); } if let Ok(name) = env::var("LC_NUMERIC") { return Ok(name); } if let Ok(name) = env::var("LC_MONETARY") { return Ok(name); } if let Ok(name) = env::var("LANG") { return Ok(name); } Ok("C".to_string()) } num-format-0.4.0/src/system_locale/windows.rs010064400007650000024000000327501343306115400175200ustar0000000000000000#![cfg(all(feature = "with-system-locale", windows))] use std::borrow::Cow; use std::collections::HashSet; use std::ffi::CStr; use std::mem; use std::ptr; use std::sync::{Arc, Mutex}; use num_format_windows::{ LOCALE_NAME_MAX_LENGTH, LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SDECIMAL, LOCALE_SGROUPING, LOCALE_SNAME, LOCALE_SNAN, LOCALE_SNEGATIVESIGN, LOCALE_SNEGINFINITY, LOCALE_SPOSINFINITY, LOCALE_SPOSITIVESIGN, LOCALE_STHOUSAND, }; use widestring::{U16CStr, U16CString}; use winapi::ctypes::c_int; use winapi::shared::minwindef::{BOOL, DWORD, LPARAM}; use winapi::um::errhandlingapi::GetLastError; use winapi::um::winnls; use winapi::um::winnt::WCHAR; use crate::error::Error; use crate::grouping::Grouping; use crate::strings::{DecString, InfString, MinString, NanString, PlusString, SepString}; use crate::system_locale::SystemLocale; lazy_static! { static ref SYSTEM_DEFAULT: Result<&'static str, Error> = { CStr::from_bytes_with_nul(LOCALE_NAME_SYSTEM_DEFAULT).map_err(|_| { Error::system_invalid_return( "LOCALE_NAME_SYSTEM_DEFAULT", "LOCALE_NAME_SYSTEM_DEFAULT from windows.h unexpectedly contains interior nul byte.", ) })?.to_str().map_err(|_| { Error::system_invalid_return( "LOCALE_NAME_SYSTEM_DEFAULT", "LOCALE_NAME_SYSTEM_DEFAULT from windows.h unexpectedly contains invalid UTF-8.", ) }) }; } pub(crate) fn available_names() -> Result, Error> { enum_system_locales_ex() } pub(crate) fn new(name: Option) -> Result { let name: Cow = match name { Some(name) => name.into(), None => (*SYSTEM_DEFAULT).clone()?.into(), }; let max_len = LOCALE_NAME_MAX_LENGTH as usize - 1; if name.len() > max_len { return Err(Error::parse_locale(name)); } let dec = { let s = get_locale_info_ex(&name, Request::Decimal)?; DecString::new(&s).map_err(|_| { Error::system_invalid_return( "get_locale_info_ex", format!( "get_locale_info_ex function from Windows API unexpectedly returned decimal \ string whose length ({} bytes) exceeds maximum currently supported by num-format \ ({} bytes).", s.len(), DecString::capacity(), ), ) })? }; let grp = { let grp_string = get_locale_info_ex(&name, Request::Grouping)?; match grp_string.as_ref() { "3;0" | "3" => Grouping::Standard, "3;2;0" | "3;2" => Grouping::Indian, "" => Grouping::Posix, _ => { return Err(Error::system_unsupported_grouping( grp_string.as_bytes().to_vec(), )); } } }; let inf = { let s = get_locale_info_ex(&name, Request::PositiveInfinity)?; InfString::new(&s).map_err(|_| { Error::system_invalid_return( "get_locale_info_ex", format!( "get_locale_info_ex function from Windows API unexpectedly returned infinity \ string whose length ({} bytes) exceeds maximum currently supported by num-format \ ({} bytes).", s.len(), InfString::capacity(), ), ) })? }; let min = { let s = get_locale_info_ex(&name, Request::MinusSign)?; MinString::new(&s).map_err(|_| { Error::system_invalid_return( "get_locale_info_ex", format!( "get_locale_info_ex function from Windows API unexpectedly returned minus sign \ string whose length ({} bytes) exceeds maximum currently supported by num-format \ ({} bytes).", s.len(), MinString::capacity(), ), ) })? }; let nan = { let s = get_locale_info_ex(&name, Request::Nan)?; NanString::new(&s).map_err(|_| { Error::system_invalid_return( "get_locale_info_ex", format!( "get_locale_info_ex function from Windows API unexpectedly returned NaN \ string whose length ({} bytes) exceeds maximum currently supported by num-format \ ({} bytes).", s.len(), NanString::capacity(), ), ) })? }; let plus = { let s = get_locale_info_ex(&name, Request::PlusSign)?; PlusString::new(&s).map_err(|_| { Error::system_invalid_return( "get_locale_info_ex", format!( "get_locale_info_ex function from Windows API unexpectedly returned plus sign \ string whose length ({} bytes) exceeds maximum currently supported by num-format \ ({} bytes).", s.len(), PlusString::capacity(), ), ) })? }; let sep = { let s = get_locale_info_ex(&name, Request::Separator)?; SepString::new(&s).map_err(|_| { Error::system_invalid_return( "get_locale_info_ex", format!( "get_locale_info_ex function from Windows API unexpectedly returned separator \ string whose length ({} bytes) exceeds maximum currently supported by num-format \ ({} bytes).", s.len(), SepString::capacity(), ), ) })? }; // we already have the name unless unless it was LOCALE_NAME_SYSTEM_DEFAULT, a special // case that doesn't correspond to our concept of name. in this special case, we have // to ask windows for the user-friendly name. the unwrap is OK, because we would never // have reached this point if LOCALE_NAME_SYSTEM_DEFAULT were an error. let name = if &name == SYSTEM_DEFAULT.as_ref().unwrap() { get_locale_info_ex(&name, Request::Name)? } else { name.into() }; let locale = SystemLocale { dec, grp, inf, min, name, nan, plus, sep, }; Ok(locale) } /// Enum representing all the things we know how to ask Windows for via the GetLocaleInfoEx API. #[derive(Copy, Clone, Debug)] pub enum Request { Decimal, Grouping, MinusSign, Name, Nan, NegativeInfinity, PositiveInfinity, PlusSign, Separator, } impl From for DWORD { fn from(request: Request) -> DWORD { use self::Request::*; match request { Decimal => LOCALE_SDECIMAL, Grouping => LOCALE_SGROUPING, MinusSign => LOCALE_SNEGATIVESIGN, Name => LOCALE_SNAME, Nan => LOCALE_SNAN, NegativeInfinity => LOCALE_SNEGINFINITY, PositiveInfinity => LOCALE_SPOSINFINITY, PlusSign => LOCALE_SPOSITIVESIGN, Separator => LOCALE_STHOUSAND, } } } /// Safe wrapper for EnumSystemLocalesEx. /// See https://docs.microsoft.com/en-us/windows/desktop/api/winnls/nf-winnls-enumsystemlocalesex. fn enum_system_locales_ex() -> Result, Error> { // global variables needed because we need to populate a HashSet inside a C callback function. lazy_static! { static ref OUTER_MUTEX: Arc> = Arc::new(Mutex::new(())); static ref INNER_MUTEX: Arc>> = Arc::new(Mutex::new(HashSet::default())); } // callback function. #[allow(non_snake_case)] unsafe extern "system" fn lpLocaleEnumProcEx( lpLocaleName: *mut WCHAR, _: DWORD, _: LPARAM, ) -> BOOL { // will be called continuously by windows until 0 is returned const CONTINUE: BOOL = 1; const STOP: BOOL = 0; if lpLocaleName.is_null() { return STOP; } let s = match U16CStr::from_ptr_str(lpLocaleName).to_string() { Ok(s) => s, Err(_) => return CONTINUE, }; if &s == "" { return CONTINUE; } let mut inner_guard = INNER_MUTEX.lock().unwrap(); let _ = inner_guard.insert(s); CONTINUE }; let set = { let outer_guard = OUTER_MUTEX.lock().unwrap(); { let mut inner_guard = INNER_MUTEX.lock().unwrap(); inner_guard.clear(); } let ret = unsafe { winnls::EnumSystemLocalesEx(Some(lpLocaleEnumProcEx), 0, 0, ptr::null_mut()) }; if ret == 0 { let err = unsafe { GetLastError() }; return Err(Error::system_invalid_return( "EnumSystemLocaleEx", format!("EnumSystemLocaleEx failed with error code {}", err), )); } let set = { let inner_guard = INNER_MUTEX.lock().unwrap(); inner_guard.clone() }; drop(outer_guard); set }; Ok(set) } /// Safe wrapper for GetLocaleInfoEx. /// See https://docs.microsoft.com/en-us/windows/desktop/api/winnls/nf-winnls-getlocaleinfoex. fn get_locale_info_ex(locale_name: &str, request: Request) -> Result { const BUF_LEN: usize = 1024; // inner function that represents actual call to GetLocaleInfoEx (will be used twice below) #[allow(non_snake_case)] fn inner( locale_name: &str, lpLocaleName: *const WCHAR, LCType: DWORD, buf_ptr: *mut WCHAR, size: c_int, ) -> Result { let size = unsafe { winnls::GetLocaleInfoEx(lpLocaleName, LCType, buf_ptr, size) }; if size == 0 { let err = unsafe { GetLastError() }; if err == 87 { return Err(Error::parse_locale(locale_name)); } return Err(Error::system_invalid_return( "GetLocaleInfoEx", format!("GetLocaleInfoEx failed with error code {}", err), )); } else if size < 0 { return Err(Error::system_invalid_return( "GetLocaleInfoEx", format!( "GetLocaleInfoEx unexpectedly returned a negative value of {}", size ), )); } // cast is OK because we've already checked that size is positive if size as usize > BUF_LEN { return Err(Error::new(format!( "GetLocaleInfoEx wants to write a string of {} WCHARs, which num-format does not \ currently support (current max is {}). if you would like num-format to support \ GetLocaleInfoEx writing longer strings, please please file an issue at \ https://github.com/bcmyers/num-format.", size, BUF_LEN, ))); } Ok(size) } // turn locale_name into windows string let locale_name_windows_string = U16CString::from_str(locale_name).map_err(|_| Error::interior_nul_byte(locale_name))?; #[allow(non_snake_case)] let lpLocaleName = locale_name_windows_string.as_ptr(); #[allow(non_snake_case)] let LCType = DWORD::from(request); // first call to GetLocaleInfoEx to get size of the data it will write. let size = inner(locale_name, lpLocaleName, LCType, ptr::null_mut(), 0)?; // second call to GetLocaleInfoEx to write data into our buffer. let mut buf: [WCHAR; BUF_LEN] = unsafe { mem::uninitialized() }; let written = inner(locale_name, lpLocaleName, LCType, buf.as_mut_ptr(), size)?; if written != size { return Err(Error::system_invalid_return( "GetLocaleInfoEx", "GetLocaleInfoEx returned an unexpected value for number of characters retrieved.", )); } let s = U16CStr::from_slice_with_nul(&buf[..written as usize]) .map_err(|_| { Error::system_invalid_return( "GetLocaleInfoEx", "Data written by GetLocaleInfoEx unexpectedly missing null byte.", ) })? .to_string() .map_err(|_| { Error::system_invalid_return( "GetLocaleInfoEx", "Data written by GetLocaleInfoEx unexpectedly contains invalid UTF-16.", ) })?; Ok(s) } #[cfg(test)] mod tests { use super::*; #[test] fn test_system_locale_windows_constructors() { let locale = new(None).unwrap(); println!("DEFAULT LOCALE NAME: {}", locale.name()); let _ = new(Some("en-US".to_string())).unwrap(); let names = available_names().unwrap(); for name in names { let _ = new(Some(name)).unwrap(); } } #[test] fn test_system_locale_windows_available_names() { use std::sync::mpsc; use std::thread; let locales = available_names().unwrap(); let (sender, receiver) = mpsc::channel(); let mut handles = Vec::new(); for _ in 0..20 { let sender = sender.clone(); let handle = thread::spawn(move || { let locales = enum_system_locales_ex().unwrap(); sender.send(locales).unwrap(); }); handles.push(handle); } let mut localess = Vec::new(); for _ in handles { let locales = receiver.recv().unwrap(); localess.push(locales); } for locales2 in localess { assert_eq!(locales, locales2) } } } num-format-0.4.0/src/to_formatted_str.rs010064400007650000024000000006601343304455300165410ustar0000000000000000use crate::buffer::Buffer; use crate::format::Format; use crate::sealed::Sealed; /// Marker trait for number types that can be formatted without heap allocation (see [`Buffer`]). /// /// This trait is sealed; so you may not implement it on your own types. /// /// [`Buffer`]: struct.Buffer.html pub trait ToFormattedStr: Sealed { #[doc(hidden)] fn read_to_buffer(&self, buf: &mut Buffer, format: &F) -> usize; } num-format-0.4.0/src/to_formatted_string.rs010064400007650000024000000034121343304455300172350ustar0000000000000000#![cfg(feature = "std")] use std::fmt; use std::io; use crate::constants::MAX_BUF_LEN; use crate::sealed::Sealed; use crate::{Buffer, Format, ToFormattedStr}; /// A key trait. Gives numbers the [`to_formatted_string`] method. /// /// This trait is sealed; so you may not implement it on your own types. /// /// [`to_formatted_string`]: trait.ToFormattedString.html#method.to_formatted_string pub trait ToFormattedString: Sealed { #[doc(hidden)] fn read_to_fmt_writer(&self, w: W, format: &F) -> Result where F: Format, W: fmt::Write; #[doc(hidden)] fn read_to_io_writer(&self, w: W, format: &F) -> Result where F: Format, W: io::Write; /// Returns a string representation of the number formatted according to the provided format. fn to_formatted_string(&self, format: &F) -> String where F: Format, { let mut s = String::with_capacity(MAX_BUF_LEN); let _ = self.read_to_fmt_writer(&mut s, format).unwrap(); s } } impl ToFormattedString for T where T: ToFormattedStr, { #[inline(always)] fn read_to_fmt_writer(&self, mut w: W, format: &F) -> Result where F: Format, W: fmt::Write, { let mut buf = Buffer::default(); let c = self.read_to_buffer(&mut buf, format); w.write_str(buf.as_str())?; Ok(c) } #[inline(always)] fn read_to_io_writer(&self, mut w: W, format: &F) -> Result where F: Format, W: io::Write, { let mut buf = Buffer::default(); let c = self.read_to_buffer(&mut buf, format); w.write_all(buf.as_bytes())?; Ok(c) } } num-format-0.4.0/src/write_formatted.rs010064400007650000024000000131151343304455300163600ustar0000000000000000#![cfg(feature = "std")] use std::fmt; use std::io; use crate::{Format, ToFormattedString}; /// A key trait. Gives types in the standard library that implement [`io::Write`] /// or [`fmt::Write`], such as `&mut [u8]` and `&mut String`, a [`write_formatted`] method for writing /// formatted numbers. /// /// [`fmt::Write`]: https://doc.rust-lang.org/stable/std/fmt/trait.Write.html /// [`io::Write`]: https://doc.rust-lang.org/stable/std/io/trait.Write.html /// [`write_formatted`]: trait.WriteFormatted.html#method.write_formatted pub trait WriteFormatted { /// Formats the provided number according to the provided format and then writes the resulting /// bytes to the object. Meant to be analagous to [`io::Write`]'s [`write_all`] method or /// [`fmt::Write`]'s [`write_str`] method. On success, returns the number of bytes written. /// /// # Errors /// /// Returns an [`io::Error`] under the same conditions as [`io::Write`]'s [`write_all`] method. /// /// [`fmt::Write`]: https://doc.rust-lang.org/stable/std/fmt/trait.Write.html /// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html /// [`io::Write`]: https://doc.rust-lang.org/stable/std/io/trait.Write.html /// [`write_all`]: https://doc.rust-lang.org/stable/std/io/trait.Write.html#method.write_all /// [`write_str`]: https://doc.rust-lang.org/stable/std/fmt/trait.Write.html#tymethod.write_str fn write_formatted(&mut self, n: &N, format: &F) -> Result where F: Format, N: ToFormattedString; } macro_rules! impl_for_fmt_write { () => { #[inline(always)] fn write_formatted(&mut self, n: &N, format: &F) -> Result where F: Format, N: ToFormattedString, { n.read_to_fmt_writer(self, format).map_err(|e| io::Error::new(io::ErrorKind::Other, e)) } }; } macro_rules! impl_for_io_write { () => { #[inline(always)] fn write_formatted(&mut self, n: &N, format: &F) -> Result where F: Format, N: ToFormattedString, { n.read_to_io_writer(self, format) } }; } #[rustfmt::skip] mod any { use std::fs; use std::net; use std::process; use super::*; impl WriteFormatted for Box { impl_for_io_write!(); } impl WriteFormatted for io::BufWriter { impl_for_io_write!(); } impl WriteFormatted for process::ChildStdin { impl_for_io_write!(); } impl WriteFormatted for io::Cursor> { impl_for_io_write!(); } impl WriteFormatted for io::Cursor> { impl_for_io_write!(); } impl<'a> WriteFormatted for io::Cursor<&'a mut [u8]> { impl_for_io_write!(); } impl<'a> WriteFormatted for io::Cursor<&'a mut Vec> { impl_for_io_write!(); } impl WriteFormatted for fs::File { impl_for_io_write!(); } impl WriteFormatted for io::LineWriter { impl_for_io_write!(); } impl WriteFormatted for io::Sink { impl_for_io_write!(); } impl WriteFormatted for io::Stderr { impl_for_io_write!(); } impl WriteFormatted for io::Stdout { impl_for_io_write!(); } impl WriteFormatted for String { impl_for_fmt_write!(); } impl WriteFormatted for net::TcpStream { impl_for_io_write!(); } impl WriteFormatted for Vec { impl_for_io_write!(); } impl<'a> WriteFormatted for io::StderrLock<'a> { impl_for_io_write!(); } impl<'a> WriteFormatted for io::StdoutLock<'a> { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut [u8] { impl_for_io_write!(); } impl<'a, W: io::Write + ?Sized> WriteFormatted for &'a mut Box { impl_for_io_write!(); } impl<'a, W: io::Write> WriteFormatted for &'a mut io::BufWriter { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut process::ChildStdin { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut io::Cursor> { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut io::Cursor> { impl_for_io_write!(); } impl<'a, 'b> WriteFormatted for &'a mut io::Cursor<&'b mut [u8]> { impl_for_io_write!(); } impl<'a, 'b> WriteFormatted for &'a mut io::Cursor<&'b mut Vec> { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a fs::File { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut fs::File { impl_for_io_write!(); } impl<'a, 'b> WriteFormatted for &'a mut fmt::Formatter<'b> { impl_for_fmt_write!(); } impl<'a, W: io::Write> WriteFormatted for &'a mut io::LineWriter { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut io::Sink { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut io::Stderr { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut io::Stdout { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut String { impl_for_fmt_write!(); } impl<'a> WriteFormatted for &'a net::TcpStream { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut net::TcpStream { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut Vec { impl_for_io_write!(); } impl<'a, 'b> WriteFormatted for &'a mut io::StderrLock<'b> { impl_for_io_write!(); } impl<'a, 'b> WriteFormatted for &'a mut io::StdoutLock<'b> { impl_for_io_write!(); } } #[cfg(unix)] #[rustfmt::skip] mod unix { use std::os::unix::net::UnixStream; use super::*; impl WriteFormatted for UnixStream { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a UnixStream { impl_for_io_write!(); } impl<'a> WriteFormatted for &'a mut UnixStream { impl_for_io_write!(); } } num-format-0.4.0/tests/common/mod.rs010064400007650000024000000026271343304455300156110ustar0000000000000000use core::str; use lazy_static::lazy_static; use num_format::{CustomFormat, Grouping}; lazy_static! { pub(crate) static ref POLICIES: [CustomFormat; 5] = { let four_byte_char = "𠜱"; let longest_minus_sign = unsafe { str::from_utf8_unchecked(&[226u8, 128, 142, 45, 226, 128, 142]) }; [ CustomFormat::builder() .grouping(Grouping::Standard) .minus_sign("-") .separator(",") .build() .unwrap(), CustomFormat::builder() .grouping(Grouping::Standard) .minus_sign(longest_minus_sign) .separator(four_byte_char) .build() .unwrap(), CustomFormat::builder() .grouping(Grouping::Indian) .minus_sign(longest_minus_sign) .separator(four_byte_char) .build() .unwrap(), CustomFormat::builder() .grouping(Grouping::Posix) .minus_sign(longest_minus_sign) .separator(four_byte_char) .build() .unwrap(), CustomFormat::builder() .grouping(Grouping::Standard) .minus_sign(longest_minus_sign) .separator("") .build() .unwrap(), ] }; } num-format-0.4.0/tests/test_errors.rs010064400007650000024000000056031343306216400161100ustar0000000000000000#[cfg(not(feature = "std"))] #[test] fn test_errors_capacity() { use num_format::utils::SeparatorStr; use num_format::{CustomFormat, ErrorKind}; let s = "123456789"; match SeparatorStr::new(s) { Ok(_) => panic!(), Err(e) => match e.kind() { ErrorKind::Capacity { len, cap } => { assert_eq!(*len, 9); assert_eq!(*cap, 8); } _ => panic!(), }, } match CustomFormat::builder().separator(s).build() { Ok(_) => panic!(), Err(e) => match e.kind() { ErrorKind::Capacity { len, cap } => { assert_eq!(*len, 9); assert_eq!(*cap, 8); } _ => panic!(), }, } } #[cfg(feature = "std")] #[test] fn test_errors_capacity() { use num_format::utils::SeparatorStr; use num_format::CustomFormat; let s = "123456789"; match SeparatorStr::new(s) { Ok(_) => panic!(), Err(e) => assert_eq!( "Attempted to write input of length 9 bytes into a buffer with capacity 8 bytes.", &e.to_string(), ), } match CustomFormat::builder().separator(s).build() { Ok(_) => panic!(), Err(e) => assert_eq!( "Attempted to write input of length 9 bytes into a buffer with capacity 8 bytes.", &e.to_string(), ), } } #[cfg(all(feature = "with-system-locale", any(unix, windows)))] #[test] fn test_errors_interior_null_byte() { use std::str; use num_format::SystemLocale; let b = b"Hello\0World"; let s = str::from_utf8(&b[..]).unwrap(); match SystemLocale::from_name(s) { Ok(_) => panic!(), Err(e) => assert_eq!( "Locale name Hello\u{0}World contains an interior nul byte, which is not allowed.", &e.to_string() ), } } #[cfg(not(feature = "std"))] #[test] fn test_errors_parse_locale() { use num_format::{ErrorKind, Locale}; let s = "123456789"; match Locale::from_name(s) { Ok(_) => panic!(), Err(e) => match e.kind() { ErrorKind::ParseLocale(array_string) => assert_eq!(s, array_string.as_str()), _ => panic!(), }, } } #[cfg(feature = "std")] #[test] fn test_errors_parse_locale() { use num_format::Locale; let s = "123456789"; match Locale::from_name(s) { Ok(_) => panic!(), Err(e) => assert_eq!( "Failed to parse 123456789 into a valid locale.", &e.to_string(), ), } } #[cfg(all(feature = "with-system-locale", any(unix, windows)))] #[test] fn test_errors_parse_system_locale() { use num_format::SystemLocale; let s = "123456789"; match SystemLocale::from_name(s) { Ok(_) => panic!(), Err(e) => assert_eq!( "Failed to parse 123456789 into a valid locale.", &e.to_string(), ), } } num-format-0.4.0/tests/test_no_bytes_written.rs010064400007650000024000000032641343307500700201730ustar0000000000000000#![cfg(feature = "std")] use std::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize}; use num_format::{CustomFormat, Locale, WriteFormatted}; #[test] fn test_no_bytes_written() { macro_rules! test1 { ( $( $n:expr ),* ) => { { $( let mut s = String::new(); let c = s.write_formatted(&$n, &Locale::en).unwrap(); assert_eq!(c, 5); )* } }; } test1!( 1_000u16, 1_000u32, 1_000usize, 1_000u64, 1_000u128, 1_000i16, 1_000i32, 1_000isize, 1_000i64, 1_000i128, NonZeroU16::new(1_000).unwrap(), NonZeroU32::new(1_000).unwrap(), NonZeroUsize::new(1_000).unwrap(), NonZeroU64::new(1_000).unwrap(), NonZeroU128::new(1_000).unwrap() ); macro_rules! test2 { ( $( $n:expr ),* ) => { { $( let mut s = String::new(); let format = CustomFormat::builder().separator("𠜱").build().unwrap(); let c = s.write_formatted(&$n, &format).unwrap(); assert_eq!(c, 8); )* } }; } test2!( 1_000u16, 1_000u32, 1_000usize, 1_000u64, 1_000u128, 1_000i16, 1_000i32, 1_000isize, 1_000i64, 1_000i128, NonZeroU16::new(1_000).unwrap(), NonZeroU32::new(1_000).unwrap(), NonZeroUsize::new(1_000).unwrap(), NonZeroU64::new(1_000).unwrap(), NonZeroU128::new(1_000).unwrap() ); } num-format-0.4.0/tests/test_non_zero.rs010064400007650000024000000234001343305315300164160ustar0000000000000000mod common; use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; use num_format::{Buffer, CustomFormat}; #[cfg(feature = "std")] use num_format::{ToFormattedString, WriteFormatted}; use crate::common::POLICIES; #[test] fn test_non_zero_u8() { let test_cases: &[(&str, NonZeroU8, &CustomFormat)] = &[ ("1", NonZeroU8::new(1).unwrap(), &POLICIES[0]), ("1", NonZeroU8::new(1).unwrap(), &POLICIES[1]), ("1", NonZeroU8::new(1).unwrap(), &POLICIES[2]), ("1", NonZeroU8::new(1).unwrap(), &POLICIES[3]), ("1", NonZeroU8::new(1).unwrap(), &POLICIES[4]), ("255", NonZeroU8::new(std::u8::MAX).unwrap(), &POLICIES[0]), ("255", NonZeroU8::new(std::u8::MAX).unwrap(), &POLICIES[1]), ("255", NonZeroU8::new(std::u8::MAX).unwrap(), &POLICIES[2]), ("255", NonZeroU8::new(std::u8::MAX).unwrap(), &POLICIES[3]), ("255", NonZeroU8::new(std::u8::MAX).unwrap(), &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_non_zero_u16() { let test_cases: &[(&str, NonZeroU16, &CustomFormat)] = &[ ("1", NonZeroU16::new(1).unwrap(), &POLICIES[0]), ("1", NonZeroU16::new(1).unwrap(), &POLICIES[1]), ("1", NonZeroU16::new(1).unwrap(), &POLICIES[2]), ("1", NonZeroU16::new(1).unwrap(), &POLICIES[3]), ("1", NonZeroU16::new(1).unwrap(), &POLICIES[4]), ( "65,535", NonZeroU16::new(std::u16::MAX).unwrap(), &POLICIES[0], ), ( "65𠜱535", NonZeroU16::new(std::u16::MAX).unwrap(), &POLICIES[1], ), ( "65𠜱535", NonZeroU16::new(std::u16::MAX).unwrap(), &POLICIES[2], ), ( "65535", NonZeroU16::new(std::u16::MAX).unwrap(), &POLICIES[3], ), ( "65535", NonZeroU16::new(std::u16::MAX).unwrap(), &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_non_zero_u32() { let test_cases: &[(&str, NonZeroU32, &CustomFormat)] = &[ ("1", NonZeroU32::new(1).unwrap(), &POLICIES[0]), ("1", NonZeroU32::new(1).unwrap(), &POLICIES[1]), ("1", NonZeroU32::new(1).unwrap(), &POLICIES[2]), ("1", NonZeroU32::new(1).unwrap(), &POLICIES[3]), ("1", NonZeroU32::new(1).unwrap(), &POLICIES[4]), ( "4,294,967,295", NonZeroU32::new(std::u32::MAX).unwrap(), &POLICIES[0], ), ( "4𠜱294𠜱967𠜱295", NonZeroU32::new(std::u32::MAX).unwrap(), &POLICIES[1], ), ( "4𠜱29𠜱49𠜱67𠜱295", NonZeroU32::new(std::u32::MAX).unwrap(), &POLICIES[2], ), ( "4294967295", NonZeroU32::new(std::u32::MAX).unwrap(), &POLICIES[3], ), ( "4294967295", NonZeroU32::new(std::u32::MAX).unwrap(), &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_non_zero_usize() { let test_cases: &[(&str, NonZeroUsize, &CustomFormat)] = &[ ("1", NonZeroUsize::new(1).unwrap(), &POLICIES[0]), ("1", NonZeroUsize::new(1).unwrap(), &POLICIES[1]), ("1", NonZeroUsize::new(1).unwrap(), &POLICIES[2]), ("1", NonZeroUsize::new(1).unwrap(), &POLICIES[3]), ("1", NonZeroUsize::new(1).unwrap(), &POLICIES[4]), ( "18,446,744,073,709,551,615", NonZeroUsize::new(std::usize::MAX).unwrap(), &POLICIES[0], ), ( "18𠜱446𠜱744𠜱073𠜱709𠜱551𠜱615", NonZeroUsize::new(std::usize::MAX).unwrap(), &POLICIES[1], ), ( "1𠜱84𠜱46𠜱74𠜱40𠜱73𠜱70𠜱95𠜱51𠜱615", NonZeroUsize::new(std::usize::MAX).unwrap(), &POLICIES[2], ), ( "18446744073709551615", NonZeroUsize::new(std::usize::MAX).unwrap(), &POLICIES[3], ), ( "18446744073709551615", NonZeroUsize::new(std::usize::MAX).unwrap(), &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_non_zero_u64() { let test_cases: &[(&str, NonZeroU64, &CustomFormat)] = &[ ("1", NonZeroU64::new(1).unwrap(), &POLICIES[0]), ("1", NonZeroU64::new(1).unwrap(), &POLICIES[1]), ("1", NonZeroU64::new(1).unwrap(), &POLICIES[2]), ("1", NonZeroU64::new(1).unwrap(), &POLICIES[3]), ("1", NonZeroU64::new(1).unwrap(), &POLICIES[4]), ( "18,446,744,073,709,551,615", NonZeroU64::new(std::u64::MAX).unwrap(), &POLICIES[0], ), ( "18𠜱446𠜱744𠜱073𠜱709𠜱551𠜱615", NonZeroU64::new(std::u64::MAX).unwrap(), &POLICIES[1], ), ( "1𠜱84𠜱46𠜱74𠜱40𠜱73𠜱70𠜱95𠜱51𠜱615", NonZeroU64::new(std::u64::MAX).unwrap(), &POLICIES[2], ), ( "18446744073709551615", NonZeroU64::new(std::u64::MAX).unwrap(), &POLICIES[3], ), ( "18446744073709551615", NonZeroU64::new(std::u64::MAX).unwrap(), &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_non_zero_u128() { let test_cases: &[(&str, NonZeroU128, &CustomFormat)] = &[ ("1", NonZeroU128::new(1).unwrap(), &POLICIES[0]), ("1", NonZeroU128::new(1).unwrap(), &POLICIES[1]), ("1", NonZeroU128::new(1).unwrap(), &POLICIES[2]), ("1", NonZeroU128::new(1).unwrap(), &POLICIES[3]), ("1", NonZeroU128::new(1).unwrap(), &POLICIES[4]), ( "340,282,366,920,938,463,463,374,607,431,768,211,455", NonZeroU128::new(std::u128::MAX).unwrap(), &POLICIES[0], ), ( "340𠜱282𠜱366𠜱920𠜱938𠜱463𠜱463𠜱374𠜱607𠜱431𠜱768𠜱211𠜱455", NonZeroU128::new(std::u128::MAX).unwrap(), &POLICIES[1], ), ( "34𠜱02𠜱82𠜱36𠜱69𠜱20𠜱93𠜱84𠜱63𠜱46𠜱33𠜱74𠜱60𠜱74𠜱31𠜱76𠜱82𠜱11𠜱455", NonZeroU128::new(std::u128::MAX).unwrap(), &POLICIES[2], ), ( "340282366920938463463374607431768211455", NonZeroU128::new(std::u128::MAX).unwrap(), &POLICIES[3], ), ( "340282366920938463463374607431768211455", NonZeroU128::new(std::u128::MAX).unwrap(), &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } num-format-0.4.0/tests/test_num_bigint.rs010064400007650000024000000147261343306220600167320ustar0000000000000000#![cfg(feature = "with-num-bigint")] mod common; use num_bigint::{BigInt, BigUint, Sign}; use num_format::{CustomFormat, ToFormattedString, WriteFormatted}; use crate::common::POLICIES; #[test] fn test_num_big_int() { let test_cases: &[(&str, BigInt, &CustomFormat)] = &[ ("\u{200e}-\u{200e}1𠜱000", BigInt::new(Sign::Minus, vec![1000]), &POLICIES[2]), ("\u{200e}-\u{200e}1𠜱00𠜱000", BigInt::new(Sign::Minus, vec![100000]), &POLICIES[2]), ("1", BigInt::new(Sign::Plus, vec![1]), &POLICIES[0]), ("1", BigInt::new(Sign::Plus, vec![1]), &POLICIES[1]), ("1", BigInt::new(Sign::Plus, vec![1]), &POLICIES[2]), ("1", BigInt::new(Sign::Plus, vec![1]), &POLICIES[3]), ("1", BigInt::new(Sign::Plus, vec![1]), &POLICIES[4]), ( "340,282,366,920,938,463,463,374,607,431,768,211,455", BigInt::new( Sign::Plus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[0], ), ( "340𠜱282𠜱366𠜱920𠜱938𠜱463𠜱463𠜱374𠜱607𠜱431𠜱768𠜱211𠜱455", BigInt::new( Sign::Plus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[1], ), ( "34𠜱02𠜱82𠜱36𠜱69𠜱20𠜱93𠜱84𠜱63𠜱46𠜱33𠜱74𠜱60𠜱74𠜱31𠜱76𠜱82𠜱11𠜱455", BigInt::new( Sign::Plus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[2], ), ( "340282366920938463463374607431768211455", BigInt::new( Sign::Plus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[3], ), ( "340282366920938463463374607431768211455", BigInt::new( Sign::Plus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[4], ), ( "-340,282,366,920,938,463,463,374,607,431,768,211,455", BigInt::new( Sign::Minus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[0], ), ( "\u{200e}-\u{200e}340𠜱282𠜱366𠜱920𠜱938𠜱463𠜱463𠜱374𠜱607𠜱431𠜱768𠜱211𠜱455", BigInt::new( Sign::Minus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[1], ), ( "\u{200e}-\u{200e}34𠜱02𠜱82𠜱36𠜱69𠜱20𠜱93𠜱84𠜱63𠜱46𠜱33𠜱74𠜱60𠜱74𠜱31𠜱76𠜱82𠜱11𠜱455", BigInt::new( Sign::Minus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[2], ), ( "\u{200e}-\u{200e}340282366920938463463374607431768211455", BigInt::new( Sign::Minus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[3], ), ( "\u{200e}-\u{200e}340282366920938463463374607431768211455", BigInt::new( Sign::Minus, vec![std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX], ), &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted (io::Write) let mut v = Vec::new(); v.write_formatted(input, *format).unwrap(); let s = String::from_utf8(v).unwrap(); assert_eq!(expected.to_string(), s); // WriteFormatted (fmt::Write) let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } #[test] fn test_num_big_uint() { let test_cases: &[(&str, BigUint, &CustomFormat)] = &[ ("1", BigUint::new(vec![1]), &POLICIES[0]), ("1", BigUint::new(vec![1]), &POLICIES[1]), ("1", BigUint::new(vec![1]), &POLICIES[2]), ("1", BigUint::new(vec![1]), &POLICIES[3]), ("1", BigUint::new(vec![1]), &POLICIES[4]), ( "340,282,366,920,938,463,463,374,607,431,768,211,455", BigUint::new(vec![ std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX, ]), &POLICIES[0], ), ( "340𠜱282𠜱366𠜱920𠜱938𠜱463𠜱463𠜱374𠜱607𠜱431𠜱768𠜱211𠜱455", BigUint::new(vec![ std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX, ]), &POLICIES[1], ), ( "34𠜱02𠜱82𠜱36𠜱69𠜱20𠜱93𠜱84𠜱63𠜱46𠜱33𠜱74𠜱60𠜱74𠜱31𠜱76𠜱82𠜱11𠜱455", BigUint::new(vec![ std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX, ]), &POLICIES[2], ), ( "340282366920938463463374607431768211455", BigUint::new(vec![ std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX, ]), &POLICIES[3], ), ( "340282366920938463463374607431768211455", BigUint::new(vec![ std::u32::MAX, std::u32::MAX, std::u32::MAX, std::u32::MAX, ]), &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted (io::Write) let mut v = Vec::new(); v.write_formatted(input, *format).unwrap(); let s = String::from_utf8(v).unwrap(); assert_eq!(expected.to_string(), s); // WriteFormatted (fmt::Write) let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } num-format-0.4.0/tests/test_serialization.rs010064400007650000024000000021501343306222300174370ustar0000000000000000#![cfg(feature = "with-serde")] #[test] fn test_serialization() { use num_format::{ Buffer, CustomFormat, CustomFormatBuilder, Error, ErrorKind, Grouping, Locale, }; use serde::{Deserialize, Serialize}; fn serializable() {} serializable::(); serializable::(); serializable::(); serializable::(); serializable::(); serializable::(); serializable::(); fn deserializable<'de, T: Deserialize<'de>>() {} deserializable::(); deserializable::(); deserializable::(); deserializable::(); deserializable::(); deserializable::(); deserializable::(); } #[cfg(feature = "with-system-locale")] #[test] fn test_serialization_system() { use num_format::SystemLocale; use serde::{Deserialize, Serialize}; fn serializable() {} serializable::(); fn deserializable<'de, T: Deserialize<'de>>() {} deserializable::(); } num-format-0.4.0/tests/test_signed.rs010064400007650000024000000246141343304455300160520ustar0000000000000000mod common; use num_format::{Buffer, CustomFormat}; #[cfg(feature = "std")] use num_format::{ToFormattedString, WriteFormatted}; use crate::common::POLICIES; #[test] fn test_i8() { let test_cases: &[(&str, i8, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("127", std::i8::MAX, &POLICIES[0]), ("127", std::i8::MAX, &POLICIES[1]), ("127", std::i8::MAX, &POLICIES[2]), ("127", std::i8::MAX, &POLICIES[3]), ("127", std::i8::MAX, &POLICIES[4]), ("-128", std::i8::MIN, &POLICIES[0]), ("\u{200e}-\u{200e}128", std::i8::MIN, &POLICIES[1]), ("\u{200e}-\u{200e}128", std::i8::MIN, &POLICIES[2]), ("\u{200e}-\u{200e}128", std::i8::MIN, &POLICIES[3]), ("\u{200e}-\u{200e}128", std::i8::MIN, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_i16() { let test_cases: &[(&str, i16, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("32,767", std::i16::MAX, &POLICIES[0]), ("32𠜱767", std::i16::MAX, &POLICIES[1]), ("32𠜱767", std::i16::MAX, &POLICIES[2]), ("32767", std::i16::MAX, &POLICIES[3]), ("32767", std::i16::MAX, &POLICIES[4]), ("-32,768", std::i16::MIN, &POLICIES[0]), ("\u{200e}-\u{200e}32𠜱768", std::i16::MIN, &POLICIES[1]), ("\u{200e}-\u{200e}32𠜱768", std::i16::MIN, &POLICIES[2]), ("\u{200e}-\u{200e}32768", std::i16::MIN, &POLICIES[3]), ("\u{200e}-\u{200e}32768", std::i16::MIN, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_i32() { let test_cases: &[(&str, i32, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("2,147,483,647", std::i32::MAX, &POLICIES[0]), ("2𠜱147𠜱483𠜱647", std::i32::MAX, &POLICIES[1]), ("2𠜱14𠜱74𠜱83𠜱647", std::i32::MAX, &POLICIES[2]), ("2147483647", std::i32::MAX, &POLICIES[3]), ("2147483647", std::i32::MAX, &POLICIES[4]), ("-2,147,483,648", std::i32::MIN, &POLICIES[0]), ( "\u{200e}-\u{200e}2𠜱147𠜱483𠜱648", std::i32::MIN, &POLICIES[1], ), ( "\u{200e}-\u{200e}2𠜱14𠜱74𠜱83𠜱648", std::i32::MIN, &POLICIES[2], ), ("\u{200e}-\u{200e}2147483648", std::i32::MIN, &POLICIES[3]), ("\u{200e}-\u{200e}2147483648", std::i32::MIN, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_isize() { let test_cases: &[(&str, isize, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("9,223,372,036,854,775,807", std::isize::MAX, &POLICIES[0]), ( "9𠜱223𠜱372𠜱036𠜱854𠜱775𠜱807", std::isize::MAX, &POLICIES[1], ), ( "92𠜱23𠜱37𠜱20𠜱36𠜱85𠜱47𠜱75𠜱807", std::isize::MAX, &POLICIES[2], ), ("9223372036854775807", std::isize::MAX, &POLICIES[3]), ("9223372036854775807", std::isize::MAX, &POLICIES[4]), ("-9,223,372,036,854,775,808", std::isize::MIN, &POLICIES[0]), ( "\u{200e}-\u{200e}9𠜱223𠜱372𠜱036𠜱854𠜱775𠜱808", std::isize::MIN, &POLICIES[1], ), ( "\u{200e}-\u{200e}92𠜱23𠜱37𠜱20𠜱36𠜱85𠜱47𠜱75𠜱808", std::isize::MIN, &POLICIES[2], ), ( "\u{200e}-\u{200e}9223372036854775808", std::isize::MIN, &POLICIES[3], ), ( "\u{200e}-\u{200e}9223372036854775808", std::isize::MIN, &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_i64() { let test_cases: &[(&str, i64, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("9,223,372,036,854,775,807", std::i64::MAX, &POLICIES[0]), ( "9𠜱223𠜱372𠜱036𠜱854𠜱775𠜱807", std::i64::MAX, &POLICIES[1], ), ( "92𠜱23𠜱37𠜱20𠜱36𠜱85𠜱47𠜱75𠜱807", std::i64::MAX, &POLICIES[2], ), ("9223372036854775807", std::i64::MAX, &POLICIES[3]), ("9223372036854775807", std::i64::MAX, &POLICIES[4]), ("-9,223,372,036,854,775,808", std::i64::MIN, &POLICIES[0]), ( "\u{200e}-\u{200e}9𠜱223𠜱372𠜱036𠜱854𠜱775𠜱808", std::i64::MIN, &POLICIES[1], ), ( "\u{200e}-\u{200e}92𠜱23𠜱37𠜱20𠜱36𠜱85𠜱47𠜱75𠜱808", std::i64::MIN, &POLICIES[2], ), ( "\u{200e}-\u{200e}9223372036854775808", std::i64::MIN, &POLICIES[3], ), ( "\u{200e}-\u{200e}9223372036854775808", std::i64::MIN, &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_i128() { let test_cases: &[(&str, i128, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ( "170,141,183,460,469,231,731,687,303,715,884,105,727", std::i128::MAX, &POLICIES[0], ), ( "170𠜱141𠜱183𠜱460𠜱469𠜱231𠜱731𠜱687𠜱303𠜱715𠜱884𠜱105𠜱727", std::i128::MAX, &POLICIES[1], ), ( "17𠜱01𠜱41𠜱18𠜱34𠜱60𠜱46𠜱92𠜱31𠜱73𠜱16𠜱87𠜱30𠜱37𠜱15𠜱88𠜱41𠜱05𠜱727", std::i128::MAX, &POLICIES[2], ), ( "170141183460469231731687303715884105727", std::i128::MAX, &POLICIES[3], ), ( "170141183460469231731687303715884105727", std::i128::MAX, &POLICIES[4], ), ( "-170,141,183,460,469,231,731,687,303,715,884,105,728", std::i128::MIN, &POLICIES[0], ), ( "\u{200e}-\u{200e}170𠜱141𠜱183𠜱460𠜱469𠜱231𠜱731𠜱687𠜱303𠜱715𠜱884𠜱105𠜱728", std::i128::MIN, &POLICIES[1], ), ( "\u{200e}-\u{200e}17𠜱01𠜱41𠜱18𠜱34𠜱60𠜱46𠜱92𠜱31𠜱73𠜱16𠜱87𠜱30𠜱37𠜱15𠜱88𠜱41𠜱05𠜱728", std::i128::MIN, &POLICIES[2], ), ( "\u{200e}-\u{200e}170141183460469231731687303715884105728", std::i128::MIN, &POLICIES[3], ), ( "\u{200e}-\u{200e}170141183460469231731687303715884105728", std::i128::MIN, &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } num-format-0.4.0/tests/test_system_locale_unix.rs010064400007650000024000000013231343306224100204710ustar0000000000000000#![cfg(all(feature = "with-system-locale", unix))] use std::cmp::Ordering; use std::env; use num_format::SystemLocale; #[test] fn test_unix() { let set = SystemLocale::available_names().unwrap(); let mut vec = set.iter().map(|s| s.to_string()).collect::>(); vec.sort_by(|_, _| { if rand::random() { Ordering::Greater } else { Ordering::Less } }); assert!(!vec.is_empty()); for name in &vec { println!("{}", name); let locale1 = SystemLocale::from_name(name.to_string()).unwrap(); env::set_var("LC_ALL", name); let locale2 = SystemLocale::default().unwrap(); assert_eq!(locale1, locale2); } } num-format-0.4.0/tests/test_system_locale_windows.rs010064400007650000024000000004561343306225000212060ustar0000000000000000#![cfg(all(feature = "with-system-locale", windows))] use num_format::SystemLocale; #[test] fn test_windows() { let names = SystemLocale::available_names().unwrap(); assert!(!names.is_empty()); for name in &names { let _ = SystemLocale::from_name(name.as_ref()).unwrap(); } } num-format-0.4.0/tests/test_unsigned.rs010064400007650000024000000164501343306225600164140ustar0000000000000000mod common; use num_format::{Buffer, CustomFormat}; #[cfg(feature = "std")] use num_format::{ToFormattedString, WriteFormatted}; use crate::common::POLICIES; #[test] fn test_u8() { let test_cases: &[(&str, u8, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("255", std::u8::MAX, &POLICIES[0]), ("255", std::u8::MAX, &POLICIES[1]), ("255", std::u8::MAX, &POLICIES[2]), ("255", std::u8::MAX, &POLICIES[3]), ("255", std::u8::MAX, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_u16() { let test_cases: &[(&str, u16, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("65,535", std::u16::MAX, &POLICIES[0]), ("65𠜱535", std::u16::MAX, &POLICIES[1]), ("65𠜱535", std::u16::MAX, &POLICIES[2]), ("65535", std::u16::MAX, &POLICIES[3]), ("65535", std::u16::MAX, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_u32() { let test_cases: &[(&str, u32, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("4,294,967,295", std::u32::MAX, &POLICIES[0]), ("4𠜱294𠜱967𠜱295", std::u32::MAX, &POLICIES[1]), ("4𠜱29𠜱49𠜱67𠜱295", std::u32::MAX, &POLICIES[2]), ("4294967295", std::u32::MAX, &POLICIES[3]), ("4294967295", std::u32::MAX, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_usize() { let test_cases: &[(&str, usize, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("18,446,744,073,709,551,615", std::usize::MAX, &POLICIES[0]), ( "18𠜱446𠜱744𠜱073𠜱709𠜱551𠜱615", std::usize::MAX, &POLICIES[1], ), ( "1𠜱84𠜱46𠜱74𠜱40𠜱73𠜱70𠜱95𠜱51𠜱615", std::usize::MAX, &POLICIES[2], ), ("18446744073709551615", std::usize::MAX, &POLICIES[3]), ("18446744073709551615", std::usize::MAX, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_u64() { let test_cases: &[(&str, u64, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ("18,446,744,073,709,551,615", std::u64::MAX, &POLICIES[0]), ( "18𠜱446𠜱744𠜱073𠜱709𠜱551𠜱615", std::u64::MAX, &POLICIES[1], ), ( "1𠜱84𠜱46𠜱74𠜱40𠜱73𠜱70𠜱95𠜱51𠜱615", std::u64::MAX, &POLICIES[2], ), ("18446744073709551615", std::u64::MAX, &POLICIES[3]), ("18446744073709551615", std::u64::MAX, &POLICIES[4]), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } #[test] fn test_u128() { let test_cases: &[(&str, u128, &CustomFormat)] = &[ ("0", 0, &POLICIES[0]), ("0", 0, &POLICIES[1]), ("0", 0, &POLICIES[2]), ("0", 0, &POLICIES[3]), ("0", 0, &POLICIES[4]), ( "340,282,366,920,938,463,463,374,607,431,768,211,455", std::u128::MAX, &POLICIES[0], ), ( "340𠜱282𠜱366𠜱920𠜱938𠜱463𠜱463𠜱374𠜱607𠜱431𠜱768𠜱211𠜱455", std::u128::MAX, &POLICIES[1], ), ( "34𠜱02𠜱82𠜱36𠜱69𠜱20𠜱93𠜱84𠜱63𠜱46𠜱33𠜱74𠜱60𠜱74𠜱31𠜱76𠜱82𠜱11𠜱455", std::u128::MAX, &POLICIES[2], ), ( "340282366920938463463374607431768211455", std::u128::MAX, &POLICIES[3], ), ( "340282366920938463463374607431768211455", std::u128::MAX, &POLICIES[4], ), ]; for (expected, input, format) in test_cases { // Buffer let mut buf = Buffer::default(); buf.write_formatted(input, *format); assert_eq!(*expected, buf.as_str()); #[cfg(feature = "std")] { // ToFormattedString assert_eq!(expected.to_string(), input.to_formatted_string(*format)); // WriteFormatted let mut s = String::new(); s.write_formatted(input, *format).unwrap(); assert_eq!(expected.to_string(), s); } } } num-format-0.4.0/.cargo_vcs_info.json0000644000000001120000000000000131530ustar00{ "git": { "sha1": "98c3c9f06eea7d3222faab6f79d4dcf88be02674" } }