lexical_parse_float/
options.rs

1//! Configuration options for parsing floats.
2
3#![allow(clippy::must_use_candidate)]
4
5use lexical_util::ascii::{is_valid_ascii, is_valid_letter_slice};
6use lexical_util::error::Error;
7use lexical_util::options::{self, ParseOptions};
8use lexical_util::result::Result;
9use static_assertions::const_assert;
10
11/// Maximum length for a special string.
12const MAX_SPECIAL_STRING_LENGTH: usize = 50;
13
14/// Builder for `Options`.
15#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
16pub struct OptionsBuilder {
17    /// Disable the use of arbitrary-precision arithmetic, and always
18    /// return the results from the fast or intermediate path algorithms.
19    lossy: bool,
20    /// Character to designate the exponent component of a float.
21    exponent: u8,
22    /// Character to separate the integer from the fraction components.
23    decimal_point: u8,
24    /// String representation of Not A Number, aka `NaN`.
25    nan_string: Option<&'static [u8]>,
26    /// Short string representation of `Infinity`.
27    inf_string: Option<&'static [u8]>,
28    /// Long string representation of `Infinity`.
29    infinity_string: Option<&'static [u8]>,
30}
31
32impl OptionsBuilder {
33    /// Create new options builder with default options.
34    #[inline(always)]
35    pub const fn new() -> Self {
36        Self {
37            lossy: false,
38            exponent: b'e',
39            decimal_point: b'.',
40            nan_string: Some(b"NaN"),
41            inf_string: Some(b"inf"),
42            infinity_string: Some(b"infinity"),
43        }
44    }
45
46    // GETTERS
47
48    /// Get if we disable the use of arbitrary-precision arithmetic.
49    #[inline(always)]
50    pub const fn get_lossy(&self) -> bool {
51        self.lossy
52    }
53
54    /// Get the character to designate the exponent component of a float.
55    #[inline(always)]
56    pub const fn get_exponent(&self) -> u8 {
57        self.exponent
58    }
59
60    /// Get the character to separate the integer from the fraction components.
61    #[inline(always)]
62    pub const fn get_decimal_point(&self) -> u8 {
63        self.decimal_point
64    }
65
66    /// Get the string representation for `NaN`.
67    #[inline(always)]
68    pub const fn get_nan_string(&self) -> Option<&'static [u8]> {
69        self.nan_string
70    }
71
72    /// Get the short string representation for `Infinity`.
73    #[inline(always)]
74    pub const fn get_inf_string(&self) -> Option<&'static [u8]> {
75        self.inf_string
76    }
77
78    /// Get the long string representation for `Infinity`.
79    #[inline(always)]
80    pub const fn get_infinity_string(&self) -> Option<&'static [u8]> {
81        self.infinity_string
82    }
83
84    // SETTERS
85
86    /// Set if we disable the use of arbitrary-precision arithmetic.
87    #[must_use]
88    #[inline(always)]
89    pub const fn lossy(mut self, lossy: bool) -> Self {
90        self.lossy = lossy;
91        self
92    }
93
94    /// Set the character to designate the exponent component of a float.
95    #[must_use]
96    #[inline(always)]
97    pub const fn exponent(mut self, exponent: u8) -> Self {
98        self.exponent = exponent;
99        self
100    }
101
102    /// Set the character to separate the integer from the fraction components.
103    #[must_use]
104    #[inline(always)]
105    pub const fn decimal_point(mut self, decimal_point: u8) -> Self {
106        self.decimal_point = decimal_point;
107        self
108    }
109
110    /// Set the string representation for `NaN`.
111    #[must_use]
112    #[inline(always)]
113    pub const fn nan_string(mut self, nan_string: Option<&'static [u8]>) -> Self {
114        self.nan_string = nan_string;
115        self
116    }
117
118    /// Set the short string representation for `Infinity`.
119    #[must_use]
120    #[inline(always)]
121    pub const fn inf_string(mut self, inf_string: Option<&'static [u8]>) -> Self {
122        self.inf_string = inf_string;
123        self
124    }
125
126    /// Set the long string representation for `Infinity`.
127    #[must_use]
128    #[inline(always)]
129    pub const fn infinity_string(mut self, infinity_string: Option<&'static [u8]>) -> Self {
130        self.infinity_string = infinity_string;
131        self
132    }
133
134    // BUILDERS
135
136    /// Determine if `nan_str` is valid.
137    #[inline(always)]
138    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
139    pub const fn nan_str_is_valid(&self) -> bool {
140        if self.nan_string.is_none() {
141            return true;
142        }
143
144        let nan = unwrap_str(self.nan_string);
145        let length = nan.len();
146        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
147            false
148        } else if !matches!(nan[0], b'N' | b'n') {
149            false
150        } else if !is_valid_letter_slice(nan) {
151            false
152        } else {
153            true
154        }
155    }
156
157    /// Determine if `inf_str` is valid.
158    #[inline(always)]
159    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
160    pub const fn inf_str_is_valid(&self) -> bool {
161        if self.infinity_string.is_none() && self.inf_string.is_some() {
162            return false;
163        } else if self.inf_string.is_none() {
164            return true;
165        }
166
167        let inf = unwrap_str(self.inf_string);
168        let length = inf.len();
169        let infinity = unwrap_str(self.infinity_string);
170        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
171            false
172        } else if !matches!(inf[0], b'I' | b'i') {
173            false
174        } else if length > infinity.len() {
175            false
176        } else if !is_valid_letter_slice(inf) {
177            false
178        } else {
179            true
180        }
181    }
182
183    /// Determine if `infinity_string` is valid.
184    #[inline(always)]
185    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
186    pub const fn infinity_string_is_valid(&self) -> bool {
187        if self.infinity_string.is_none() && self.inf_string.is_some() {
188            return false;
189        } else if self.infinity_string.is_none() {
190            return true;
191        }
192        let inf = unwrap_str(self.inf_string);
193        let infinity = unwrap_str(self.infinity_string);
194        let length = infinity.len();
195        if length == 0 || length > MAX_SPECIAL_STRING_LENGTH {
196            false
197        } else if !matches!(infinity[0], b'I' | b'i') {
198            false
199        } else if length < inf.len() {
200            false
201        } else if !is_valid_letter_slice(infinity) {
202            false
203        } else {
204            true
205        }
206    }
207
208    /// Check if the builder state is valid.
209    #[inline(always)]
210    #[allow(clippy::if_same_then_else, clippy::needless_bool)] // reason = "more idiomatic"
211    pub const fn is_valid(&self) -> bool {
212        if !is_valid_ascii(self.exponent) {
213            false
214        } else if !is_valid_ascii(self.decimal_point) {
215            false
216        } else if !self.nan_str_is_valid() {
217            false
218        } else if !self.inf_str_is_valid() {
219            false
220        } else if !self.infinity_string_is_valid() {
221            false
222        } else {
223            true
224        }
225    }
226
227    /// Build the Options struct without validation.
228    ///
229    /// # Panics
230    ///
231    /// This is completely safe, however, misusing this, especially
232    /// the `nan_string`, `inf_string`, and `infinity_string` could
233    /// panic at runtime. Always use [`MAX_SPECIAL_STRING_LENGTH`] and
234    /// check if [`Self::is_valid`] prior to using a created format string.
235    #[inline(always)]
236    pub const fn build_unchecked(&self) -> Options {
237        Options {
238            lossy: self.lossy,
239            exponent: self.exponent,
240            decimal_point: self.decimal_point,
241            nan_string: self.nan_string,
242            inf_string: self.inf_string,
243            infinity_string: self.infinity_string,
244        }
245    }
246
247    /// Build the Options struct.
248    ///
249    /// # Errors
250    ///
251    /// If the NaN, Inf, or Infinity strings are too long or invalid
252    /// digits/characters are provided for some numerical formats.
253    #[inline(always)]
254    #[allow(clippy::if_same_then_else)] // reason = "more idiomatic"
255    pub const fn build(&self) -> Result<Options> {
256        if !is_valid_ascii(self.exponent) {
257            return Err(Error::InvalidExponentSymbol);
258        } else if !is_valid_ascii(self.decimal_point) {
259            return Err(Error::InvalidDecimalPoint);
260        }
261
262        if self.nan_string.is_some() {
263            let nan = unwrap_str(self.nan_string);
264            if nan.is_empty() || !matches!(nan[0], b'N' | b'n') {
265                return Err(Error::InvalidNanString);
266            } else if !is_valid_letter_slice(nan) {
267                return Err(Error::InvalidNanString);
268            } else if nan.len() > MAX_SPECIAL_STRING_LENGTH {
269                return Err(Error::NanStringTooLong);
270            }
271        }
272
273        if self.inf_string.is_some() && self.infinity_string.is_none() {
274            return Err(Error::InfinityStringTooShort);
275        }
276
277        if self.inf_string.is_some() {
278            let inf = unwrap_str(self.inf_string);
279            if inf.is_empty() || !matches!(inf[0], b'I' | b'i') {
280                return Err(Error::InvalidInfString);
281            } else if !is_valid_letter_slice(inf) {
282                return Err(Error::InvalidInfString);
283            } else if inf.len() > MAX_SPECIAL_STRING_LENGTH {
284                return Err(Error::InfStringTooLong);
285            }
286        }
287
288        if self.infinity_string.is_some() {
289            let inf = unwrap_str(self.inf_string);
290            let infinity = unwrap_str(self.infinity_string);
291            if infinity.is_empty() || !matches!(infinity[0], b'I' | b'i') {
292                return Err(Error::InvalidInfinityString);
293            } else if !is_valid_letter_slice(infinity) {
294                return Err(Error::InvalidInfinityString);
295            } else if infinity.len() > MAX_SPECIAL_STRING_LENGTH {
296                return Err(Error::InfinityStringTooLong);
297            } else if infinity.len() < inf.len() {
298                return Err(Error::InfinityStringTooShort);
299            }
300        }
301
302        Ok(self.build_unchecked())
303    }
304}
305
306impl Default for OptionsBuilder {
307    #[inline(always)]
308    fn default() -> Self {
309        Self::new()
310    }
311}
312
313/// Options to customize parsing floats.
314///
315/// # Examples
316///
317/// ```rust
318/// use lexical_parse_float::Options;
319///
320/// # pub fn main() {
321/// let options = Options::builder()
322///     .lossy(true)
323///     .nan_string(Some(b"NaN"))
324///     .inf_string(Some(b"Inf"))
325///     .infinity_string(Some(b"Infinity"))
326///     .build()
327///     .unwrap();
328/// # }
329/// ```
330#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
331pub struct Options {
332    /// Disable the use of arbitrary-precision arithmetic, and always
333    /// return the results from the fast or intermediate path algorithms.
334    lossy: bool,
335    /// Character to designate the exponent component of a float.
336    exponent: u8,
337    /// Character to separate the integer from the fraction components.
338    decimal_point: u8,
339    /// String representation of Not A Number, aka `NaN`.
340    nan_string: Option<&'static [u8]>,
341    /// Short string representation of `Infinity`.
342    inf_string: Option<&'static [u8]>,
343    /// Long string representation of `Infinity`.
344    infinity_string: Option<&'static [u8]>,
345}
346
347impl Options {
348    // CONSTRUCTORS
349
350    /// Create options with default values.
351    #[inline(always)]
352    pub const fn new() -> Self {
353        Self::builder().build_unchecked()
354    }
355
356    /// Create the default options for a given radix.
357    #[inline(always)]
358    #[cfg(feature = "power-of-two")]
359    pub const fn from_radix(radix: u8) -> Self {
360        // Need to determine the correct exponent character ('e' or '^'),
361        // since the default character is `e` normally, but this is a valid
362        // digit for radix >= 15.
363        let mut builder = Self::builder();
364        if radix >= 15 {
365            builder = builder.exponent(b'^');
366        }
367        builder.build_unchecked()
368    }
369
370    // GETTERS
371
372    /// Check if the options state is valid.
373    #[inline(always)]
374    pub const fn is_valid(&self) -> bool {
375        self.rebuild().is_valid()
376    }
377
378    /// Get if we disable the use of arbitrary-precision arithmetic.
379    #[inline(always)]
380    pub const fn lossy(&self) -> bool {
381        self.lossy
382    }
383
384    /// Get the character to designate the exponent component of a float.
385    #[inline(always)]
386    pub const fn exponent(&self) -> u8 {
387        self.exponent
388    }
389
390    /// Get the character to separate the integer from the fraction components.
391    #[inline(always)]
392    pub const fn decimal_point(&self) -> u8 {
393        self.decimal_point
394    }
395
396    /// Get the string representation for `NaN`.
397    #[inline(always)]
398    pub const fn nan_string(&self) -> Option<&'static [u8]> {
399        self.nan_string
400    }
401
402    /// Get the short string representation for `Infinity`.
403    #[inline(always)]
404    pub const fn inf_string(&self) -> Option<&'static [u8]> {
405        self.inf_string
406    }
407
408    /// Get the long string representation for `Infinity`.
409    #[inline(always)]
410    pub const fn infinity_string(&self) -> Option<&'static [u8]> {
411        self.infinity_string
412    }
413
414    // SETTERS
415
416    /// Set if we disable the use of arbitrary-precision arithmetic.
417    #[inline(always)]
418    pub fn set_lossy(&mut self, lossy: bool) {
419        self.lossy = lossy;
420    }
421
422    /// Set the character to designate the exponent component of a float.
423    #[inline(always)]
424    pub fn set_exponent(&mut self, exponent: u8) {
425        self.exponent = exponent;
426    }
427
428    /// Set the character to separate the integer from the fraction components.
429    #[inline(always)]
430    pub fn set_decimal_point(&mut self, decimal_point: u8) {
431        self.decimal_point = decimal_point;
432    }
433
434    /// Set the string representation for `NaN`.
435    #[inline(always)]
436    pub fn set_nan_string(&mut self, nan_string: Option<&'static [u8]>) {
437        self.nan_string = nan_string;
438    }
439
440    /// Set the short string representation for `Infinity`
441    #[inline(always)]
442    pub fn set_inf_string(&mut self, inf_string: Option<&'static [u8]>) {
443        self.inf_string = inf_string;
444    }
445
446    /// Set the long string representation for `Infinity`
447    #[inline(always)]
448    pub fn set_infinity_string(&mut self, infinity_string: Option<&'static [u8]>) {
449        self.infinity_string = infinity_string;
450    }
451
452    // BUILDERS
453
454    /// Get `OptionsBuilder` as a static function.
455    #[must_use]
456    #[inline(always)]
457    pub const fn builder() -> OptionsBuilder {
458        OptionsBuilder::new()
459    }
460
461    /// Create `OptionsBuilder` using existing values.
462    #[must_use]
463    #[inline(always)]
464    pub const fn rebuild(&self) -> OptionsBuilder {
465        OptionsBuilder {
466            lossy: self.lossy,
467            exponent: self.exponent,
468            decimal_point: self.decimal_point,
469            nan_string: self.nan_string,
470            inf_string: self.inf_string,
471            infinity_string: self.infinity_string,
472        }
473    }
474}
475
476impl Default for Options {
477    #[inline(always)]
478    fn default() -> Self {
479        Self::new()
480    }
481}
482
483impl ParseOptions for Options {
484    #[inline(always)]
485    fn is_valid(&self) -> bool {
486        Self::is_valid(self)
487    }
488}
489
490/// Unwrap `Option` as a const fn.
491#[inline(always)]
492const fn unwrap_str(option: Option<&'static [u8]>) -> &'static [u8] {
493    match option {
494        Some(x) => x,
495        None => &[],
496    }
497}
498
499// PRE-DEFINED CONSTANTS
500// ---------------------
501
502// Only constants that differ from the standard version are included.
503
504/// Standard number format.
505#[rustfmt::skip]
506pub const STANDARD: Options = Options::new();
507const_assert!(STANDARD.is_valid());
508
509/// Numerical format with a decimal comma.
510/// This is the standard numerical format for most of the world.
511#[rustfmt::skip]
512pub const DECIMAL_COMMA: Options = Options::builder()
513        .decimal_point(b',')
514        .build_unchecked();
515const_assert!(DECIMAL_COMMA.is_valid());
516
517/// Numerical format for hexadecimal floats, which use a `p` exponent.
518#[rustfmt::skip]
519pub const HEX_FLOAT: Options = Options::builder()
520        .exponent(b'p')
521        .build_unchecked();
522const_assert!(HEX_FLOAT.is_valid());
523
524/// Numerical format where `^` is used as the exponent notation character.
525/// This isn't very common, but is useful when `e` or `p` are valid digits.
526#[rustfmt::skip]
527pub const CARAT_EXPONENT: Options = Options::builder()
528        .exponent(b'^')
529        .build_unchecked();
530const_assert!(CARAT_EXPONENT.is_valid());
531
532/// Number format for a `Rust` literal floating-point number.
533#[rustfmt::skip]
534pub const RUST_LITERAL: Options = Options::builder()
535        .nan_string(options::RUST_LITERAL)
536        .inf_string(options::RUST_LITERAL)
537        .infinity_string(options::RUST_LITERAL)
538        .build_unchecked();
539const_assert!(RUST_LITERAL.is_valid());
540
541/// Number format for a `Python` literal floating-point number.
542#[rustfmt::skip]
543pub const PYTHON_LITERAL: Options = Options::builder()
544        .nan_string(options::PYTHON_LITERAL)
545        .inf_string(options::PYTHON_LITERAL)
546        .infinity_string(options::PYTHON_LITERAL)
547        .build_unchecked();
548const_assert!(PYTHON_LITERAL.is_valid());
549
550/// Number format for a `C++` literal floating-point number.
551#[rustfmt::skip]
552pub const CXX_LITERAL: Options = Options::builder()
553        .nan_string(options::CXX_LITERAL_NAN)
554        .inf_string(options::CXX_LITERAL_INF)
555        .infinity_string(options::CXX_LITERAL_INFINITY)
556        .build_unchecked();
557const_assert!(CXX_LITERAL.is_valid());
558
559/// Number format for a `C` literal floating-point number.
560#[rustfmt::skip]
561pub const C_LITERAL: Options = Options::builder()
562        .nan_string(options::C_LITERAL_NAN)
563        .inf_string(options::C_LITERAL_INF)
564        .infinity_string(options::C_LITERAL_INFINITY)
565        .build_unchecked();
566const_assert!(CXX_LITERAL.is_valid());
567
568/// Number format for a `Ruby` literal floating-point number.
569#[rustfmt::skip]
570pub const RUBY_LITERAL: Options = Options::builder()
571        .nan_string(options::RUBY_LITERAL_NAN)
572        .inf_string(options::RUBY_LITERAL_INF)
573        .infinity_string(options::RUBY_LITERAL_INF)
574        .build_unchecked();
575const_assert!(RUBY_LITERAL.is_valid());
576
577/// Number format to parse a `Ruby` float from string.
578/// `Ruby` can write NaN and Infinity as strings, but won't round-trip them back to floats.
579#[rustfmt::skip]
580pub const RUBY_STRING: Options = Options::builder()
581        .nan_string(options::RUBY_STRING_NONE)
582        .inf_string(options::RUBY_STRING_NONE)
583        .infinity_string(options::RUBY_STRING_NONE)
584        .build_unchecked();
585const_assert!(RUBY_STRING.is_valid());
586
587/// Number format for a `Swift` literal floating-point number.
588#[rustfmt::skip]
589pub const SWIFT_LITERAL: Options = Options::builder()
590        .nan_string(options::SWIFT_LITERAL)
591        .inf_string(options::SWIFT_LITERAL)
592        .infinity_string(options::SWIFT_LITERAL)
593        .build_unchecked();
594const_assert!(SWIFT_LITERAL.is_valid());
595
596/// Number format for a `Go` literal floating-point number.
597#[rustfmt::skip]
598pub const GO_LITERAL: Options = Options::builder()
599        .nan_string(options::GO_LITERAL)
600        .inf_string(options::GO_LITERAL)
601        .infinity_string(options::GO_LITERAL)
602        .build_unchecked();
603const_assert!(GO_LITERAL.is_valid());
604
605/// Number format for a `Haskell` literal floating-point number.
606#[rustfmt::skip]
607pub const HASKELL_LITERAL: Options = Options::builder()
608        .nan_string(options::HASKELL_LITERAL)
609        .inf_string(options::HASKELL_LITERAL)
610        .infinity_string(options::HASKELL_LITERAL)
611        .build_unchecked();
612const_assert!(HASKELL_LITERAL.is_valid());
613
614/// Number format to parse a `Haskell` float from string.
615#[rustfmt::skip]
616pub const HASKELL_STRING: Options = Options::builder()
617        .inf_string(options::HASKELL_STRING_INF)
618        .infinity_string(options::HASKELL_STRING_INFINITY)
619        .build_unchecked();
620const_assert!(HASKELL_STRING.is_valid());
621
622/// Number format for a `Javascript` literal floating-point number.
623#[rustfmt::skip]
624pub const JAVASCRIPT_LITERAL: Options = Options::builder()
625        .inf_string(options::JAVASCRIPT_INF)
626        .infinity_string(options::JAVASCRIPT_INFINITY)
627        .build_unchecked();
628const_assert!(JAVASCRIPT_LITERAL.is_valid());
629
630/// Number format to parse a `Javascript` float from string.
631#[rustfmt::skip]
632pub const JAVASCRIPT_STRING: Options = Options::builder()
633        .inf_string(options::JAVASCRIPT_INF)
634        .infinity_string(options::JAVASCRIPT_INFINITY)
635        .build_unchecked();
636const_assert!(JAVASCRIPT_STRING.is_valid());
637
638/// Number format for a `Perl` literal floating-point number.
639#[rustfmt::skip]
640pub const PERL_LITERAL: Options = Options::builder()
641        .nan_string(options::PERL_LITERAL)
642        .inf_string(options::PERL_LITERAL)
643        .infinity_string(options::PERL_LITERAL)
644        .build_unchecked();
645const_assert!(PERL_LITERAL.is_valid());
646
647/// Number format for a `PHP` literal floating-point number.
648#[rustfmt::skip]
649pub const PHP_LITERAL: Options = Options::builder()
650        .nan_string(options::PHP_LITERAL_NAN)
651        .inf_string(options::PHP_LITERAL_INF)
652        .infinity_string(options::PHP_LITERAL_INFINITY)
653        .build_unchecked();
654const_assert!(PHP_LITERAL.is_valid());
655
656/// Number format for a `Java` literal floating-point number.
657#[rustfmt::skip]
658pub const JAVA_LITERAL: Options = Options::builder()
659        .nan_string(options::JAVA_LITERAL)
660        .inf_string(options::JAVA_LITERAL)
661        .infinity_string(options::JAVA_LITERAL)
662        .build_unchecked();
663const_assert!(JAVA_LITERAL.is_valid());
664
665/// Number format to parse a `Java` float from string.
666#[rustfmt::skip]
667pub const JAVA_STRING: Options = Options::builder()
668        .inf_string(options::JAVA_STRING_INF)
669        .infinity_string(options::JAVA_STRING_INFINITY)
670        .build_unchecked();
671const_assert!(JAVA_STRING.is_valid());
672
673/// Number format for an `R` literal floating-point number.
674#[rustfmt::skip]
675pub const R_LITERAL: Options = Options::builder()
676        .inf_string(options::R_LITERAL_INF)
677        .infinity_string(options::R_LITERAL_INFINITY)
678        .build_unchecked();
679const_assert!(R_LITERAL.is_valid());
680
681/// Number format for a `Kotlin` literal floating-point number.
682#[rustfmt::skip]
683pub const KOTLIN_LITERAL: Options = Options::builder()
684        .nan_string(options::KOTLIN_LITERAL)
685        .inf_string(options::KOTLIN_LITERAL)
686        .infinity_string(options::KOTLIN_LITERAL)
687        .build_unchecked();
688const_assert!(KOTLIN_LITERAL.is_valid());
689
690/// Number format to parse a `Kotlin` float from string.
691#[rustfmt::skip]
692pub const KOTLIN_STRING: Options = Options::builder()
693        .inf_string(options::KOTLIN_STRING_INF)
694        .infinity_string(options::KOTLIN_STRING_INFINITY)
695        .build_unchecked();
696const_assert!(KOTLIN_STRING.is_valid());
697
698/// Number format for a `Julia` literal floating-point number.
699#[rustfmt::skip]
700pub const JULIA_LITERAL: Options = Options::builder()
701        .inf_string(options::JULIA_LITERAL_INF)
702        .infinity_string(options::JULIA_LITERAL_INFINITY)
703        .build_unchecked();
704const_assert!(JULIA_LITERAL.is_valid());
705
706/// Number format for a `C#` literal floating-point number.
707#[rustfmt::skip]
708pub const CSHARP_LITERAL: Options = Options::builder()
709        .nan_string(options::CSHARP_LITERAL)
710        .inf_string(options::CSHARP_LITERAL)
711        .infinity_string(options::CSHARP_LITERAL)
712        .build_unchecked();
713const_assert!(CSHARP_LITERAL.is_valid());
714
715/// Number format to parse a `C#` float from string.
716#[rustfmt::skip]
717pub const CSHARP_STRING: Options = Options::builder()
718        .inf_string(options::CSHARP_STRING_INF)
719        .infinity_string(options::CSHARP_STRING_INFINITY)
720        .build_unchecked();
721const_assert!(CSHARP_STRING.is_valid());
722
723/// Number format for a `Kawa` literal floating-point number.
724#[rustfmt::skip]
725pub const KAWA_LITERAL: Options = Options::builder()
726        .nan_string(options::KAWA)
727        .inf_string(options::KAWA)
728        .infinity_string(options::KAWA)
729        .build_unchecked();
730const_assert!(KAWA_LITERAL.is_valid());
731
732/// Number format to parse a `Kawa` float from string.
733#[rustfmt::skip]
734pub const KAWA_STRING: Options = Options::builder()
735        .nan_string(options::KAWA)
736        .inf_string(options::KAWA)
737        .infinity_string(options::KAWA)
738        .build_unchecked();
739const_assert!(KAWA_STRING.is_valid());
740
741/// Number format for a `Gambit-C` literal floating-point number.
742#[rustfmt::skip]
743pub const GAMBITC_LITERAL: Options = Options::builder()
744        .nan_string(options::GAMBITC)
745        .inf_string(options::GAMBITC)
746        .infinity_string(options::GAMBITC)
747        .build_unchecked();
748const_assert!(GAMBITC_LITERAL.is_valid());
749
750/// Number format to parse a `Gambit-C` float from string.
751#[rustfmt::skip]
752pub const GAMBITC_STRING: Options = Options::builder()
753        .nan_string(options::GAMBITC)
754        .inf_string(options::GAMBITC)
755        .infinity_string(options::GAMBITC)
756        .build_unchecked();
757const_assert!(GAMBITC_STRING.is_valid());
758
759/// Number format for a `Guile` literal floating-point number.
760#[rustfmt::skip]
761pub const GUILE_LITERAL: Options = Options::builder()
762        .nan_string(options::GUILE)
763        .inf_string(options::GUILE)
764        .infinity_string(options::GUILE)
765        .build_unchecked();
766const_assert!(GUILE_LITERAL.is_valid());
767
768/// Number format to parse a `Guile` float from string.
769#[rustfmt::skip]
770pub const GUILE_STRING: Options = Options::builder()
771        .nan_string(options::GUILE)
772        .inf_string(options::GUILE)
773        .infinity_string(options::GUILE)
774        .build_unchecked();
775const_assert!(GUILE_STRING.is_valid());
776
777/// Number format for a `Clojure` literal floating-point number.
778#[rustfmt::skip]
779pub const CLOJURE_LITERAL: Options = Options::builder()
780        .nan_string(options::CLOJURE_LITERAL)
781        .inf_string(options::CLOJURE_LITERAL)
782        .infinity_string(options::CLOJURE_LITERAL)
783        .build_unchecked();
784const_assert!(CLOJURE_LITERAL.is_valid());
785
786/// Number format to parse a `Clojure` float from string.
787#[rustfmt::skip]
788pub const CLOJURE_STRING: Options = Options::builder()
789        .inf_string(options::CLOJURE_STRING_INF)
790        .infinity_string(options::CLOJURE_STRING_INFINITY)
791        .build_unchecked();
792const_assert!(CLOJURE_STRING.is_valid());
793
794/// Number format for an `Erlang` literal floating-point number.
795#[rustfmt::skip]
796pub const ERLANG_LITERAL: Options = Options::builder()
797        .nan_string(options::ERLANG_LITERAL_NAN)
798        .build_unchecked();
799const_assert!(ERLANG_LITERAL.is_valid());
800
801/// Number format to parse an `Erlang` float from string.
802#[rustfmt::skip]
803pub const ERLANG_STRING: Options = Options::builder()
804        .nan_string(options::ERLANG_STRING)
805        .inf_string(options::ERLANG_STRING)
806        .infinity_string(options::ERLANG_STRING)
807        .build_unchecked();
808const_assert!(ERLANG_STRING.is_valid());
809
810/// Number format for an `Elm` literal floating-point number.
811#[rustfmt::skip]
812pub const ELM_LITERAL: Options = Options::builder()
813        .nan_string(options::ELM_LITERAL)
814        .inf_string(options::ELM_LITERAL)
815        .infinity_string(options::ELM_LITERAL)
816        .build_unchecked();
817const_assert!(ELM_LITERAL.is_valid());
818
819/// Number format to parse an `Elm` float from string.
820#[rustfmt::skip]
821pub const ELM_STRING: Options = Options::builder()
822        .nan_string(options::ELM_STRING_NAN)
823        .inf_string(options::ELM_STRING_INF)
824        .infinity_string(options::ELM_STRING_INFINITY)
825        .build_unchecked();
826const_assert!(ELM_STRING.is_valid());
827
828/// Number format for a `Scala` literal floating-point number.
829#[rustfmt::skip]
830pub const SCALA_LITERAL: Options = Options::builder()
831        .nan_string(options::SCALA_LITERAL)
832        .inf_string(options::SCALA_LITERAL)
833        .infinity_string(options::SCALA_LITERAL)
834        .build_unchecked();
835const_assert!(SCALA_LITERAL.is_valid());
836
837/// Number format to parse a `Scala` float from string.
838#[rustfmt::skip]
839pub const SCALA_STRING: Options = Options::builder()
840        .inf_string(options::SCALA_STRING_INF)
841        .infinity_string(options::SCALA_STRING_INFINITY)
842        .build_unchecked();
843const_assert!(SCALA_STRING.is_valid());
844
845/// Number format for an `Elixir` literal floating-point number.
846#[rustfmt::skip]
847pub const ELIXIR_LITERAL: Options = Options::builder()
848        .nan_string(options::ELIXIR)
849        .inf_string(options::ELIXIR)
850        .infinity_string(options::ELIXIR)
851        .build_unchecked();
852const_assert!(ELIXIR_LITERAL.is_valid());
853
854/// Number format to parse an `Elixir` float from string.
855#[rustfmt::skip]
856pub const ELIXIR_STRING: Options = Options::builder()
857        .nan_string(options::ELIXIR)
858        .inf_string(options::ELIXIR)
859        .infinity_string(options::ELIXIR)
860        .build_unchecked();
861const_assert!(ELIXIR_STRING.is_valid());
862
863/// Number format for a `FORTRAN` literal floating-point number.
864#[rustfmt::skip]
865pub const FORTRAN_LITERAL: Options = Options::builder()
866        .nan_string(options::FORTRAN_LITERAL)
867        .inf_string(options::FORTRAN_LITERAL)
868        .infinity_string(options::FORTRAN_LITERAL)
869        .build_unchecked();
870const_assert!(FORTRAN_LITERAL.is_valid());
871
872/// Number format for a `D` literal floating-point number.
873#[rustfmt::skip]
874pub const D_LITERAL: Options = Options::builder()
875        .nan_string(options::D_LITERAL)
876        .inf_string(options::D_LITERAL)
877        .infinity_string(options::D_LITERAL)
878        .build_unchecked();
879const_assert!(D_LITERAL.is_valid());
880
881/// Number format for a `Coffeescript` literal floating-point number.
882#[rustfmt::skip]
883pub const COFFEESCRIPT_LITERAL: Options = Options::builder()
884        .inf_string(options::COFFEESCRIPT_INF)
885        .infinity_string(options::COFFEESCRIPT_INFINITY)
886        .build_unchecked();
887const_assert!(COFFEESCRIPT_LITERAL.is_valid());
888
889/// Number format to parse a `Coffeescript` float from string.
890#[rustfmt::skip]
891pub const COFFEESCRIPT_STRING: Options = Options::builder()
892        .inf_string(options::COFFEESCRIPT_INF)
893        .infinity_string(options::COFFEESCRIPT_INFINITY)
894        .build_unchecked();
895const_assert!(COFFEESCRIPT_STRING.is_valid());
896
897/// Number format for a `COBOL` literal floating-point number.
898#[rustfmt::skip]
899pub const COBOL_LITERAL: Options = Options::builder()
900        .nan_string(options::COBOL)
901        .inf_string(options::COBOL)
902        .infinity_string(options::COBOL)
903        .build_unchecked();
904const_assert!(COBOL_LITERAL.is_valid());
905
906/// Number format to parse a `COBOL` float from string.
907#[rustfmt::skip]
908pub const COBOL_STRING: Options = Options::builder()
909        .nan_string(options::COBOL)
910        .inf_string(options::COBOL)
911        .infinity_string(options::COBOL)
912        .build_unchecked();
913const_assert!(COBOL_STRING.is_valid());
914
915/// Number format for an `F#` literal floating-point number.
916#[rustfmt::skip]
917pub const FSHARP_LITERAL: Options = Options::builder()
918        .nan_string(options::FSHARP_LITERAL_NAN)
919        .inf_string(options::FSHARP_LITERAL_INF)
920        .infinity_string(options::FSHARP_LITERAL_INFINITY)
921        .build_unchecked();
922const_assert!(FSHARP_LITERAL.is_valid());
923
924/// Number format for a Visual Basic literal floating-point number.
925#[rustfmt::skip]
926pub const VB_LITERAL: Options = Options::builder()
927        .nan_string(options::VB_LITERAL)
928        .inf_string(options::VB_LITERAL)
929        .infinity_string(options::VB_LITERAL)
930        .build_unchecked();
931const_assert!(VB_LITERAL.is_valid());
932
933/// Number format to parse a `Visual Basic` float from string.
934#[rustfmt::skip]
935pub const VB_STRING: Options = Options::builder()
936        .inf_string(options::VB_STRING_INF)
937        .infinity_string(options::VB_STRING_INFINITY)
938        .build_unchecked();
939const_assert!(VB_STRING.is_valid());
940
941/// Number format for an `OCaml` literal floating-point number.
942#[rustfmt::skip]
943pub const OCAML_LITERAL: Options = Options::builder()
944        .nan_string(options::OCAML_LITERAL_NAN)
945        .inf_string(options::OCAML_LITERAL_INF)
946        .infinity_string(options::OCAML_LITERAL_INFINITY)
947        .build_unchecked();
948const_assert!(OCAML_LITERAL.is_valid());
949
950/// Number format for an `Objective-C` literal floating-point number.
951#[rustfmt::skip]
952pub const OBJECTIVEC_LITERAL: Options = Options::builder()
953        .nan_string(options::OBJECTIVEC)
954        .inf_string(options::OBJECTIVEC)
955        .infinity_string(options::OBJECTIVEC)
956        .build_unchecked();
957const_assert!(OBJECTIVEC_LITERAL.is_valid());
958
959/// Number format to parse an `Objective-C` float from string.
960#[rustfmt::skip]
961pub const OBJECTIVEC_STRING: Options = Options::builder()
962        .nan_string(options::OBJECTIVEC)
963        .inf_string(options::OBJECTIVEC)
964        .infinity_string(options::OBJECTIVEC)
965        .build_unchecked();
966const_assert!(OBJECTIVEC_STRING.is_valid());
967
968/// Number format for an `ReasonML` literal floating-point number.
969#[rustfmt::skip]
970pub const REASONML_LITERAL: Options = Options::builder()
971        .nan_string(options::REASONML_LITERAL_NAN)
972        .inf_string(options::REASONML_LITERAL_INF)
973        .infinity_string(options::REASONML_LITERAL_INFINITY)
974        .build_unchecked();
975const_assert!(REASONML_LITERAL.is_valid());
976
977/// Number format for a `MATLAB` literal floating-point number.
978#[rustfmt::skip]
979pub const MATLAB_LITERAL: Options = Options::builder()
980        .inf_string(options::MATLAB_LITERAL_INF)
981        .infinity_string(options::MATLAB_LITERAL_INFINITY)
982        .build_unchecked();
983const_assert!(MATLAB_LITERAL.is_valid());
984
985/// Number format for a `Zig` literal floating-point number.
986#[rustfmt::skip]
987pub const ZIG_LITERAL: Options = Options::builder()
988        .nan_string(options::ZIG_LITERAL)
989        .inf_string(options::ZIG_LITERAL)
990        .infinity_string(options::ZIG_LITERAL)
991        .build_unchecked();
992const_assert!(ZIG_LITERAL.is_valid());
993
994/// Number format for a `Sage` literal floating-point number.
995#[rustfmt::skip]
996pub const SAGE_LITERAL: Options = Options::builder()
997        .inf_string(options::SAGE_LITERAL_INF)
998        .infinity_string(options::SAGE_LITERAL_INFINITY)
999        .build_unchecked();
1000const_assert!(SAGE_LITERAL.is_valid());
1001
1002/// Number format for a `JSON` literal floating-point number.
1003#[rustfmt::skip]
1004pub const JSON: Options = Options::builder()
1005        .nan_string(options::JSON)
1006        .inf_string(options::JSON)
1007        .infinity_string(options::JSON)
1008        .build_unchecked();
1009const_assert!(JSON.is_valid());
1010
1011/// Number format for a `TOML` literal floating-point number.
1012#[rustfmt::skip]
1013pub const TOML: Options = Options::builder()
1014        .nan_string(options::TOML)
1015        .inf_string(options::TOML)
1016        .infinity_string(options::TOML)
1017        .build_unchecked();
1018const_assert!(TOML.is_valid());
1019
1020/// Number format for a `YAML` literal floating-point number.
1021#[rustfmt::skip]
1022pub const YAML: Options = JSON;
1023
1024/// Number format for an `XML` literal floating-point number.
1025#[rustfmt::skip]
1026pub const XML: Options = Options::builder()
1027        .inf_string(options::XML_INF)
1028        .infinity_string(options::XML_INFINITY)
1029        .build_unchecked();
1030const_assert!(XML.is_valid());
1031
1032/// Number format for a `SQLite` literal floating-point number.
1033#[rustfmt::skip]
1034pub const SQLITE: Options = Options::builder()
1035        .nan_string(options::SQLITE)
1036        .inf_string(options::SQLITE)
1037        .infinity_string(options::SQLITE)
1038        .build_unchecked();
1039const_assert!(SQLITE.is_valid());
1040
1041/// Number format for a `PostgreSQL` literal floating-point number.
1042#[rustfmt::skip]
1043pub const POSTGRESQL: Options = Options::builder()
1044        .nan_string(options::POSTGRESQL)
1045        .inf_string(options::POSTGRESQL)
1046        .infinity_string(options::POSTGRESQL)
1047        .build_unchecked();
1048const_assert!(POSTGRESQL.is_valid());
1049
1050/// Number format for a `MySQL` literal floating-point number.
1051#[rustfmt::skip]
1052pub const MYSQL: Options = Options::builder()
1053        .nan_string(options::MYSQL)
1054        .inf_string(options::MYSQL)
1055        .infinity_string(options::MYSQL)
1056        .build_unchecked();
1057const_assert!(MYSQL.is_valid());
1058
1059/// Number format for a `MongoDB` literal floating-point number.
1060#[rustfmt::skip]
1061pub const MONGODB: Options = Options::builder()
1062        .inf_string(options::MONGODB_INF)
1063        .infinity_string(options::MONGODB_INFINITY)
1064        .build_unchecked();
1065const_assert!(MONGODB.is_valid());