Coverage Report

Created: 2026-08-31 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rust-lexical/lexical-parse-integer/src/options.rs
Line
Count
Source
1
//! Configuration options for parsing integers.
2
//!
3
//! # Pre-Defined Formats
4
//!
5
//! This contains pre-defined options optimized for either the parsing of large
6
//! or small numbers.
7
//! - [`SMALL_NUMBERS`][`SMALL_NUMBERS`]: Optimize the parsing of small
8
//!   integers, at a major performance cost to larger values.
9
//! - [`LARGE_NUMBERS`][`LARGE_NUMBERS`]: Optimize the parsing of large
10
//!   integers, at a slight performance cost to smaller values.
11
//!
12
//! # Examples
13
//!
14
//! ```rust
15
//! use lexical_parse_integer::{FromLexicalWithOptions, Options};
16
//! use lexical_parse_integer::format::STANDARD;
17
//!
18
//! const OPTIONS: Options = Options::builder()
19
//!     .no_multi_digit(true)
20
//!     .build_strict();
21
//!
22
//! let value = "1234";
23
//! let result = u64::from_lexical_with_options::<STANDARD>(value.as_bytes(), &OPTIONS);
24
//! assert_eq!(result, Ok(1234));
25
//! ```
26
27
use lexical_util::options::ParseOptions;
28
use lexical_util::result::Result;
29
30
/// Builder for [`Options`].
31
///
32
/// # Examples
33
///
34
/// ```rust
35
/// use lexical_parse_integer::{FromLexicalWithOptions, Options};
36
/// use lexical_parse_integer::format::STANDARD;
37
///
38
/// const OPTIONS: Options = Options::builder()
39
///     .no_multi_digit(true)
40
///     .build_strict();
41
///
42
/// let value = "1234";
43
/// let result = u64::from_lexical_with_options::<STANDARD>(value.as_bytes(), &OPTIONS);
44
/// assert_eq!(result, Ok(1234));
45
/// ```
46
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
47
pub struct OptionsBuilder {
48
    /// Disable multi-digit optimizations.
49
    ///
50
    /// Using multi-digit optimizations allows parsing many digits
51
    /// from longer input strings at once which can dramatically
52
    /// improve performance (>70%) for long strings, but the
53
    /// increased branching can decrease performance for simple
54
    /// strings by 5-20%. Choose based on your inputs.
55
    no_multi_digit: bool,
56
}
57
58
impl OptionsBuilder {
59
    /// Create new options builder with default options.
60
    #[inline(always)]
61
    pub const fn new() -> Self {
62
        Self {
63
            no_multi_digit: true,
64
        }
65
    }
66
67
    // GETTERS
68
69
    /// Get if we disable the use of multi-digit optimizations.
70
    ///
71
    /// Defaults to [`true`].
72
    ///
73
    /// # Examples
74
    ///
75
    /// ```rust
76
    /// use lexical_parse_integer::Options;
77
    ///
78
    /// let builder = Options::builder();
79
    /// assert_eq!(builder.get_no_multi_digit(), true);
80
    /// ```
81
    #[inline(always)]
82
    pub const fn get_no_multi_digit(&self) -> bool {
83
        self.no_multi_digit
84
    }
85
86
    // SETTERS
87
88
    /// Set if we disable the use of multi-digit optimizations.
89
    ///
90
    /// Defaults to [`true`].
91
    ///
92
    /// # Examples
93
    ///
94
    /// ```rust
95
    /// use lexical_parse_integer::Options;
96
    ///
97
    /// const OPTIONS: Options = Options::builder()
98
    ///     .no_multi_digit(false)
99
    ///     .build_strict();
100
    /// assert_eq!(OPTIONS.get_no_multi_digit(), false);
101
    /// ```
102
    #[inline(always)]
103
    pub const fn no_multi_digit(mut self, no_multi_digit: bool) -> Self {
104
        self.no_multi_digit = no_multi_digit;
105
        self
106
    }
107
108
    // BUILDERS
109
110
    /// Check if the builder state is valid (always [`true`]).
111
    #[inline(always)]
112
    pub const fn is_valid(&self) -> bool {
113
        true
114
    }
115
116
    /// Build the [`Options`] struct without validation.
117
    ///
118
    /// <div class="warning">
119
    ///
120
    /// This is completely safe, however, misusing this could cause panics at
121
    /// runtime. Always check if [`is_valid`] prior to using the built
122
    /// options.
123
    ///
124
    /// </div>
125
    ///
126
    /// [`is_valid`]: Self::is_valid
127
    #[inline(always)]
128
    pub const fn build_unchecked(&self) -> Options {
129
        Options {
130
            no_multi_digit: self.no_multi_digit,
131
        }
132
    }
133
134
    /// Build the [`Options`] struct.
135
    ///
136
    /// This can never panic.
137
    ///
138
    /// <!-- # Panics
139
    ///
140
    /// If the built options are not valid. This should always
141
    /// be used within a const context to avoid panics at runtime.
142
    /// -->
143
    #[inline(always)]
144
    pub const fn build_strict(&self) -> Options {
145
        match self.build() {
146
            Ok(value) => value,
147
            Err(error) => core::panic!("{}", error.description()),
148
        }
149
    }
150
151
    /// Build the [`Options`] struct. Always [`Ok`].
152
    #[inline(always)]
153
    pub const fn build(&self) -> Result<Options> {
154
        Ok(self.build_unchecked())
155
    }
156
}
157
158
impl Default for OptionsBuilder {
159
    #[inline(always)]
160
    fn default() -> Self {
161
        Self::new()
162
    }
163
}
164
165
/// Options to customize the parsing integers.
166
///
167
/// # Examples
168
///
169
/// ```rust
170
/// use lexical_parse_integer::{FromLexicalWithOptions, Options};
171
/// use lexical_parse_integer::format::STANDARD;
172
///
173
/// const OPTIONS: Options = Options::builder()
174
///     .no_multi_digit(true)
175
///     .build_strict();
176
///
177
/// let value = "1234";
178
/// let result = u64::from_lexical_with_options::<STANDARD>(value.as_bytes(), &OPTIONS);
179
/// assert_eq!(result, Ok(1234));
180
/// ```
181
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
182
pub struct Options {
183
    /// Disable multi-digit optimizations.
184
    ///
185
    /// Using multi-digit optimizations allows parsing many digits
186
    /// from longer input strings at once which can dramatically
187
    /// improve performance (>70%) for long strings, but the
188
    /// increased branching can decrease performance for simple
189
    /// strings by 5-20%. Choose based on your inputs.
190
    no_multi_digit: bool,
191
}
192
193
impl Options {
194
    /// Create [`Options`] with default values.
195
    #[must_use]
196
    #[inline(always)]
197
    pub const fn new() -> Self {
198
        Self::builder().build_unchecked()
199
    }
200
201
    /// Create the default options for a given radix.
202
    #[inline(always)]
203
    #[cfg(feature = "power-of-two")]
204
    pub const fn from_radix(_: u8) -> Self {
205
        Self::new()
206
    }
207
208
    // GETTERS
209
210
    /// Check if the builder state is valid (always [`true`]).
211
    #[inline(always)]
212
    pub const fn is_valid(&self) -> bool {
213
        self.rebuild().is_valid()
214
    }
215
216
    /// Get if we disable the use of multi-digit optimizations.
217
    ///
218
    /// Defaults to [`true`].
219
    ///
220
    /// # Examples
221
    ///
222
    /// ```rust
223
    /// use lexical_parse_integer::options::Options;
224
    ///
225
    /// const OPTIONS: Options = Options::builder()
226
    ///     .no_multi_digit(true)
227
    ///     .build_strict();
228
    /// assert_eq!(OPTIONS.get_no_multi_digit(), true);
229
    /// ```
230
    #[inline(always)]
231
251
    pub const fn get_no_multi_digit(&self) -> bool {
232
251
        self.no_multi_digit
233
251
    }
234
235
    // SETTERS
236
237
    /// Set if we disable the use of multi-digit optimizations.
238
    #[deprecated = "Setters should have a `set_` prefix. Use `set_no_multi_digit` instead. Will be removed in 2.0."]
239
    #[inline(always)]
240
    pub fn no_multi_digit(&mut self, no_multi_digit: bool) {
241
        self.no_multi_digit = no_multi_digit;
242
    }
243
244
    /// Set if we disable the use of multi-digit optimizations.
245
    #[deprecated = "Options should be treated as immutable, use `OptionsBuilder` instead. Will be removed in 2.0."]
246
    #[inline(always)]
247
    pub fn set_no_multi_digit(&mut self, no_multi_digit: bool) {
248
        self.no_multi_digit = no_multi_digit;
249
    }
250
251
    // BUILDERS
252
253
    /// Get [`OptionsBuilder`] as a static function.
254
    #[inline(always)]
255
    pub const fn builder() -> OptionsBuilder {
256
        OptionsBuilder::new()
257
    }
258
259
    /// Create [`OptionsBuilder`] using existing values.
260
    #[inline(always)]
261
    pub const fn rebuild(&self) -> OptionsBuilder {
262
        OptionsBuilder {
263
            no_multi_digit: self.no_multi_digit,
264
        }
265
    }
266
}
267
268
impl Default for Options {
269
    #[inline(always)]
270
    fn default() -> Self {
271
        Self::new()
272
    }
273
}
274
275
impl ParseOptions for Options {
276
    #[inline(always)]
277
    fn is_valid(&self) -> bool {
278
        Self::is_valid(self)
279
    }
280
}
281
282
// PRE-DEFINED CONSTANTS
283
// ---------------------
284
285
/// Standard number format.
286
#[rustfmt::skip]
287
pub const STANDARD: Options = Options::new();
288
289
/// Options optimized for small numbers.
290
#[rustfmt::skip]
291
pub const SMALL_NUMBERS: Options = Options::builder()
292
    .no_multi_digit(true)
293
    .build_strict();
294
295
/// Options optimized for large numbers and long strings.
296
#[rustfmt::skip]
297
pub const LARGE_NUMBERS: Options = Options::builder()
298
    .no_multi_digit(false)
299
    .build_strict();