lexical_util/
format_builder.rs

1//! Builder for the number format.
2
3use crate::format_flags as flags;
4use core::{mem, num};
5use static_assertions::const_assert;
6
7/// Type with the exact same size as a `u8`.
8pub type OptionU8 = Option<num::NonZeroU8>;
9
10// Ensure the sizes are identical.
11const_assert!(mem::size_of::<OptionU8>() == mem::size_of::<u8>());
12
13/// Add single flag to SyntaxFormat.
14macro_rules! add_flag {
15    ($format:ident, $bool:expr, $flag:ident) => {
16        if $bool {
17            $format |= flags::$flag;
18        }
19    };
20}
21
22/// Add multiple flags to SyntaxFormat.
23macro_rules! add_flags {
24    ($format:ident ; $($bool:expr, $flag:ident ;)*) => {{
25        $(add_flag!($format, $bool, $flag);)*
26    }};
27}
28
29/// Determine if a flag is set in the format.
30macro_rules! has_flag {
31    ($format:ident, $flag:ident) => {
32        $format & flags::$flag != 0
33    };
34}
35
36/// Unwrap `Option` as a const fn.
37#[inline(always)]
38const fn unwrap_or_zero(option: OptionU8) -> u8 {
39    match option {
40        Some(x) => x.get(),
41        None => 0,
42    }
43}
44
45/// Build number format from specifications.
46///
47/// Returns the format on calling build if it was able to compile the format,
48/// otherwise, returns None.
49///
50/// # Fields
51///
52/// * `digit_separator`                         - Character to separate digits.
53/// * `mantissa_radix`                          - Radix for mantissa digits.
54/// * `exponent_base`                           - Base for the exponent.
55/// * `exponent_radix`                          - Radix for the exponent digits.
56/// * `base_prefix`                             - Optional character for the base prefix.
57/// * `base_suffix`                             - Optional character for the base suffix.
58/// * `required_integer_digits`                 - If digits are required before the decimal point.
59/// * `required_fraction_digits`                - If digits are required after the decimal point.
60/// * `required_exponent_digits`                - If digits are required after the exponent character.
61/// * `required_mantissa_digits`                - If at least 1 significant digit is required.
62/// * `no_positive_mantissa_sign`               - If positive sign before the mantissa is not allowed.
63/// * `required_mantissa_sign`                  - If positive sign before the mantissa is required.
64/// * `no_exponent_notation`                    - If exponent notation is not allowed.
65/// * `no_positive_exponent_sign`               - If positive sign before the exponent is not allowed.
66/// * `required_exponent_sign`                  - If sign before the exponent is required.
67/// * `no_exponent_without_fraction`            - If exponent without fraction is not allowed.
68/// * `no_special`                              - If special (non-finite) values are not allowed.
69/// * `case_sensitive_special`                  - If special (non-finite) values are case-sensitive.
70/// * `no_integer_leading_zeros`                - If leading zeros before an integer are not allowed.
71/// * `no_float_leading_zeros`                  - If leading zeros before a float are not allowed.
72/// * `required_exponent_notation`              - If exponent notation is required.
73/// * `case_sensitive_exponent`                 - If exponent characters are case-sensitive.
74/// * `case_sensitive_base_prefix`              - If base prefixes are case-sensitive.
75/// * `case_sensitive_base_suffix`              - If base suffixes are case-sensitive.
76/// * `integer_internal_digit_separator`        - If digit separators are allowed between integer digits.
77/// * `fraction_internal_digit_separator`       - If digit separators are allowed between fraction digits.
78/// * `exponent_internal_digit_separator`       - If digit separators are allowed between exponent digits.
79/// * `integer_leading_digit_separator`         - If a digit separator is allowed before any integer digits.
80/// * `fraction_leading_digit_separator`        - If a digit separator is allowed before any fraction digits.
81/// * `exponent_leading_digit_separator`        - If a digit separator is allowed before any exponent digits.
82/// * `integer_trailing_digit_separator`        - If a digit separator is allowed after any integer digits.
83/// * `fraction_trailing_digit_separator`       - If a digit separator is allowed after any fraction digits.
84/// * `exponent_trailing_digit_separator`       - If a digit separator is allowed after any exponent digits.
85/// * `integer_consecutive_digit_separator`     - If multiple consecutive integer digit separators are allowed.
86/// * `fraction_consecutive_digit_separator`    - If multiple consecutive fraction digit separators are allowed.
87/// * `special_digit_separator`                 - If any digit separators are allowed in special (non-finite) values.
88///
89/// # Write Integer Fields
90///
91/// No fields are used for writing integers.
92///
93/// # Parse Integer Fields
94///
95/// These fields are used for parsing integers:
96///
97/// * `digit_separator`
98/// * `mantissa_radix`
99/// * `base_prefix`
100/// * `base_suffix`
101/// * `no_positive_mantissa_sign`
102/// * `required_mantissa_sign`
103/// * `no_integer_leading_zeros`
104/// * `integer_internal_digit_separator`
105/// * `integer_leading_digit_separator`
106/// * `integer_trailing_digit_separator`
107/// * `integer_consecutive_digit_separator`
108///
109/// # Write Float Fields
110///
111/// These fields are used for writing floats:
112///
113/// * `mantissa_radix`
114/// * `exponent_base`
115/// * `exponent_radix`
116/// * `no_positive_mantissa_sign`
117/// * `required_mantissa_sign`
118/// * `no_exponent_notation`
119/// * `no_positive_exponent_sign`
120/// * `required_exponent_sign`
121/// * `required_exponent_notation`
122///
123/// # Parse Float Fields
124///
125/// These fields are used for parsing floats:
126///
127/// * `digit_separator`
128/// * `mantissa_radix`
129/// * `exponent_base`
130/// * `exponent_radix`
131/// * `base_prefix`
132/// * `base_suffix`
133/// * `required_integer_digits`
134/// * `required_fraction_digits`
135/// * `required_exponent_digits`
136/// * `no_positive_mantissa_sign`
137/// * `required_mantissa_sign`
138/// * `no_exponent_notation`
139/// * `no_positive_exponent_sign`
140/// * `required_exponent_sign`
141/// * `no_exponent_without_fraction`
142/// * `no_special`
143/// * `case_sensitive_special`
144/// * `no_integer_leading_zeros`
145/// * `no_float_leading_zeros`
146/// * `required_exponent_notation`
147/// * `case_sensitive_exponent`
148/// * `case_sensitive_base_prefix`
149/// * `case_sensitive_base_suffix`
150/// * `integer_internal_digit_separator`
151/// * `fraction_internal_digit_separator`
152/// * `exponent_internal_digit_separator`
153/// * `integer_leading_digit_separator`
154/// * `fraction_leading_digit_separator`
155/// * `exponent_leading_digit_separator`
156/// * `integer_trailing_digit_separator`
157/// * `fraction_trailing_digit_separator`
158/// * `exponent_trailing_digit_separator`
159/// * `integer_consecutive_digit_separator`
160/// * `fraction_consecutive_digit_separator`
161/// * `special_digit_separator`
162pub struct NumberFormatBuilder {
163    digit_separator: OptionU8,
164    base_prefix: OptionU8,
165    base_suffix: OptionU8,
166    mantissa_radix: u8,
167    exponent_base: OptionU8,
168    exponent_radix: OptionU8,
169    required_integer_digits: bool,
170    required_fraction_digits: bool,
171    required_exponent_digits: bool,
172    required_mantissa_digits: bool,
173    no_positive_mantissa_sign: bool,
174    required_mantissa_sign: bool,
175    no_exponent_notation: bool,
176    no_positive_exponent_sign: bool,
177    required_exponent_sign: bool,
178    no_exponent_without_fraction: bool,
179    no_special: bool,
180    case_sensitive_special: bool,
181    no_integer_leading_zeros: bool,
182    no_float_leading_zeros: bool,
183    required_exponent_notation: bool,
184    case_sensitive_exponent: bool,
185    case_sensitive_base_prefix: bool,
186    case_sensitive_base_suffix: bool,
187    integer_internal_digit_separator: bool,
188    fraction_internal_digit_separator: bool,
189    exponent_internal_digit_separator: bool,
190    integer_leading_digit_separator: bool,
191    fraction_leading_digit_separator: bool,
192    exponent_leading_digit_separator: bool,
193    integer_trailing_digit_separator: bool,
194    fraction_trailing_digit_separator: bool,
195    exponent_trailing_digit_separator: bool,
196    integer_consecutive_digit_separator: bool,
197    fraction_consecutive_digit_separator: bool,
198    exponent_consecutive_digit_separator: bool,
199    special_digit_separator: bool,
200}
201
202impl NumberFormatBuilder {
203    // CONSTRUCTORS
204
205    /// Create new NumberFormatBuilder with default arguments.
206    #[inline(always)]
207    pub const fn new() -> Self {
208        Self {
209            digit_separator: None,
210            base_prefix: None,
211            base_suffix: None,
212            mantissa_radix: 10,
213            exponent_base: None,
214            exponent_radix: None,
215            required_integer_digits: false,
216            required_fraction_digits: false,
217            required_exponent_digits: true,
218            required_mantissa_digits: true,
219            no_positive_mantissa_sign: false,
220            required_mantissa_sign: false,
221            no_exponent_notation: false,
222            no_positive_exponent_sign: false,
223            required_exponent_sign: false,
224            no_exponent_without_fraction: false,
225            no_special: false,
226            case_sensitive_special: false,
227            no_integer_leading_zeros: false,
228            no_float_leading_zeros: false,
229            required_exponent_notation: false,
230            case_sensitive_exponent: false,
231            case_sensitive_base_prefix: false,
232            case_sensitive_base_suffix: false,
233            integer_internal_digit_separator: false,
234            fraction_internal_digit_separator: false,
235            exponent_internal_digit_separator: false,
236            integer_leading_digit_separator: false,
237            fraction_leading_digit_separator: false,
238            exponent_leading_digit_separator: false,
239            integer_trailing_digit_separator: false,
240            fraction_trailing_digit_separator: false,
241            exponent_trailing_digit_separator: false,
242            integer_consecutive_digit_separator: false,
243            fraction_consecutive_digit_separator: false,
244            exponent_consecutive_digit_separator: false,
245            special_digit_separator: false,
246        }
247    }
248
249    /// Create number format for standard, binary number.
250    #[cfg(feature = "power-of-two")]
251    pub const fn binary() -> u128 {
252        Self::from_radix(2)
253    }
254
255    /// Create number format for standard, octal number.
256    #[cfg(feature = "power-of-two")]
257    pub const fn octal() -> u128 {
258        Self::from_radix(8)
259    }
260
261    /// Create number format for standard, decimal number.
262    pub const fn decimal() -> u128 {
263        let mut builder = Self::new();
264        builder.mantissa_radix = 10;
265        builder.exponent_base = num::NonZeroU8::new(10);
266        builder.exponent_radix = num::NonZeroU8::new(10);
267        builder.build()
268    }
269
270    /// Create number format for standard, hexadecimal number.
271    #[cfg(feature = "power-of-two")]
272    pub const fn hexadecimal() -> u128 {
273        Self::from_radix(16)
274    }
275
276    /// Create number format from radix.
277    #[cfg(feature = "power-of-two")]
278    pub const fn from_radix(radix: u8) -> u128 {
279        Self::new()
280            .radix(radix)
281            .exponent_base(num::NonZeroU8::new(radix))
282            .exponent_radix(num::NonZeroU8::new(radix))
283            .build()
284    }
285
286    // GETTERS
287
288    /// Get the digit separator for the number format.
289    #[inline(always)]
290    pub const fn get_digit_separator(&self) -> OptionU8 {
291        self.digit_separator
292    }
293
294    /// Get the radix for mantissa digits.
295    #[inline(always)]
296    pub const fn get_mantissa_radix(&self) -> u8 {
297        self.mantissa_radix
298    }
299
300    /// Get the radix for the exponent.
301    #[inline(always)]
302    pub const fn get_exponent_base(&self) -> OptionU8 {
303        self.exponent_base
304    }
305
306    /// Get the radix for exponent digits.
307    #[inline(always)]
308    pub const fn get_exponent_radix(&self) -> OptionU8 {
309        self.exponent_radix
310    }
311
312    /// Get the optional character for the base prefix.
313    #[inline(always)]
314    pub const fn get_base_prefix(&self) -> OptionU8 {
315        self.base_prefix
316    }
317
318    /// Get the optional character for the base suffix.
319    #[inline(always)]
320    pub const fn get_base_suffix(&self) -> OptionU8 {
321        self.base_suffix
322    }
323
324    /// Get if digits are required before the decimal point.
325    #[inline(always)]
326    pub const fn get_required_integer_digits(&self) -> bool {
327        self.required_integer_digits
328    }
329
330    /// Get if digits are required after the decimal point.
331    #[inline(always)]
332    pub const fn get_required_fraction_digits(&self) -> bool {
333        self.required_fraction_digits
334    }
335
336    /// Get if digits are required after the exponent character.
337    #[inline(always)]
338    pub const fn get_required_exponent_digits(&self) -> bool {
339        self.required_exponent_digits
340    }
341
342    /// Get if at least 1 significant digit is required.
343    #[inline(always)]
344    pub const fn get_required_mantissa_digits(&self) -> bool {
345        self.required_mantissa_digits
346    }
347
348    /// Get if a positive sign before the mantissa is not allowed.
349    #[inline(always)]
350    pub const fn get_no_positive_mantissa_sign(&self) -> bool {
351        self.no_positive_mantissa_sign
352    }
353
354    /// Get if a sign symbol before the mantissa is required.
355    #[inline(always)]
356    pub const fn get_required_mantissa_sign(&self) -> bool {
357        self.required_mantissa_sign
358    }
359
360    /// Get if exponent notation is not allowed.
361    #[inline(always)]
362    pub const fn get_no_exponent_notation(&self) -> bool {
363        self.no_exponent_notation
364    }
365
366    /// Get if a positive sign before the exponent is not allowed.
367    #[inline(always)]
368    pub const fn get_no_positive_exponent_sign(&self) -> bool {
369        self.no_positive_exponent_sign
370    }
371
372    /// Get if a sign symbol before the exponent is required.
373    #[inline(always)]
374    pub const fn get_required_exponent_sign(&self) -> bool {
375        self.required_exponent_sign
376    }
377
378    /// Get if an exponent without fraction is not allowed.
379    #[inline(always)]
380    pub const fn get_no_exponent_without_fraction(&self) -> bool {
381        self.no_exponent_without_fraction
382    }
383
384    /// Get if special (non-finite) values are not allowed.
385    #[inline(always)]
386    pub const fn get_no_special(&self) -> bool {
387        self.no_special
388    }
389
390    /// Get if special (non-finite) values are case-sensitive.
391    #[inline(always)]
392    pub const fn get_case_sensitive_special(&self) -> bool {
393        self.case_sensitive_special
394    }
395
396    /// Get if leading zeros before an integer are not allowed.
397    #[inline(always)]
398    pub const fn get_no_integer_leading_zeros(&self) -> bool {
399        self.no_integer_leading_zeros
400    }
401
402    /// Get if leading zeros before a float are not allowed.
403    #[inline(always)]
404    pub const fn get_no_float_leading_zeros(&self) -> bool {
405        self.no_float_leading_zeros
406    }
407
408    /// Get if exponent notation is required.
409    #[inline(always)]
410    pub const fn get_required_exponent_notation(&self) -> bool {
411        self.required_exponent_notation
412    }
413
414    /// Get if exponent characters are case-sensitive.
415    #[inline(always)]
416    pub const fn get_case_sensitive_exponent(&self) -> bool {
417        self.case_sensitive_exponent
418    }
419
420    /// Get if base prefixes are case-sensitive.
421    #[inline(always)]
422    pub const fn get_case_sensitive_base_prefix(&self) -> bool {
423        self.case_sensitive_base_prefix
424    }
425
426    /// Get if base suffixes are case-sensitive.
427    #[inline(always)]
428    pub const fn get_case_sensitive_base_suffix(&self) -> bool {
429        self.case_sensitive_base_suffix
430    }
431
432    /// Get if digit separators are allowed between integer digits.
433    #[inline(always)]
434    pub const fn get_integer_internal_digit_separator(&self) -> bool {
435        self.integer_internal_digit_separator
436    }
437
438    /// Get if digit separators are allowed between fraction digits.
439    #[inline(always)]
440    pub const fn get_fraction_internal_digit_separator(&self) -> bool {
441        self.fraction_internal_digit_separator
442    }
443
444    /// Get if digit separators are allowed between exponent digits.
445    #[inline(always)]
446    pub const fn get_exponent_internal_digit_separator(&self) -> bool {
447        self.exponent_internal_digit_separator
448    }
449
450    /// Get if a digit separator is allowed before any integer digits.
451    #[inline(always)]
452    pub const fn get_integer_leading_digit_separator(&self) -> bool {
453        self.integer_leading_digit_separator
454    }
455
456    /// Get if a digit separator is allowed before any fraction digits.
457    #[inline(always)]
458    pub const fn get_fraction_leading_digit_separator(&self) -> bool {
459        self.fraction_leading_digit_separator
460    }
461
462    /// Get if a digit separator is allowed before any exponent digits.
463    #[inline(always)]
464    pub const fn get_exponent_leading_digit_separator(&self) -> bool {
465        self.exponent_leading_digit_separator
466    }
467
468    /// Get if a digit separator is allowed after any integer digits.
469    #[inline(always)]
470    pub const fn get_integer_trailing_digit_separator(&self) -> bool {
471        self.integer_trailing_digit_separator
472    }
473
474    /// Get if a digit separator is allowed after any fraction digits.
475    #[inline(always)]
476    pub const fn get_fraction_trailing_digit_separator(&self) -> bool {
477        self.fraction_trailing_digit_separator
478    }
479
480    /// Get if a digit separator is allowed after any exponent digits.
481    #[inline(always)]
482    pub const fn get_exponent_trailing_digit_separator(&self) -> bool {
483        self.exponent_trailing_digit_separator
484    }
485
486    /// Get if multiple consecutive integer digit separators are allowed.
487    #[inline(always)]
488    pub const fn get_integer_consecutive_digit_separator(&self) -> bool {
489        self.integer_consecutive_digit_separator
490    }
491
492    /// Get if multiple consecutive fraction digit separators are allowed.
493    #[inline(always)]
494    pub const fn get_fraction_consecutive_digit_separator(&self) -> bool {
495        self.fraction_consecutive_digit_separator
496    }
497
498    /// Get if multiple consecutive exponent digit separators are allowed.
499    #[inline(always)]
500    pub const fn get_exponent_consecutive_digit_separator(&self) -> bool {
501        self.exponent_consecutive_digit_separator
502    }
503
504    /// Get if any digit separators are allowed in special (non-finite) values.
505    #[inline(always)]
506    pub const fn get_special_digit_separator(&self) -> bool {
507        self.special_digit_separator
508    }
509
510    // SETTERS
511
512    /// Set the digit separator for the number format.
513    #[inline(always)]
514    #[cfg(feature = "format")]
515    pub const fn digit_separator(mut self, character: OptionU8) -> Self {
516        self.digit_separator = character;
517        self
518    }
519
520    /// Alias for mantissa radix.
521    #[inline(always)]
522    #[cfg(feature = "power-of-two")]
523    pub const fn radix(self, radix: u8) -> Self {
524        self.mantissa_radix(radix)
525    }
526
527    /// Set the radix for mantissa digits.
528    #[inline(always)]
529    #[cfg(feature = "power-of-two")]
530    pub const fn mantissa_radix(mut self, radix: u8) -> Self {
531        self.mantissa_radix = radix;
532        self
533    }
534
535    /// Set the radix for the exponent.
536    #[inline(always)]
537    #[cfg(feature = "power-of-two")]
538    pub const fn exponent_base(mut self, base: OptionU8) -> Self {
539        self.exponent_base = base;
540        self
541    }
542
543    /// Set the radix for exponent digits.
544    #[inline(always)]
545    #[cfg(feature = "power-of-two")]
546    pub const fn exponent_radix(mut self, radix: OptionU8) -> Self {
547        self.exponent_radix = radix;
548        self
549    }
550
551    /// Set the optional character for the base prefix.
552    #[inline(always)]
553    #[cfg(all(feature = "power-of-two", feature = "format"))]
554    pub const fn base_prefix(mut self, base_prefix: OptionU8) -> Self {
555        self.base_prefix = base_prefix;
556        self
557    }
558
559    /// Set the optional character for the base suffix.
560    #[inline(always)]
561    #[cfg(all(feature = "power-of-two", feature = "format"))]
562    pub const fn base_suffix(mut self, base_suffix: OptionU8) -> Self {
563        self.base_suffix = base_suffix;
564        self
565    }
566
567    /// Set if digits are required before the decimal point.
568    #[inline(always)]
569    #[cfg(feature = "format")]
570    pub const fn required_integer_digits(mut self, flag: bool) -> Self {
571        self.required_integer_digits = flag;
572        self
573    }
574
575    /// Set if digits are required after the decimal point.
576    #[inline(always)]
577    #[cfg(feature = "format")]
578    pub const fn required_fraction_digits(mut self, flag: bool) -> Self {
579        self.required_fraction_digits = flag;
580        self
581    }
582
583    /// Set if digits are required after the exponent character.
584    #[inline(always)]
585    #[cfg(feature = "format")]
586    pub const fn required_exponent_digits(mut self, flag: bool) -> Self {
587        self.required_exponent_digits = flag;
588        self
589    }
590
591    /// Set if at least 1 significant digit is required.
592    #[inline(always)]
593    #[cfg(feature = "format")]
594    pub const fn required_mantissa_digits(mut self, flag: bool) -> Self {
595        self.required_mantissa_digits = flag;
596        self
597    }
598
599    /// Set if digits are required for all float components.
600    #[inline(always)]
601    #[cfg(feature = "format")]
602    pub const fn required_digits(mut self, flag: bool) -> Self {
603        self = self.required_integer_digits(flag);
604        self = self.required_fraction_digits(flag);
605        self = self.required_exponent_digits(flag);
606        self = self.required_mantissa_digits(flag);
607        self
608    }
609
610    /// Set if a positive sign before the mantissa is not allowed.
611    #[inline(always)]
612    #[cfg(feature = "format")]
613    pub const fn no_positive_mantissa_sign(mut self, flag: bool) -> Self {
614        self.no_positive_mantissa_sign = flag;
615        self
616    }
617
618    /// Set if a sign symbol before the mantissa is required.
619    #[inline(always)]
620    #[cfg(feature = "format")]
621    pub const fn required_mantissa_sign(mut self, flag: bool) -> Self {
622        self.required_mantissa_sign = flag;
623        self
624    }
625
626    /// Set if exponent notation is not allowed.
627    #[inline(always)]
628    #[cfg(feature = "format")]
629    pub const fn no_exponent_notation(mut self, flag: bool) -> Self {
630        self.no_exponent_notation = flag;
631        self
632    }
633
634    /// Set if a positive sign before the exponent is not allowed.
635    #[inline(always)]
636    #[cfg(feature = "format")]
637    pub const fn no_positive_exponent_sign(mut self, flag: bool) -> Self {
638        self.no_positive_exponent_sign = flag;
639        self
640    }
641
642    /// Set if a sign symbol before the exponent is required.
643    #[inline(always)]
644    #[cfg(feature = "format")]
645    pub const fn required_exponent_sign(mut self, flag: bool) -> Self {
646        self.required_exponent_sign = flag;
647        self
648    }
649
650    /// Set if an exponent without fraction is not allowed.
651    #[inline(always)]
652    #[cfg(feature = "format")]
653    pub const fn no_exponent_without_fraction(mut self, flag: bool) -> Self {
654        self.no_exponent_without_fraction = flag;
655        self
656    }
657
658    /// Set if special (non-finite) values are not allowed.
659    #[inline(always)]
660    #[cfg(feature = "format")]
661    pub const fn no_special(mut self, flag: bool) -> Self {
662        self.no_special = flag;
663        self
664    }
665
666    /// Set if special (non-finite) values are case-sensitive.
667    #[inline(always)]
668    #[cfg(feature = "format")]
669    pub const fn case_sensitive_special(mut self, flag: bool) -> Self {
670        self.case_sensitive_special = flag;
671        self
672    }
673
674    /// Set if leading zeros before an integer are not allowed.
675    #[inline(always)]
676    #[cfg(feature = "format")]
677    pub const fn no_integer_leading_zeros(mut self, flag: bool) -> Self {
678        self.no_integer_leading_zeros = flag;
679        self
680    }
681
682    /// Set if leading zeros before a float are not allowed.
683    #[inline(always)]
684    #[cfg(feature = "format")]
685    pub const fn no_float_leading_zeros(mut self, flag: bool) -> Self {
686        self.no_float_leading_zeros = flag;
687        self
688    }
689
690    /// Set if exponent notation is required.
691    #[inline(always)]
692    #[cfg(feature = "format")]
693    pub const fn required_exponent_notation(mut self, flag: bool) -> Self {
694        self.required_exponent_notation = flag;
695        self
696    }
697
698    /// Set if exponent characters are case-sensitive.
699    #[inline(always)]
700    #[cfg(feature = "format")]
701    pub const fn case_sensitive_exponent(mut self, flag: bool) -> Self {
702        self.case_sensitive_exponent = flag;
703        self
704    }
705
706    /// Set if base prefixes are case-sensitive.
707    #[inline(always)]
708    #[cfg(all(feature = "power-of-two", feature = "format"))]
709    pub const fn case_sensitive_base_prefix(mut self, flag: bool) -> Self {
710        self.case_sensitive_base_prefix = flag;
711        self
712    }
713
714    /// Set if base suffixes are case-sensitive.
715    #[inline(always)]
716    #[cfg(all(feature = "power-of-two", feature = "format"))]
717    pub const fn case_sensitive_base_suffix(mut self, flag: bool) -> Self {
718        self.case_sensitive_base_suffix = flag;
719        self
720    }
721
722    /// Set if digit separators are allowed between integer digits.
723    #[inline(always)]
724    #[cfg(feature = "format")]
725    pub const fn integer_internal_digit_separator(mut self, flag: bool) -> Self {
726        self.integer_internal_digit_separator = flag;
727        self
728    }
729
730    /// Set if digit separators are allowed between fraction digits.
731    #[inline(always)]
732    #[cfg(feature = "format")]
733    pub const fn fraction_internal_digit_separator(mut self, flag: bool) -> Self {
734        self.fraction_internal_digit_separator = flag;
735        self
736    }
737
738    /// Set if digit separators are allowed between exponent digits.
739    #[inline(always)]
740    #[cfg(feature = "format")]
741    pub const fn exponent_internal_digit_separator(mut self, flag: bool) -> Self {
742        self.exponent_internal_digit_separator = flag;
743        self
744    }
745
746    /// Set all internal digit separator flags.
747    #[inline(always)]
748    #[cfg(feature = "format")]
749    pub const fn internal_digit_separator(mut self, flag: bool) -> Self {
750        self = self.integer_internal_digit_separator(flag);
751        self = self.fraction_internal_digit_separator(flag);
752        self = self.exponent_internal_digit_separator(flag);
753        self
754    }
755
756    /// Set if a digit separator is allowed before any integer digits.
757    #[inline(always)]
758    #[cfg(feature = "format")]
759    pub const fn integer_leading_digit_separator(mut self, flag: bool) -> Self {
760        self.integer_leading_digit_separator = flag;
761        self
762    }
763
764    /// Set if a digit separator is allowed before any fraction digits.
765    #[inline(always)]
766    #[cfg(feature = "format")]
767    pub const fn fraction_leading_digit_separator(mut self, flag: bool) -> Self {
768        self.fraction_leading_digit_separator = flag;
769        self
770    }
771
772    /// Set if a digit separator is allowed before any exponent digits.
773    #[inline(always)]
774    #[cfg(feature = "format")]
775    pub const fn exponent_leading_digit_separator(mut self, flag: bool) -> Self {
776        self.exponent_leading_digit_separator = flag;
777        self
778    }
779
780    /// Set all leading digit separator flags.
781    #[inline(always)]
782    #[cfg(feature = "format")]
783    pub const fn leading_digit_separator(mut self, flag: bool) -> Self {
784        self = self.integer_leading_digit_separator(flag);
785        self = self.fraction_leading_digit_separator(flag);
786        self = self.exponent_leading_digit_separator(flag);
787        self
788    }
789
790    /// Set if a digit separator is allowed after any integer digits.
791    #[inline(always)]
792    #[cfg(feature = "format")]
793    pub const fn integer_trailing_digit_separator(mut self, flag: bool) -> Self {
794        self.integer_trailing_digit_separator = flag;
795        self
796    }
797
798    /// Set if a digit separator is allowed after any fraction digits.
799    #[inline(always)]
800    #[cfg(feature = "format")]
801    pub const fn fraction_trailing_digit_separator(mut self, flag: bool) -> Self {
802        self.fraction_trailing_digit_separator = flag;
803        self
804    }
805
806    /// Set if a digit separator is allowed after any exponent digits.
807    #[inline(always)]
808    #[cfg(feature = "format")]
809    pub const fn exponent_trailing_digit_separator(mut self, flag: bool) -> Self {
810        self.exponent_trailing_digit_separator = flag;
811        self
812    }
813
814    /// Set all trailing digit separator flags.
815    #[inline(always)]
816    #[cfg(feature = "format")]
817    pub const fn trailing_digit_separator(mut self, flag: bool) -> Self {
818        self = self.integer_trailing_digit_separator(flag);
819        self = self.fraction_trailing_digit_separator(flag);
820        self = self.exponent_trailing_digit_separator(flag);
821        self
822    }
823
824    /// Set if multiple consecutive integer digit separators are allowed.
825    #[inline(always)]
826    #[cfg(feature = "format")]
827    pub const fn integer_consecutive_digit_separator(mut self, flag: bool) -> Self {
828        self.integer_consecutive_digit_separator = flag;
829        self
830    }
831
832    /// Set if multiple consecutive fraction digit separators are allowed.
833    #[inline(always)]
834    #[cfg(feature = "format")]
835    pub const fn fraction_consecutive_digit_separator(mut self, flag: bool) -> Self {
836        self.fraction_consecutive_digit_separator = flag;
837        self
838    }
839
840    /// Set if multiple consecutive exponent digit separators are allowed.
841    #[inline(always)]
842    #[cfg(feature = "format")]
843    pub const fn exponent_consecutive_digit_separator(mut self, flag: bool) -> Self {
844        self.exponent_consecutive_digit_separator = flag;
845        self
846    }
847
848    /// Set all consecutive digit separator flags.
849    #[inline(always)]
850    #[cfg(feature = "format")]
851    pub const fn consecutive_digit_separator(mut self, flag: bool) -> Self {
852        self = self.integer_consecutive_digit_separator(flag);
853        self = self.fraction_consecutive_digit_separator(flag);
854        self = self.exponent_consecutive_digit_separator(flag);
855        self
856    }
857
858    /// Set if any digit separators are allowed in special (non-finite) values.
859    #[inline(always)]
860    #[cfg(feature = "format")]
861    pub const fn special_digit_separator(mut self, flag: bool) -> Self {
862        self.special_digit_separator = flag;
863        self
864    }
865
866    /// Set all digit separator flag masks.
867    #[inline(always)]
868    #[cfg(feature = "format")]
869    pub const fn digit_separator_flags(mut self, flag: bool) -> Self {
870        self = self.integer_digit_separator_flags(flag);
871        self = self.fraction_digit_separator_flags(flag);
872        self = self.exponent_digit_separator_flags(flag);
873        self = self.special_digit_separator(flag);
874        self
875    }
876
877    /// Set all integer digit separator flag masks.
878    #[inline(always)]
879    #[cfg(feature = "format")]
880    pub const fn integer_digit_separator_flags(mut self, flag: bool) -> Self {
881        self = self.integer_internal_digit_separator(flag);
882        self = self.integer_leading_digit_separator(flag);
883        self = self.integer_trailing_digit_separator(flag);
884        self = self.integer_consecutive_digit_separator(flag);
885        self
886    }
887
888    /// Set all fraction digit separator flag masks.
889    #[inline(always)]
890    #[cfg(feature = "format")]
891    pub const fn fraction_digit_separator_flags(mut self, flag: bool) -> Self {
892        self = self.fraction_internal_digit_separator(flag);
893        self = self.fraction_leading_digit_separator(flag);
894        self = self.fraction_trailing_digit_separator(flag);
895        self = self.fraction_consecutive_digit_separator(flag);
896        self
897    }
898
899    /// Set all exponent digit separator flag masks.
900    #[inline(always)]
901    #[cfg(feature = "format")]
902    pub const fn exponent_digit_separator_flags(mut self, flag: bool) -> Self {
903        self = self.exponent_internal_digit_separator(flag);
904        self = self.exponent_leading_digit_separator(flag);
905        self = self.exponent_trailing_digit_separator(flag);
906        self = self.exponent_consecutive_digit_separator(flag);
907        self
908    }
909
910    // BUILDER
911
912    /// Create 128-bit, packed number format struct from builder options.
913    ///
914    /// NOTE: This function will never fail, due to issues with panicking
915    /// (and therefore unwrapping Errors/Options) in const fns. It is
916    /// therefore up to you to ensure the format is valid, called via the
917    /// `is_valid` function on `NumberFormat`.
918    #[inline]
919    pub const fn build(&self) -> u128 {
920        let mut format: u128 = 0;
921        add_flags!(
922            format ;
923            self.required_integer_digits, REQUIRED_INTEGER_DIGITS ;
924            self.required_fraction_digits, REQUIRED_FRACTION_DIGITS ;
925            self.required_exponent_digits, REQUIRED_EXPONENT_DIGITS ;
926            self.required_mantissa_digits, REQUIRED_MANTISSA_DIGITS ;
927            self.no_positive_mantissa_sign, NO_POSITIVE_MANTISSA_SIGN ;
928            self.required_mantissa_sign, REQUIRED_MANTISSA_SIGN ;
929            self.no_exponent_notation, NO_EXPONENT_NOTATION ;
930            self.no_positive_exponent_sign, NO_POSITIVE_EXPONENT_SIGN ;
931            self.required_exponent_sign, REQUIRED_EXPONENT_SIGN ;
932            self.no_exponent_without_fraction, NO_EXPONENT_WITHOUT_FRACTION ;
933            self.no_special, NO_SPECIAL ;
934            self.case_sensitive_special, CASE_SENSITIVE_SPECIAL ;
935            self.no_integer_leading_zeros, NO_INTEGER_LEADING_ZEROS ;
936            self.no_float_leading_zeros, NO_FLOAT_LEADING_ZEROS ;
937            self.required_exponent_notation, REQUIRED_EXPONENT_NOTATION ;
938            self.case_sensitive_exponent, CASE_SENSITIVE_EXPONENT ;
939            self.case_sensitive_base_prefix, CASE_SENSITIVE_BASE_PREFIX ;
940            self.case_sensitive_base_suffix, CASE_SENSITIVE_BASE_SUFFIX ;
941            self.integer_internal_digit_separator, INTEGER_INTERNAL_DIGIT_SEPARATOR ;
942            self.fraction_internal_digit_separator, FRACTION_INTERNAL_DIGIT_SEPARATOR ;
943            self.exponent_internal_digit_separator, EXPONENT_INTERNAL_DIGIT_SEPARATOR ;
944            self.integer_leading_digit_separator, INTEGER_LEADING_DIGIT_SEPARATOR ;
945            self.fraction_leading_digit_separator, FRACTION_LEADING_DIGIT_SEPARATOR ;
946            self.exponent_leading_digit_separator, EXPONENT_LEADING_DIGIT_SEPARATOR ;
947            self.integer_trailing_digit_separator, INTEGER_TRAILING_DIGIT_SEPARATOR ;
948            self.fraction_trailing_digit_separator, FRACTION_TRAILING_DIGIT_SEPARATOR ;
949            self.exponent_trailing_digit_separator, EXPONENT_TRAILING_DIGIT_SEPARATOR ;
950            self.integer_consecutive_digit_separator, INTEGER_CONSECUTIVE_DIGIT_SEPARATOR ;
951            self.fraction_consecutive_digit_separator, FRACTION_CONSECUTIVE_DIGIT_SEPARATOR ;
952            self.exponent_consecutive_digit_separator, EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR ;
953            self.special_digit_separator, SPECIAL_DIGIT_SEPARATOR ;
954        );
955        if format & flags::DIGIT_SEPARATOR_FLAG_MASK != 0 {
956            format |=
957                (unwrap_or_zero(self.digit_separator) as u128) << flags::DIGIT_SEPARATOR_SHIFT;
958        }
959        format |= (unwrap_or_zero(self.base_prefix) as u128) << flags::BASE_PREFIX_SHIFT;
960        format |= (unwrap_or_zero(self.base_suffix) as u128) << flags::BASE_SUFFIX_SHIFT;
961        format |= (self.mantissa_radix as u128) << flags::MANTISSA_RADIX_SHIFT;
962        format |= (unwrap_or_zero(self.exponent_base) as u128) << flags::EXPONENT_BASE_SHIFT;
963        format |= (unwrap_or_zero(self.exponent_radix) as u128) << flags::EXPONENT_RADIX_SHIFT;
964
965        format
966    }
967
968    /// Re-create builder from format.
969    #[inline]
970    pub const fn rebuild(format: u128) -> Self {
971        NumberFormatBuilder {
972            digit_separator: num::NonZeroU8::new(flags::digit_separator(format)),
973            base_prefix: num::NonZeroU8::new(flags::base_prefix(format)),
974            base_suffix: num::NonZeroU8::new(flags::base_suffix(format)),
975            mantissa_radix: flags::mantissa_radix(format) as u8,
976            exponent_base: num::NonZeroU8::new(flags::exponent_base(format) as u8),
977            exponent_radix: num::NonZeroU8::new(flags::exponent_radix(format) as u8),
978            required_integer_digits: has_flag!(format, REQUIRED_INTEGER_DIGITS),
979            required_fraction_digits: has_flag!(format, REQUIRED_FRACTION_DIGITS),
980            required_exponent_digits: has_flag!(format, REQUIRED_EXPONENT_DIGITS),
981            required_mantissa_digits: has_flag!(format, REQUIRED_MANTISSA_DIGITS),
982            no_positive_mantissa_sign: has_flag!(format, NO_POSITIVE_MANTISSA_SIGN),
983            required_mantissa_sign: has_flag!(format, REQUIRED_MANTISSA_SIGN),
984            no_exponent_notation: has_flag!(format, NO_EXPONENT_NOTATION),
985            no_positive_exponent_sign: has_flag!(format, NO_POSITIVE_EXPONENT_SIGN),
986            required_exponent_sign: has_flag!(format, REQUIRED_EXPONENT_SIGN),
987            no_exponent_without_fraction: has_flag!(format, NO_EXPONENT_WITHOUT_FRACTION),
988            no_special: has_flag!(format, NO_SPECIAL),
989            case_sensitive_special: has_flag!(format, CASE_SENSITIVE_SPECIAL),
990            no_integer_leading_zeros: has_flag!(format, NO_INTEGER_LEADING_ZEROS),
991            no_float_leading_zeros: has_flag!(format, NO_FLOAT_LEADING_ZEROS),
992            required_exponent_notation: has_flag!(format, REQUIRED_EXPONENT_NOTATION),
993            case_sensitive_exponent: has_flag!(format, CASE_SENSITIVE_EXPONENT),
994            case_sensitive_base_prefix: has_flag!(format, CASE_SENSITIVE_BASE_PREFIX),
995            case_sensitive_base_suffix: has_flag!(format, CASE_SENSITIVE_BASE_SUFFIX),
996            integer_internal_digit_separator: has_flag!(format, INTEGER_INTERNAL_DIGIT_SEPARATOR),
997            fraction_internal_digit_separator: has_flag!(format, FRACTION_INTERNAL_DIGIT_SEPARATOR),
998            exponent_internal_digit_separator: has_flag!(format, EXPONENT_INTERNAL_DIGIT_SEPARATOR),
999            integer_leading_digit_separator: has_flag!(format, INTEGER_LEADING_DIGIT_SEPARATOR),
1000            fraction_leading_digit_separator: has_flag!(format, FRACTION_LEADING_DIGIT_SEPARATOR),
1001            exponent_leading_digit_separator: has_flag!(format, EXPONENT_LEADING_DIGIT_SEPARATOR),
1002            integer_trailing_digit_separator: has_flag!(format, INTEGER_TRAILING_DIGIT_SEPARATOR),
1003            fraction_trailing_digit_separator: has_flag!(format, FRACTION_TRAILING_DIGIT_SEPARATOR),
1004            exponent_trailing_digit_separator: has_flag!(format, EXPONENT_TRAILING_DIGIT_SEPARATOR),
1005            integer_consecutive_digit_separator: has_flag!(
1006                format,
1007                INTEGER_CONSECUTIVE_DIGIT_SEPARATOR
1008            ),
1009            fraction_consecutive_digit_separator: has_flag!(
1010                format,
1011                FRACTION_CONSECUTIVE_DIGIT_SEPARATOR
1012            ),
1013            exponent_consecutive_digit_separator: has_flag!(
1014                format,
1015                EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR
1016            ),
1017            special_digit_separator: has_flag!(format, SPECIAL_DIGIT_SEPARATOR),
1018        }
1019    }
1020}
1021
1022impl Default for NumberFormatBuilder {
1023    #[inline(always)]
1024    fn default() -> Self {
1025        Self::new()
1026    }
1027}