lexical_write_float/
options.rs

1//! Configuration options for writing floats.
2//!
3//! This enables extensive control over how the float is written, from
4//! control characters like the decimal point, to the use of exponent
5//! notation, and the number of significant digits.
6//!
7//! # Examples
8//!
9//! For example, to customize the writing of numbers for new exponent
10//! and decimal point characters, you would use [`Options`] to create
11//! a custom format and write the integer using the format.
12//!
13//! ```rust
14//! # use core::{num, str};
15//! use lexical_write_float::{FormattedSize, Options, ToLexicalWithOptions};
16//! use lexical_write_float::format::STANDARD;
17//!
18//! let value = 1.234e45f64;
19//!
20//! const CUSTOM: Options = Options::builder()
21//!     // write exponents as "1.2^10" and not "1.2e10"
22//!     .exponent(b'^')
23//!     // use the European decimal point, so "1,2" and not "1.2"
24//!     .decimal_point(b',')
25//!     .build_strict();
26//!
27//! const BUFFER_SIZE: usize = CUSTOM.buffer_size_const::<f64, STANDARD>();
28//! let mut buffer = [0u8; BUFFER_SIZE];
29//! let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &CUSTOM);
30//! assert_eq!(str::from_utf8(digits), Ok("1,234^45"));
31//! ```
32//!
33//! # Pre-Defined Formats
34//!
35//! These are the pre-defined formats for parsing numbers from various
36//! programming, markup, and data languages.
37//!
38//! - [`STANDARD`]: Standard number format.
39//! - [`DECIMAL_COMMA`]: Numerical format with a decimal comma.
40//! - [`HEX_FLOAT`]: Numerical format for hexadecimal floats, which use a `p`
41//!   exponent.
42//! - [`CARAT_EXPONENT`]: Numerical format where `^` is used as the exponent
43//!   notation character.
44//! - [`RUST_LITERAL`]: Number format for a [`Rust`] literal floating-point
45//!   number.
46//! - [`PYTHON_LITERAL`]: Number format for a [`Python`] literal floating-point
47//!   number.
48//! - [`CXX_LITERAL`]: Number format for a [`C++`] literal floating-point
49//!   number.
50//! - [`C_LITERAL`]: Number format for a [`C`] literal floating-point number.
51//! - [`RUBY_LITERAL`]: Number format for a [`Ruby`] literal floating-point
52//!   number.
53//! - [`RUBY_STRING`]: Number format to parse a [`Ruby`] float from string.
54//! - [`SWIFT_LITERAL`]: Number format for a [`Swift`] literal floating-point
55//!   number.
56//! - [`GO_LITERAL`]: Number format for a [`Golang`] literal floating-point
57//!   number.
58//! - [`HASKELL_LITERAL`]: Number format for a [`Haskell`] literal
59//!   floating-point number.
60//! - [`HASKELL_STRING`]: Number format to parse a [`Haskell`] float from
61//!   string.
62//! - [`JAVASCRIPT_LITERAL`]: Number format for a [`Javascript`] literal
63//!   floating-point number.
64//! - [`JAVASCRIPT_STRING`]: Number format to parse a [`Javascript`] float from
65//!   string.
66//! - [`PERL_LITERAL`]: Number format for a [`Perl`] literal floating-point
67//!   number.
68//! - [`PHP_LITERAL`]: Number format for a [`PHP`] literal floating-point
69//!   number.
70//! - [`JAVA_LITERAL`]: Number format for a [`Java`] literal floating-point
71//!   number.
72//! - [`JAVA_STRING`]: Number format to parse a [`Java`] float from string.
73//! - [`R_LITERAL`]: Number format for an [`R`] literal floating-point number.
74//! - [`KOTLIN_LITERAL`]: Number format for a [`Kotlin`] literal floating-point
75//!   number.
76//! - [`KOTLIN_STRING`]: Number format to parse a [`Kotlin`] float from string.
77//! - [`JULIA_LITERAL`]: Number format for a [`Julia`] literal floating-point
78//!   number.
79//! - [`CSHARP_LITERAL`]: Number format for a [`C#`] literal floating-point
80//!   number.
81//! - [`CSHARP_STRING`]: Number format to parse a [`C#`] float from string.
82//! - [`KAWA_LITERAL`]: Number format for a [`Kawa`] literal floating-point
83//!   number.
84//! - [`KAWA_STRING`]: Number format to parse a [`Kawa`] float from string.
85//! - [`GAMBITC_LITERAL`]: Number format for a [`Gambit-C`] literal
86//!   floating-point number.
87//! - [`GAMBITC_STRING`]: Number format to parse a [`Gambit-C`] float from
88//!   string.
89//! - [`GUILE_LITERAL`]: Number format for a [`Guile`] literal floating-point
90//!   number.
91//! - [`GUILE_STRING`]: Number format to parse a [`Guile`] float from string.
92//! - [`CLOJURE_LITERAL`]: Number format for a [`Clojure`] literal
93//!   floating-point number.
94//! - [`CLOJURE_STRING`]: Number format to parse a [`Clojure`] float from
95//!   string.
96//! - [`ERLANG_LITERAL`]: Number format for an [`Erlang`] literal floating-point
97//!   number.
98//! - [`ERLANG_STRING`]: Number format to parse an [`Erlang`] float from string.
99//! - [`ELM_LITERAL`]: Number format for an [`Elm`] literal floating-point
100//!   number.
101//! - [`ELM_STRING`]: Number format to parse an [`Elm`] float from string.
102//! - [`SCALA_LITERAL`]: Number format for a [`Scala`] literal floating-point
103//!   number.
104//! - [`SCALA_STRING`]: Number format to parse a [`Scala`] float from string.
105//! - [`ELIXIR_LITERAL`]: Number format for an [`Elixir`] literal floating-point
106//!   number.
107//! - [`ELIXIR_STRING`]: Number format to parse an [`Elixir`] float from string.
108//! - [`FORTRAN_LITERAL`]: Number format for a [`FORTRAN`] literal
109//!   floating-point number.
110//! - [`D_LITERAL`]: Number format for a [`D`] literal floating-point number.
111//! - [`COFFEESCRIPT_LITERAL`]: Number format for a [`Coffeescript`] literal
112//!   floating-point number.
113//! - [`COFFEESCRIPT_STRING`]: Number format to parse a [`Coffeescript`] float
114//!   from string.
115//! - [`COBOL_LITERAL`]: Number format for a [`COBOL`] literal floating-point
116//!   number.
117//! - [`COBOL_STRING`]: Number format to parse a [`COBOL`] float from string.
118//! - [`FSHARP_LITERAL`]: Number format for an [`F#`] literal floating-point
119//!   number.
120//! - [`VB_LITERAL`]: Number format for a [`Visual Basic`] literal
121//!   floating-point number.
122//! - [`VB_STRING`]: Number format to parse a [`Visual Basic`] float from
123//!   string.
124//! - [`OCAML_LITERAL`]: Number format for an [`OCaml`] literal floating-point
125//!   number.
126//! - [`OBJECTIVEC_LITERAL`]: Number format for an [`Objective-C`] literal
127//!   floating-point number.
128//! - [`OBJECTIVEC_STRING`]: Number format to parse an [`Objective-C`] float
129//!   from string.
130//! - [`REASONML_LITERAL`]: Number format for an [`ReasonML`] literal
131//!   floating-point number.
132//! - [`MATLAB_LITERAL`]: Number format for a [`MATLAB`] literal floating-point
133//!   number.
134//! - [`ZIG_LITERAL`]: Number format for a [`Zig`] literal floating-point
135//!   number.
136//! - [`SAGE_LITERAL`]: Number format for a [`Sage`] literal floating-point
137//!   number.
138//! - [`JSON`]: Number format for a [`JSON`][`JSON-REF`] literal floating-point
139//!   number.
140//! - [`TOML`]: Number format for a [`TOML`][`TOML-REF`] literal floating-point
141//!   number.
142//! - [`YAML`]: Number format for a [`YAML`][`YAML-REF`] literal floating-point
143//!   number.
144//! - [`XML`]: Number format for an [`XML`][`XML-REF`] literal floating-point
145//!   number.
146//! - [`SQLITE`]: Number format for a [`SQLite`] literal floating-point number.
147//! - [`POSTGRESQL`]: Number format for a [`PostgreSQL`] literal floating-point
148//!   number.
149//! - [`MYSQL`]: Number format for a [`MySQL`] literal floating-point number.
150//! - [`MONGODB`]: Number format for a [`MongoDB`] literal floating-point
151//!   number.
152//!
153//! <!-- References -->
154//!
155//! [`Rust`]: https://www.rust-lang.org/
156//! [`Python`]: https://www.python.org/
157//! [`C++`]: https://en.cppreference.com/w/
158//! [`C`]: https://en.cppreference.com/w/c
159//! [`Ruby`]: https://www.ruby-lang.org/en/
160//! [`Swift`]: https://developer.apple.com/swift/
161//! [`Golang`]: https://go.dev/
162//! [`Haskell`]: https://www.haskell.org/
163//! [`Javascript`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
164//! [`Perl`]: https://www.perl.org/
165//! [`PHP`]: https://www.php.net/
166//! [`Java`]: https://www.java.com/en/
167//! [`R`]: https://www.r-project.org/
168//! [`Kotlin`]: https://kotlinlang.org/
169//! [`Julia`]: https://julialang.org/
170//! [`C#`]: https://learn.microsoft.com/en-us/dotnet/csharp/
171//! [`Kawa`]: https://www.gnu.org/software/kawa/
172//! [`Gambit-C`]: https://gambitscheme.org/
173//! [`Guile`]: https://www.gnu.org/software/guile/
174//! [`Clojure`]: https://clojure.org/
175//! [`Erlang`]: https://www.erlang.org/
176//! [`Elm`]: https://elm-lang.org/
177//! [`Scala`]: https://www.scala-lang.org/
178//! [`Elixir`]: https://elixir-lang.org/
179//! [`FORTRAN`]: https://fortran-lang.org/
180//! [`D`]: https://dlang.org/
181//! [`Coffeescript`]: https://coffeescript.org/
182//! [`Cobol`]: https://www.ibm.com/think/topics/cobol
183//! [`F#`]: https://fsharp.org/
184//! [`Visual Basic`]: https://learn.microsoft.com/en-us/dotnet/visual-basic/
185//! [`OCaml`]: https://ocaml.org/
186//! [`Objective-C`]: https://en.wikipedia.org/wiki/Objective-C
187//! [`ReasonML`]: https://reasonml.github.io/
188//! [`Matlab`]: https://www.mathworks.com/products/matlab.html
189//! [`Zig`]: https://ziglang.org/
190//! [`Sage`]: https://www.sagemath.org/
191//! [`JSON-REF`]: https://www.json.org/json-en.html
192//! [`TOML-REF`]: https://toml.io/en/
193//! [`YAML-REF`]: https://yaml.org/
194//! [`XML-REF`]: https://en.wikipedia.org/wiki/XML
195//! [`SQLite`]: https://www.sqlite.org/
196//! [`PostgreSQL`]: https://www.postgresql.org/
197//! [`MySQL`]: https://www.mysql.com/
198//! [`MongoDB`]: https://www.mongodb.com/
199
200use core::num;
201
202use lexical_util::ascii::{is_valid_ascii, is_valid_letter_slice};
203use lexical_util::constants::FormattedSize;
204use lexical_util::error::Error;
205use lexical_util::format::NumberFormat;
206use lexical_util::options::{self, WriteOptions};
207use lexical_util::result::Result;
208
209// NOTE: Rust guarantees the sizes are the same:
210//  https://doc.rust-lang.org/std/num/struct.NonZero.html
211
212/// Type with the exact same size as a `usize`.
213#[doc(hidden)]
214pub type OptionUsize = Option<num::NonZeroUsize>;
215
216/// Type with the exact same size as a `i32`.
217#[doc(hidden)]
218pub type OptionI32 = Option<num::NonZeroI32>;
219
220/// Const evaluation of `max` for integers.
221macro_rules! max {
222    ($x:expr, $y:expr) => {{
223        let x = $x;
224        let y = $y;
225        if x >= y {
226            x
227        } else {
228            y
229        }
230    }};
231}
232
233/// Const evaluation of `min` for integers.
234macro_rules! min {
235    ($x:expr, $y:expr) => {{
236        let x = $x;
237        let y = $y;
238        if x <= y {
239            x
240        } else {
241            y
242        }
243    }};
244}
245
246/// Enumeration for how to round floats with precision control.
247///
248/// For example, using [`Round`][RoundMode::Round], `1.2345` rounded
249/// to 4 digits would be `1.235`, while [`Truncate`][RoundMode::Truncate]
250/// would be `1.234`.
251#[derive(Debug, Copy, Clone, PartialEq, Eq)]
252pub enum RoundMode {
253    /// Round to the nearest float string with the given number of significant
254    /// digits.
255    Round,
256
257    /// Truncate the float string with the given number of significant digits.
258    Truncate,
259}
260
261/// Maximum length for a special string.
262pub const MAX_SPECIAL_STRING_LENGTH: usize = 50;
263
264/// Builder for [`Options`].
265///
266/// This enables extensive control over how the float is written, from
267/// control characters like the decimal point, to the use of exponent
268/// notation, and the number of significant digits.
269///
270/// # Examples
271///
272/// For example, to customize the writing of numbers for new exponent
273/// and decimal point characters, you would use:
274///
275/// ```rust
276/// # use core::{num, str};
277/// use lexical_write_float::{FormattedSize, Options, ToLexicalWithOptions};
278/// use lexical_write_float::format::STANDARD;
279///
280/// let value = 1.234e45f64;
281///
282/// const CUSTOM: Options = Options::builder()
283///     // write exponents as "1.2^10" and not "1.2e10"
284///     .exponent(b'^')
285///     // use the European decimal point, so "1,2" and not "1.2"
286///     .decimal_point(b',')
287///     .build_strict();
288///
289/// const BUFFER_SIZE: usize = CUSTOM.buffer_size_const::<f64, STANDARD>();
290/// let mut buffer = [0u8; BUFFER_SIZE];
291/// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &CUSTOM);
292/// assert_eq!(str::from_utf8(digits), Ok("1,234^45"));
293/// ```
294#[derive(Debug, Clone, PartialEq, Eq)]
295pub struct OptionsBuilder {
296    /// Maximum number of significant digits to write.
297    ///
298    /// If not set, it defaults to the algorithm's default.
299    max_significant_digits: OptionUsize,
300
301    /// Minimum number of significant digits to write.
302    ///
303    /// If not set, it defaults to the algorithm's default.
304    /// Note that this isn't fully respected: if you wish to format
305    /// `0.1` with 25 significant digits, the correct result **should**
306    /// be `0.100000000000000005551115`. However, we would output
307    /// `0.100000000000000000000000`, which is still the nearest float.
308    min_significant_digits: OptionUsize,
309
310    /// Maximum exponent prior to using scientific notation.
311    ///
312    /// This is ignored if the exponent base is not the same as the mantissa
313    /// radix. If not provided, use the algorithm's default.
314    positive_exponent_break: OptionI32,
315
316    /// Minimum exponent prior to using scientific notation.
317    ///
318    /// This is ignored if the exponent base is not the same as the mantissa
319    /// radix. If not provided, use the algorithm's default.
320    negative_exponent_break: OptionI32,
321
322    /// Rounding mode for writing digits with precision control.
323    round_mode: RoundMode,
324
325    /// Trim the trailing ".0" from integral float strings.
326    ///
327    /// If used in conjunction with [`min_significant_digits`],
328    /// this will still trim all the significant digits if an integral
329    /// value is provided.
330    ///
331    /// [`min_significant_digits`]: Self::min_significant_digits
332    trim_floats: bool,
333
334    /// Character to designate the exponent component of a float.
335    exponent: u8,
336
337    /// Character to separate the integer from the fraction components.
338    decimal_point: u8,
339
340    /// String representation of Not A Number, aka `NaN`.
341    nan_string: Option<&'static [u8]>,
342
343    /// String representation of `Infinity`.
344    inf_string: Option<&'static [u8]>,
345}
346
347impl OptionsBuilder {
348    // CONSTRUCTORS
349
350    #[inline(always)]
351    pub const fn new() -> Self {
352        Self {
353            max_significant_digits: None,
354            min_significant_digits: None,
355            positive_exponent_break: None,
356            negative_exponent_break: None,
357            round_mode: RoundMode::Round,
358            trim_floats: false,
359            exponent: b'e',
360            decimal_point: b'.',
361            nan_string: Some(b"NaN"),
362            inf_string: Some(b"inf"),
363        }
364    }
365
366    // GETTERS
367
368    /// Get the maximum number of significant digits to write.
369    ///
370    /// This limits the total number of written digits, truncating based
371    /// on the [`round_mode`] if more digits would normally be written. If
372    /// no value is provided, then it writes as many digits as required to
373    /// create an unambiguous representation of the float.
374    ///
375    /// # Examples
376    ///
377    /// ```rust
378    /// use lexical_write_float::Options;
379    ///
380    /// let builder = Options::builder();
381    /// assert_eq!(builder.get_max_significant_digits(), None);
382    /// ```
383    ///
384    /// [`round_mode`]: Self::round_mode
385    #[inline(always)]
386    pub const fn get_max_significant_digits(&self) -> OptionUsize {
387        self.max_significant_digits
388    }
389
390    /// Get the minimum number of significant digits to write.
391    ///
392    /// If more digits exist, such as writing "1.2" with a minimum of 5
393    /// significant digits, then `0`s are appended to the end of the digits. If
394    /// no value is provided, then it writes as few digits as required to
395    /// create an unambiguous representation of the float.
396    ///
397    /// # Examples
398    ///
399    /// ```rust
400    /// use lexical_write_float::Options;
401    ///
402    /// let builder = Options::builder();
403    /// assert_eq!(builder.get_min_significant_digits(), None);
404    /// ```
405    #[inline(always)]
406    pub const fn get_min_significant_digits(&self) -> OptionUsize {
407        self.min_significant_digits
408    }
409
410    /// Get the maximum exponent prior to using scientific notation.
411    ///
412    /// If the value is set to `300`, then any value with magnitude `>= 1e300`
413    /// (for base 10) will be writen in exponent notation, while any lower
414    /// value will be written in decimal form. If no value is provided, for
415    /// decimal floats, this defaults to `9`.
416    ///
417    /// # Examples
418    ///
419    /// ```rust
420    /// use lexical_write_float::Options;
421    ///
422    /// let builder = Options::builder();
423    /// assert_eq!(builder.get_positive_exponent_break(), None);
424    /// ```
425    #[inline(always)]
426    pub const fn get_positive_exponent_break(&self) -> OptionI32 {
427        self.positive_exponent_break
428    }
429
430    /// Get the minimum exponent prior to using scientific notation.
431    ///
432    /// If the value is set to `-300`, then any value with magnitude `< 1e-300`
433    /// (for base 10) will be writen in exponent notation, while any larger
434    /// value will be written in decimal form. If no value is provided, for
435    /// decimal floats, this defaults to `-5`.
436    ///
437    /// # Examples
438    ///
439    /// ```rust
440    /// use lexical_write_float::Options;
441    ///
442    /// let builder = Options::builder();
443    /// assert_eq!(builder.get_negative_exponent_break(), None);
444    /// ```
445    #[inline(always)]
446    pub const fn get_negative_exponent_break(&self) -> OptionI32 {
447        self.negative_exponent_break
448    }
449
450    /// Get the rounding mode for writing digits with precision control.
451    ///
452    /// For example, writing `1.23456` with 5 significant digits with
453    /// [`RoundMode::Round`] would produce `"1.2346"` while
454    /// [`RoundMode::Truncate`] would produce `"1.2345"`. Defaults to
455    /// [`RoundMode::Round`].
456    ///
457    /// # Examples
458    ///
459    /// ```rust
460    /// use lexical_write_float::{Options, RoundMode};
461    ///
462    /// let builder = Options::builder();
463    /// assert_eq!(builder.get_round_mode(), RoundMode::Round);
464    /// ```
465    #[inline(always)]
466    pub const fn get_round_mode(&self) -> RoundMode {
467        self.round_mode
468    }
469
470    /// Get if we should trim a trailing `".0"` from integral floats.
471    ///
472    /// If used in conjunction with [`min_significant_digits`],
473    /// this will still trim all the significant digits if an integral
474    /// value is provided. Defaults to [`false`].
475    ///
476    /// # Examples
477    ///
478    /// ```rust
479    /// use lexical_write_float::Options;
480    ///
481    /// let builder = Options::builder();
482    /// assert_eq!(builder.get_trim_floats(), false);
483    /// ```
484    ///
485    /// [`min_significant_digits`]: Self::min_significant_digits
486    #[inline(always)]
487    pub const fn get_trim_floats(&self) -> bool {
488        self.trim_floats
489    }
490
491    /// Get the character to designate the exponent component of a float.
492    ///
493    /// Any non-control character is valid, but `\t` to `\r` are also valid.
494    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `e`.
495    ///
496    /// # Examples
497    ///
498    /// ```rust
499    /// use lexical_write_float::Options;
500    ///
501    /// let builder = Options::builder();
502    /// assert_eq!(builder.get_exponent(), b'e');
503    /// ```
504    #[inline(always)]
505    pub const fn get_exponent(&self) -> u8 {
506        self.exponent
507    }
508
509    /// Get the character to separate the integer from the fraction components.
510    ///
511    /// Any non-control character is valid, but `\t` to `\r` are also valid.
512    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `.`.
513    ///
514    /// # Examples
515    ///
516    /// ```rust
517    /// use lexical_write_float::Options;
518    ///
519    /// let builder = Options::builder();
520    /// assert_eq!(builder.get_decimal_point(), b'.');
521    /// ```
522    #[inline(always)]
523    pub const fn get_decimal_point(&self) -> u8 {
524        self.decimal_point
525    }
526
527    /// Get the string representation for `NaN`.
528    ///
529    /// The first character must start with `N` or `n` and all characters must
530    /// be valid ASCII letters (`A-Z` or `a-z`).  If set to `None`, then writing
531    /// [`NaN`][f64::NAN] leads to an error. Defaults to `NaN`.
532    ///
533    /// # Examples
534    ///
535    /// ```rust
536    /// use lexical_write_float::Options;
537    ///
538    /// let builder = Options::builder();
539    /// assert_eq!(builder.get_nan_string(), Some("NaN".as_bytes()));
540    /// ```
541    #[inline(always)]
542    pub const fn get_nan_string(&self) -> Option<&'static [u8]> {
543        self.nan_string
544    }
545
546    /// Get the string representation for `Infinity`.
547    ///
548    /// The first character must start with `I` or `i` and all characters must
549    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
550    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
551    ///
552    /// # Examples
553    ///
554    /// ```rust
555    /// use lexical_write_float::Options;
556    ///
557    /// let builder = Options::builder();
558    /// assert_eq!(builder.get_inf_string(), Some("inf".as_bytes()));
559    /// ```
560    #[inline(always)]
561    pub const fn get_inf_string(&self) -> Option<&'static [u8]> {
562        self.inf_string
563    }
564
565    /// Get the string representation for `Infinity`. Alias for
566    /// [`get_inf_string`].
567    ///
568    /// The first character must start with `I` or `i` and all characters must
569    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
570    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
571    ///
572    /// [`get_inf_string`]: Self::get_inf_string
573    ///
574    /// # Examples
575    ///
576    /// ```rust
577    /// use lexical_write_float::Options;
578    ///
579    /// let builder = Options::builder();
580    /// assert_eq!(builder.get_infinity_string(), Some("inf".as_bytes()));
581    /// ```
582    #[inline(always)]
583    pub const fn get_infinity_string(&self) -> Option<&'static [u8]> {
584        self.inf_string
585    }
586
587    // SETTERS
588
589    /// Set the maximum number of significant digits to write.
590    ///
591    /// This limits the total number of written digits, truncating based
592    /// on the [`round_mode`] if more digits would normally be written. If
593    /// no value is provided, then it writes as many digits as required to
594    /// create an unambiguous representation of the float.
595    ///
596    /// # Examples
597    ///
598    /// ```rust
599    /// use core::num::NonZeroUsize;
600    ///
601    /// use lexical_write_float::Options;
602    ///
603    /// let max_digits = NonZeroUsize::new(300);
604    /// let builder = Options::builder()
605    ///     .max_significant_digits(max_digits);
606    /// assert_eq!(builder.get_max_significant_digits(), max_digits);
607    /// ```
608    ///
609    /// # Panics
610    ///
611    /// This will panic when building the options or writing the float if the
612    /// value is smaller than [`min_significant_digits`].
613    ///
614    /// [`round_mode`]: Self::round_mode
615    /// [`min_significant_digits`]: Self::min_significant_digits
616    #[inline(always)]
617    pub const fn max_significant_digits(mut self, max_significant_digits: OptionUsize) -> Self {
618        self.max_significant_digits = max_significant_digits;
619        self
620    }
621
622    /// Set the minimum number of significant digits to write.
623    ///
624    /// If more digits exist, such as writing "1.2" with a minimum of 5
625    /// significant digits, then `0`s are appended to the end of the digits.
626    /// If no value is provided, then it writes as few digits as required to
627    /// create an unambiguous representation of the float.
628    ///
629    /// # Examples
630    ///
631    /// ```rust
632    /// use core::num::NonZeroUsize;
633    ///
634    /// use lexical_write_float::Options;
635    ///
636    /// let min_digits = NonZeroUsize::new(10);
637    /// let builder = Options::builder()
638    ///     .min_significant_digits(min_digits);
639    /// assert_eq!(builder.get_min_significant_digits(), min_digits);
640    /// ```
641    ///
642    /// # Panics
643    ///
644    /// This will panic when building the options or writing the float if the
645    /// value is larger than [`max_significant_digits`].
646    ///
647    /// [`max_significant_digits`]: Self::max_significant_digits
648    #[inline(always)]
649    pub const fn min_significant_digits(mut self, min_significant_digits: OptionUsize) -> Self {
650        self.min_significant_digits = min_significant_digits;
651        self
652    }
653
654    /// Set the maximum exponent prior to using scientific notation.
655    ///
656    /// If the value is set to `300`, then any value with magnitude `>= 1e300`
657    /// (for base 10) will be writen in exponent notation, while any lower
658    /// value will be written in decimal form. If no value is provided, for
659    /// decimal floats, this defaults to `9`.
660    ///
661    /// # Examples
662    ///
663    /// ```rust
664    /// use core::num::NonZeroI32;
665    ///
666    /// use lexical_write_float::Options;
667    ///
668    /// let pos_break = NonZeroI32::new(3);
669    /// let builder = Options::builder()
670    ///     .positive_exponent_break(pos_break);
671    /// assert_eq!(builder.get_positive_exponent_break(), pos_break);
672    /// ```
673    ///
674    /// # Panics
675    ///
676    /// Panics if the value is `<= 0`.
677    #[inline(always)]
678    pub const fn positive_exponent_break(mut self, positive_exponent_break: OptionI32) -> Self {
679        self.positive_exponent_break = positive_exponent_break;
680        self
681    }
682
683    /// Set the minimum exponent prior to using scientific notation.
684    ///
685    /// If the value is set to `-300`, then any value with magnitude `< 1e-300`
686    /// (for base 10) will be writen in exponent notation, while any larger
687    /// value will be written in decimal form. If no value is provided, for
688    /// decimal floats, this defaults to `-5`.
689    ///
690    /// # Examples
691    ///
692    /// ```rust
693    /// use core::num::NonZeroI32;
694    ///
695    /// use lexical_write_float::Options;
696    ///
697    /// let neg_break = NonZeroI32::new(-3);
698    /// let builder = Options::builder()
699    ///     .negative_exponent_break(neg_break);
700    /// assert_eq!(builder.get_negative_exponent_break(), neg_break);
701    /// ```
702    ///
703    /// # Panics
704    ///
705    /// Panics if the value is `>= 0`.
706    #[inline(always)]
707    pub const fn negative_exponent_break(mut self, negative_exponent_break: OptionI32) -> Self {
708        self.negative_exponent_break = negative_exponent_break;
709        self
710    }
711
712    /// Set the rounding mode for writing digits with precision control.
713    ///
714    /// For example, writing `1.23456` with 5 significant digits with
715    /// [`RoundMode::Round`] would produce `"1.2346"` while
716    /// [`RoundMode::Truncate`] would produce `"1.2345"`. Defaults to
717    /// [`RoundMode::Round`].
718    ///
719    /// # Examples
720    ///
721    /// ```rust
722    /// # #[cfg(all(feature = "format", feature = "radix"))] {
723    /// use core::{num, str};
724    ///
725    /// use lexical_write_float::{RoundMode, Options, ToLexicalWithOptions};
726    /// use lexical_write_float::format::STANDARD;
727    ///
728    ///  let value = 1.23456f64;
729    ///
730    /// // truncating
731    /// const TRUNCATE: Options = Options::builder()
732    ///     // truncate numbers when writing less digits than present, rather than round
733    ///     .round_mode(RoundMode::Truncate)
734    ///     // the maximum number of significant digits to write
735    ///     .max_significant_digits(num::NonZeroUsize::new(5))
736    ///     // build the options, panicking if they're invalid
737    ///     .build_strict();
738    /// const TRUNCATE_SIZE: usize = TRUNCATE.buffer_size_const::<f64, STANDARD>();
739    /// let mut buffer = [0u8; TRUNCATE_SIZE];
740    /// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &TRUNCATE);
741    /// assert_eq!(str::from_utf8(digits), Ok("1.2345"));
742    ///
743    /// // rounding
744    /// const ROUND: Options = Options::builder()
745    ///     // round to the nearest number when writing less digits than present
746    ///     .round_mode(RoundMode::Round)
747    ///     // the maximum number of significant digits to write
748    ///     .max_significant_digits(num::NonZeroUsize::new(5))
749    ///     // build the options, panicking if they're invalid
750    ///     .build_strict();
751    /// const ROUND_SIZE: usize = ROUND.buffer_size_const::<f64, STANDARD>();
752    /// let mut buffer = [0u8; ROUND_SIZE];
753    /// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &ROUND);
754    /// assert_eq!(str::from_utf8(digits), Ok("1.2346"));
755    /// # }
756    /// ```
757    #[inline(always)]
758    pub const fn round_mode(mut self, round_mode: RoundMode) -> Self {
759        self.round_mode = round_mode;
760        self
761    }
762
763    /// Set if we should trim a trailing `".0"` from integral floats.
764    ///
765    /// If used in conjunction with [`min_significant_digits`],
766    /// this will still trim all the significant digits if an integral
767    /// value is provided. Defaults to [`false`].
768    ///
769    /// # Examples
770    ///
771    /// ```rust
772    /// use lexical_write_float::Options;
773    ///
774    /// let builder = Options::builder()
775    ///     .trim_floats(true);
776    /// assert_eq!(builder.get_trim_floats(), true);
777    /// ```
778    ///
779    /// [`min_significant_digits`]: Self::min_significant_digits
780    #[inline(always)]
781    pub const fn trim_floats(mut self, trim_floats: bool) -> Self {
782        self.trim_floats = trim_floats;
783        self
784    }
785
786    /// Set the character to designate the exponent component of a float.
787    ///
788    /// Any non-control character is valid, but `\t` to `\r` are also valid.
789    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `e`.
790    ///
791    /// # Examples
792    ///
793    /// ```rust
794    /// use lexical_write_float::Options;
795    ///
796    /// let builder = Options::builder()
797    ///     .exponent(b'^');
798    /// assert_eq!(builder.get_exponent(), b'^');
799    /// ```
800    #[inline(always)]
801    pub const fn exponent(mut self, exponent: u8) -> Self {
802        self.exponent = exponent;
803        self
804    }
805
806    /// Set the character to separate the integer from the fraction components.
807    ///
808    /// Any non-control character is valid, but `\t` to `\r` are also valid.
809    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `.`.
810    ///
811    /// # Examples
812    ///
813    /// ```rust
814    /// use lexical_write_float::Options;
815    ///
816    /// let builder = Options::builder()
817    ///     .decimal_point(b'^');
818    /// assert_eq!(builder.get_decimal_point(), b'^');
819    /// ```
820    #[inline(always)]
821    pub const fn decimal_point(mut self, decimal_point: u8) -> Self {
822        self.decimal_point = decimal_point;
823        self
824    }
825
826    /// Set the string representation for `NaN`.
827    ///
828    /// The first character must start with `N` or `n` and all characters must
829    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
830    /// [`NaN`][f64::NAN] returns an error. Defaults to `NaN`.
831    ///
832    /// # Examples
833    ///
834    /// ```rust
835    /// use lexical_write_float::Options;
836    ///
837    /// let builder = Options::builder()
838    ///     .nan_string(Some(b"nan"));
839    /// assert_eq!(builder.get_nan_string(), Some(b"nan".as_ref()));
840    /// ```
841    ///
842    /// Panics
843    ///
844    /// Setting a value with more than 50 elements will panic at runtime. You
845    /// should always build the format using [`build_strict`] or checking
846    /// [`is_valid`] prior to using the format, to avoid unexpected panics.
847    ///
848    /// [`FORMATTED_SIZE`]: `lexical_util::constants::FormattedSize::FORMATTED_SIZE`
849    /// [`build_strict`]: Self::build_strict
850    /// [`is_valid`]: Self::is_valid
851    #[inline(always)]
852    pub const fn nan_string(mut self, nan_string: Option<&'static [u8]>) -> Self {
853        self.nan_string = nan_string;
854        self
855    }
856
857    /// Set the string representation for `Infinity`.
858    ///
859    /// The first character must start with `I` or `i` and all characters must
860    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
861    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
862    ///
863    /// # Examples
864    ///
865    /// ```rust
866    /// use lexical_write_float::Options;
867    ///
868    /// let builder = Options::builder()
869    ///     .inf_string(Some(b"infinity"));
870    /// assert_eq!(builder.get_inf_string(), Some(b"infinity".as_ref()));
871    /// ```
872    ///
873    /// Panics
874    ///
875    /// Setting a value with more than 50 elements will panic at runtime. You
876    /// should always build the format using [`build_strict`] or checking
877    /// [`is_valid`] prior to using the format, to avoid unexpected panics.
878    ///
879    /// [`FORMATTED_SIZE`]: `lexical_util::constants::FormattedSize::FORMATTED_SIZE`
880    /// [`build_strict`]: Self::build_strict
881    /// [`is_valid`]: Self::is_valid
882    #[inline(always)]
883    pub const fn inf_string(mut self, inf_string: Option<&'static [u8]>) -> Self {
884        self.inf_string = inf_string;
885        self
886    }
887
888    /// Set the string representation for `Infinity`. Alias for [`inf_string`].
889    ///
890    /// The first character must start with `I` or `i` and all characters must
891    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
892    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
893    ///
894    /// [`inf_string`]: Self::inf_string
895    ///
896    /// # Examples
897    ///
898    /// ```rust
899    /// use lexical_write_float::Options;
900    ///
901    /// let builder = Options::builder()
902    ///     .infinity_string(Some(b"infinity"));
903    /// assert_eq!(builder.get_infinity_string(), Some(b"infinity".as_ref()));
904    /// ```
905    ///
906    /// Panics
907    ///
908    /// Setting a value with more than 50 elements will panic at runtime. You
909    /// should always build the format using [`build_strict`] or checking
910    /// [`is_valid`] prior to using the format, to avoid unexpected panics.
911    ///
912    /// [`FORMATTED_SIZE`]: `lexical_util::constants::FormattedSize::FORMATTED_SIZE`
913    /// [`build_strict`]: Self::build_strict
914    /// [`is_valid`]: Self::is_valid
915    #[inline(always)]
916    pub const fn infinity_string(self, inf_string: Option<&'static [u8]>) -> Self {
917        self.inf_string(inf_string)
918    }
919
920    // BUILDERS
921
922    /// Determine if [`nan_string`][`Self::nan_string`] is valid.
923    #[doc(hidden)]
924    #[inline(always)]
925    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason="more logical"
926    pub const fn nan_str_is_valid(&self) -> bool {
927        if self.nan_string.is_none() {
928            return true;
929        }
930
931        let nan = unwrap_str(self.nan_string);
932        let length = nan.len();
933        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
934            false
935        } else if !matches!(nan[0], b'N' | b'n') {
936            false
937        } else if !is_valid_letter_slice(nan) {
938            false
939        } else {
940            true
941        }
942    }
943
944    /// Determine if [`inf_string`][`Self::inf_string`] is valid.
945    #[doc(hidden)]
946    #[inline(always)]
947    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason="more logical"
948    pub const fn inf_str_is_valid(&self) -> bool {
949        if self.inf_string.is_none() {
950            return true;
951        }
952
953        let inf = unwrap_str(self.inf_string);
954        let length = inf.len();
955        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
956            false
957        } else if !matches!(inf[0], b'I' | b'i') {
958            false
959        } else if !is_valid_letter_slice(inf) {
960            false
961        } else {
962            true
963        }
964    }
965
966    /// Check if the builder state is valid.
967    #[inline(always)]
968    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason="more logical"
969    pub const fn is_valid(&self) -> bool {
970        if !is_valid_ascii(self.exponent) {
971            false
972        } else if !is_valid_ascii(self.decimal_point) {
973            false
974        } else if !self.nan_str_is_valid() {
975            false
976        } else if !self.inf_str_is_valid() {
977            false
978        } else {
979            true
980        }
981    }
982
983    /// Build the [`Options`] struct without validation.
984    ///
985    /// <div class="warning">
986    ///
987    /// This is completely safe, however, misusing this, especially
988    /// the [`nan_string`] and [`inf_string`] representations could cause
989    /// panics at runtime. Always use [`is_valid`] prior to using the built
990    /// options.
991    ///
992    /// </div>
993    ///
994    /// [`inf_string`]: Self::inf_string
995    /// [`nan_string`]: Self::nan_string
996    /// [`is_valid`]: Self::is_valid
997    #[inline(always)]
998    pub const fn build_unchecked(&self) -> Options {
999        Options {
1000            max_significant_digits: self.max_significant_digits,
1001            min_significant_digits: self.min_significant_digits,
1002            positive_exponent_break: self.positive_exponent_break,
1003            negative_exponent_break: self.negative_exponent_break,
1004            round_mode: self.round_mode,
1005            trim_floats: self.trim_floats,
1006            exponent: self.exponent,
1007            decimal_point: self.decimal_point,
1008            nan_string: self.nan_string,
1009            inf_string: self.inf_string,
1010        }
1011    }
1012
1013    /// Build the [`Options`] struct, panicking if the builder is invalid.
1014    ///
1015    /// # Panics
1016    ///
1017    /// If the built options are not valid. This should always
1018    /// be used within a const context to avoid panics at runtime.
1019    #[inline(always)]
1020    pub const fn build_strict(&self) -> Options {
1021        match self.build() {
1022            Ok(value) => value,
1023            Err(error) => core::panic!("{}", error.description()),
1024        }
1025    }
1026
1027    /// Build the [`Options`] struct.
1028    ///
1029    /// If the format is not valid, than an error is returned,
1030    /// otherwise, the successful value is returned.
1031    #[inline(always)]
1032    #[allow(clippy::if_same_then_else)] // reason="more logical"
1033    pub const fn build(&self) -> Result<Options> {
1034        if self.nan_string.is_some() {
1035            let nan = unwrap_str(self.nan_string);
1036            if nan.is_empty() || !matches!(nan[0], b'N' | b'n') {
1037                return Err(Error::InvalidNanString);
1038            } else if !is_valid_letter_slice(nan) {
1039                return Err(Error::InvalidNanString);
1040            } else if nan.len() > MAX_SPECIAL_STRING_LENGTH {
1041                return Err(Error::NanStringTooLong);
1042            }
1043        }
1044
1045        if self.inf_string.is_some() {
1046            let inf = unwrap_str(self.inf_string);
1047            if inf.is_empty() || !matches!(inf[0], b'I' | b'i') {
1048                return Err(Error::InvalidInfString);
1049            } else if !is_valid_letter_slice(inf) {
1050                return Err(Error::InvalidInfString);
1051            } else if inf.len() > MAX_SPECIAL_STRING_LENGTH {
1052                return Err(Error::InfStringTooLong);
1053            }
1054        }
1055
1056        let min_digits = unwrap_or_zero_usize(self.min_significant_digits);
1057        let max_digits = unwrap_or_max_usize(self.max_significant_digits);
1058        if max_digits < min_digits {
1059            Err(Error::InvalidFloatPrecision)
1060        } else if unwrap_or_zero_i32(self.negative_exponent_break) > 0 {
1061            Err(Error::InvalidNegativeExponentBreak)
1062        } else if unwrap_or_zero_i32(self.positive_exponent_break) < 0 {
1063            Err(Error::InvalidPositiveExponentBreak)
1064        } else if !is_valid_ascii(self.exponent) {
1065            Err(Error::InvalidExponentSymbol)
1066        } else if !is_valid_ascii(self.decimal_point) {
1067            Err(Error::InvalidDecimalPoint)
1068        } else {
1069            Ok(self.build_unchecked())
1070        }
1071    }
1072}
1073
1074impl Default for OptionsBuilder {
1075    #[inline(always)]
1076    fn default() -> Self {
1077        Self::new()
1078    }
1079}
1080
1081/// Options to customize writing floats.
1082///
1083/// This enables extensive control over how the float is written, from
1084/// control characters like the decimal point, to the use of exponent
1085/// notation, and the number of significant digits.
1086///
1087/// # Examples
1088///
1089/// Writing a simple float with custom special strings and
1090/// formatting integral floats as integers can be done as:
1091///
1092/// ```rust
1093/// use core::str;
1094///
1095/// use lexical_write_float::{Options, ToLexical, ToLexicalWithOptions};
1096/// use lexical_write_float::format::STANDARD;
1097///
1098/// const OPTS: Options = Options::builder()
1099///     .trim_floats(true)
1100///     .nan_string(Some(b"NaN"))
1101///     .inf_string(Some(b"Inf"))
1102///     .build_strict();
1103///
1104/// const SIZE: usize = OPTS.buffer_size_const::<f64, STANDARD>();
1105/// let mut buffer = [0u8; SIZE];
1106///
1107/// // trim floats
1108/// let digits = 12345.0f64.to_lexical_with_options::<STANDARD>(&mut buffer, &OPTS);
1109/// assert_eq!(str::from_utf8(digits), Ok("12345"));
1110///
1111/// // don't trim floats
1112/// let digits = 12345.0f64.to_lexical(&mut buffer);
1113/// assert_eq!(str::from_utf8(digits), Ok("12345.0"));
1114/// ```
1115#[derive(Debug, Clone, PartialEq, Eq)]
1116pub struct Options {
1117    /// Maximum number of significant digits to write.
1118    /// If not set, it defaults to the algorithm's default.
1119    max_significant_digits: OptionUsize,
1120
1121    /// Minimum number of significant digits to write.
1122    /// If not set, it defaults to the algorithm's default.
1123    min_significant_digits: OptionUsize,
1124
1125    /// Maximum exponent prior to using scientific notation.
1126    /// This is ignored if the exponent base is not the same as the mantissa
1127    /// radix. If not provided, use the algorithm's default.
1128    positive_exponent_break: OptionI32,
1129
1130    /// Minimum exponent prior to using scientific notation.
1131    /// This is ignored if the exponent base is not the same as the mantissa
1132    /// radix. If not provided, use the algorithm's default.
1133    negative_exponent_break: OptionI32,
1134
1135    /// Rounding mode for writing digits with precision control.
1136    round_mode: RoundMode,
1137
1138    /// Trim the trailing ".0" from integral float strings.
1139    ///
1140    /// If used in conjunction with [`min_significant_digits`],
1141    /// this will still trim all the significant digits if an integral
1142    /// value is provided.
1143    ///
1144    /// [`min_significant_digits`]: Self::min_significant_digits
1145    trim_floats: bool,
1146
1147    /// Character to designate the exponent component of a float.
1148    exponent: u8,
1149
1150    /// Character to separate the integer from the fraction components.
1151    decimal_point: u8,
1152
1153    /// String representation of Not A Number, aka `NaN`.
1154    nan_string: Option<&'static [u8]>,
1155
1156    /// String representation of `Infinity`.
1157    inf_string: Option<&'static [u8]>,
1158}
1159
1160impl Options {
1161    // CONSTRUCTORS
1162
1163    /// Create options with default values.
1164    #[inline(always)]
1165    pub const fn new() -> Self {
1166        Self::builder().build_unchecked()
1167    }
1168
1169    /// Create the default options for a given radix.
1170    ///
1171    /// <div class="warning">
1172    ///
1173    /// This function will never fail even if the radix is invalid. It is up to
1174    /// the caller to ensure the format is valid using
1175    /// [`Options::is_valid`]. Only radixes from `2` to `36` should be used.
1176    ///
1177    /// </div>
1178    #[inline(always)]
1179    #[cfg(feature = "power-of-two")]
1180    // FIXME: When we release a major version, validate the radix.
1181    pub const fn from_radix(radix: u8) -> Self {
1182        // Need to determine the correct exponent character ('e' or '^'),
1183        // since the default character is `e` normally, but this is a valid
1184        // digit for radix >= 15.
1185        let mut builder = Self::builder();
1186        if radix >= 15 {
1187            builder = builder.exponent(b'^');
1188        }
1189        builder.build_unchecked()
1190    }
1191
1192    /// Get an upper bound on the required buffer size.
1193    ///
1194    /// This is used when custom formatting options, such as significant
1195    /// digits specifiers or custom exponent breaks, are used, which
1196    /// can lead to more or less significant digits being written than
1197    /// expected. If using the default formatting options, then this will
1198    /// always be [`FORMATTED_SIZE`][FormattedSize::FORMATTED_SIZE] or
1199    /// [`FORMATTED_SIZE_DECIMAL`][FormattedSize::FORMATTED_SIZE_DECIMAL],
1200    /// depending on the radix.
1201    ///
1202    /// # Examples
1203    ///
1204    /// ```rust
1205    /// # #[cfg(all(feature = "format", feature = "radix"))] {
1206    /// use core::{num, str};
1207    ///
1208    /// use lexical_write_float::{FormattedSize, Options, ToLexicalWithOptions};
1209    /// use lexical_write_float::format::STANDARD;
1210    ///
1211    /// const DEFAULT: Options = Options::builder()
1212    ///     // require at least 3 significant digits, so `0.01` would be `"0.0100"`.
1213    ///     .min_significant_digits(num::NonZeroUsize::new(3))
1214    ///     // allow at most 5 significant digits, so `1.23456` would be `"1.2346"`.
1215    ///     .max_significant_digits(num::NonZeroUsize::new(5))
1216    ///     // build our format, erroring if it's invalid
1217    ///     .build_strict();
1218    /// assert_eq!(DEFAULT.buffer_size_const::<f64, STANDARD>(), f64::FORMATTED_SIZE_DECIMAL);
1219    ///
1220    /// const CUSTOM: Options = Options::builder()
1221    ///     // require at least 300 significant digits.
1222    ///     .min_significant_digits(num::NonZeroUsize::new(300))
1223    ///     // allow at most 500 significant digits.
1224    ///     .max_significant_digits(num::NonZeroUsize::new(500))
1225    ///     // only write values with magnitude above 1e300 in exponent notation
1226    ///     .positive_exponent_break(num::NonZeroI32::new(300))
1227    ///     // only write values with magnitude below 1e-300 in exponent notation
1228    ///     .negative_exponent_break(num::NonZeroI32::new(-300))
1229    ///     .build_strict();
1230    /// // 300 for the significant digits (500 is never reachable), 300 extra
1231    /// // due to the exponent breakoff, 1 for the sign, 1 for the decimal point
1232    /// // in all cases, this is enough including the exponent character and sign.
1233    /// assert_eq!(CUSTOM.buffer_size_const::<f64, STANDARD>(), 602);
1234    ///
1235    /// // now, write out value to bytes
1236    /// const SIZE: usize = CUSTOM.buffer_size_const::<f64, STANDARD>();
1237    /// let mut buffer = [0u8; SIZE];
1238    /// let value = 1.23456e-299f64;
1239    /// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &CUSTOM);
1240    ///
1241    /// // validate our printed digits. 600!
1242    /// assert_eq!(digits.len(), 600);
1243    /// assert!(!digits.contains(&b'e') && !digits.contains(&b'E'));
1244    /// assert!(digits.starts_with(b"0.000000000000000000000000"));
1245    ///
1246    /// // validate the round-trip
1247    /// assert_eq!(str::from_utf8(digits).unwrap().parse::<f64>(), Ok(value));
1248    ///
1249    /// // let's serialize a slightly smaller value
1250    /// let value = 1.23456e-301f64;
1251    /// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &CUSTOM);
1252    /// assert_eq!(digits.len(), 306);
1253    /// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &CUSTOM);
1254    /// # }
1255    /// ```
1256    #[inline(always)]
1257    pub const fn buffer_size_const<T: FormattedSize, const FORMAT: u128>(&self) -> usize {
1258        let format = NumberFormat::<{ FORMAT }> {};
1259
1260        // NOTE: This looks like it's off by 2 but it's not. We have only 2 as a
1261        // baseline for the mantissa sign and decimal point, but we don't
1262        // hard-code in 2 for the exponent sign and character. But we consider
1263        // those cases already when the exponent breakof >= 5 (13 for radix).
1264        // Say we have `1.2345612345612346e-300` for a breakoff of `-300` with
1265        // 300 min significant digits, which would be:
1266        //  - "0." (integral + decimal point)
1267        // - "0" * 299 (leading zeros for e-300)
1268        // - "123456" * 50 (300 significant digits)
1269        //
1270        // This is exactly 601 characters, with which a sign bit is 602.
1271        // If we go any lower, we have `1.2e-301`, which then would become
1272        // `1.23456...e-301`, or would be 306 characters.
1273
1274        // quick optimizations if no custom formatting options are used
1275        // we ensure that the mantissa and exponent radix are the same.
1276        let formatted_size = if format.radix() == 10 {
1277            T::FORMATTED_SIZE_DECIMAL
1278        } else {
1279            T::FORMATTED_SIZE
1280        };
1281
1282        // At least 2 for the decimal point and sign.
1283        let mut count: usize = 2;
1284
1285        // First need to calculate maximum number of digits from leading or
1286        // trailing zeros, IE, the exponent break.
1287        if !format.no_exponent_notation() {
1288            let min_exp = match self.negative_exponent_break() {
1289                Some(v) => v.get(),
1290                None => -5,
1291            };
1292            let max_exp = match self.positive_exponent_break() {
1293                Some(v) => v.get(),
1294                None => 9,
1295            };
1296            let exp = max!(min_exp.abs(), max_exp) as usize;
1297            if cfg!(feature = "power-of-two") && exp < 13 {
1298                // 11 for the exponent digits in binary, 1 for the sign, 1 for the symbol
1299                count += 13;
1300            } else if exp < 5 {
1301                // 3 for the exponent digits in decimal, 1 for the sign, 1 for the symbol
1302                count += 5;
1303            } else {
1304                // More leading or trailing zeros than the exponent digits.
1305                count += exp;
1306            }
1307        } else if cfg!(feature = "power-of-two") {
1308            // Min is 2^-1075.
1309            count += 1075;
1310        } else {
1311            // Min is 10^-324.
1312            count += 324;
1313        }
1314
1315        // Now add the number of significant digits.
1316        let radix = format.radix();
1317        let formatted_digits = if radix == 10 {
1318            // Really should be 18, but add some extra to be cautious.
1319            28
1320        } else {
1321            //  BINARY:
1322            //      53 significant mantissa bits for binary, add a few extra.
1323            //  RADIX:
1324            //      Our limit is `delta`. The maximum relative delta is 2.22e-16,
1325            //      around 1. If we have values below 1, our delta is smaller, but
1326            //      the max fraction is also a lot smaller. Above, and our fraction
1327            //      must be < 1.0, so our delta is less significant. Therefore,
1328            //      if our fraction is just less than 1, for a float near 2.0,
1329            //      we can do at **maximum** 33 digits (for base 3). Let's just
1330            //      assume it's a lot higher, and go with 64.
1331            64
1332        };
1333        let digits = if let Some(max_digits) = self.max_significant_digits() {
1334            min!(formatted_digits, max_digits.get())
1335        } else {
1336            formatted_digits
1337        };
1338        let digits = if let Some(min_digits) = self.min_significant_digits() {
1339            max!(digits, min_digits.get())
1340        } else {
1341            digits
1342        };
1343        count += digits;
1344
1345        // we need to make sure we have at least enough room for the
1346        // default formatting size, no matter what, just as a precaution.
1347        count = max!(count, formatted_size);
1348
1349        count
1350    }
1351
1352    // GETTERS
1353
1354    /// Check if the options state is valid.
1355    #[inline(always)]
1356    pub const fn is_valid(&self) -> bool {
1357        self.rebuild().is_valid()
1358    }
1359
1360    /// Get the maximum number of significant digits to write.
1361    ///
1362    /// This limits the total number of written digits, truncating based
1363    /// on the [`round_mode`] if more digits would normally be written. If
1364    /// no value is provided, then it writes as many digits as required to
1365    /// create an unambiguous representation of the float.
1366    ///
1367    /// # Examples
1368    ///
1369    /// ```rust
1370    /// use core::num::NonZeroUsize;
1371    ///
1372    /// use lexical_write_float::Options;
1373    ///
1374    /// const MAX_DIGITS: Option<NonZeroUsize> = NonZeroUsize::new(300);
1375    /// const OPTIONS: Options = Options::builder()
1376    ///     .max_significant_digits(MAX_DIGITS)
1377    ///     .build_strict();
1378    /// assert_eq!(OPTIONS.max_significant_digits(), MAX_DIGITS);
1379    /// ```
1380    ///
1381    /// [`round_mode`]: Self::round_mode
1382    #[inline(always)]
1383    pub const fn max_significant_digits(&self) -> OptionUsize {
1384        self.max_significant_digits
1385    }
1386
1387    /// Get the minimum number of significant digits to write.
1388    ///
1389    /// If more digits exist, such as writing "1.2" with a minimum of 5
1390    /// significant digits, then `0`s are appended to the end of the digits.
1391    /// If no value is provided, then it writes as few digits as required to
1392    /// create an unambiguous representation of the float.
1393    ///
1394    /// # Examples
1395    ///
1396    /// ```rust
1397    /// use core::num::NonZeroUsize;
1398    ///
1399    /// use lexical_write_float::Options;
1400    ///
1401    /// const MIN_DIGITS: Option<NonZeroUsize> = NonZeroUsize::new(10);
1402    /// const OPTIONS: Options = Options::builder()
1403    ///     .min_significant_digits(MIN_DIGITS)
1404    ///     .build_strict();
1405    /// assert_eq!(OPTIONS.min_significant_digits(), MIN_DIGITS);
1406    /// ```
1407    #[inline(always)]
1408    pub const fn min_significant_digits(&self) -> OptionUsize {
1409        self.min_significant_digits
1410    }
1411
1412    /// Get the maximum exponent prior to using scientific notation.
1413    ///
1414    /// If the value is set to `300`, then any value with magnitude `>= 1e300`
1415    /// (for base 10) will be writen in exponent notation, while any lower
1416    /// value will be written in decimal form. If no value is provided, for
1417    /// decimal floats, this defaults to `9`.
1418    ///
1419    /// # Examples
1420    ///
1421    /// ```rust
1422    /// use core::num::NonZeroI32;
1423    ///
1424    /// use lexical_write_float::Options;
1425    ///
1426    /// const POS_BREAK: Option<NonZeroI32> = NonZeroI32::new(3);
1427    /// const OPTIONS: Options = Options::builder()
1428    ///     .positive_exponent_break(POS_BREAK)
1429    ///     .build_strict();
1430    /// assert_eq!(OPTIONS.positive_exponent_break(), POS_BREAK);
1431    /// ```
1432    #[inline(always)]
1433    pub const fn positive_exponent_break(&self) -> OptionI32 {
1434        self.positive_exponent_break
1435    }
1436
1437    /// Get the minimum exponent prior to using scientific notation.
1438    ///
1439    /// If the value is set to `-300`, then any value with magnitude `< 1e-300`
1440    /// (for base 10) will be writen in exponent notation, while any larger
1441    /// value will be written in decimal form. If no value is provided, for
1442    /// decimal floats, this defaults to `-5`.
1443    ///
1444    /// # Examples
1445    ///
1446    /// ```rust
1447    /// use core::num::NonZeroI32;
1448    ///
1449    /// use lexical_write_float::Options;
1450    ///
1451    /// const NEG_BREAK: Option<NonZeroI32> = NonZeroI32::new(-3);
1452    /// const OPTIONS: Options = Options::builder()
1453    ///     .negative_exponent_break(NEG_BREAK)
1454    ///     .build_strict();
1455    /// assert_eq!(OPTIONS.negative_exponent_break(), NEG_BREAK);
1456    /// ```
1457    #[inline(always)]
1458    pub const fn negative_exponent_break(&self) -> OptionI32 {
1459        self.negative_exponent_break
1460    }
1461
1462    /// Get the rounding mode for writing digits with precision control.
1463    ///
1464    /// For example, writing `1.23456` with 5 significant digits with
1465    /// [`RoundMode::Round`] would produce `"1.2346"` while
1466    /// [`RoundMode::Truncate`] would produce `"1.2345"`. Defaults to
1467    /// [`RoundMode::Round`].
1468    ///
1469    /// # Examples
1470    ///
1471    /// ```rust
1472    /// use lexical_write_float::{Options, RoundMode};
1473    ///
1474    /// const OPTIONS: Options = Options::builder()
1475    ///     .round_mode(RoundMode::Truncate)
1476    ///     .build_strict();
1477    /// assert_eq!(OPTIONS.round_mode(), RoundMode::Truncate);
1478    /// ```
1479    #[inline(always)]
1480    pub const fn round_mode(&self) -> RoundMode {
1481        self.round_mode
1482    }
1483
1484    /// Get if we should trim a trailing `".0"` from integral floats.
1485    ///
1486    /// If used in conjunction with [`min_significant_digits`],
1487    /// this will still trim all the significant digits if an integral
1488    /// value is provided. Defaults to [`false`].
1489    ///
1490    /// # Examples
1491    ///
1492    /// ```rust
1493    /// use lexical_write_float::Options;
1494    ///
1495    /// const OPTIONS: Options = Options::builder()
1496    ///     .trim_floats(true)
1497    ///     .build_strict();
1498    /// assert_eq!(OPTIONS.trim_floats(), true);
1499    /// ```
1500    ///
1501    /// [`min_significant_digits`]: Self::min_significant_digits
1502    #[inline(always)]
1503    pub const fn trim_floats(&self) -> bool {
1504        self.trim_floats
1505    }
1506
1507    /// Get the character to designate the exponent component of a float.
1508    ///
1509    /// Any non-control character is valid, but `\t` to `\r` are also valid.
1510    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `e`.
1511    ///
1512    /// # Examples
1513    ///
1514    /// ```rust
1515    /// use lexical_write_float::Options;
1516    ///
1517    /// const OPTIONS: Options = Options::builder()
1518    ///     .exponent(b'^')
1519    ///     .build_strict();
1520    /// assert_eq!(OPTIONS.exponent(), b'^');
1521    /// ```
1522    #[inline(always)]
1523    pub const fn exponent(&self) -> u8 {
1524        self.exponent
1525    }
1526
1527    /// Get the character to separate the integer from the fraction components.
1528    ///
1529    /// Any non-control character is valid, but `\t` to `\r` are also valid.
1530    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `.`.
1531    ///
1532    /// # Examples
1533    ///
1534    /// ```rust
1535    /// use lexical_write_float::Options;
1536    ///
1537    /// const OPTIONS: Options = Options::builder()
1538    ///     .exponent(b',')
1539    ///     .build_strict();
1540    /// assert_eq!(OPTIONS.exponent(), b',');
1541    /// ```
1542    #[inline(always)]
1543    pub const fn decimal_point(&self) -> u8 {
1544        self.decimal_point
1545    }
1546
1547    /// Get the string representation for `NaN`.
1548    ///
1549    /// The first character must start with `N` or `n` and all characters must
1550    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
1551    /// [`NaN`][f64::NAN] returns an error. Defaults to `NaN`.
1552    ///
1553    /// # Examples
1554    ///
1555    /// ```rust
1556    /// use lexical_write_float::Options;
1557    ///
1558    /// const OPTIONS: Options = Options::builder()
1559    ///     .nan_string(Some(b"nan"))
1560    ///     .build_strict();
1561    /// assert_eq!(OPTIONS.nan_string(), Some(b"nan".as_ref()));
1562    /// ```
1563    #[inline(always)]
1564    pub const fn nan_string(&self) -> Option<&'static [u8]> {
1565        self.nan_string
1566    }
1567
1568    /// Get the string representation for `Infinity`.
1569    ///
1570    /// The first character must start with `I` or `i` and all characters must
1571    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
1572    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
1573    ///
1574    /// # Examples
1575    ///
1576    /// ```rust
1577    /// use lexical_write_float::Options;
1578    ///
1579    /// const OPTIONS: Options = Options::builder()
1580    ///     .inf_string(Some(b"infinity"))
1581    ///     .build_strict();
1582    /// assert_eq!(OPTIONS.inf_string(), Some(b"infinity".as_ref()));
1583    /// ```
1584    #[inline(always)]
1585    pub const fn inf_string(&self) -> Option<&'static [u8]> {
1586        self.inf_string
1587    }
1588
1589    /// Get the string representation for `Infinity`. Alias for [`inf_string`].
1590    ///
1591    /// The first character must start with `I` or `i` and all characters must
1592    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then writing
1593    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
1594    ///
1595    /// [`inf_string`]: Self::inf_string
1596    ///
1597    /// # Examples
1598    ///
1599    /// ```rust
1600    /// use lexical_write_float::Options;
1601    ///
1602    /// const OPTIONS: Options = Options::builder()
1603    ///     .infinity_string(Some(b"infinity"))
1604    ///     .build_strict();
1605    /// assert_eq!(OPTIONS.infinity_string(), Some(b"infinity".as_ref()));
1606    /// ```
1607    #[inline(always)]
1608    pub const fn infinity_string(&self) -> Option<&'static [u8]> {
1609        self.inf_string
1610    }
1611
1612    // SETTERS
1613
1614    /// Set the maximum number of significant digits to write.
1615    ///
1616    /// This limits the total number of written digits, truncating based
1617    /// on the [`round_mode`] if more digits would normally be written.
1618    ///
1619    /// # Panics
1620    ///
1621    /// This will panic when writing the float if the value is smaller than
1622    /// [`min_significant_digits`].
1623    ///
1624    /// [`round_mode`]: Self::round_mode
1625    /// [`min_significant_digits`]: Self::min_significant_digits
1626    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1627    #[inline(always)]
1628    pub fn set_max_significant_digits(&mut self, max_significant_digits: OptionUsize) {
1629        self.max_significant_digits = max_significant_digits;
1630    }
1631
1632    /// Set the minimum number of significant digits to write.
1633    ///
1634    /// If more digits exist, such as writing "1.2" with a minimum of 5
1635    /// significant digits, then `0`s are appended to the end of the digits.
1636    ///
1637    /// # Panics
1638    ///
1639    /// This will panic when writing the float if the value is larger than
1640    /// [`max_significant_digits`].
1641    ///
1642    /// [`max_significant_digits`]: Self::max_significant_digits
1643    #[inline(always)]
1644    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1645    pub fn set_min_significant_digits(&mut self, min_significant_digits: OptionUsize) {
1646        self.min_significant_digits = min_significant_digits;
1647    }
1648
1649    /// Set the maximum exponent prior to using scientific notation.
1650    ///
1651    /// If the value is set to `300`, then any value with magnitude `>= 1e300`
1652    /// (for base 10) will be writen in exponent notation, while any lower
1653    /// value will be written in decimal form.
1654    #[inline(always)]
1655    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1656    pub fn set_positive_exponent_break(&mut self, positive_exponent_break: OptionI32) {
1657        self.positive_exponent_break = positive_exponent_break;
1658    }
1659
1660    /// Set the minimum exponent prior to using scientific notation.
1661    ///
1662    /// If the value is set to `-300`, then any value with magnitude `< 1e-300`
1663    /// (for base 10) will be writen in exponent notation, while any larger
1664    /// value will be written in decimal form.
1665    #[inline(always)]
1666    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1667    pub fn set_negative_exponent_break(&mut self, negative_exponent_break: OptionI32) {
1668        self.negative_exponent_break = negative_exponent_break;
1669    }
1670
1671    /// Set the rounding mode for writing digits with precision control.
1672    ///
1673    /// For example, writing `1.23456` with 5 significant digits with
1674    /// [`RoundMode::Round`] would produce `"1.2346"` while
1675    /// [`RoundMode::Truncate`] would produce `"1.2345"`.
1676    #[inline(always)]
1677    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1678    pub fn set_round_mode(&mut self, round_mode: RoundMode) {
1679        self.round_mode = round_mode;
1680    }
1681
1682    /// Set if we should trim a trailing `".0"` from integral floats.
1683    ///
1684    /// If used in conjunction with [`min_significant_digits`],
1685    /// this will still trim all the significant digits if an integral
1686    /// value is provided.
1687    ///
1688    /// [`min_significant_digits`]: Self::min_significant_digits
1689    #[inline(always)]
1690    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1691    pub fn set_trim_floats(&mut self, trim_floats: bool) {
1692        self.trim_floats = trim_floats;
1693    }
1694
1695    /// Set the character to designate the exponent component of a float.
1696    ///
1697    /// # Safety
1698    ///
1699    /// Always safe, but may produce invalid output if the exponent
1700    /// is not a valid ASCII character.
1701    #[inline(always)]
1702    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1703    pub fn set_exponent(&mut self, exponent: u8) {
1704        self.exponent = exponent;
1705    }
1706
1707    /// Set the character to separate the integer from the fraction components.
1708    ///
1709    /// # Safety
1710    ///
1711    /// Always safe, but may produce invalid output if the decimal point
1712    /// is not a valid ASCII character.
1713    #[inline(always)]
1714    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1715    pub fn set_decimal_point(&mut self, decimal_point: u8) {
1716        self.decimal_point = decimal_point;
1717    }
1718
1719    /// Set the string representation for `NaN`.
1720    ///
1721    /// Panics
1722    ///
1723    /// Setting a value too large may cause a panic even if [`FORMATTED_SIZE`]
1724    /// elements are provided.
1725    ///
1726    /// [`FORMATTED_SIZE`]: `lexical_util::constants::FormattedSize::FORMATTED_SIZE`
1727    #[inline(always)]
1728    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1729    pub fn set_nan_string(&mut self, nan_string: Option<&'static [u8]>) {
1730        self.nan_string = nan_string;
1731    }
1732
1733    /// Set the short string representation for `Infinity`
1734    ///
1735    /// Panics
1736    ///
1737    /// Setting a value too large may cause a panic even if [`FORMATTED_SIZE`]
1738    /// elements are provided.
1739    ///
1740    /// [`FORMATTED_SIZE`]: `lexical_util::constants::FormattedSize::FORMATTED_SIZE`
1741    #[inline(always)]
1742    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
1743    pub fn set_inf_string(&mut self, inf_string: Option<&'static [u8]>) {
1744        self.inf_string = inf_string;
1745    }
1746
1747    // BUILDERS
1748
1749    /// Get [`OptionsBuilder`] as a static function.
1750    #[inline(always)]
1751    pub const fn builder() -> OptionsBuilder {
1752        OptionsBuilder::new()
1753    }
1754
1755    /// Create [`OptionsBuilder`] using existing values.
1756    #[inline(always)]
1757    pub const fn rebuild(&self) -> OptionsBuilder {
1758        OptionsBuilder {
1759            max_significant_digits: self.max_significant_digits,
1760            min_significant_digits: self.min_significant_digits,
1761            positive_exponent_break: self.positive_exponent_break,
1762            negative_exponent_break: self.negative_exponent_break,
1763            round_mode: self.round_mode,
1764            trim_floats: self.trim_floats,
1765            exponent: self.exponent,
1766            decimal_point: self.decimal_point,
1767            nan_string: self.nan_string,
1768            inf_string: self.inf_string,
1769        }
1770    }
1771}
1772
1773impl Default for Options {
1774    #[inline(always)]
1775    fn default() -> Self {
1776        Self::new()
1777    }
1778}
1779
1780impl WriteOptions for Options {
1781    #[inline(always)]
1782    fn is_valid(&self) -> bool {
1783        Self::is_valid(self)
1784    }
1785
1786    #[doc = lexical_util::write_options_doc!()]
1787    #[inline(always)]
1788    fn buffer_size<T: FormattedSize, const FORMAT: u128>(&self) -> usize {
1789        self.buffer_size_const::<T, FORMAT>()
1790    }
1791}
1792
1793/// Define `unwrap_or_zero` for a custom type.
1794macro_rules! unwrap_or_zero {
1795    ($name:ident, $opt:ident, $t:ident) => {
1796        /// Unwrap `Option` as a const fn.
1797        #[inline(always)]
1798        const fn $name(option: $opt) -> $t {
1799            match option {
1800                Some(x) => x.get(),
1801                None => 0,
1802            }
1803        }
1804    };
1805}
1806
1807unwrap_or_zero!(unwrap_or_zero_usize, OptionUsize, usize);
1808unwrap_or_zero!(unwrap_or_zero_i32, OptionI32, i32);
1809
1810/// Unwrap `Option` as a const fn.
1811#[inline(always)]
1812const fn unwrap_or_max_usize(option: OptionUsize) -> usize {
1813    match option {
1814        Some(x) => x.get(),
1815        None => usize::MAX,
1816    }
1817}
1818
1819/// Unwrap `Option` as a const fn.
1820#[inline(always)]
1821const fn unwrap_str(option: Option<&'static [u8]>) -> &'static [u8] {
1822    match option {
1823        Some(x) => x,
1824        None => &[],
1825    }
1826}
1827
1828// PRE-DEFINED CONSTANTS
1829// ---------------------
1830
1831// Only constants that differ from the standard version are included.
1832
1833/// Standard number format.
1834#[rustfmt::skip]
1835pub const STANDARD: Options = Options::new();
1836
1837/// Numerical format with a decimal comma.
1838///
1839/// This is the standard numerical format for most of the world.
1840#[rustfmt::skip]
1841pub const DECIMAL_COMMA: Options = Options::builder()
1842    .decimal_point(b',')
1843    .build_strict();
1844
1845/// Numerical format for hexadecimal floats, which use a `p` exponent.
1846#[rustfmt::skip]
1847pub const HEX_FLOAT: Options = Options::builder()
1848    .exponent(b'p')
1849    .build_strict();
1850
1851/// Numerical format where `^` is used as the exponent notation character.
1852///
1853/// This isn't very common, but is useful when `e` or `p` are valid digits.
1854#[rustfmt::skip]
1855pub const CARAT_EXPONENT: Options = Options::builder()
1856    .exponent(b'^')
1857    .build_strict();
1858
1859/// Number format for a [`Rust`] literal floating-point number.
1860///
1861/// [`Rust`]: https://www.rust-lang.org/
1862#[rustfmt::skip]
1863pub const RUST_LITERAL: Options = Options::builder()
1864    .nan_string(options::RUST_LITERAL)
1865    .inf_string(options::RUST_LITERAL)
1866    .build_strict();
1867
1868/// Number format for a [`Python`] literal floating-point number.
1869///
1870/// [`Python`]: https://www.python.org/
1871#[rustfmt::skip]
1872pub const PYTHON_LITERAL: Options = Options::builder()
1873    .nan_string(options::PYTHON_LITERAL)
1874    .inf_string(options::PYTHON_LITERAL)
1875    .build_strict();
1876
1877/// Number format for a [`C++`] literal floating-point number.
1878///
1879/// [`C++`]: https://en.cppreference.com/w/
1880#[rustfmt::skip]
1881pub const CXX_LITERAL: Options = Options::builder()
1882    .nan_string(options::CXX_LITERAL_NAN)
1883    .inf_string(options::CXX_LITERAL_INF)
1884    .build_strict();
1885
1886/// Number format for a [`C`] literal floating-point number.
1887///
1888/// [`C`]: https://en.cppreference.com/w/c
1889#[rustfmt::skip]
1890pub const C_LITERAL: Options = Options::builder()
1891    .nan_string(options::C_LITERAL_NAN)
1892    .inf_string(options::C_LITERAL_INF)
1893    .build_strict();
1894
1895/// Number format for a [`Ruby`] literal floating-point number.
1896///
1897/// [`Ruby`]: https://www.ruby-lang.org/en/
1898#[rustfmt::skip]
1899pub const RUBY_LITERAL: Options = Options::builder()
1900    .positive_exponent_break(num::NonZeroI32::new(14))
1901    .negative_exponent_break(num::NonZeroI32::new(-4))
1902    .nan_string(options::RUBY_LITERAL_NAN)
1903    .inf_string(options::RUBY_LITERAL_INF)
1904    .build_strict();
1905
1906/// Number format to parse a [`Ruby`] float from string.
1907///
1908/// [`Ruby`]: https://www.ruby-lang.org/en/
1909#[rustfmt::skip]
1910pub const RUBY_STRING: Options = Options::builder()
1911    .nan_string(options::RUBY_LITERAL_NAN)
1912    .inf_string(options::RUBY_LITERAL_INF)
1913    .build_strict();
1914
1915/// Number format for a [`Swift`] literal floating-point number.
1916///
1917/// [`Swift`]: https://developer.apple.com/swift/
1918#[rustfmt::skip]
1919pub const SWIFT_LITERAL: Options = Options::builder()
1920    .nan_string(options::SWIFT_LITERAL)
1921    .inf_string(options::SWIFT_LITERAL)
1922    .build_strict();
1923
1924/// Number format for a [`Golang`] literal floating-point number.
1925///
1926/// [`Golang`]: https://go.dev/
1927#[rustfmt::skip]
1928pub const GO_LITERAL: Options = Options::builder()
1929    .nan_string(options::GO_LITERAL)
1930    .inf_string(options::GO_LITERAL)
1931    .build_strict();
1932
1933/// Number format for a [`Haskell`] literal floating-point number.
1934///
1935/// [`Haskell`]: https://www.haskell.org/
1936#[rustfmt::skip]
1937pub const HASKELL_LITERAL: Options = Options::builder()
1938    .nan_string(options::HASKELL_LITERAL)
1939    .inf_string(options::HASKELL_LITERAL)
1940    .build_strict();
1941
1942/// Number format to parse a [`Haskell`] float from string.
1943///
1944/// [`Haskell`]: https://www.haskell.org/
1945#[rustfmt::skip]
1946pub const HASKELL_STRING: Options = Options::builder()
1947    .inf_string(options::HASKELL_STRING_INF)
1948    .build_strict();
1949
1950/// Number format for a [`Javascript`] literal floating-point number.
1951///
1952/// [`Javascript`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
1953#[rustfmt::skip]
1954pub const JAVASCRIPT_LITERAL: Options = Options::builder()
1955    .inf_string(options::JAVASCRIPT_INF)
1956    .build_strict();
1957
1958/// Number format to parse a [`Javascript`] float from string.
1959///
1960/// [`Javascript`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
1961#[rustfmt::skip]
1962pub const JAVASCRIPT_STRING: Options = Options::builder()
1963    .inf_string(options::JAVASCRIPT_INF)
1964    .build_strict();
1965
1966/// Number format for a [`Perl`] literal floating-point number.
1967///
1968/// [`Perl`]: https://www.perl.org/
1969#[rustfmt::skip]
1970pub const PERL_LITERAL: Options = Options::builder()
1971    .nan_string(options::PERL_LITERAL)
1972    .inf_string(options::PERL_LITERAL)
1973    .build_strict();
1974
1975/// Number format for a [`PHP`] literal floating-point number.
1976///
1977/// [`PHP`]: https://www.php.net/
1978#[rustfmt::skip]
1979pub const PHP_LITERAL: Options = Options::builder()
1980    .nan_string(options::PHP_LITERAL_NAN)
1981    .inf_string(options::PHP_LITERAL_INF)
1982    .build_strict();
1983
1984/// Number format for a [`Java`] literal floating-point number.
1985///
1986/// [`Java`]: https://www.java.com/en/
1987#[rustfmt::skip]
1988pub const JAVA_LITERAL: Options = Options::builder()
1989    .nan_string(options::JAVA_LITERAL)
1990    .inf_string(options::JAVA_LITERAL)
1991    .build_strict();
1992
1993/// Number format to parse a [`Java`] float from string.
1994///
1995/// [`Java`]: https://www.java.com/en/
1996#[rustfmt::skip]
1997pub const JAVA_STRING: Options = Options::builder()
1998    .inf_string(options::JAVA_STRING_INF)
1999    .build_strict();
2000
2001/// Number format for an [`R`] literal floating-point number.
2002///
2003/// [`R`]: https://www.r-project.org/
2004#[rustfmt::skip]
2005pub const R_LITERAL: Options = Options::builder()
2006    .inf_string(options::R_LITERAL_INF)
2007    .build_strict();
2008
2009/// Number format for a [`Kotlin`] literal floating-point number.
2010///
2011/// [`Kotlin`]: https://kotlinlang.org/
2012#[rustfmt::skip]
2013pub const KOTLIN_LITERAL: Options = Options::builder()
2014    .nan_string(options::KOTLIN_LITERAL)
2015    .inf_string(options::KOTLIN_LITERAL)
2016    .build_strict();
2017
2018/// Number format to parse a [`Kotlin`] float from string.
2019///
2020/// [`Kotlin`]: https://kotlinlang.org/
2021#[rustfmt::skip]
2022pub const KOTLIN_STRING: Options = Options::builder()
2023    .inf_string(options::KOTLIN_STRING_INF)
2024    .build_strict();
2025
2026/// Number format for a [`Julia`] literal floating-point number.
2027///
2028/// [`Julia`]: https://julialang.org/
2029#[rustfmt::skip]
2030pub const JULIA_LITERAL: Options = Options::builder()
2031    .inf_string(options::JULIA_LITERAL_INF)
2032    .build_strict();
2033
2034/// Number format for a [`C#`] literal floating-point number.
2035///
2036/// [`C#`]: https://learn.microsoft.com/en-us/dotnet/csharp/
2037#[rustfmt::skip]
2038pub const CSHARP_LITERAL: Options = Options::builder()
2039    .nan_string(options::CSHARP_LITERAL)
2040    .inf_string(options::CSHARP_LITERAL)
2041    .build_strict();
2042
2043/// Number format to parse a [`C#`] float from string.
2044///
2045/// [`C#`]: https://learn.microsoft.com/en-us/dotnet/csharp/
2046#[rustfmt::skip]
2047pub const CSHARP_STRING: Options = Options::builder()
2048    .inf_string(options::CSHARP_STRING_INF)
2049    .build_strict();
2050
2051/// Number format for a [`Kawa`] literal floating-point number.
2052///
2053/// [`Kawa`]: https://www.gnu.org/software/kawa/
2054#[rustfmt::skip]
2055pub const KAWA_LITERAL: Options = Options::builder()
2056    .nan_string(options::KAWA)
2057    .inf_string(options::KAWA)
2058    .build_strict();
2059
2060/// Number format to parse a [`Kawa`] float from string.
2061///
2062/// [`Kawa`]: https://www.gnu.org/software/kawa/
2063#[rustfmt::skip]
2064pub const KAWA_STRING: Options = Options::builder()
2065    .nan_string(options::KAWA)
2066    .inf_string(options::KAWA)
2067    .build_strict();
2068
2069/// Number format for a [`Gambit-C`] literal floating-point number.
2070///
2071/// [`Gambit-C`]: https://gambitscheme.org/
2072#[rustfmt::skip]
2073pub const GAMBITC_LITERAL: Options = Options::builder()
2074    .nan_string(options::GAMBITC)
2075    .inf_string(options::GAMBITC)
2076    .build_strict();
2077
2078/// Number format to parse a [`Gambit-C`] float from string.
2079///
2080/// [`Gambit-C`]: https://gambitscheme.org/
2081#[rustfmt::skip]
2082pub const GAMBITC_STRING: Options = Options::builder()
2083    .nan_string(options::GAMBITC)
2084    .inf_string(options::GAMBITC)
2085    .build_strict();
2086
2087/// Number format for a [`Guile`] literal floating-point number.
2088///
2089/// [`Guile`]: https://www.gnu.org/software/guile/
2090#[rustfmt::skip]
2091pub const GUILE_LITERAL: Options = Options::builder()
2092    .nan_string(options::GUILE)
2093    .inf_string(options::GUILE)
2094    .build_strict();
2095
2096/// Number format to parse a [`Guile`] float from string.
2097///
2098/// [`Guile`]: https://www.gnu.org/software/guile/
2099#[rustfmt::skip]
2100pub const GUILE_STRING: Options = Options::builder()
2101    .nan_string(options::GUILE)
2102    .inf_string(options::GUILE)
2103    .build_strict();
2104
2105/// Number format for a [`Clojure`] literal floating-point number.
2106///
2107/// [`Clojure`]: https://clojure.org/
2108#[rustfmt::skip]
2109pub const CLOJURE_LITERAL: Options = Options::builder()
2110    .nan_string(options::CLOJURE_LITERAL)
2111    .inf_string(options::CLOJURE_LITERAL)
2112    .build_strict();
2113
2114/// Number format to parse a [`Clojure`] float from string.
2115///
2116/// [`Clojure`]: https://clojure.org/
2117#[rustfmt::skip]
2118pub const CLOJURE_STRING: Options = Options::builder()
2119    .inf_string(options::CLOJURE_STRING_INF)
2120    .build_strict();
2121
2122/// Number format for an [`Erlang`] literal floating-point number.
2123///
2124/// [`Erlang`]: https://www.erlang.org/
2125#[rustfmt::skip]
2126pub const ERLANG_LITERAL: Options = Options::builder()
2127    .nan_string(options::ERLANG_LITERAL_NAN)
2128    .build_strict();
2129
2130/// Number format to parse an [`Erlang`] float from string.
2131///
2132/// [`Erlang`]: https://www.erlang.org/
2133#[rustfmt::skip]
2134pub const ERLANG_STRING: Options = Options::builder()
2135    .nan_string(options::ERLANG_STRING)
2136    .inf_string(options::ERLANG_STRING)
2137    .build_strict();
2138
2139/// Number format for an [`Elm`] literal floating-point number.
2140///
2141/// [`Elm`]: https://elm-lang.org/
2142#[rustfmt::skip]
2143pub const ELM_LITERAL: Options = Options::builder()
2144    .nan_string(options::ELM_LITERAL)
2145    .inf_string(options::ELM_LITERAL)
2146    .build_strict();
2147
2148/// Number format to parse an [`Elm`] float from string.
2149///
2150/// [`Elm`]: https://elm-lang.org/
2151#[rustfmt::skip]
2152pub const ELM_STRING: Options = Options::builder()
2153    .nan_string(options::ELM_STRING_NAN)
2154    .inf_string(options::ELM_STRING_INF)
2155    .build_strict();
2156
2157/// Number format for a [`Scala`] literal floating-point number.
2158///
2159/// [`Scala`]: https://www.scala-lang.org/
2160#[rustfmt::skip]
2161pub const SCALA_LITERAL: Options = Options::builder()
2162    .nan_string(options::SCALA_LITERAL)
2163    .inf_string(options::SCALA_LITERAL)
2164    .build_strict();
2165
2166/// Number format to parse a [`Scala`] float from string.
2167///
2168/// [`Scala`]: https://www.scala-lang.org/
2169#[rustfmt::skip]
2170pub const SCALA_STRING: Options = Options::builder()
2171    .inf_string(options::SCALA_STRING_INF)
2172    .build_strict();
2173
2174/// Number format for an [`Elixir`] literal floating-point number.
2175///
2176/// [`Elixir`]: https://elixir-lang.org/
2177#[rustfmt::skip]
2178pub const ELIXIR_LITERAL: Options = Options::builder()
2179    .nan_string(options::ELIXIR)
2180    .inf_string(options::ELIXIR)
2181    .build_strict();
2182
2183/// Number format to parse an [`Elixir`] float from string.
2184///
2185/// [`Elixir`]: https://elixir-lang.org/
2186#[rustfmt::skip]
2187pub const ELIXIR_STRING: Options = Options::builder()
2188    .nan_string(options::ELIXIR)
2189    .inf_string(options::ELIXIR)
2190    .build_strict();
2191
2192/// Number format for a [`FORTRAN`] literal floating-point number.
2193///
2194/// [`FORTRAN`]: https://fortran-lang.org/
2195#[rustfmt::skip]
2196pub const FORTRAN_LITERAL: Options = Options::builder()
2197    .nan_string(options::FORTRAN_LITERAL)
2198    .inf_string(options::FORTRAN_LITERAL)
2199    .build_strict();
2200
2201/// Number format for a [`D`] literal floating-point number.
2202///
2203/// [`D`]: https://dlang.org/
2204#[rustfmt::skip]
2205pub const D_LITERAL: Options = Options::builder()
2206    .nan_string(options::D_LITERAL)
2207    .inf_string(options::D_LITERAL)
2208    .build_strict();
2209
2210/// Number format for a [`Coffeescript`] literal floating-point number.
2211///
2212/// [`Coffeescript`]: https://coffeescript.org/
2213#[rustfmt::skip]
2214pub const COFFEESCRIPT_LITERAL: Options = Options::builder()
2215    .inf_string(options::COFFEESCRIPT_INF)
2216    .build_strict();
2217
2218/// Number format to parse a [`Coffeescript`] float from string.
2219///
2220/// [`Coffeescript`]: https://coffeescript.org/
2221#[rustfmt::skip]
2222pub const COFFEESCRIPT_STRING: Options = Options::builder()
2223    .inf_string(options::COFFEESCRIPT_INF)
2224    .build_strict();
2225
2226/// Number format for a [`COBOL`] literal floating-point number.
2227///
2228/// [`Cobol`]: https://www.ibm.com/think/topics/cobol
2229#[rustfmt::skip]
2230pub const COBOL_LITERAL: Options = Options::builder()
2231    .nan_string(options::COBOL)
2232    .inf_string(options::COBOL)
2233    .build_strict();
2234
2235/// Number format to parse a [`COBOL`] float from string.
2236///
2237/// [`Cobol`]: https://www.ibm.com/think/topics/cobol
2238#[rustfmt::skip]
2239pub const COBOL_STRING: Options = Options::builder()
2240    .nan_string(options::COBOL)
2241    .inf_string(options::COBOL)
2242    .build_strict();
2243
2244/// Number format for an [`F#`] literal floating-point number.
2245///
2246/// [`F#`]: https://fsharp.org/
2247#[rustfmt::skip]
2248pub const FSHARP_LITERAL: Options = Options::builder()
2249    .nan_string(options::FSHARP_LITERAL_NAN)
2250    .inf_string(options::FSHARP_LITERAL_INF)
2251    .build_strict();
2252
2253/// Number format for a [`Visual Basic`] literal floating-point number.
2254///
2255/// [`Visual Basic`]: https://learn.microsoft.com/en-us/dotnet/visual-basic/
2256#[rustfmt::skip]
2257pub const VB_LITERAL: Options = Options::builder()
2258    .nan_string(options::VB_LITERAL)
2259    .inf_string(options::VB_LITERAL)
2260    .build_strict();
2261
2262/// Number format to parse a [`Visual Basic`] float from string.
2263///
2264/// [`Visual Basic`]: https://learn.microsoft.com/en-us/dotnet/visual-basic/
2265#[rustfmt::skip]
2266pub const VB_STRING: Options = Options::builder()
2267    .inf_string(options::VB_STRING_INF)
2268    .build_strict();
2269
2270/// Number format for an [`OCaml`] literal floating-point number.
2271///
2272/// [`OCaml`]: https://ocaml.org/
2273#[rustfmt::skip]
2274pub const OCAML_LITERAL: Options = Options::builder()
2275    .nan_string(options::OCAML_LITERAL_NAN)
2276    .inf_string(options::OCAML_LITERAL_INF)
2277    .build_strict();
2278
2279/// Number format for an [`Objective-C`] literal floating-point number.
2280///
2281/// [`Objective-C`]: https://en.wikipedia.org/wiki/Objective-C
2282#[rustfmt::skip]
2283pub const OBJECTIVEC_LITERAL: Options = Options::builder()
2284    .nan_string(options::OBJECTIVEC)
2285    .inf_string(options::OBJECTIVEC)
2286    .build_strict();
2287
2288/// Number format to parse an [`Objective-C`] float from string.
2289///
2290/// [`Objective-C`]: https://en.wikipedia.org/wiki/Objective-C
2291#[rustfmt::skip]
2292pub const OBJECTIVEC_STRING: Options = Options::builder()
2293    .nan_string(options::OBJECTIVEC)
2294    .inf_string(options::OBJECTIVEC)
2295    .build_strict();
2296
2297/// Number format for an [`ReasonML`] literal floating-point number.
2298///
2299/// [`ReasonML`]: https://reasonml.github.io/
2300#[rustfmt::skip]
2301pub const REASONML_LITERAL: Options = Options::builder()
2302    .nan_string(options::REASONML_LITERAL_NAN)
2303    .inf_string(options::REASONML_LITERAL_INF)
2304    .build_strict();
2305
2306/// Number format for a [`MATLAB`] literal floating-point number.
2307///
2308/// [`Matlab`]: https://www.mathworks.com/products/matlab.html
2309#[rustfmt::skip]
2310pub const MATLAB_LITERAL: Options = Options::builder()
2311    .inf_string(options::MATLAB_LITERAL_INF)
2312    .build_strict();
2313
2314/// Number format for a [`Zig`] literal floating-point number.
2315///
2316/// [`Zig`]: https://ziglang.org/
2317#[rustfmt::skip]
2318pub const ZIG_LITERAL: Options = Options::builder()
2319    .nan_string(options::ZIG_LITERAL)
2320    .inf_string(options::ZIG_LITERAL)
2321    .build_strict();
2322
2323/// Number format for a [`Sage`] literal floating-point number.
2324///
2325/// [`Sage`]: https://www.sagemath.org/
2326#[rustfmt::skip]
2327pub const SAGE_LITERAL: Options = Options::builder()
2328    .inf_string(options::SAGE_LITERAL_INF)
2329    .build_strict();
2330
2331/// Number format for a [`JSON`][`JSON-REF`] literal floating-point number.
2332///
2333/// [`JSON-REF`]: https://www.json.org/json-en.html
2334#[rustfmt::skip]
2335pub const JSON: Options = Options::builder()
2336    .nan_string(options::JSON)
2337    .inf_string(options::JSON)
2338    .build_strict();
2339
2340/// Number format for a [`TOML`][`TOML-REF`] literal floating-point number.
2341///
2342/// [`TOML-REF`]: https://toml.io/en/
2343#[rustfmt::skip]
2344pub const TOML: Options = Options::builder()
2345    .nan_string(options::TOML)
2346    .inf_string(options::TOML)
2347    .build_strict();
2348
2349/// Number format for a [`YAML`][`YAML-REF`] literal floating-point number.
2350///
2351/// [`YAML-REF`]: https://yaml.org/
2352#[rustfmt::skip]
2353pub const YAML: Options = JSON;
2354
2355/// Number format for an [`XML`][`XML-REF`] literal floating-point number.
2356///
2357/// [`XML-REF`]: https://en.wikipedia.org/wiki/XML
2358#[rustfmt::skip]
2359pub const XML: Options = Options::builder()
2360    .inf_string(options::XML_INF)
2361    .build_strict();
2362
2363/// Number format for a [`SQLite`] literal floating-point number.
2364///
2365/// [`SQLite`]: https://www.sqlite.org/
2366#[rustfmt::skip]
2367pub const SQLITE: Options = Options::builder()
2368    .nan_string(options::SQLITE)
2369    .inf_string(options::SQLITE)
2370    .build_strict();
2371
2372/// Number format for a [`PostgreSQL`] literal floating-point number.
2373///
2374/// [`PostgreSQL`]: https://www.postgresql.org/
2375#[rustfmt::skip]
2376pub const POSTGRESQL: Options = Options::builder()
2377    .nan_string(options::POSTGRESQL)
2378    .inf_string(options::POSTGRESQL)
2379    .build_strict();
2380
2381/// Number format for a [`MySQL`] literal floating-point number.
2382///
2383/// [`MySQL`]: https://www.mysql.com/
2384#[rustfmt::skip]
2385pub const MYSQL: Options = Options::builder()
2386    .nan_string(options::MYSQL)
2387    .inf_string(options::MYSQL)
2388    .build_strict();
2389
2390/// Number format for a [`MongoDB`] literal floating-point number.
2391///
2392/// [`MongoDB`]: https://www.mongodb.com/
2393#[rustfmt::skip]
2394pub const MONGODB: Options = Options::builder()
2395    .inf_string(options::MONGODB_INF)
2396    .build_strict();