lexical_util/
lib.rs

1//! Shared utilities for lexical conversion routines.
2//!
3//! These are not meant to be used publicly for any numeric
4//! conversion routines, but provide optimized math routines,
5//! format packed struct definitions, and custom iterators
6//! for all workspaces.
7//!
8//! # Features
9//!
10//! * `power-of-two` - Add support for parsing and writing power-of-two integer
11//!   strings.
12//! * `radix` - Add support for parsing and writing strings of any radix.
13//! * `format` - Add support for custom number formats.
14//! * `write-integers` - Add support for writing integers (used for
15//!   [`lexical-write-integer`]).
16//! * `write-floats` - Add support for writing floats (used for
17//!   [`lexical-write-float`]).
18//! * `parse-integers` - Add support for parsing integers (used for
19//!   [`lexical-parse-integer`]).
20//! * `parse-floats` - Add support for parsing floats (used for
21//!   [`lexical-write-float`]).
22//! * `compact` - Reduce code size at the cost of performance.
23//! * `f16` - Enable support for half-precision [`f16`][`ieee-f16`] and
24//!   [`bf16`][`brain-float`] floats.
25//! * `std` (Default) - Disable to allow use in a [`no_std`] environment.
26//!
27//! [`no_std`]: https://docs.rust-embedded.org/book/intro/no-std.html
28//! [`ieee-f16`]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
29//! [`brain-float`]: https://en.wikipedia.org/wiki/Bfloat16_floating-point_format
30//!
31//! # Public API
32//!
33//! [`lexical-util`] mainly exists as an implementation detail for
34//! the other lexical crates, although its API is mostly stable. If you would
35//! like to use a high-level API that writes to and parses from [`String`] and
36//! [`str`], respectively, please look at [`lexical`] instead. If you would like
37//! an API that supports multiple numeric conversions without a dependency on
38//! [`alloc`], please look at [`lexical-core`] instead.
39//!
40//! <div class="warning">
41//!
42//! Any undocumented, implementation details may change release-to-release
43//! without major or minor version changes. Use internal implementation details
44//! at your own risk. Any changes other than to [`NumberFormatBuilder`],
45//! [`NumberFormat`], [`mod@format`], and [`mod@options`] will not be considered
46//! a breaking change.
47//!
48//! </div>
49//!
50//! # Version Support
51//!
52//! The minimum, standard, required version is [`1.63.0`][`rust-1.63.0`], for
53//! const generic support. Older versions of lexical support older Rust
54//! versions.
55//!
56//! # Safety Guarantees
57//!
58//! For a detailed breakdown on the use of [`unsafe`], how and why our traits
59//! are implemented safely, and how to verify this, see [`Safety`].
60//!
61//! [`lexical`]: https://crates.io/crates/lexical
62//! [`lexical-parse-float`]: https://crates.io/crates/lexical-parse-float
63//! [`lexical-parse-integer`]: https://crates.io/crates/lexical-parse-integer
64//! [`lexical-write-float`]: https://crates.io/crates/lexical-write-float
65//! [`lexical-write-integer`]: https://crates.io/crates/lexical-write-integer
66//! [`lexical-core`]: https://crates.io/crates/lexical-core
67//! [`lexical-util`]: https://crates.io/crates/lexical-util
68//! [`rust-1.63.0`]: https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html
69//! [`alloc`]: https://doc.rust-lang.org/alloc/
70//! [`String`]: https://doc.rust-lang.org/alloc/string/struct.String.html
71//! [`Safety`]: https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-util/docs/Safety.md
72//! [`unsafe`]: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
73
74// FIXME: Implement clippy/allow reasons once we drop support for 1.80.0 and below
75// Clippy reasons were stabilized in 1.81.0.
76
77// We want to have the same safety guarantees as Rust core,
78// so we allow unused unsafe to clearly document safety guarantees.
79#![allow(unused_unsafe)]
80#![cfg_attr(feature = "lint", warn(unsafe_op_in_unsafe_fn))]
81#![cfg_attr(not(feature = "std"), no_std)]
82#![cfg_attr(docsrs, feature(doc_cfg))]
83#![cfg_attr(docsrs, feature(doc_auto_cfg))]
84#![deny(
85    clippy::doc_markdown,
86    clippy::unnecessary_safety_comment,
87    clippy::semicolon_if_nothing_returned,
88    clippy::unwrap_used,
89    clippy::as_underscore
90)]
91#![allow(
92    // used when concepts are logically separate
93    clippy::match_same_arms,
94    // loss of precision is intentional
95    clippy::integer_division,
96    // mathematical names use 1-character identifiers
97    clippy::min_ident_chars,
98    // these are not cryptographically secure contexts
99    clippy::integer_division_remainder_used,
100    // this can be intentional
101    clippy::module_name_repetitions,
102    // this is intentional: already passing a pointer and need performance
103    clippy::needless_pass_by_value,
104    // we use this for inline formatting for unsafe blocks
105    clippy::semicolon_inside_block,
106)]
107
108pub mod algorithm;
109pub mod ascii;
110pub mod assert;
111pub mod bf16;
112pub mod constants;
113pub mod digit;
114pub mod div128;
115pub mod error;
116pub mod extended_float;
117pub mod f16;
118pub mod format;
119pub mod iterator;
120pub mod mul;
121pub mod num;
122pub mod options;
123pub mod result;
124pub mod step;
125
126mod api;
127mod feature_format;
128mod format_builder;
129mod format_flags;
130mod libm;
131mod noskip;
132mod not_feature_format;
133mod prebuilt_formats;
134mod skip;
135
136#[cfg(any(feature = "write-floats", feature = "write-integers"))]
137pub use constants::{FormattedSize, BUFFER_SIZE};
138pub use error::Error;
139pub use format::{NumberFormat, NumberFormatBuilder};
140#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
141pub use options::ParseOptions;
142#[cfg(any(feature = "write-floats", feature = "write-integers"))]
143pub use options::WriteOptions;
144pub use result::Result;