lexical_parse_integer/lib.rs
1//! Fast lexical string-to-integer conversion routines.
2//!
3//! The default implementations are highly optimized both for simple
4//! strings, as well as input with large numbers of digits. In order to
5//! keep performance optimal for simple strings, we avoid overly branching
6//! to minimize the number of branches (and therefore optimization checks).
7//! Most of the branches in the code are resolved at compile-time, and
8//! the resulting ASM is monitored to ensure there are no regressions. For
9//! larger strings, a limited number of optimization checks are included
10//! to try faster, multi-digit parsing algorithms. For 32-bit integers,
11//! we try to parse 4 digits at a time, and for 64-bit and larger integers,
12//! we try to parse 8 digits at a time. Attempting both checks leads to
13//! significant performance penalties for simple strings, so only 1
14//! optimization is used at at a time.
15//!
16//! In addition, a compact, fallback algorithm uses a naive, simple
17//! algorithm, parsing only a single digit at a time. This avoid any
18//! unnecessary branching and produces smaller binaries, but comes
19//! at a significant performance penalty for integers with more digits.
20//!
21//! # Features
22//!
23//! * `std` - Use the standard library.
24//! * `power-of-two` - Add support for parsing power-of-two integer strings.
25//! * `radix` - Add support for strings of any radix.
26//! * `format` - Add support for parsing custom integer formats.
27//! * `compact` - Reduce code size at the cost of performance.
28//! * `safe` - Ensure only memory-safe indexing is used.
29//!
30//! `safe` is a no-op, since all parsers are memory-safe by default.
31//!
32//! # Note
33//!
34//! Only documented functionality is considered part of the public API:
35//! any of the modules, internal functions, or structs may change
36//! release-to-release without major or minor version changes. Use
37//! internal implementation details at your own risk.
38//!
39//! lexical-parse-integer mainly exists as an implementation detail for
40//! lexical-core, although its API is stable. If you would like to use
41//! a high-level API that writes to and parses from `String` and `&str`,
42//! respectively, please look at [lexical](https://crates.io/crates/lexical)
43//! instead. If you would like an API that supports multiple numeric
44//! conversions, please look at [lexical-core](https://crates.io/crates/lexical-core)
45//! instead.
46//!
47//! # Version Support
48//!
49//! The minimum, standard, required version is 1.63.0, for const generic
50//! support. Older versions of lexical support older Rust versions.
51//!
52//! # Design
53//!
54//! - [Algorithm Approach](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-integer/docs/Algorithm.md)
55//! - [Benchmarks](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-integer/docs/Benchmarks.md)
56//! - [Comprehensive Benchmarks](https://github.com/Alexhuszagh/lexical-benchmarks)
57
58// FIXME: Implement clippy/allow reasons once we drop support for 1.80.0 and below
59// Clippy reasons were stabilized in 1.81.0.
60
61// We want to have the same safety guarantees as Rust core,
62// so we allow unused unsafe to clearly document safety guarantees.
63#![allow(unused_unsafe)]
64#![cfg_attr(feature = "lint", warn(unsafe_op_in_unsafe_fn))]
65#![cfg_attr(not(feature = "std"), no_std)]
66#![deny(
67 clippy::doc_markdown,
68 clippy::unnecessary_safety_comment,
69 clippy::semicolon_if_nothing_returned,
70 clippy::unwrap_used,
71 clippy::as_underscore,
72 clippy::doc_markdown
73)]
74#![allow(
75 // used when concepts are logically separate
76 clippy::match_same_arms,
77 // loss of precision is intentional
78 clippy::integer_division,
79 // mathematical names use 1-character identifiers
80 clippy::min_ident_chars,
81 // these are not cryptographically secure contexts
82 clippy::integer_division_remainder_used,
83 // this can be intentional
84 clippy::module_name_repetitions,
85 // this is intentional: already passing a pointer and need performance
86 clippy::needless_pass_by_value,
87 // we use this for inline formatting for unsafe blocks
88 clippy::semicolon_inside_block,
89)]
90
91pub mod algorithm;
92pub mod options;
93pub mod parse;
94
95mod api;
96
97// Re-exports
98pub use lexical_util::error::Error;
99pub use lexical_util::format::{self, NumberFormatBuilder};
100pub use lexical_util::options::ParseOptions;
101pub use lexical_util::result::Result;
102
103pub use self::api::{FromLexical, FromLexicalWithOptions};
104#[doc(inline)]
105pub use self::options::{Options, OptionsBuilder};