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§

algorithm
Simple, shared algorithms for slices and iterators.
ascii
Utilities for working with ASCII characters.
assert
Debugging assertions to check a radix is valid.
constants
Pre-defined constants for numeric types.
digit
Utilities to process digits.
div128
Optimized division algorithms for u128.
error
Error type for numeric parsing functions.
extended_float
Extended precision floating-point type.
format
Public API for the number format packed struct.
iterator
Specialized iterator traits.
mul
Fast multiplication routines.
num
Utilities for Rust numbers.
options
Shared traits for the options API.
result
Result type for numeric parsing functions.
step
The maximum digits that can be held in a u64 for a given radix without overflow.

Macros§

from_lexical
Define FromLexical trait.
from_lexical_with_options
Define FromLexicalWithOptions trait.
to_lexical
Define ToLexical trait.
to_lexical_with_options
Define ToLexicalWithOptions trait.