lexical_parse_float/
options.rs

1//! Configuration options for parsing floats.
2//!
3//! This enables extensive control over how the float is parsed, from
4//! control characters like the decimal point and the valid non-finite
5//! float representations.
6//!
7//! # Examples
8//!
9//! For example, to parse a European-style float:
10//!
11//! ```rust
12//! use lexical_parse_float::{FromLexicalWithOptions, Options};
13//! use lexical_parse_float::format::STANDARD;
14//!
15//! const OPTIONS: Options = Options::builder()
16//!     .decimal_point(b',')
17//!     .build_strict();
18//! let value = "1,2345e300";
19//! let result = f64::from_lexical_with_options::<STANDARD>(value.as_bytes(), &OPTIONS);
20//! assert_eq!(result, Ok(1.2345e300));
21//! ```
22//!
23//! # Pre-Defined Formats
24//!
25//! These are the pre-defined formats for parsing numbers from various
26//! programming, markup, and data languages.
27//!
28//! - [`STANDARD`]: Standard number format.
29//! - [`DECIMAL_COMMA`]: Numerical format with a decimal comma.
30//! - [`HEX_FLOAT`]: Numerical format for hexadecimal floats, which use a `p`
31//!   exponent.
32//! - [`RUST_LITERAL`]: Number format for a [`Rust`] literal floating-point
33//!   number.
34//! - [`PYTHON_LITERAL`]: Number format for a [`Python`] literal floating-point
35//!   number.
36//! - [`CXX_LITERAL`]: Number format for a [`C++`] literal floating-point
37//!   number.
38//! - [`C_LITERAL`]: Number format for a [`C`] literal floating-point number.
39//! - [`RUBY_LITERAL`]: Number format for a [`Ruby`] literal floating-point
40//!   number.
41//! - [`RUBY_STRING`]: Number format to parse a [`Ruby`] float from string.
42//! - [`SWIFT_LITERAL`]: Number format for a [`Swift`] literal floating-point
43//!   number.
44//! - [`GO_LITERAL`]: Number format for a [`Golang`] literal floating-point
45//!   number.
46//! - [`HASKELL_LITERAL`]: Number format for a [`Haskell`] literal
47//!   floating-point number.
48//! - [`HASKELL_STRING`]: Number format to parse a [`Haskell`] float from
49//!   string.
50//! - [`JAVASCRIPT_LITERAL`]: Number format for a [`Javascript`] literal
51//!   floating-point number.
52//! - [`JAVASCRIPT_STRING`]: Number format to parse a [`Javascript`] float from
53//!   string.
54//! - [`PERL_LITERAL`]: Number format for a [`Perl`] literal floating-point
55//!   number.
56//! - [`PHP_LITERAL`]: Number format for a [`PHP`] literal floating-point
57//!   number.
58//! - [`JAVA_LITERAL`]: Number format for a [`Java`] literal floating-point
59//!   number.
60//! - [`JAVA_STRING`]: Number format to parse a [`Java`] float from string.
61//! - [`R_LITERAL`]: Number format for an [`R`] literal floating-point number.
62//! - [`KOTLIN_LITERAL`]: Number format for a [`Kotlin`] literal floating-point
63//!   number.
64//! - [`KOTLIN_STRING`]: Number format to parse a [`Kotlin`] float from string.
65//! - [`JULIA_LITERAL`]: Number format for a [`Julia`] literal floating-point
66//!   number.
67//! - [`CSHARP_LITERAL`]: Number format for a [`C#`] literal floating-point
68//!   number.
69//! - [`CSHARP_STRING`]: Number format to parse a [`C#`] float from string.
70//! - [`KAWA_LITERAL`]: Number format for a [`Kawa`] literal floating-point
71//!   number.
72//! - [`KAWA_STRING`]: Number format to parse a [`Kawa`] float from string.
73//! - [`GAMBITC_LITERAL`]: Number format for a [`Gambit-C`] literal
74//!   floating-point number.
75//! - [`GAMBITC_STRING`]: Number format to parse a [`Gambit-C`] float from
76//!   string.
77//! - [`GUILE_LITERAL`]: Number format for a [`Guile`] literal floating-point
78//!   number.
79//! - [`GUILE_STRING`]: Number format to parse a [`Guile`] float from string.
80//! - [`CLOJURE_LITERAL`]: Number format for a [`Clojure`] literal
81//!   floating-point number.
82//! - [`CLOJURE_STRING`]: Number format to parse a [`Clojure`] float from
83//!   string.
84//! - [`ERLANG_LITERAL`]: Number format for an [`Erlang`] literal floating-point
85//!   number.
86//! - [`ERLANG_STRING`]: Number format to parse an [`Erlang`] float from string.
87//! - [`ELM_LITERAL`]: Number format for an [`Elm`] literal floating-point
88//!   number.
89//! - [`ELM_STRING`]: Number format to parse an [`Elm`] float from string.
90//! - [`SCALA_LITERAL`]: Number format for a [`Scala`] literal floating-point
91//!   number.
92//! - [`SCALA_STRING`]: Number format to parse a [`Scala`] float from string.
93//! - [`ELIXIR_LITERAL`]: Number format for an [`Elixir`] literal floating-point
94//!   number.
95//! - [`ELIXIR_STRING`]: Number format to parse an [`Elixir`] float from string.
96//! - [`FORTRAN_LITERAL`]: Number format for a [`FORTRAN`] literal
97//!   floating-point number.
98//! - [`D_LITERAL`]: Number format for a [`D`] literal floating-point number.
99//! - [`COFFEESCRIPT_LITERAL`]: Number format for a [`Coffeescript`] literal
100//!   floating-point number.
101//! - [`COFFEESCRIPT_STRING`]: Number format to parse a [`Coffeescript`] float
102//!   from string.
103//! - [`COBOL_LITERAL`]: Number format for a [`COBOL`] literal floating-point
104//!   number.
105//! - [`COBOL_STRING`]: Number format to parse a [`COBOL`] float from string.
106//! - [`FSHARP_LITERAL`]: Number format for an [`F#`] literal floating-point
107//!   number.
108//! - [`VB_LITERAL`]: Number format for a [`Visual Basic`] literal
109//!   floating-point number.
110//! - [`VB_STRING`]: Number format to parse a [`Visual Basic`] float from
111//!   string.
112//! - [`OCAML_LITERAL`]: Number format for an [`OCaml`] literal floating-point
113//!   number.
114//! - [`OBJECTIVEC_LITERAL`]: Number format for an [`Objective-C`] literal
115//!   floating-point number.
116//! - [`OBJECTIVEC_STRING`]: Number format to parse an [`Objective-C`] float
117//!   from string.
118//! - [`REASONML_LITERAL`]: Number format for an [`ReasonML`] literal
119//!   floating-point number.
120//! - [`MATLAB_LITERAL`]: Number format for a [`MATLAB`] literal floating-point
121//!   number.
122//! - [`ZIG_LITERAL`]: Number format for a [`Zig`] literal floating-point
123//!   number.
124//! - [`SAGE_LITERAL`]: Number format for a [`Sage`] literal floating-point
125//!   number.
126//! - [`JSON`]: Number format for a [`JSON`][`JSON-REF`] literal floating-point
127//!   number.
128//! - [`TOML`]: Number format for a [`TOML`][`TOML-REF`] literal floating-point
129//!   number.
130//! - [`YAML`]: Number format for a [`YAML`][`YAML-REF`] literal floating-point
131//!   number.
132//! - [`XML`]: Number format for an [`XML`][`XML-REF`] literal floating-point
133//!   number.
134//! - [`SQLITE`]: Number format for a [`SQLite`] literal floating-point number.
135//! - [`POSTGRESQL`]: Number format for a [`PostgreSQL`] literal floating-point
136//!   number.
137//! - [`MYSQL`]: Number format for a [`MySQL`] literal floating-point number.
138//! - [`MONGODB`]: Number format for a [`MongoDB`] literal floating-point
139//!   number.
140//!
141//! <!-- References -->
142//!
143//! [`Rust`]: https://www.rust-lang.org/
144//! [`Python`]: https://www.python.org/
145//! [`C++`]: https://en.cppreference.com/w/
146//! [`C`]: https://en.cppreference.com/w/c
147//! [`Ruby`]: https://www.ruby-lang.org/en/
148//! [`Swift`]: https://developer.apple.com/swift/
149//! [`Golang`]: https://go.dev/
150//! [`Haskell`]: https://www.haskell.org/
151//! [`Javascript`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
152//! [`Perl`]: https://www.perl.org/
153//! [`PHP`]: https://www.php.net/
154//! [`Java`]: https://www.java.com/en/
155//! [`R`]: https://www.r-project.org/
156//! [`Kotlin`]: https://kotlinlang.org/
157//! [`Julia`]: https://julialang.org/
158//! [`C#`]: https://learn.microsoft.com/en-us/dotnet/csharp/
159//! [`Kawa`]: https://www.gnu.org/software/kawa/
160//! [`Gambit-C`]: https://gambitscheme.org/
161//! [`Guile`]: https://www.gnu.org/software/guile/
162//! [`Clojure`]: https://clojure.org/
163//! [`Erlang`]: https://www.erlang.org/
164//! [`Elm`]: https://elm-lang.org/
165//! [`Scala`]: https://www.scala-lang.org/
166//! [`Elixir`]: https://elixir-lang.org/
167//! [`FORTRAN`]: https://fortran-lang.org/
168//! [`D`]: https://dlang.org/
169//! [`Coffeescript`]: https://coffeescript.org/
170//! [`Cobol`]: https://www.ibm.com/think/topics/cobol
171//! [`F#`]: https://fsharp.org/
172//! [`Visual Basic`]: https://learn.microsoft.com/en-us/dotnet/visual-basic/
173//! [`OCaml`]: https://ocaml.org/
174//! [`Objective-C`]: https://en.wikipedia.org/wiki/Objective-C
175//! [`ReasonML`]: https://reasonml.github.io/
176//! [`Matlab`]: https://www.mathworks.com/products/matlab.html
177//! [`Zig`]: https://ziglang.org/
178//! [`Sage`]: https://www.sagemath.org/
179//! [`JSON-REF`]: https://www.json.org/json-en.html
180//! [`TOML-REF`]: https://toml.io/en/
181//! [`YAML-REF`]: https://yaml.org/
182//! [`XML-REF`]: https://en.wikipedia.org/wiki/XML
183//! [`SQLite`]: https://www.sqlite.org/
184//! [`PostgreSQL`]: https://www.postgresql.org/
185//! [`MySQL`]: https://www.mysql.com/
186//! [`MongoDB`]: https://www.mongodb.com/
187
188#![allow(clippy::must_use_candidate)]
189
190use lexical_util::ascii::{is_valid_ascii, is_valid_letter_slice};
191use lexical_util::error::Error;
192use lexical_util::options::{self, ParseOptions};
193use lexical_util::result::Result;
194
195/// Maximum length for a special string.
196pub const MAX_SPECIAL_STRING_LENGTH: usize = 50;
197
198/// Builder for [`Options`].
199///
200/// This enables extensive control over how the float is parsed, from
201/// control characters like the decimal point and the valid non-finite
202/// float representations.
203///
204/// # Examples
205///
206/// ```rust
207/// use lexical_parse_float::{FromLexicalWithOptions, Options};
208/// use lexical_parse_float::format::STANDARD;
209///
210/// const OPTIONS: Options = Options::builder()
211///     .decimal_point(b',')
212///     .build_strict();
213/// let value = "1,2345e300";
214/// let result = f64::from_lexical_with_options::<STANDARD>(value.as_bytes(), &OPTIONS);
215/// assert_eq!(result, Ok(1.2345e300));
216/// ```
217#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
218pub struct OptionsBuilder {
219    /// Disable the use of arbitrary-precision arithmetic, and always
220    /// return the results from the fast or intermediate path algorithms.
221    lossy: bool,
222    /// Character to designate the exponent component of a float.
223    exponent: u8,
224    /// Character to separate the integer from the fraction components.
225    decimal_point: u8,
226    /// String representation of Not A Number, aka `NaN`.
227    nan_string: Option<&'static [u8]>,
228    /// Short string representation of `Infinity`.
229    inf_string: Option<&'static [u8]>,
230    /// Long string representation of `Infinity`.
231    infinity_string: Option<&'static [u8]>,
232}
233
234impl OptionsBuilder {
235    /// Create new options builder with default options.
236    #[inline(always)]
237    pub const fn new() -> Self {
238        Self {
239            lossy: false,
240            exponent: b'e',
241            decimal_point: b'.',
242            nan_string: Some(b"NaN"),
243            inf_string: Some(b"inf"),
244            infinity_string: Some(b"infinity"),
245        }
246    }
247
248    // GETTERS
249
250    /// Get if we disable the use of arbitrary-precision arithmetic.
251    ///
252    /// Lossy algorithms never use the fallback, slow algorithm. Defaults to
253    /// [`false`].
254    ///
255    /// # Examples
256    ///
257    /// ```rust
258    /// use lexical_parse_float::options::Options;
259    ///
260    /// assert_eq!(Options::builder().get_lossy(), false);
261    /// ```
262    #[inline(always)]
263    pub const fn get_lossy(&self) -> bool {
264        self.lossy
265    }
266
267    /// Get the character to designate the exponent component of a float.
268    ///
269    /// Any non-control character is valid, but `\t` to `\r` are also valid.
270    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `e`.
271    ///
272    /// # Examples
273    ///
274    /// ```rust
275    /// use lexical_parse_float::options::Options;
276    ///
277    /// assert_eq!(Options::builder().get_exponent(), b'e');
278    /// ```
279    #[inline(always)]
280    pub const fn get_exponent(&self) -> u8 {
281        self.exponent
282    }
283
284    /// Get the character to separate the integer from the fraction components.
285    ///
286    /// Any non-control character is valid, but `\t` to `\r` are also valid.
287    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `.`.
288    ///
289    /// # Examples
290    ///
291    /// ```rust
292    /// use lexical_parse_float::options::Options;
293    ///
294    /// assert_eq!(Options::builder().get_decimal_point(), b'.');
295    /// ```
296    #[inline(always)]
297    pub const fn get_decimal_point(&self) -> u8 {
298        self.decimal_point
299    }
300
301    /// Get the string representation for `NaN`.
302    ///
303    /// The first character must start with `N` or `n` and all characters must
304    /// be valid ASCII letters (`A-Z` or `a-z`). Defaults to `NaN`.
305    ///
306    /// # Examples
307    ///
308    /// ```rust
309    /// use lexical_parse_float::Options;
310    ///
311    /// let builder = Options::builder();
312    /// assert_eq!(builder.get_nan_string(), Some("NaN".as_bytes()));
313    /// ```
314    #[inline(always)]
315    pub const fn get_nan_string(&self) -> Option<&'static [u8]> {
316        self.nan_string
317    }
318
319    /// Get the short string representation for `Infinity`.
320    ///
321    /// The first character must start with `I` or `i` and all characters must
322    /// be valid ASCII letters (`A-Z` or `a-z`). Defaults to `inf`.
323    ///
324    /// # Examples
325    ///
326    /// ```rust
327    /// use lexical_parse_float::Options;
328    ///
329    /// let builder = Options::builder();
330    /// assert_eq!(builder.get_inf_string(), Some("inf".as_bytes()));
331    /// ```
332    #[inline(always)]
333    pub const fn get_inf_string(&self) -> Option<&'static [u8]> {
334        self.inf_string
335    }
336
337    /// Get the long string representation for `Infinity`.
338    ///
339    /// The first character must start with `I` or `i` and all characters must
340    /// be valid ASCII letters (`A-Z` or `a-z`). Defaults to `infinity`.
341    ///
342    /// [`get_inf_string`]: Self::get_inf_string
343    ///
344    /// # Examples
345    ///
346    /// ```rust
347    /// use lexical_parse_float::Options;
348    ///
349    /// let builder = Options::builder();
350    /// assert_eq!(builder.get_infinity_string(), Some("infinity".as_bytes()));
351    /// ```
352    #[inline(always)]
353    pub const fn get_infinity_string(&self) -> Option<&'static [u8]> {
354        self.infinity_string
355    }
356
357    // SETTERS
358
359    /// Set if we disable the use of arbitrary-precision arithmetic.
360    ///
361    /// Lossy algorithms never use the fallback, slow algorithm. Defaults to
362    /// [`false`].
363    ///
364    /// # Examples
365    ///
366    /// ```rust
367    /// use lexical_parse_float::options::Options;
368    ///
369    /// const OPTIONS: Options = Options::builder()
370    ///     .lossy(true)
371    ///     .build_strict();
372    /// assert_eq!(OPTIONS.lossy(), true);
373    /// ```
374    #[must_use]
375    #[inline(always)]
376    pub const fn lossy(mut self, lossy: bool) -> Self {
377        self.lossy = lossy;
378        self
379    }
380
381    /// Set the character to designate the exponent component of a float.
382    ///
383    /// Any non-control character is valid, but `\t` to `\r` are also valid.
384    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `e`.
385    ///
386    /// # Examples
387    ///
388    /// ```rust
389    /// use lexical_parse_float::options::Options;
390    ///
391    /// const OPTIONS: Options = Options::builder()
392    ///     .exponent(b'^')
393    ///     .build_strict();
394    /// assert_eq!(OPTIONS.exponent(), b'^');
395    /// ```
396    #[must_use]
397    #[inline(always)]
398    pub const fn exponent(mut self, exponent: u8) -> Self {
399        self.exponent = exponent;
400        self
401    }
402
403    /// Set the character to separate the integer from the fraction components.
404    ///
405    /// Any non-control character is valid, but `\t` to `\r` are also valid.
406    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `.`.
407    ///
408    /// # Examples
409    ///
410    /// ```rust
411    /// use lexical_parse_float::options::Options;
412    ///
413    /// const OPTIONS: Options = Options::builder()
414    ///     .exponent(b',')
415    ///     .build_strict();
416    /// assert_eq!(OPTIONS.exponent(), b',');
417    /// ```
418    #[must_use]
419    #[inline(always)]
420    pub const fn decimal_point(mut self, decimal_point: u8) -> Self {
421        self.decimal_point = decimal_point;
422        self
423    }
424
425    /// Set the string representation for `NaN`.
426    ///
427    /// The first character must start with `N` or `n` and all characters must
428    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then parsing
429    /// [`NaN`][f64::NAN] returns an error. Defaults to `NaN`.
430    ///
431    /// # Examples
432    ///
433    /// ```rust
434    /// use lexical_parse_float::Options;
435    ///
436    /// const OPTIONS: Options = Options::builder()
437    ///     .nan_string(Some(b"nan"))
438    ///     .build_strict();
439    /// assert_eq!(OPTIONS.nan_string(), Some(b"nan".as_ref()));
440    /// ```
441    ///
442    /// Panics
443    ///
444    /// Setting a value with more than 50 elements will panic at runtime. You
445    /// should always build the format using [`build_strict`] or checking
446    /// [`is_valid`] prior to using the format, to avoid unexpected panics.
447    ///
448    /// [`build_strict`]: Self::build_strict
449    /// [`is_valid`]: Self::is_valid
450    #[must_use]
451    #[inline(always)]
452    pub const fn nan_string(mut self, nan_string: Option<&'static [u8]>) -> Self {
453        self.nan_string = nan_string;
454        self
455    }
456
457    /// Set the short string representation for `Infinity`.
458    ///
459    /// The first character must start with `I` or `i` and all characters must
460    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then parsing
461    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
462    ///
463    /// # Examples
464    ///
465    /// ```rust
466    /// use lexical_parse_float::Options;
467    ///
468    /// const OPTIONS: Options = Options::builder()
469    ///     .inf_string(Some(b"Infinity"))
470    ///     .build_strict();
471    /// assert_eq!(OPTIONS.inf_string(), Some(b"Infinity".as_ref()));
472    /// ```
473    ///
474    /// Panics
475    ///
476    /// Setting a value with more than 50 elements or one that is longer than
477    /// [`infinity_string`] will panic at runtime. You should always build
478    /// the format using [`build_strict`] or checking [`is_valid`] prior to
479    /// using the format, to avoid unexpected panics.
480    ///
481    /// [`infinity_string`]: Self::infinity_string
482    /// [`build_strict`]: Self::build_strict
483    /// [`is_valid`]: Self::is_valid
484    #[must_use]
485    #[inline(always)]
486    pub const fn inf_string(mut self, inf_string: Option<&'static [u8]>) -> Self {
487        self.inf_string = inf_string;
488        self
489    }
490
491    /// Set the long string representation for `Infinity`.
492    ///
493    /// The first character must start with `I` or `i` and all characters must
494    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then parsing
495    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `infinity`.
496    ///
497    /// # Examples
498    ///
499    /// ```rust
500    /// use lexical_parse_float::Options;
501    ///
502    /// const OPTIONS: Options = Options::builder()
503    ///     .infinity_string(Some(b"Infinity"))
504    ///     .build_strict();
505    /// assert_eq!(OPTIONS.infinity_string(), Some(b"Infinity".as_ref()));
506    /// ```
507    ///
508    /// Panics
509    ///
510    /// Setting a value with more than 50 elements or one that is shorter than
511    /// [`inf_string`] will panic at runtime. You should always build the format
512    /// using [`build_strict`] or checking [`is_valid`] prior to
513    /// using the format, to avoid unexpected panics.
514    ///
515    /// [`inf_string`]: Self::inf_string
516    /// [`build_strict`]: Self::build_strict
517    /// [`is_valid`]: Self::is_valid
518    #[must_use]
519    #[inline(always)]
520    pub const fn infinity_string(mut self, infinity_string: Option<&'static [u8]>) -> Self {
521        self.infinity_string = infinity_string;
522        self
523    }
524
525    // BUILDERS
526
527    /// Determine if [`nan_string`] is valid.
528    ///
529    /// [`nan_string`]: Self::nan_string
530    #[doc(hidden)]
531    #[inline(always)]
532    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
533    pub const fn nan_str_is_valid(&self) -> bool {
534        if self.nan_string.is_none() {
535            return true;
536        }
537
538        let nan = unwrap_str(self.nan_string);
539        let length = nan.len();
540        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
541            false
542        } else if !matches!(nan[0], b'N' | b'n') {
543            false
544        } else if !is_valid_letter_slice(nan) {
545            false
546        } else {
547            true
548        }
549    }
550
551    /// Determine if [`inf_string`] is valid.
552    ///
553    /// [`inf_string`]: Self::inf_string
554    #[doc(hidden)]
555    #[inline(always)]
556    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
557    pub const fn inf_str_is_valid(&self) -> bool {
558        if self.infinity_string.is_none() && self.inf_string.is_some() {
559            return false;
560        } else if self.inf_string.is_none() {
561            return true;
562        }
563
564        let inf = unwrap_str(self.inf_string);
565        let length = inf.len();
566        let infinity = unwrap_str(self.infinity_string);
567        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
568            false
569        } else if !matches!(inf[0], b'I' | b'i') {
570            false
571        } else if length > infinity.len() {
572            false
573        } else if !is_valid_letter_slice(inf) {
574            false
575        } else {
576            true
577        }
578    }
579
580    /// Determine if [`infinity_string`] is valid.
581    ///
582    /// [`infinity_string`]: Self::infinity_string
583    #[doc(hidden)]
584    #[inline(always)]
585    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
586    pub const fn infinity_string_is_valid(&self) -> bool {
587        if self.infinity_string.is_none() && self.inf_string.is_some() {
588            return false;
589        } else if self.infinity_string.is_none() {
590            return true;
591        }
592        let inf = unwrap_str(self.inf_string);
593        let infinity = unwrap_str(self.infinity_string);
594        let length = infinity.len();
595        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
596            false
597        } else if !matches!(infinity[0], b'I' | b'i') {
598            false
599        } else if length < inf.len() {
600            false
601        } else if !is_valid_letter_slice(infinity) {
602            false
603        } else {
604            true
605        }
606    }
607
608    /// Check if the builder state is valid.
609    #[inline(always)]
610    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
611    pub const fn is_valid(&self) -> bool {
612        if !is_valid_ascii(self.exponent) {
613            false
614        } else if !is_valid_ascii(self.decimal_point) {
615            false
616        } else if !self.nan_str_is_valid() {
617            false
618        } else if !self.inf_str_is_valid() {
619            false
620        } else if !self.infinity_string_is_valid() {
621            false
622        } else {
623            true
624        }
625    }
626
627    /// Build the [`Options`] struct without validation.
628    ///
629    /// # Panics
630    ///
631    /// This is completely safe, however, misusing this, especially
632    /// the [`nan_string`], [`inf_string`], and [`infinity_string`] could
633    /// panic at runtime. Always use [`is_valid`] prior to using the built
634    /// options.
635    ///
636    /// [`inf_string`]: Self::inf_string
637    /// [`nan_string`]: Self::nan_string
638    /// [`infinity_string`]: Self::infinity_string
639    /// [`is_valid`]: Self::is_valid
640    #[inline(always)]
641    pub const fn build_unchecked(&self) -> Options {
642        Options {
643            lossy: self.lossy,
644            exponent: self.exponent,
645            decimal_point: self.decimal_point,
646            nan_string: self.nan_string,
647            inf_string: self.inf_string,
648            infinity_string: self.infinity_string,
649        }
650    }
651
652    /// Build the [`Options`] struct, panicking if the builder is invalid.
653    ///
654    /// # Panics
655    ///
656    /// If the built options are not valid. This should always
657    /// be used within a const context to avoid panics at runtime.
658    #[inline(always)]
659    pub const fn build_strict(&self) -> Options {
660        match self.build() {
661            Ok(value) => value,
662            Err(error) => core::panic!("{}", error.description()),
663        }
664    }
665
666    /// Build the [`Options`] struct.
667    ///
668    /// # Errors
669    ///
670    /// If the NaN, Inf, or Infinity strings are too long or invalid
671    /// digits/characters are provided for some numerical formats.
672    #[inline(always)]
673    #[allow(clippy::if_same_then_else)] // reason = "more idiomatic"
674    pub const fn build(&self) -> Result<Options> {
675        if !is_valid_ascii(self.exponent) {
676            return Err(Error::InvalidExponentSymbol);
677        } else if !is_valid_ascii(self.decimal_point) {
678            return Err(Error::InvalidDecimalPoint);
679        }
680
681        if self.nan_string.is_some() {
682            let nan = unwrap_str(self.nan_string);
683            if nan.is_empty() || !matches!(nan[0], b'N' | b'n') {
684                return Err(Error::InvalidNanString);
685            } else if !is_valid_letter_slice(nan) {
686                return Err(Error::InvalidNanString);
687            } else if nan.len() > MAX_SPECIAL_STRING_LENGTH {
688                return Err(Error::NanStringTooLong);
689            }
690        }
691
692        if self.inf_string.is_some() && self.infinity_string.is_none() {
693            return Err(Error::InfinityStringTooShort);
694        }
695
696        if self.inf_string.is_some() {
697            let inf = unwrap_str(self.inf_string);
698            if inf.is_empty() || !matches!(inf[0], b'I' | b'i') {
699                return Err(Error::InvalidInfString);
700            } else if !is_valid_letter_slice(inf) {
701                return Err(Error::InvalidInfString);
702            } else if inf.len() > MAX_SPECIAL_STRING_LENGTH {
703                return Err(Error::InfStringTooLong);
704            }
705        }
706
707        if self.infinity_string.is_some() {
708            let inf = unwrap_str(self.inf_string);
709            let infinity = unwrap_str(self.infinity_string);
710            if infinity.is_empty() || !matches!(infinity[0], b'I' | b'i') {
711                return Err(Error::InvalidInfinityString);
712            } else if !is_valid_letter_slice(infinity) {
713                return Err(Error::InvalidInfinityString);
714            } else if infinity.len() > MAX_SPECIAL_STRING_LENGTH {
715                return Err(Error::InfinityStringTooLong);
716            } else if infinity.len() < inf.len() {
717                return Err(Error::InfinityStringTooShort);
718            }
719        }
720
721        Ok(self.build_unchecked())
722    }
723}
724
725impl Default for OptionsBuilder {
726    #[inline(always)]
727    fn default() -> Self {
728        Self::new()
729    }
730}
731
732/// Options to customize parsing floats.
733///
734/// This enables extensive control over how the float is parsed, from
735/// control characters like the decimal point and the valid non-finite
736/// float representations.
737///
738/// # Examples
739///
740/// ```rust
741/// use lexical_parse_float::{FromLexicalWithOptions, Options};
742/// use lexical_parse_float::format::STANDARD;
743///
744/// const OPTIONS: Options = Options::builder()
745///     .lossy(true)
746///     .nan_string(Some(b"NaN"))
747///     .inf_string(Some(b"Inf"))
748///     .infinity_string(Some(b"Infinity"))
749///     .build_strict();
750///
751/// let value = "1.2345e300";
752/// let result = f64::from_lexical_with_options::<STANDARD>(value.as_bytes(), &OPTIONS);
753/// assert_eq!(result, Ok(1.2345e300));
754///
755/// let value = "NaN";
756/// let result = f64::from_lexical_with_options::<STANDARD>(value.as_bytes(), &OPTIONS);
757/// assert_eq!(result.map(|x| x.is_nan()), Ok(true));
758/// ```
759#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
760pub struct Options {
761    /// Disable the use of arbitrary-precision arithmetic, and always
762    /// return the results from the fast or intermediate path algorithms.
763    lossy: bool,
764    /// Character to designate the exponent component of a float.
765    exponent: u8,
766    /// Character to separate the integer from the fraction components.
767    decimal_point: u8,
768    /// String representation of Not A Number, aka `NaN`.
769    nan_string: Option<&'static [u8]>,
770    /// Short string representation of `Infinity`.
771    inf_string: Option<&'static [u8]>,
772    /// Long string representation of `Infinity`.
773    infinity_string: Option<&'static [u8]>,
774}
775
776impl Options {
777    // CONSTRUCTORS
778
779    /// Create options with default values.
780    #[inline(always)]
781    pub const fn new() -> Self {
782        Self::builder().build_unchecked()
783    }
784
785    /// Create the default options for a given radix.
786    ///
787    /// This sets the exponent to `^` for any radix where `e`
788    /// would be a valid digit.
789    #[inline(always)]
790    #[cfg(feature = "power-of-two")]
791    pub const fn from_radix(radix: u8) -> Self {
792        // Need to determine the correct exponent character ('e' or '^'),
793        // since the default character is `e` normally, but this is a valid
794        // digit for radix >= 15.
795        let mut builder = Self::builder();
796        if radix >= 15 {
797            builder = builder.exponent(b'^');
798        }
799        builder.build_unchecked()
800    }
801
802    // GETTERS
803
804    /// Check if the options state is valid.
805    #[inline(always)]
806    pub const fn is_valid(&self) -> bool {
807        self.rebuild().is_valid()
808    }
809
810    /// Get if we disable the use of arbitrary-precision arithmetic.
811    ///
812    /// Lossy algorithms never use the fallback, slow algorithm. Defaults to
813    /// [`false`].
814    ///
815    /// # Examples
816    ///
817    /// ```rust
818    /// use lexical_parse_float::options::Options;
819    ///
820    /// assert_eq!(Options::new().lossy(), false);
821    /// ```
822    #[inline(always)]
823    pub const fn lossy(&self) -> bool {
824        self.lossy
825    }
826
827    /// Get the character to designate the exponent component of a float.
828    ///
829    /// Any non-control character is valid, but `\t` to `\r` are also valid.
830    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `e`.
831    ///
832    /// # Examples
833    ///
834    /// ```rust
835    /// use lexical_parse_float::options::Options;
836    ///
837    /// assert_eq!(Options::new().exponent(), b'e');
838    /// ```
839    #[inline(always)]
840    pub const fn exponent(&self) -> u8 {
841        self.exponent
842    }
843
844    /// Get the character to separate the integer from the fraction components.
845    ///
846    /// Any non-control character is valid, but `\t` to `\r` are also valid.
847    /// The full range is `[0x09, 0x0D]` and `[0x20, 0x7F]`. Defaults to `.`.
848    ///
849    /// # Examples
850    ///
851    /// ```rust
852    /// use lexical_parse_float::options::Options;
853    ///
854    /// assert_eq!(Options::new().decimal_point(), b'.');
855    /// ```
856    #[inline(always)]
857    pub const fn decimal_point(&self) -> u8 {
858        self.decimal_point
859    }
860
861    /// Get the string representation for `NaN`.
862    ///
863    /// The first character must start with `N` or `n` and all characters must
864    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then parsing
865    /// [`NaN`][f64::NAN] returns an error. Defaults to `NaN`.
866    ///
867    /// # Examples
868    ///
869    /// ```rust
870    /// use lexical_parse_float::options::Options;
871    ///
872    /// assert_eq!(Options::new().nan_string(), Some(b"NaN".as_ref()));
873    /// ```
874    #[inline(always)]
875    pub const fn nan_string(&self) -> Option<&'static [u8]> {
876        self.nan_string
877    }
878
879    /// Get the short string representation for `Infinity`.
880    ///
881    /// The first character must start with `I` or `i` and all characters must
882    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then parsing
883    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `inf`.
884    ///
885    /// # Examples
886    ///
887    /// ```rust
888    /// use lexical_parse_float::options::Options;
889    ///
890    /// assert_eq!(Options::new().inf_string(), Some(b"inf".as_ref()));
891    /// ```
892    #[inline(always)]
893    pub const fn inf_string(&self) -> Option<&'static [u8]> {
894        self.inf_string
895    }
896
897    /// Get the long string representation for `Infinity`.
898    ///
899    /// The first character must start with `I` or `i` and all characters must
900    /// be valid ASCII letters (`A-Z` or `a-z`). If set to `None`, then parsing
901    /// [`Infinity`][f64::INFINITY] returns an error. Defaults to `infinity`.
902    ///
903    /// # Examples
904    ///
905    /// ```rust
906    /// use lexical_parse_float::options::Options;
907    ///
908    /// assert_eq!(Options::new().infinity_string(), Some(b"infinity".as_ref()));
909    /// ```
910    #[inline(always)]
911    pub const fn infinity_string(&self) -> Option<&'static [u8]> {
912        self.infinity_string
913    }
914
915    // SETTERS
916
917    /// Set if we disable the use of arbitrary-precision arithmetic.
918    #[inline(always)]
919    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
920    pub fn set_lossy(&mut self, lossy: bool) {
921        self.lossy = lossy;
922    }
923
924    /// Set the character to designate the exponent component of a float.
925    #[inline(always)]
926    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
927    pub fn set_exponent(&mut self, exponent: u8) {
928        self.exponent = exponent;
929    }
930
931    /// Set the character to separate the integer from the fraction components.
932    #[inline(always)]
933    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
934    pub fn set_decimal_point(&mut self, decimal_point: u8) {
935        self.decimal_point = decimal_point;
936    }
937
938    /// Set the string representation for `NaN`.
939    #[inline(always)]
940    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
941    pub fn set_nan_string(&mut self, nan_string: Option<&'static [u8]>) {
942        self.nan_string = nan_string;
943    }
944
945    /// Set the short string representation for `Infinity`
946    #[inline(always)]
947    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
948    pub fn set_inf_string(&mut self, inf_string: Option<&'static [u8]>) {
949        self.inf_string = inf_string;
950    }
951
952    /// Set the long string representation for `Infinity`
953    #[inline(always)]
954    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
955    pub fn set_infinity_string(&mut self, infinity_string: Option<&'static [u8]>) {
956        self.infinity_string = infinity_string;
957    }
958
959    // BUILDERS
960
961    /// Get [`OptionsBuilder`] as a static function.
962    #[must_use]
963    #[inline(always)]
964    pub const fn builder() -> OptionsBuilder {
965        OptionsBuilder::new()
966    }
967
968    /// Create [`OptionsBuilder`] using existing values.
969    #[must_use]
970    #[inline(always)]
971    pub const fn rebuild(&self) -> OptionsBuilder {
972        OptionsBuilder {
973            lossy: self.lossy,
974            exponent: self.exponent,
975            decimal_point: self.decimal_point,
976            nan_string: self.nan_string,
977            inf_string: self.inf_string,
978            infinity_string: self.infinity_string,
979        }
980    }
981}
982
983impl Default for Options {
984    #[inline(always)]
985    fn default() -> Self {
986        Self::new()
987    }
988}
989
990impl ParseOptions for Options {
991    #[inline(always)]
992    fn is_valid(&self) -> bool {
993        Self::is_valid(self)
994    }
995}
996
997/// Unwrap `Option` as a const fn.
998#[inline(always)]
999const fn unwrap_str(option: Option<&'static [u8]>) -> &'static [u8] {
1000    match option {
1001        Some(x) => x,
1002        None => &[],
1003    }
1004}
1005
1006// PRE-DEFINED CONSTANTS
1007// ---------------------
1008
1009// Only constants that differ from the standard version are included.
1010
1011/// Standard number format.
1012#[rustfmt::skip]
1013pub const STANDARD: Options = Options::new();
1014
1015/// Numerical format with a decimal comma.
1016/// This is the standard numerical format for most of the world.
1017#[rustfmt::skip]
1018pub const DECIMAL_COMMA: Options = Options::builder()
1019    .decimal_point(b',')
1020    .build_strict();
1021
1022/// Numerical format for hexadecimal floats, which use a `p` exponent.
1023#[rustfmt::skip]
1024pub const HEX_FLOAT: Options = Options::builder()
1025    .exponent(b'p')
1026    .build_strict();
1027
1028/// Numerical format where `^` is used as the exponent notation character.
1029/// This isn't very common, but is useful when `e` or `p` are valid digits.
1030#[rustfmt::skip]
1031pub const CARAT_EXPONENT: Options = Options::builder()
1032    .exponent(b'^')
1033    .build_strict();
1034
1035/// Number format for a `Rust` literal floating-point number.
1036#[rustfmt::skip]
1037pub const RUST_LITERAL: Options = Options::builder()
1038    .nan_string(options::RUST_LITERAL)
1039    .inf_string(options::RUST_LITERAL)
1040    .infinity_string(options::RUST_LITERAL)
1041    .build_strict();
1042
1043/// Number format for a `Python` literal floating-point number.
1044#[rustfmt::skip]
1045pub const PYTHON_LITERAL: Options = Options::builder()
1046    .nan_string(options::PYTHON_LITERAL)
1047    .inf_string(options::PYTHON_LITERAL)
1048    .infinity_string(options::PYTHON_LITERAL)
1049    .build_strict();
1050
1051/// Number format for a `C++` literal floating-point number.
1052#[rustfmt::skip]
1053pub const CXX_LITERAL: Options = Options::builder()
1054    .nan_string(options::CXX_LITERAL_NAN)
1055    .inf_string(options::CXX_LITERAL_INF)
1056    .infinity_string(options::CXX_LITERAL_INFINITY)
1057    .build_strict();
1058
1059/// Number format for a `C` literal floating-point number.
1060#[rustfmt::skip]
1061pub const C_LITERAL: Options = Options::builder()
1062    .nan_string(options::C_LITERAL_NAN)
1063    .inf_string(options::C_LITERAL_INF)
1064    .infinity_string(options::C_LITERAL_INFINITY)
1065    .build_strict();
1066
1067/// Number format for a `Ruby` literal floating-point number.
1068#[rustfmt::skip]
1069pub const RUBY_LITERAL: Options = Options::builder()
1070    .nan_string(options::RUBY_LITERAL_NAN)
1071    .inf_string(options::RUBY_LITERAL_INF)
1072    .infinity_string(options::RUBY_LITERAL_INF)
1073    .build_strict();
1074
1075/// Number format to parse a `Ruby` float from string.
1076/// `Ruby` can write NaN and Infinity as strings, but won't round-trip them back to floats.
1077#[rustfmt::skip]
1078pub const RUBY_STRING: Options = Options::builder()
1079    .nan_string(options::RUBY_STRING_NONE)
1080    .inf_string(options::RUBY_STRING_NONE)
1081    .infinity_string(options::RUBY_STRING_NONE)
1082    .build_strict();
1083
1084/// Number format for a `Swift` literal floating-point number.
1085#[rustfmt::skip]
1086pub const SWIFT_LITERAL: Options = Options::builder()
1087    .nan_string(options::SWIFT_LITERAL)
1088    .inf_string(options::SWIFT_LITERAL)
1089    .infinity_string(options::SWIFT_LITERAL)
1090    .build_strict();
1091
1092/// Number format for a `Go` literal floating-point number.
1093#[rustfmt::skip]
1094pub const GO_LITERAL: Options = Options::builder()
1095    .nan_string(options::GO_LITERAL)
1096    .inf_string(options::GO_LITERAL)
1097    .infinity_string(options::GO_LITERAL)
1098    .build_strict();
1099
1100/// Number format for a `Haskell` literal floating-point number.
1101#[rustfmt::skip]
1102pub const HASKELL_LITERAL: Options = Options::builder()
1103    .nan_string(options::HASKELL_LITERAL)
1104    .inf_string(options::HASKELL_LITERAL)
1105    .infinity_string(options::HASKELL_LITERAL)
1106    .build_strict();
1107
1108/// Number format to parse a `Haskell` float from string.
1109#[rustfmt::skip]
1110pub const HASKELL_STRING: Options = Options::builder()
1111    .inf_string(options::HASKELL_STRING_INF)
1112    .infinity_string(options::HASKELL_STRING_INFINITY)
1113    .build_strict();
1114
1115/// Number format for a `Javascript` literal floating-point number.
1116#[rustfmt::skip]
1117pub const JAVASCRIPT_LITERAL: Options = Options::builder()
1118    .inf_string(options::JAVASCRIPT_INF)
1119    .infinity_string(options::JAVASCRIPT_INFINITY)
1120    .build_strict();
1121
1122/// Number format to parse a `Javascript` float from string.
1123#[rustfmt::skip]
1124pub const JAVASCRIPT_STRING: Options = Options::builder()
1125    .inf_string(options::JAVASCRIPT_INF)
1126    .infinity_string(options::JAVASCRIPT_INFINITY)
1127    .build_strict();
1128
1129/// Number format for a `Perl` literal floating-point number.
1130#[rustfmt::skip]
1131pub const PERL_LITERAL: Options = Options::builder()
1132    .nan_string(options::PERL_LITERAL)
1133    .inf_string(options::PERL_LITERAL)
1134    .infinity_string(options::PERL_LITERAL)
1135    .build_strict();
1136
1137/// Number format for a `PHP` literal floating-point number.
1138#[rustfmt::skip]
1139pub const PHP_LITERAL: Options = Options::builder()
1140    .nan_string(options::PHP_LITERAL_NAN)
1141    .inf_string(options::PHP_LITERAL_INF)
1142    .infinity_string(options::PHP_LITERAL_INFINITY)
1143    .build_strict();
1144
1145/// Number format for a `Java` literal floating-point number.
1146#[rustfmt::skip]
1147pub const JAVA_LITERAL: Options = Options::builder()
1148    .nan_string(options::JAVA_LITERAL)
1149    .inf_string(options::JAVA_LITERAL)
1150    .infinity_string(options::JAVA_LITERAL)
1151    .build_strict();
1152
1153/// Number format to parse a `Java` float from string.
1154#[rustfmt::skip]
1155pub const JAVA_STRING: Options = Options::builder()
1156    .inf_string(options::JAVA_STRING_INF)
1157    .infinity_string(options::JAVA_STRING_INFINITY)
1158    .build_strict();
1159
1160/// Number format for an `R` literal floating-point number.
1161#[rustfmt::skip]
1162pub const R_LITERAL: Options = Options::builder()
1163    .inf_string(options::R_LITERAL_INF)
1164    .infinity_string(options::R_LITERAL_INFINITY)
1165    .build_strict();
1166
1167/// Number format for a `Kotlin` literal floating-point number.
1168#[rustfmt::skip]
1169pub const KOTLIN_LITERAL: Options = Options::builder()
1170    .nan_string(options::KOTLIN_LITERAL)
1171    .inf_string(options::KOTLIN_LITERAL)
1172    .infinity_string(options::KOTLIN_LITERAL)
1173    .build_strict();
1174
1175/// Number format to parse a `Kotlin` float from string.
1176#[rustfmt::skip]
1177pub const KOTLIN_STRING: Options = Options::builder()
1178    .inf_string(options::KOTLIN_STRING_INF)
1179    .infinity_string(options::KOTLIN_STRING_INFINITY)
1180    .build_strict();
1181
1182/// Number format for a `Julia` literal floating-point number.
1183#[rustfmt::skip]
1184pub const JULIA_LITERAL: Options = Options::builder()
1185    .inf_string(options::JULIA_LITERAL_INF)
1186    .infinity_string(options::JULIA_LITERAL_INFINITY)
1187    .build_strict();
1188
1189/// Number format for a `C#` literal floating-point number.
1190#[rustfmt::skip]
1191pub const CSHARP_LITERAL: Options = Options::builder()
1192    .nan_string(options::CSHARP_LITERAL)
1193    .inf_string(options::CSHARP_LITERAL)
1194    .infinity_string(options::CSHARP_LITERAL)
1195    .build_strict();
1196
1197/// Number format to parse a `C#` float from string.
1198#[rustfmt::skip]
1199pub const CSHARP_STRING: Options = Options::builder()
1200    .inf_string(options::CSHARP_STRING_INF)
1201    .infinity_string(options::CSHARP_STRING_INFINITY)
1202    .build_strict();
1203
1204/// Number format for a `Kawa` literal floating-point number.
1205#[rustfmt::skip]
1206pub const KAWA_LITERAL: Options = Options::builder()
1207    .nan_string(options::KAWA)
1208    .inf_string(options::KAWA)
1209    .infinity_string(options::KAWA)
1210    .build_strict();
1211
1212/// Number format to parse a `Kawa` float from string.
1213#[rustfmt::skip]
1214pub const KAWA_STRING: Options = Options::builder()
1215    .nan_string(options::KAWA)
1216    .inf_string(options::KAWA)
1217    .infinity_string(options::KAWA)
1218    .build_strict();
1219
1220/// Number format for a `Gambit-C` literal floating-point number.
1221#[rustfmt::skip]
1222pub const GAMBITC_LITERAL: Options = Options::builder()
1223    .nan_string(options::GAMBITC)
1224    .inf_string(options::GAMBITC)
1225    .infinity_string(options::GAMBITC)
1226    .build_strict();
1227
1228/// Number format to parse a `Gambit-C` float from string.
1229#[rustfmt::skip]
1230pub const GAMBITC_STRING: Options = Options::builder()
1231    .nan_string(options::GAMBITC)
1232    .inf_string(options::GAMBITC)
1233    .infinity_string(options::GAMBITC)
1234    .build_strict();
1235
1236/// Number format for a `Guile` literal floating-point number.
1237#[rustfmt::skip]
1238pub const GUILE_LITERAL: Options = Options::builder()
1239    .nan_string(options::GUILE)
1240    .inf_string(options::GUILE)
1241    .infinity_string(options::GUILE)
1242    .build_strict();
1243
1244/// Number format to parse a `Guile` float from string.
1245#[rustfmt::skip]
1246pub const GUILE_STRING: Options = Options::builder()
1247    .nan_string(options::GUILE)
1248    .inf_string(options::GUILE)
1249    .infinity_string(options::GUILE)
1250    .build_strict();
1251
1252/// Number format for a `Clojure` literal floating-point number.
1253#[rustfmt::skip]
1254pub const CLOJURE_LITERAL: Options = Options::builder()
1255    .nan_string(options::CLOJURE_LITERAL)
1256    .inf_string(options::CLOJURE_LITERAL)
1257    .infinity_string(options::CLOJURE_LITERAL)
1258    .build_strict();
1259
1260/// Number format to parse a `Clojure` float from string.
1261#[rustfmt::skip]
1262pub const CLOJURE_STRING: Options = Options::builder()
1263    .inf_string(options::CLOJURE_STRING_INF)
1264    .infinity_string(options::CLOJURE_STRING_INFINITY)
1265    .build_strict();
1266
1267/// Number format for an `Erlang` literal floating-point number.
1268#[rustfmt::skip]
1269pub const ERLANG_LITERAL: Options = Options::builder()
1270    .nan_string(options::ERLANG_LITERAL_NAN)
1271    .build_strict();
1272
1273/// Number format to parse an `Erlang` float from string.
1274#[rustfmt::skip]
1275pub const ERLANG_STRING: Options = Options::builder()
1276    .nan_string(options::ERLANG_STRING)
1277    .inf_string(options::ERLANG_STRING)
1278    .infinity_string(options::ERLANG_STRING)
1279    .build_strict();
1280
1281/// Number format for an `Elm` literal floating-point number.
1282#[rustfmt::skip]
1283pub const ELM_LITERAL: Options = Options::builder()
1284    .nan_string(options::ELM_LITERAL)
1285    .inf_string(options::ELM_LITERAL)
1286    .infinity_string(options::ELM_LITERAL)
1287    .build_strict();
1288
1289/// Number format to parse an `Elm` float from string.
1290#[rustfmt::skip]
1291pub const ELM_STRING: Options = Options::builder()
1292    .nan_string(options::ELM_STRING_NAN)
1293    .inf_string(options::ELM_STRING_INF)
1294    .infinity_string(options::ELM_STRING_INFINITY)
1295    .build_strict();
1296
1297/// Number format for a `Scala` literal floating-point number.
1298#[rustfmt::skip]
1299pub const SCALA_LITERAL: Options = Options::builder()
1300    .nan_string(options::SCALA_LITERAL)
1301    .inf_string(options::SCALA_LITERAL)
1302    .infinity_string(options::SCALA_LITERAL)
1303    .build_strict();
1304
1305/// Number format to parse a `Scala` float from string.
1306#[rustfmt::skip]
1307pub const SCALA_STRING: Options = Options::builder()
1308    .inf_string(options::SCALA_STRING_INF)
1309    .infinity_string(options::SCALA_STRING_INFINITY)
1310    .build_strict();
1311
1312/// Number format for an `Elixir` literal floating-point number.
1313#[rustfmt::skip]
1314pub const ELIXIR_LITERAL: Options = Options::builder()
1315    .nan_string(options::ELIXIR)
1316    .inf_string(options::ELIXIR)
1317    .infinity_string(options::ELIXIR)
1318    .build_strict();
1319
1320/// Number format to parse an `Elixir` float from string.
1321#[rustfmt::skip]
1322pub const ELIXIR_STRING: Options = Options::builder()
1323    .nan_string(options::ELIXIR)
1324    .inf_string(options::ELIXIR)
1325    .infinity_string(options::ELIXIR)
1326    .build_strict();
1327
1328/// Number format for a `FORTRAN` literal floating-point number.
1329#[rustfmt::skip]
1330pub const FORTRAN_LITERAL: Options = Options::builder()
1331    .nan_string(options::FORTRAN_LITERAL)
1332    .inf_string(options::FORTRAN_LITERAL)
1333    .infinity_string(options::FORTRAN_LITERAL)
1334    .build_strict();
1335
1336/// Number format for a `D` literal floating-point number.
1337#[rustfmt::skip]
1338pub const D_LITERAL: Options = Options::builder()
1339    .nan_string(options::D_LITERAL)
1340    .inf_string(options::D_LITERAL)
1341    .infinity_string(options::D_LITERAL)
1342    .build_strict();
1343
1344/// Number format for a `Coffeescript` literal floating-point number.
1345#[rustfmt::skip]
1346pub const COFFEESCRIPT_LITERAL: Options = Options::builder()
1347    .inf_string(options::COFFEESCRIPT_INF)
1348    .infinity_string(options::COFFEESCRIPT_INFINITY)
1349    .build_strict();
1350
1351/// Number format to parse a `Coffeescript` float from string.
1352#[rustfmt::skip]
1353pub const COFFEESCRIPT_STRING: Options = Options::builder()
1354    .inf_string(options::COFFEESCRIPT_INF)
1355    .infinity_string(options::COFFEESCRIPT_INFINITY)
1356    .build_strict();
1357
1358/// Number format for a `COBOL` literal floating-point number.
1359#[rustfmt::skip]
1360pub const COBOL_LITERAL: Options = Options::builder()
1361    .nan_string(options::COBOL)
1362    .inf_string(options::COBOL)
1363    .infinity_string(options::COBOL)
1364    .build_strict();
1365
1366/// Number format to parse a `COBOL` float from string.
1367#[rustfmt::skip]
1368pub const COBOL_STRING: Options = Options::builder()
1369    .nan_string(options::COBOL)
1370    .inf_string(options::COBOL)
1371    .infinity_string(options::COBOL)
1372    .build_strict();
1373
1374/// Number format for an `F#` literal floating-point number.
1375#[rustfmt::skip]
1376pub const FSHARP_LITERAL: Options = Options::builder()
1377    .nan_string(options::FSHARP_LITERAL_NAN)
1378    .inf_string(options::FSHARP_LITERAL_INF)
1379    .infinity_string(options::FSHARP_LITERAL_INFINITY)
1380    .build_strict();
1381
1382/// Number format for a Visual Basic literal floating-point number.
1383#[rustfmt::skip]
1384pub const VB_LITERAL: Options = Options::builder()
1385    .nan_string(options::VB_LITERAL)
1386    .inf_string(options::VB_LITERAL)
1387    .infinity_string(options::VB_LITERAL)
1388    .build_strict();
1389
1390/// Number format to parse a `Visual Basic` float from string.
1391#[rustfmt::skip]
1392pub const VB_STRING: Options = Options::builder()
1393    .inf_string(options::VB_STRING_INF)
1394    .infinity_string(options::VB_STRING_INFINITY)
1395    .build_strict();
1396
1397/// Number format for an `OCaml` literal floating-point number.
1398#[rustfmt::skip]
1399pub const OCAML_LITERAL: Options = Options::builder()
1400    .nan_string(options::OCAML_LITERAL_NAN)
1401    .inf_string(options::OCAML_LITERAL_INF)
1402    .infinity_string(options::OCAML_LITERAL_INFINITY)
1403    .build_strict();
1404
1405/// Number format for an `Objective-C` literal floating-point number.
1406#[rustfmt::skip]
1407pub const OBJECTIVEC_LITERAL: Options = Options::builder()
1408    .nan_string(options::OBJECTIVEC)
1409    .inf_string(options::OBJECTIVEC)
1410    .infinity_string(options::OBJECTIVEC)
1411    .build_strict();
1412
1413/// Number format to parse an `Objective-C` float from string.
1414#[rustfmt::skip]
1415pub const OBJECTIVEC_STRING: Options = Options::builder()
1416    .nan_string(options::OBJECTIVEC)
1417    .inf_string(options::OBJECTIVEC)
1418    .infinity_string(options::OBJECTIVEC)
1419    .build_strict();
1420
1421/// Number format for an `ReasonML` literal floating-point number.
1422#[rustfmt::skip]
1423pub const REASONML_LITERAL: Options = Options::builder()
1424    .nan_string(options::REASONML_LITERAL_NAN)
1425    .inf_string(options::REASONML_LITERAL_INF)
1426    .infinity_string(options::REASONML_LITERAL_INFINITY)
1427    .build_strict();
1428
1429/// Number format for a `MATLAB` literal floating-point number.
1430#[rustfmt::skip]
1431pub const MATLAB_LITERAL: Options = Options::builder()
1432    .inf_string(options::MATLAB_LITERAL_INF)
1433    .infinity_string(options::MATLAB_LITERAL_INFINITY)
1434    .build_strict();
1435
1436/// Number format for a `Zig` literal floating-point number.
1437#[rustfmt::skip]
1438pub const ZIG_LITERAL: Options = Options::builder()
1439    .nan_string(options::ZIG_LITERAL)
1440    .inf_string(options::ZIG_LITERAL)
1441    .infinity_string(options::ZIG_LITERAL)
1442    .build_strict();
1443
1444/// Number format for a `Sage` literal floating-point number.
1445#[rustfmt::skip]
1446pub const SAGE_LITERAL: Options = Options::builder()
1447    .inf_string(options::SAGE_LITERAL_INF)
1448    .infinity_string(options::SAGE_LITERAL_INFINITY)
1449    .build_strict();
1450
1451/// Number format for a `JSON` literal floating-point number.
1452#[rustfmt::skip]
1453pub const JSON: Options = Options::builder()
1454    .nan_string(options::JSON)
1455    .inf_string(options::JSON)
1456    .infinity_string(options::JSON)
1457    .build_strict();
1458
1459/// Number format for a `TOML` literal floating-point number.
1460#[rustfmt::skip]
1461pub const TOML: Options = Options::builder()
1462    .nan_string(options::TOML)
1463    .inf_string(options::TOML)
1464    .infinity_string(options::TOML)
1465    .build_strict();
1466
1467/// Number format for a `YAML` literal floating-point number.
1468#[rustfmt::skip]
1469pub const YAML: Options = JSON;
1470
1471/// Number format for an `XML` literal floating-point number.
1472#[rustfmt::skip]
1473pub const XML: Options = Options::builder()
1474    .inf_string(options::XML_INF)
1475    .infinity_string(options::XML_INFINITY)
1476    .build_strict();
1477
1478/// Number format for a `SQLite` literal floating-point number.
1479#[rustfmt::skip]
1480pub const SQLITE: Options = Options::builder()
1481    .nan_string(options::SQLITE)
1482    .inf_string(options::SQLITE)
1483    .infinity_string(options::SQLITE)
1484    .build_strict();
1485
1486/// Number format for a `PostgreSQL` literal floating-point number.
1487#[rustfmt::skip]
1488pub const POSTGRESQL: Options = Options::builder()
1489    .nan_string(options::POSTGRESQL)
1490    .inf_string(options::POSTGRESQL)
1491    .infinity_string(options::POSTGRESQL)
1492    .build_strict();
1493
1494/// Number format for a `MySQL` literal floating-point number.
1495#[rustfmt::skip]
1496pub const MYSQL: Options = Options::builder()
1497    .nan_string(options::MYSQL)
1498    .inf_string(options::MYSQL)
1499    .infinity_string(options::MYSQL)
1500    .build_strict();
1501
1502/// Number format for a `MongoDB` literal floating-point number.
1503#[rustfmt::skip]
1504pub const MONGODB: Options = Options::builder()
1505    .inf_string(options::MONGODB_INF)
1506    .infinity_string(options::MONGODB_INFINITY)
1507    .build_strict();