lexical/
lib.rs

1//! Fast lexical conversion routines.
2//!
3//! Fast lexical conversion routines for both `std` and `no_std` environments.
4//! lexical provides routines to convert numbers to and from decimal
5//! strings. lexical also supports non-base 10 numbers, with the `radix`
6//! feature, for both integers and floats. lexical is customizable
7//! and yet simple to use: despite supporting nearly every float and
8//! integer format available, it only exports 2 write functions
9//! and 4 parse functions.
10//!
11//! lexical is well-tested, and has been downloaded more than 5 million
12//! times and currently has no known errors in correctness. lexical
13//! prioritizes performance above all else, and aims to be competitive
14//! or faster than any other float or integer parser and writer.
15//!
16//! # Getting Started
17//!
18//! ```rust
19//! # #[cfg(all(
20//! #     feature = "parse-floats",
21//! #     feature = "parse-integers",
22//! #     feature = "write-floats",
23//! #     feature = "write-integers",
24//! # ))]
25//! # {
26//! // Number to string
27//! lexical::to_string(3.0);            // "3.0", always has a fraction suffix.
28//! lexical::to_string(3);              // "3"
29//!
30//! // String to number.
31//! let i: i32 = lexical::parse("3").unwrap();      // 3, auto-type deduction.
32//! let f: f32 = lexical::parse("3.5").unwrap();    // 3.5
33//! let d = lexical::parse::<f64, _>("3.5");        // Ok(3.5), successful parse.
34//! let d = lexical::parse::<f64, _>("3a");         // Err(Error(_)), failed to parse.
35//! # }
36//! ```
37//!
38//! # Conversion API
39#![cfg_attr(feature = "write", doc = " **To String**")]
40#![cfg_attr(feature = "write", doc = "")]
41#![cfg_attr(feature = "write", doc = " - [`to_string`]")]
42#![cfg_attr(feature = "write", doc = " - [`to_string_with_options`]")]
43//!
44#![cfg_attr(feature = "write", doc = " **From String**")]
45#![cfg_attr(feature = "write", doc = "")]
46#![cfg_attr(feature = "parse", doc = " - [`parse`]")]
47#![cfg_attr(feature = "parse", doc = " - [`parse_partial`]")]
48#![cfg_attr(feature = "parse", doc = " - [`parse_with_options`]")]
49#![cfg_attr(feature = "parse", doc = " - [`parse_partial_with_options`]")]
50//!
51//! # Features
52//!
53//! In accordance with the Rust ethos, all features are additive: the crate
54//! may be build with `--all-features` without issue.  The following features
55//! are enabled by default:
56//!
57//! * `std`
58//! * `write-integers`
59//! * `write-floats`
60//! * `parse-integers`
61//! * `parse-floats`
62//!
63//! A complete description of supported features includes:
64//!
65//! #### std
66//!
67//! Enable use of the standard library. Currently, the standard library
68//! is not used for any functionality, and may be disabled without any
69//! change in functionality on stable.
70//!
71//! #### write-integers
72//!
73//! Enable support for writing integers to string.
74//!
75//! #### write-floats
76//!
77//! Enable support for writing floating-point numbers to string.
78//!
79//! #### parse-integers
80//!
81//! Enable support for parsing integers from string.
82//!
83//! #### parsing-floats
84//!
85//! Enable support for parsing floating-point numbers from string.
86//!
87//! #### format
88//!
89//! Adds support for the entire format API (using [`NumberFormatBuilder`]).
90//! This allows extensive configurability for parsing and writing numbers
91//! in custom formats, with different valid syntax requirements.
92//!
93//! For example, in JSON, the following floats are valid or invalid:
94//!
95//! ```text
96//! -1          // valid
97//! +1          // invalid
98//! 1           // valid
99//! 1.          // invalid
100//! .1          // invalid
101//! 0.1         // valid
102//! nan         // invalid
103//! inf         // invalid
104//! Infinity    // invalid
105//! ```
106//!
107//! All of the finite numbers are valid in Rust, and Rust provides constants
108//! for non-finite floats. In order to parse standard-conforming JSON floats
109//! using lexical, you may use the following approach:
110//!
111//! ```rust
112//! # #[cfg(all(feature = "parse-floats", feature = "format"))] {
113//! use lexical_core::{format, parse_with_options, ParseFloatOptions, Result};
114//!
115//! fn parse_json_float<Bytes: AsRef<[u8]>>(bytes: Bytes) -> Result<f64> {
116//!     let options = ParseFloatOptions::new();
117//!     parse_with_options::<_, { format::JSON }>(bytes.as_ref(), &options)
118//! }
119//! # }
120//! ```
121//!
122//! See the [Number Format](#number-format) section below for more information.
123//!
124//! #### power-of-two
125//!
126//! Enable doing numeric conversions to and from strings with power-of-two
127//! radixes. This avoids most of the overhead and binary bloat of the radix
128//! feature, while enabling support for the most commonly-used radixes.
129//!
130//! #### radix
131//!
132//! Enable doing numeric conversions to and from strings for all radixes.
133//! This requires substantially more static storage than `power-of-two`,
134//! and increases compile times by a fair amount, but can be quite useful
135//! for esoteric programming languages which use duodecimal floats, for
136//! example.
137//!
138//! #### compact
139//!
140//! Reduce the generated code size at the cost of performance. This minimizes
141//! the number of static tables, inlining, and generics used, drastically
142//! reducing the size of the generated binaries.
143//!
144//! #### safe
145//!
146//! This replaces most unchecked indexing, required in cases where the
147//! compiler cannot elide the check, with checked indexing. However,
148//! it does not fully replace all unsafe behavior with safe behavior.
149//! To minimize the risk of undefined behavior and out-of-bounds reads/writers,
150//! extensive edge-cases, property-based tests, and fuzzing is done with both
151//! the safe feature enabled and disabled, with the tests verified by Miri
152//! and Valgrind.
153//!
154//! # Configuration API
155//!
156//! Lexical provides two main levels of configuration:
157//! - The [`NumberFormatBuilder`], creating a packed struct with custom
158//!   formatting options.
159//! - The Options API.
160//!
161//! ## Number Format
162//!
163//! The number format class provides numerous flags to specify
164//! number parsing or writing. When the `power-of-two` feature is
165//! enabled, additional flags are added:
166//! - The radix for the significant digits (default `10`).
167//! - The radix for the exponent base (default `10`).
168//! - The radix for the exponent digits (default `10`).
169//!
170//! When the `format` feature is enabled, numerous other syntax and
171//! digit separator flags are enabled, including:
172//! - A digit separator character, to group digits for increased legibility.
173//! - Whether leading, trailing, internal, and consecutive digit separators are
174//!   allowed.
175//! - Toggling required float components, such as digits before the decimal
176//!   point.
177//! - Toggling whether special floats are allowed or are case-sensitive.
178//!
179//! Many pre-defined constants therefore exist to simplify common use-cases,
180//! including:
181//! - `JSON`, `XML`, `TOML`, `YAML`, `SQLite`, and many more.
182//! - `Rust`, `Python`, `C#`, `FORTRAN`, `COBOL` literals and strings, and many
183//!   more.
184//!
185//! ## Options API
186//!
187//! The Options API provides high-level options to specify number parsing
188//! or writing, options not intrinsically tied to a number format.
189//! For example, the Options API provides:
190//! - The exponent character (default `b'e'`, or `b'^'`).
191//! - The decimal point character (default `b'.'`).
192//! - Custom `NaN`, `Infinity` string representations.
193//! - Whether to trim the fraction component from integral floats.
194//! - The exponent break point for scientific notation.
195//! - The maximum and minimum number of significant digits to write.
196//! - The rounding mode when truncating significant digits while writing.
197//!
198//! The available options are:
199#![cfg_attr(feature = "parse-floats", doc = " - [`ParseFloatOptions`]")]
200#![cfg_attr(feature = "parse-integers", doc = " - [`ParseIntegerOptions`]")]
201#![cfg_attr(feature = "write-floats", doc = " - [`WriteFloatOptions`]")]
202#![cfg_attr(feature = "write-integers", doc = " - [`WriteIntegerOptions`]")]
203//!
204//! In addition, pre-defined constants for each category of options may
205//! be found in their respective modules.
206//!
207//! ## Example
208//!
209//! An example of creating your own options to parse European-style
210//! numbers (which use commas as decimal points, and periods as digit
211//! separators) is as follows:
212//!
213//! ```
214//! # pub fn main() {
215//! # #[cfg(all(feature = "parse_floats", feature = "format"))] {
216//! // This creates a format to parse a European-style float number.
217//! // The decimal point is a comma, and the digit separators (optional)
218//! // are periods.
219//! const EUROPEAN: u128 = lexical::NumberFormatBuilder::new()
220//!     .digit_separator(b'.')
221//!     .build()
222//!     .unwrap();
223//! let options = lexical_core::ParseFloatOptions::builder()
224//!     .decimal_point(b',')
225//!     .build()
226//!     .unwrap();
227//! assert_eq!(
228//!     lexical::parse_with_options::<f32, EUROPEAN, _>("300,10", &options),
229//!     Ok(300.10)
230//! );
231//!
232//! // Another example, using a pre-defined constant for JSON.
233//! const JSON: u128 = lexical::format::JSON;
234//! let options = lexical::ParseFloatOptions::new();
235//! assert_eq!(
236//!     lexical::parse_with_options::<f32, JSON, _>("0e1", &options),
237//!     Ok(0.0)
238//! );
239//! assert_eq!(
240//!     lexical::parse_with_options::<f32, JSON, _>("1E+2", &options),
241//!     Ok(100.0)
242//! );
243//! # }
244//! # }
245//! ```
246//!
247//! # Version Support
248//!
249//! The minimum, standard, required version is 1.63.0, for const generic
250//! support. Older versions of lexical support older Rust versions.
251//!
252//! # Safety
253//!
254//! There is no non-trivial unsafe behavior in [lexical][crate] itself,
255//! however, any incorrect safety invariants in our parsers and writers
256//! (`lexical-parse-float`, `lexical-parse-integer`, `lexical-write-float`,
257//! and `lexical-write-integer`) could cause those safety invariants to
258//! be broken.
259//!
260//! [`to_string`]: fn.to_string.html
261//! [`to_string_with_options`]: fn.to_string_with_options.html
262//! [`write_with_options`]: crate::write_with_options
263//! [`parse`]: crate::parse
264//! [`parse_partial`]: crate::parse_partial
265//! [`parse_with_options`]: crate::parse_with_options
266//! [`parse_partial_with_options`]: crate::parse_partial_with_options
267//!
268//! [`NumberFormatBuilder`]: crate::NumberFormatBuilder
269//! [`ParseFloatOptions`]: crate::ParseFloatOptions
270//! [`ParseIntegerOptions`]: crate::ParseIntegerOptions
271//! [`WriteFloatOptions`]: crate::WriteFloatOptions
272//! [`WriteIntegerOptions`]: crate::WriteIntegerOptions
273
274// We want to have the same safety guarantees as Rust core,
275// so we allow unused unsafe to clearly document safety guarantees.
276#![allow(unused_unsafe)]
277#![cfg_attr(feature = "lint", warn(unsafe_op_in_unsafe_fn))]
278#![cfg_attr(not(feature = "std"), no_std)]
279#![deny(
280    clippy::doc_markdown,
281    clippy::unnecessary_safety_comment,
282    clippy::semicolon_if_nothing_returned,
283    clippy::unwrap_used,
284    clippy::as_underscore,
285    clippy::doc_markdown
286)]
287#![allow(
288    // used when concepts are logically separate
289    clippy::match_same_arms,
290    // loss of precision is intentional
291    clippy::integer_division,
292    // mathematical names use 1-character identifiers
293    clippy::min_ident_chars,
294    // these are not cryptographically secure contexts
295    clippy::integer_division_remainder_used,
296    // this can be intentional
297    clippy::module_name_repetitions,
298    // this is intentional: already passing a pointer and need performance
299    clippy::needless_pass_by_value,
300    // we use this for inline formatting for unsafe blocks
301    clippy::semicolon_inside_block,
302)]
303
304// Ensure our features are properly enabled. This means no parse without
305// parse support, etc.
306#[cfg(all(feature = "parse", not(any(feature = "parse-integers", feature = "parse-floats"))))]
307compile_error!(
308    "Do not use the `parse` feature directly. Use `parse-integers` and/or `parse-floats` instead."
309);
310
311#[cfg(all(feature = "write", not(any(feature = "write-integers", feature = "write-floats"))))]
312compile_error!(
313    "Do not use the `write` feature directly. Use `write-integers` and/or `write-floats` instead."
314);
315
316#[cfg(all(feature = "integers", not(any(feature = "write-integers", feature = "parse-integers"))))]
317compile_error!("Do not use the `integers` feature directly. Use `write-integers` and/or `parse-integers` instead.");
318
319#[cfg(all(feature = "floats", not(any(feature = "write-floats", feature = "parse-floats"))))]
320compile_error!(
321    "Do not use the `floats` feature directly. Use `write-floats` and/or `parse-floats` instead."
322);
323
324// Need an allocator for String/Vec.
325#[cfg(feature = "write")]
326#[macro_use(vec)]
327extern crate alloc;
328
329#[cfg(feature = "write")]
330use alloc::string::String;
331
332pub use lexical_core::format::{self, format_error, format_is_valid, NumberFormatBuilder};
333#[cfg(feature = "parse")]
334pub use lexical_core::Error;
335#[cfg(feature = "parse")]
336pub use lexical_core::ParseOptions;
337#[cfg(feature = "parse")]
338pub use lexical_core::Result;
339#[cfg(feature = "write")]
340pub use lexical_core::WriteOptions;
341#[cfg(feature = "f16")]
342pub use lexical_core::{bf16, f16};
343#[cfg(feature = "parse-floats")]
344pub use lexical_core::{parse_float_options, ParseFloatOptions, ParseFloatOptionsBuilder};
345#[cfg(feature = "parse-integers")]
346pub use lexical_core::{parse_integer_options, ParseIntegerOptions, ParseIntegerOptionsBuilder};
347#[cfg(feature = "write-floats")]
348pub use lexical_core::{write_float_options, WriteFloatOptions, WriteFloatOptionsBuilder};
349#[cfg(feature = "write-integers")]
350pub use lexical_core::{write_integer_options, WriteIntegerOptions, WriteIntegerOptionsBuilder};
351#[cfg(feature = "write")]
352pub use lexical_core::{FormattedSize, BUFFER_SIZE};
353#[cfg(feature = "parse")]
354pub use lexical_core::{FromLexical, FromLexicalWithOptions};
355#[cfg(feature = "write")]
356pub use lexical_core::{ToLexical, ToLexicalWithOptions};
357
358// NOTE: We cannot just use an uninitialized vector with excess capacity and
359// then use read-assign rather than `ptr::write` or `MaybeUninit.write` to
360// modify the values. When LLVM was the primary code generator, this was
361// **UNSPECIFIED** but not undefined behavior: reading undef primitives is safe:
362//  https://llvm.org/docs/LangRef.html#undefined-values
363//
364// However, a different backend such as cranelift might make this undefined
365// behavior. That is, from the perspective of Rust, this is undefined behavior:
366//
367//  ```rust
368//  let x = Vec::<u8>::with_capacity(500);
369//  let ptr = x.as_mut_ptr()
370//  let slc = slice::from_raw_parts_mut(ptr, x.capacity())
371//  // UB!!
372//  slc[0] = 1;
373//
374//  // Fine
375//  ptr.write(1);
376//  ```
377//
378// Currently, since LLVM treats it as unspecified behavior and will not drop
379// values, there is no risk of a memory leak and this is **currently** safe.
380// However, this can explode at any time, just like any undefined behavior.
381
382/// High-level conversion of a number to a decimal-encoded string.
383///
384/// * `n`       - Number to convert to string.
385///
386/// # Examples
387///
388/// ```rust
389/// # extern crate lexical;
390/// # pub fn main() {
391/// assert_eq!(lexical::to_string(5), "5");
392/// assert_eq!(lexical::to_string(0.0), "0.0");
393/// # }
394/// ```
395#[inline]
396#[cfg(feature = "write")]
397pub fn to_string<N: ToLexical>(n: N) -> String {
398    let mut buf = vec![0u8; N::FORMATTED_SIZE_DECIMAL];
399    let len = lexical_core::write(n, buf.as_mut_slice()).len();
400
401    // SAFETY: safe since the buffer is of sufficient size, len() must be <= the vec
402    // size.
403    unsafe {
404        buf.set_len(len);
405        String::from_utf8_unchecked(buf)
406    }
407}
408
409/// High-level conversion of a number to a string with custom writing options.
410///
411/// * `FORMAT`  - Packed struct containing the number format.
412/// * `n`       - Number to convert to string.
413/// * `options` - Options to specify number writing.
414///
415/// # Examples
416///
417/// ```rust
418/// # pub fn main() {
419/// const FORMAT: u128 = lexical::format::STANDARD;
420/// let options = lexical::WriteFloatOptions::builder()
421///     .trim_floats(true)
422///     .build()
423///     .unwrap();
424/// assert_eq!(lexical::to_string_with_options::<_, FORMAT>(0.0, &options), "0");
425/// assert_eq!(lexical::to_string_with_options::<_, FORMAT>(123.456, &options), "123.456");
426/// # }
427/// ```
428#[inline]
429#[cfg(feature = "write")]
430pub fn to_string_with_options<N: ToLexicalWithOptions, const FORMAT: u128>(
431    n: N,
432    options: &N::Options,
433) -> String {
434    // Need to use the `buffer_size` hint to properly deal with float formatting
435    // options.
436    let size = N::Options::buffer_size::<N, FORMAT>(options);
437    let mut buf = vec![0u8; size];
438    let slc = buf.as_mut_slice();
439    let len = lexical_core::write_with_options::<_, FORMAT>(n, slc, options).len();
440
441    // SAFETY: safe since the buffer is of sufficient size, `len()` must be <= the
442    // vec size.
443    unsafe {
444        buf.set_len(len);
445        String::from_utf8_unchecked(buf)
446    }
447}
448
449/// High-level conversion of decimal-encoded bytes to a number.
450///
451/// This function only returns a value if the entire string is
452/// successfully parsed.
453///
454/// * `bytes`   - Byte slice to convert to number.
455///
456/// # Examples
457///
458/// ```rust
459/// # extern crate lexical;
460/// # use lexical::Error;
461/// # pub fn main() {
462/// // Create our error.
463/// fn error<T>(r: lexical::Result<T>) -> Error {
464///     r.err().unwrap()
465/// }
466///
467/// // String overloads
468/// assert_eq!(lexical::parse::<i32, _>("5"), Ok(5));
469/// assert!(lexical::parse::<i32, _>("1a").err().unwrap().is_invalid_digit());
470/// assert_eq!(lexical::parse::<f32, _>("0"), Ok(0.0));
471/// assert_eq!(lexical::parse::<f32, _>("1.0"), Ok(1.0));
472/// assert_eq!(lexical::parse::<f32, _>("1."), Ok(1.0));
473///
474/// // Bytes overloads
475/// assert_eq!(lexical::parse::<i32, _>(b"5"), Ok(5));
476/// assert!(lexical::parse::<f32, _>(b"1a").err().unwrap().is_invalid_digit());
477/// assert_eq!(lexical::parse::<f32, _>(b"0"), Ok(0.0));
478/// assert_eq!(lexical::parse::<f32, _>(b"1.0"), Ok(1.0));
479/// assert_eq!(lexical::parse::<f32, _>(b"1."), Ok(1.0));
480/// # assert_eq!(lexical::parse::<f32, _>(b"5.002868148396374"), Ok(5.002868148396374));
481/// # assert_eq!(lexical::parse::<f64, _>(b"5.002868148396374"), Ok(5.002868148396374));
482/// # }
483/// ```
484#[inline]
485#[cfg(feature = "parse")]
486pub fn parse<N: FromLexical, Bytes: AsRef<[u8]>>(bytes: Bytes) -> Result<N> {
487    N::from_lexical(bytes.as_ref())
488}
489
490/// High-level, partial conversion of decimal-encoded bytes to a number.
491///
492/// This functions parses as many digits as possible, returning the parsed
493/// value and the number of digits processed if at least one character
494/// is processed. If another error, such as numerical overflow or underflow
495/// occurs, this function returns the error code and the index at which
496/// the error occurred.
497///
498/// * `bytes`   - Byte slice to convert to number.
499///
500/// # Examples
501///
502/// ```rust
503/// # extern crate lexical;
504/// # pub fn main() {
505///
506/// // String overloads
507/// assert_eq!(lexical::parse_partial::<i32, _>("5"), Ok((5, 1)));
508/// assert_eq!(lexical::parse_partial::<i32, _>("1a"), Ok((1, 1)));
509/// assert_eq!(lexical::parse_partial::<f32, _>("0"), Ok((0.0, 1)));
510/// assert_eq!(lexical::parse_partial::<f32, _>("1.0"), Ok((1.0, 3)));
511/// assert_eq!(lexical::parse_partial::<f32, _>("1."), Ok((1.0, 2)));
512///
513/// // Bytes overloads
514/// assert_eq!(lexical::parse_partial::<i32, _>(b"5"), Ok((5, 1)));
515/// assert_eq!(lexical::parse_partial::<i32, _>(b"1a"), Ok((1, 1)));
516/// assert_eq!(lexical::parse_partial::<f32, _>(b"0"), Ok((0.0, 1)));
517/// assert_eq!(lexical::parse_partial::<f32, _>(b"1.0"), Ok((1.0, 3)));
518/// assert_eq!(lexical::parse_partial::<f32, _>(b"1."), Ok((1.0, 2)));
519/// # assert_eq!(lexical::parse_partial::<f32, _>(b"5.002868148396374"), Ok((5.002868148396374, 17)));
520/// # assert_eq!(lexical::parse_partial::<f64, _>(b"5.002868148396374"), Ok((5.002868148396374, 17)));
521/// # }
522/// ```
523#[inline]
524#[cfg(feature = "parse")]
525pub fn parse_partial<N: FromLexical, Bytes: AsRef<[u8]>>(bytes: Bytes) -> Result<(N, usize)> {
526    N::from_lexical_partial(bytes.as_ref())
527}
528
529/// High-level conversion of bytes to a number with custom parsing options.
530///
531/// This function only returns a value if the entire string is
532/// successfully parsed.
533///
534/// * `FORMAT`  - Packed struct containing the number format.
535/// * `bytes`   - Byte slice to convert to number.
536/// * `options` - Options to specify number parsing.
537///
538/// # Panics
539///
540/// If the provided `FORMAT` is not valid, the function may panic. Please
541/// ensure `is_valid()` is called prior to using the format, or checking
542/// its validity using a static assertion.
543///
544/// # Examples
545///
546/// ```rust
547/// # pub fn main() {
548/// const FORMAT: u128 = lexical::format::STANDARD;
549/// let options = lexical::ParseFloatOptions::builder()
550///     .exponent(b'^')
551///     .decimal_point(b',')
552///     .build()
553///     .unwrap();
554/// assert_eq!(lexical::parse_with_options::<f32, _, FORMAT>("0", &options), Ok(0.0));
555/// assert_eq!(lexical::parse_with_options::<f32, _, FORMAT>("1,2345", &options), Ok(1.2345));
556/// assert_eq!(lexical::parse_with_options::<f32, _, FORMAT>("1,2345^4", &options), Ok(12345.0));
557/// # }
558/// ```
559#[inline]
560#[cfg(feature = "parse")]
561pub fn parse_with_options<N: FromLexicalWithOptions, Bytes: AsRef<[u8]>, const FORMAT: u128>(
562    bytes: Bytes,
563    options: &N::Options,
564) -> Result<N> {
565    N::from_lexical_with_options::<FORMAT>(bytes.as_ref(), options)
566}
567
568/// High-level, partial conversion of bytes to a number with custom parsing
569/// options.
570///
571/// This functions parses as many digits as possible, returning the parsed
572/// value and the number of digits processed if at least one character
573/// is processed. If another error, such as numerical overflow or underflow
574/// occurs, this function returns the error code and the index at which
575/// the error occurred.
576///
577/// * `FORMAT`  - Packed struct containing the number format.
578/// * `bytes`   - Byte slice to convert to number.
579/// * `options` - Options to specify number parsing.
580///
581/// # Panics
582///
583/// If the provided `FORMAT` is not valid, the function may panic. Please
584/// ensure `is_valid()` is called prior to using the format, or checking
585/// its validity using a static assertion.
586///
587/// # Examples
588///
589/// ```rust
590/// # pub fn main() {
591/// const FORMAT: u128 = lexical::format::STANDARD;
592/// let options = lexical::ParseFloatOptions::builder()
593///     .exponent(b'^')
594///     .decimal_point(b',')
595///     .build()
596///     .unwrap();
597/// assert_eq!(lexical::parse_partial_with_options::<f32, _, FORMAT>("0", &options), Ok((0.0, 1)));
598/// assert_eq!(lexical::parse_partial_with_options::<f32, _, FORMAT>("1,2345", &options), Ok((1.2345, 6)));
599/// assert_eq!(lexical::parse_partial_with_options::<f32, _, FORMAT>("1,2345^4", &options), Ok((12345.0, 8)));
600/// # }
601/// ```
602#[inline]
603#[cfg(feature = "parse")]
604pub fn parse_partial_with_options<
605    N: FromLexicalWithOptions,
606    Bytes: AsRef<[u8]>,
607    const FORMAT: u128,
608>(
609    bytes: Bytes,
610    options: &N::Options,
611) -> Result<(N, usize)> {
612    N::from_lexical_partial_with_options::<FORMAT>(bytes.as_ref(), options)
613}