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();