Coverage Report

Created: 2025-11-24 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rust-lexical/lexical-parse-float/src/options.rs
Line
Count
Source
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
190
use lexical_util::ascii::{is_valid_ascii, is_valid_letter_slice};
191
use lexical_util::error::Error;
192
use lexical_util::options::{self, ParseOptions};
193
use lexical_util::result::Result;
194
195
/// Maximum length for a special string.
196
pub 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)]
218
pub 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
234
impl OptionsBuilder {
235
    /// Create new options builder with default options.
236
    #[inline(always)]
237
0
    pub const fn new() -> Self {
238
0
        Self {
239
0
            lossy: false,
240
0
            exponent: b'e',
241
0
            decimal_point: b'.',
242
0
            nan_string: Some(b"NaN"),
243
0
            inf_string: Some(b"inf"),
244
0
            infinity_string: Some(b"infinity"),
245
0
        }
246
0
    }
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
0
    pub const fn get_lossy(&self) -> bool {
264
0
        self.lossy
265
0
    }
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
0
    pub const fn get_exponent(&self) -> u8 {
281
0
        self.exponent
282
0
    }
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
0
    pub const fn get_decimal_point(&self) -> u8 {
298
0
        self.decimal_point
299
0
    }
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
0
    pub const fn get_nan_string(&self) -> Option<&'static [u8]> {
316
0
        self.nan_string
317
0
    }
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
0
    pub const fn get_inf_string(&self) -> Option<&'static [u8]> {
334
0
        self.inf_string
335
0
    }
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
0
    pub const fn get_infinity_string(&self) -> Option<&'static [u8]> {
354
0
        self.infinity_string
355
0
    }
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
0
    pub const fn lossy(mut self, lossy: bool) -> Self {
377
0
        self.lossy = lossy;
378
0
        self
379
0
    }
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
0
    pub const fn exponent(mut self, exponent: u8) -> Self {
399
0
        self.exponent = exponent;
400
0
        self
401
0
    }
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
0
    pub const fn decimal_point(mut self, decimal_point: u8) -> Self {
421
0
        self.decimal_point = decimal_point;
422
0
        self
423
0
    }
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
0
    pub const fn nan_string(mut self, nan_string: Option<&'static [u8]>) -> Self {
453
0
        self.nan_string = nan_string;
454
0
        self
455
0
    }
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
0
    pub const fn inf_string(mut self, inf_string: Option<&'static [u8]>) -> Self {
487
0
        self.inf_string = inf_string;
488
0
        self
489
0
    }
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
0
    pub const fn infinity_string(mut self, infinity_string: Option<&'static [u8]>) -> Self {
521
0
        self.infinity_string = infinity_string;
522
0
        self
523
0
    }
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
0
    pub const fn nan_str_is_valid(&self) -> bool {
534
0
        if self.nan_string.is_none() {
535
0
            return true;
536
0
        }
537
538
0
        let nan = unwrap_str(self.nan_string);
539
0
        let length = nan.len();
540
0
        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
541
0
            false
542
0
        } else if !matches!(nan[0], b'N' | b'n') {
543
0
            false
544
0
        } else if !is_valid_letter_slice(nan) {
545
0
            false
546
        } else {
547
0
            true
548
        }
549
0
    }
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
0
    pub const fn inf_str_is_valid(&self) -> bool {
558
0
        if self.infinity_string.is_none() && self.inf_string.is_some() {
559
0
            return false;
560
0
        } else if self.inf_string.is_none() {
561
0
            return true;
562
0
        }
563
564
0
        let inf = unwrap_str(self.inf_string);
565
0
        let length = inf.len();
566
0
        let infinity = unwrap_str(self.infinity_string);
567
0
        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
568
0
            false
569
0
        } else if !matches!(inf[0], b'I' | b'i') {
570
0
            false
571
0
        } else if length > infinity.len() {
572
0
            false
573
0
        } else if !is_valid_letter_slice(inf) {
574
0
            false
575
        } else {
576
0
            true
577
        }
578
0
    }
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
0
    pub const fn infinity_string_is_valid(&self) -> bool {
587
0
        if self.infinity_string.is_none() && self.inf_string.is_some() {
588
0
            return false;
589
0
        } else if self.infinity_string.is_none() {
590
0
            return true;
591
0
        }
592
0
        let inf = unwrap_str(self.inf_string);
593
0
        let infinity = unwrap_str(self.infinity_string);
594
0
        let length = infinity.len();
595
0
        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
596
0
            false
597
0
        } else if !matches!(infinity[0], b'I' | b'i') {
598
0
            false
599
0
        } else if length < inf.len() {
600
0
            false
601
0
        } else if !is_valid_letter_slice(infinity) {
602
0
            false
603
        } else {
604
0
            true
605
        }
606
0
    }
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
0
    pub const fn is_valid(&self) -> bool {
612
0
        if !is_valid_ascii(self.exponent) {
613
0
            false
614
0
        } else if !is_valid_ascii(self.decimal_point) {
615
0
            false
616
0
        } else if !self.nan_str_is_valid() {
617
0
            false
618
0
        } else if !self.inf_str_is_valid() {
619
0
            false
620
0
        } else if !self.infinity_string_is_valid() {
621
0
            false
622
        } else {
623
0
            true
624
        }
625
0
    }
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
0
    pub const fn build_unchecked(&self) -> Options {
642
0
        Options {
643
0
            lossy: self.lossy,
644
0
            exponent: self.exponent,
645
0
            decimal_point: self.decimal_point,
646
0
            nan_string: self.nan_string,
647
0
            inf_string: self.inf_string,
648
0
            infinity_string: self.infinity_string,
649
0
        }
650
0
    }
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
0
    pub const fn build_strict(&self) -> Options {
660
0
        match self.build() {
661
0
            Ok(value) => value,
662
0
            Err(error) => core::panic!("{}", error.description()),
663
        }
664
0
    }
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
0
    pub const fn build(&self) -> Result<Options> {
675
0
        if !is_valid_ascii(self.exponent) {
676
0
            return Err(Error::InvalidExponentSymbol);
677
0
        } else if !is_valid_ascii(self.decimal_point) {
678
0
            return Err(Error::InvalidDecimalPoint);
679
0
        }
680
681
0
        if self.nan_string.is_some() {
682
0
            let nan = unwrap_str(self.nan_string);
683
0
            if nan.is_empty() || !matches!(nan[0], b'N' | b'n') {
684
0
                return Err(Error::InvalidNanString);
685
0
            } else if !is_valid_letter_slice(nan) {
686
0
                return Err(Error::InvalidNanString);
687
0
            } else if nan.len() > MAX_SPECIAL_STRING_LENGTH {
688
0
                return Err(Error::NanStringTooLong);
689
0
            }
690
0
        }
691
692
0
        if self.inf_string.is_some() && self.infinity_string.is_none() {
693
0
            return Err(Error::InfinityStringTooShort);
694
0
        }
695
696
0
        if self.inf_string.is_some() {
697
0
            let inf = unwrap_str(self.inf_string);
698
0
            if inf.is_empty() || !matches!(inf[0], b'I' | b'i') {
699
0
                return Err(Error::InvalidInfString);
700
0
            } else if !is_valid_letter_slice(inf) {
701
0
                return Err(Error::InvalidInfString);
702
0
            } else if inf.len() > MAX_SPECIAL_STRING_LENGTH {
703
0
                return Err(Error::InfStringTooLong);
704
0
            }
705
0
        }
706
707
0
        if self.infinity_string.is_some() {
708
0
            let inf = unwrap_str(self.inf_string);
709
0
            let infinity = unwrap_str(self.infinity_string);
710
0
            if infinity.is_empty() || !matches!(infinity[0], b'I' | b'i') {
711
0
                return Err(Error::InvalidInfinityString);
712
0
            } else if !is_valid_letter_slice(infinity) {
713
0
                return Err(Error::InvalidInfinityString);
714
0
            } else if infinity.len() > MAX_SPECIAL_STRING_LENGTH {
715
0
                return Err(Error::InfinityStringTooLong);
716
0
            } else if infinity.len() < inf.len() {
717
0
                return Err(Error::InfinityStringTooShort);
718
0
            }
719
0
        }
720
721
0
        Ok(self.build_unchecked())
722
0
    }
723
}
724
725
impl Default for OptionsBuilder {
726
    #[inline(always)]
727
0
    fn default() -> Self {
728
0
        Self::new()
729
0
    }
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)]
760
pub 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
776
impl Options {
777
    // CONSTRUCTORS
778
779
    /// Create options with default values.
780
    #[inline(always)]
781
0
    pub const fn new() -> Self {
782
0
        Self::builder().build_unchecked()
783
0
    }
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
0
    pub const fn is_valid(&self) -> bool {
807
0
        self.rebuild().is_valid()
808
0
    }
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
4.40k
    pub const fn lossy(&self) -> bool {
824
4.40k
        self.lossy
825
4.40k
    }
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
5.00k
    pub const fn exponent(&self) -> u8 {
841
5.00k
        self.exponent
842
5.00k
    }
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
5.00k
    pub const fn decimal_point(&self) -> u8 {
858
5.00k
        self.decimal_point
859
5.00k
    }
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
243
    pub const fn nan_string(&self) -> Option<&'static [u8]> {
876
243
        self.nan_string
877
243
    }
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
243
    pub const fn inf_string(&self) -> Option<&'static [u8]> {
894
243
        self.inf_string
895
243
    }
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
243
    pub const fn infinity_string(&self) -> Option<&'static [u8]> {
912
243
        self.infinity_string
913
243
    }
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
0
    pub fn set_lossy(&mut self, lossy: bool) {
921
0
        self.lossy = lossy;
922
0
    }
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
0
    pub fn set_exponent(&mut self, exponent: u8) {
928
0
        self.exponent = exponent;
929
0
    }
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
0
    pub fn set_decimal_point(&mut self, decimal_point: u8) {
935
0
        self.decimal_point = decimal_point;
936
0
    }
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
0
    pub fn set_nan_string(&mut self, nan_string: Option<&'static [u8]>) {
942
0
        self.nan_string = nan_string;
943
0
    }
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
0
    pub fn set_inf_string(&mut self, inf_string: Option<&'static [u8]>) {
949
0
        self.inf_string = inf_string;
950
0
    }
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
0
    pub fn set_infinity_string(&mut self, infinity_string: Option<&'static [u8]>) {
956
0
        self.infinity_string = infinity_string;
957
0
    }
958
959
    // BUILDERS
960
961
    /// Get [`OptionsBuilder`] as a static function.
962
    #[must_use]
963
    #[inline(always)]
964
0
    pub const fn builder() -> OptionsBuilder {
965
0
        OptionsBuilder::new()
966
0
    }
967
968
    /// Create [`OptionsBuilder`] using existing values.
969
    #[must_use]
970
    #[inline(always)]
971
0
    pub const fn rebuild(&self) -> OptionsBuilder {
972
0
        OptionsBuilder {
973
0
            lossy: self.lossy,
974
0
            exponent: self.exponent,
975
0
            decimal_point: self.decimal_point,
976
0
            nan_string: self.nan_string,
977
0
            inf_string: self.inf_string,
978
0
            infinity_string: self.infinity_string,
979
0
        }
980
0
    }
981
}
982
983
impl Default for Options {
984
    #[inline(always)]
985
0
    fn default() -> Self {
986
0
        Self::new()
987
0
    }
988
}
989
990
impl ParseOptions for Options {
991
    #[inline(always)]
992
0
    fn is_valid(&self) -> bool {
993
0
        Self::is_valid(self)
994
0
    }
995
}
996
997
/// Unwrap `Option` as a const fn.
998
#[inline(always)]
999
0
const fn unwrap_str(option: Option<&'static [u8]>) -> &'static [u8] {
1000
0
    match option {
1001
0
        Some(x) => x,
1002
0
        None => &[],
1003
    }
1004
0
}
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]
1013
pub 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]
1018
pub 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]
1024
pub 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]
1031
pub 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]
1037
pub 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]
1045
pub 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]
1053
pub 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]
1061
pub 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]
1069
pub 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]
1078
pub 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]
1086
pub 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]
1094
pub 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]
1102
pub 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]
1110
pub 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]
1117
pub 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]
1124
pub 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]
1131
pub 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]
1139
pub 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]
1147
pub 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]
1155
pub 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]
1162
pub 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]
1169
pub 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]
1177
pub 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]
1184
pub 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]
1191
pub 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]
1199
pub 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]
1206
pub 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]
1214
pub 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]
1222
pub 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]
1230
pub 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]
1238
pub 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]
1246
pub 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]
1254
pub 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]
1262
pub 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]
1269
pub 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]
1275
pub 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]
1283
pub 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]
1291
pub 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]
1299
pub 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]
1307
pub 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]
1314
pub 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]
1322
pub 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]
1330
pub 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]
1338
pub 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]
1346
pub 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]
1353
pub 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]
1360
pub 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]
1368
pub 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]
1376
pub 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]
1384
pub 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]
1392
pub 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]
1399
pub 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]
1407
pub 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]
1415
pub 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]
1423
pub 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]
1431
pub 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]
1438
pub 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]
1446
pub 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]
1453
pub 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]
1461
pub 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]
1469
pub const YAML: Options = JSON;
1470
1471
/// Number format for an `XML` literal floating-point number.
1472
#[rustfmt::skip]
1473
pub 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]
1480
pub 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]
1488
pub 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]
1496
pub 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]
1504
pub const MONGODB: Options = Options::builder()
1505
    .inf_string(options::MONGODB_INF)
1506
    .infinity_string(options::MONGODB_INFINITY)
1507
    .build_strict();