1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
//! Fast lexical string-to-integer conversion routines.
//!
//! This contains high-performance methods to parse integers from bytes.
//! Using [`from_lexical`] is analogous to [`parse`][`core-parse`],
//! while enabling parsing from bytes as well as [`str`].
//!
//! [`from_lexical`]: FromLexical::from_lexical
//! [`core-parse`]: core::str::FromStr
//!
//! # Getting Started
//!
//! To parse a number from bytes, use [`from_lexical`]:
//!
//! ```rust
//! # #[no_std]
//! # use core::str;
//! use lexical_parse_integer::{Error, FromLexical};
//!
//! let value = u64::from_lexical("1234".as_bytes());
//! assert_eq!(value, Ok(1234));
//!
//! let value = u64::from_lexical("18446744073709551616".as_bytes());
//! assert_eq!(value, Err(Error::Overflow(19)));
//!
//! let value = u64::from_lexical("1234 }, {\"Key\", \"Value\"}}".as_bytes());
//! assert_eq!(value, Err(Error::InvalidDigit(4)));
//! ```
//!
//! If wishing to incrementally parse a string from bytes, that is, parse as
//! many characters until an invalid digit is found, you can use the partial
//! parsers. This is useful in parsing data where the type is known, such as
//! JSON, but where the end of the number is not yet known.
//!
//! ```rust
//! # #[no_std]
//! # use core::str;
//! use lexical_parse_integer::{Error, FromLexical};
//!
//! let value = u64::from_lexical_partial("1234 }, {\"Key\", \"Value\"}}".as_bytes());
//! assert_eq!(value, Ok((1234, 4)));
//!
//! let value = u64::from_lexical_partial("18446744073709551616 }, {\"Key\", \"Value\"}}".as_bytes());
//! assert_eq!(value, Err(Error::Overflow(19)));
//! ```
//!
//! # Options/Formatting API
//!
//! Each integer parser contains extensive formatting control through
//! [`mod@format`], particularly digit [`separator`] support (that is,
//! integers such as `1_2__3`). For options, we have custom formats
//! optimized for both [`small`] and [`large`] integers.
//!
//! [`small`]: crate::options::SMALL_NUMBERS
//! [`large`]: crate::options::LARGE_NUMBERS
//! [`separator`]: NumberFormat::digit_separator
//!
//! To optimize for smaller integers at the expense of performance of larger
//! ones, you can use [`OptionsBuilder::no_multi_digit`] (defaults to [`true`]).
//!
//! ```rust
//! # use core::{num, str};
//! use lexical_parse_integer::{options, NumberFormatBuilder, FromLexicalWithOptions};
//!
//! const FORMAT: u128 = NumberFormatBuilder::new().build_strict();
//!
//! // a bit faster
//! let value = u64::from_lexical_with_options::<FORMAT>(b"12", &options::SMALL_NUMBERS);
//! assert_eq!(value, Ok(12));
//!
//! // a lot slower
//! let value = u64::from_lexical_with_options::<FORMAT>(b"18446744073709551615", &options::SMALL_NUMBERS);
//! assert_eq!(value, Ok(0xffffffffffffffff));
//! ```
//!
//! # Features
//!
//! * `format` - Add support for parsing custom integer formats.
//! * `power-of-two` - Add support for parsing power-of-two integer strings.
//! * `radix` - Add support for strings of any radix.
//! * `compact` - Reduce code size at the cost of performance.
//! * `std` (Default) - Disable to allow use in a [`no_std`] environment.
//!
//! [`no_std`]: https://docs.rust-embedded.org/book/intro/no-std.html
//!
//! A complete description of supported features includes:
//!
//! #### format
//!
//! Add support custom float formatting specifications. This should be used in
//! conjunction with [`Options`] for extensible integer parsing. This allows
//! changing the use of digit separators, requiring or not allowing signs, and
//! more.
//!
//! ##### JSON
//!
//! For example, in JSON, the following integers are valid or invalid:
//!
//! ```text
//! -1 // valid
//! +1 // invalid
//! 1 // valid
//! ```
//!
//! All of these are valid in our default format (the format of Rust strings),
//! so we must use a custom format to parse JSON strings:
//!
//! ```rust
//! # #[cfg(feature = "format")] {
//! # use core::str;
//! use lexical_parse_integer::{format, Error, FromLexicalWithOptions, Options};
//!
//! const OPTIONS: Options = Options::new();
//! let value = u64::from_lexical_with_options::<{ format::JSON }>("1234".as_bytes(), &OPTIONS);
//! assert_eq!(value, Ok(1234));
//!
//! let value = u64::from_lexical_with_options::<{ format::JSON }>("+1234".as_bytes(), &OPTIONS);
//! assert_eq!(value, Err(Error::InvalidPositiveSign(0)));
//! # }
//! ```
//!
//! ##### Custom Format
//!
//! An example of building a custom format to with digit separator support is:
//!
//! ```rust
//! # #[cfg(all(feature = "format", feature = "power-of-two"))] {
//! # use core::{num, str};
//! use lexical_parse_integer::{NumberFormatBuilder, Options, FromLexicalWithOptions};
//!
//! const FORMAT: u128 = NumberFormatBuilder::new()
//! // require that a `+` or `-` preceeds the number
//! .required_mantissa_sign(true)
//! // allow internal digit separators, that is, a special character between digits
//! .integer_internal_digit_separator(true)
//! // use `_` as the digit separator
//! .digit_separator(num::NonZeroU8::new(b'_'))
//! // allow an optional `0d` prefix to the number
//! .base_prefix(num::NonZeroU8::new(b'd'))
//! // build the number format, panicking on error
//! .build_strict();
//! const OPTIONS: Options = Options::new();
//!
//! let value = u64::from_lexical_with_options::<FORMAT>("+12_3_4".as_bytes(), &OPTIONS);
//! assert_eq!(value, Ok(1234));
//!
//! let value = u64::from_lexical_with_options::<FORMAT>("+0d12_3_4".as_bytes(), &OPTIONS);
//! assert_eq!(value, Ok(1234));
//! # }
//! ```
//!
//! For a list of all supported fields, see [Parse Integer
//! Fields][NumberFormatBuilder#parse-integer-fields].
//!
//! Enabling the [`format`](crate#format) API significantly increases compile
//! times, however, it enables a large amount of customization in how integers
//! are parsed.
//!
//! #### power-of-two
//!
//! Enable parsing numbers that are powers of two, that is, `2`, `4`, `8`, `16`,
//! and `32`.
//!
//! ```rust
//! # #[no_std]
//! # #[cfg(feature = "power-of-two")] {
//! # use core::str;
//! use lexical_parse_integer::{FromLexicalWithOptions, NumberFormatBuilder, Options};
//!
//! const BINARY: u128 = NumberFormatBuilder::binary();
//! const OPTIONS: Options = Options::new();
//! let value = u64::from_lexical_with_options::<BINARY>("10011010010".as_bytes(), &OPTIONS);
//! assert_eq!(value, Ok(1234));
//! # }
//! ```
//!
//! #### radix
//!
//! Enable parsing numbers using all radixes from `2` to `36`. This requires
//! more static storage than [`power-of-two`][crate#power-of-two], and increases
//! compile times, but can be quite useful for esoteric programming languages
//! which use duodecimal integers.
//!
//! ```rust
//! # #[no_std]
//! # #[cfg(feature = "radix")] {
//! # use core::str;
//! use lexical_parse_integer::{FromLexicalWithOptions, NumberFormatBuilder, Options};
//!
//! const BINARY: u128 = NumberFormatBuilder::from_radix(12);
//! const OPTIONS: Options = Options::new();
//! let value = u64::from_lexical_with_options::<BINARY>("86A".as_bytes(), &OPTIONS);
//! assert_eq!(value, Ok(1234));
//! # }
//! ```
//!
//! #### compact
//!
//! Reduce the generated code size at the cost of performance. This minimizes
//! the number of static tables, inlining, and generics used, drastically
//! reducing the size of the generated binaries. However, this resulting
//! performance of the generated code is much lower.
//!
//! #### std
//!
//! Enable use of the standard library. Currently, the standard library
//! is not used, and may be disabled without any change in functionality
//! on stable.
//!
//! # Higher-Level APIs
//!
//! If you would like an API that supports multiple numeric conversions rather
//! than just writing integers, use [`lexical`] or [`lexical-core`] instead.
//!
//! [`lexical`]: https://crates.io/crates/lexical
//! [`lexical-core`]: https://crates.io/crates/lexical-core
//!
//! # Version Support
//!
//! The minimum, standard, required version is [`1.63.0`][`rust-1.63.0`], for
//! const generic support. Older versions of lexical support older Rust
//! versions.
//!
//! # Algorithm
//!
//! The default implementations are highly optimized both for simple
//! strings, as well as input with large numbers of digits. In order to
//! keep performance optimal for simple strings, we avoid overly branching
//! to minimize the number of branches (and therefore optimization checks).
//! Most of the branches in the code are resolved at compile-time, and
//! the resulting ASM is monitored to ensure there are no regressions. For
//! larger strings, a limited number of optimization checks are included
//! to try faster, multi-digit parsing algorithms. For 32-bit integers,
//! we try to parse 4 digits at a time, and for 64-bit and larger integers,
//! we try to parse 8 digits at a time. Attempting both checks leads to
//! significant performance penalties for simple strings, so only 1
//! optimization is used at at a time.
//!
//! In addition, a compact, fallback algorithm uses a naive, simple
//! algorithm, parsing only a single digit at a time. This avoid any
//! unnecessary branching and produces smaller binaries, but comes
//! at a significant performance penalty for integers with more digits.
//!
//! # Design
//!
//! - [Algorithm Approach](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-integer/docs/Algorithm.md)
//! - [Benchmarks](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-integer/docs/Benchmarks.md)
//! - [Comprehensive Benchmarks](https://github.com/Alexhuszagh/lexical-benchmarks)
//!
//! [`rust-1.63.0`]: https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html
// FIXME: Implement clippy/allow reasons once we drop support for 1.80.0 and below
// Clippy reasons were stabilized in 1.81.0.
// We want to have the same safety guarantees as Rust core,
// so we allow unused unsafe to clearly document safety guarantees.
// Re-exports
pub use Error;
pub use ;
pub use ParseOptions;
pub use Result;
pub use ;
pub use ;