Crate lexical_util
source ·Expand description
Shared utilities for lexical conversion routines.
These are not meant to be used publicly for any numeric conversion routines, but provide optimized math routines, format packed struct definitions, and custom iterators for all workspaces.
§Features
std
- Use the standard library.power-of-two
- Add support for parsing power-of-two integer strings.radix
- Add support for strings of any radix.write-integers
- Add support for writing integers.write-floats
- Add support for writing floats.parse-integers
- Add support for parsing integers.parse-floats
- Add support for parsing floats.compact
- Reduce code size at the cost of performance.
§Note
None of this is considered a public API: any of the implementation details may change release-to-release without major or minor version changes. Use internal implementation details at your own risk.
lexical-util mainly exists as an implementation detail for
lexical-core, although its API is stable. If you would like to use
a high-level API that writes to and parses from String
and &str
,
respectively, please look at lexical
instead. If you would like an API that supports multiple numeric
conversions, please look at lexical-core
instead.
§Version Support
The minimum, standard, required version is 1.63.0, for const generic support. Older versions of lexical support older Rust versions.
§Safety Guarantees
The only major sources of unsafe code are wrapped in the iterator.rs
,
skip.rs
, and noskip.rs
. These are fully encapsulated into standalone
traits to clearly define safety invariants and localize any unsafety to
1 or 2 lines of code.
The core, unsafe trait is DigitsIter
and Iter
, both which expect
to be backed by a contiguous block of memory (a slice) but may skip
bytes internally. To guarantee safety, for non-skip iterators you
must implement DigitsIter::is_consumed correctly.
This must correctly determine if there are any elements left in the
iterator. If the buffer is contiguous, this can just be index == self.len()
, but for a non-contiguous iterator it must skip any digits to
advance to the element next to be returned or the iterator itself will be
unsafe. ALL other safety invariants depend on this being implemented
correctly.
To see if the cursor is at the end of the buffer, use is_buffer_empty.
Any iterators must be peekable: you must be able to read and return the next value without advancing the iterator past that point. For iterators that skip bytes, this means advancing to the next element to be returned and returning that value.
For examples of how to safely implement skip iterators, you can do something like:
impl<_> DigitsIter<_> for MyIter {
fn peek(&mut self) -> Option<u8> {
loop {
let value = self.bytes.get(self.index)?;
if value != &b'.' {
return value;
}
self.index += 1;
}
}
}
Then, next will be implemented in terms of peek, incrementing the position in the cursor just after the value. The next iteration of peek will step to the correct byte to return.
impl<_> Iterator for MyIter {
type Item = &'a u8;
fn next(&mut self) -> Option<Self::Item> {
let value = self.peek()?;
self.index += 1;
Some(value)
}
}
Modules§
- Simple, shared algorithms for slices and iterators.
- Utilities for working with ASCII characters.
- Debugging assertions to check a radix is valid.
- Pre-defined constants for numeric types.
- Utilities to process digits.
- Optimized division algorithms for u128.
- Error type for numeric parsing functions.
- Extended precision floating-point type.
- Public API for the number format packed struct.
- Specialized iterator traits.
- Fast multiplication routines.
- Utilities for Rust numbers.
- Shared traits for the options API.
- Result type for numeric parsing functions.
- The maximum digits that can be held in a u64 for a given radix without overflow.
Macros§
- Define
FromLexical
trait. - Define
FromLexicalWithOptions
trait. - Define
ToLexical
trait. - Define
ToLexicalWithOptions
trait.