lexical_core/lib.rs
1//! Fast lexical conversion routines for a [`no_std`] environment.
2//!
3//! `lexical-core` is a high-performance library for number-to-string and
4//! string-to-number conversions, without requiring a system
5//! allocator. If you would like to use a library that writes to [`String`],
6//! look at [lexical](https://crates.io/crates/lexical) instead. In addition
7//! to high performance, it's also highly configurable, supporting nearly
8//! every float and integer format available.
9//!
10//! `lexical-core` is well-tested, and has been downloaded more than 50 million
11//! times and currently has no known errors in correctness. `lexical-core`
12//! prioritizes performance above all else, and is competitive or faster
13//! than any other float or integer parser and writer.
14//!
15//! In addition, despite having a large number of features, configurability,
16//! and a focus on performance, it also aims to have fast compile times.
17//! Recent versions also add [`support`](#compact) for smaller binary sizes, as
18//! well ideal for embedded or web environments, where executable bloat can
19//! be much more detrimental than performance.
20//!
21//! [`no_std`]: https://docs.rust-embedded.org/book/intro/no-std.html
22//!
23//! # Getting Started
24//!
25//! #### Parse API
26//!
27//! The main parsing API is [`parse`] and [`parse_partial`]. For example,
28//! to parse a number from bytes, validating the entire input is a number:
29//!
30//! ```rust
31//! # #[cfg(all(feature = "parse-floats", feature = "parse-integers"))] {
32//! // String to number using Rust slices.
33//! // The argument is the byte string parsed.
34//! let f: f32 = lexical_core::parse(b"3.5").unwrap(); // 3.5
35//! let i: i32 = lexical_core::parse(b"15").unwrap(); // 15
36//! # }
37//! ```
38//!
39//! All `lexical-core` parsers are validating, they check the that entire
40//! input data is correct, and stop parsing when invalid data is found,
41//! numerical overflow, or other errors:
42//!
43//! ```rust
44//! # #[cfg(all(feature = "parse-floats", feature = "parse-integers"))] {
45//! let r = lexical_core::parse::<u8>(b"256"); // Err(ErrorCode::Overflow.into())
46//! let r = lexical_core::parse::<u8>(b"1a5"); // Err(ErrorCode::InvalidDigit.into())
47//! # }
48//! ```
49//!
50//! For streaming APIs or those incrementally parsing data fed to a parser,
51//! where the input data is known to be a float but where the float ends is
52//! currently unknown, the partial parsers will both return the data it was
53//! able to parse and the number of bytes processed:
54//!
55//! ```rust
56//! # #[cfg(feature = "parse-integers")] {
57//! let r = lexical_core::parse_partial::<i8>(b"3a5"); // Ok((3, 1))
58//! # }
59//! ```
60//!
61//! #### Write API
62//!
63//! The main parsing API is [`write`]. For example, to write a number to an
64//! existing buffer:
65//!
66//! ```rust
67//! # #[cfg(feature = "write-floats")] {
68//! use lexical_core::FormattedSize;
69//!
70//! let mut buf = [b'0'; f64::FORMATTED_SIZE];
71//! let slc = lexical_core::write::<f64>(15.1, &mut buf);
72//! assert_eq!(slc, b"15.1");
73//! # }
74//! ```
75//!
76//! If a buffer of an insufficient size is provided, the writer will panic:
77//!
78//! ```should_panic
79//! # #[cfg(feature = "write-integers")] {
80//! let mut buf = [b'0'; 1];
81//! let digits = lexical_core::write::<i64>(15, &mut buf);
82//! # }
83//! # #[cfg(not(feature = "write-integers"))] {
84//! # panic!("hidden, for the doctest to pass if the feature isn't enabled.");
85//! # }
86//! ```
87//!
88//! In order to guarantee the buffer is large enough, always ensure there
89//! are at least [`T::FORMATTED_SIZE_DECIMAL`] bytes, which requires the
90//! [`FormattedSize`] trait to be in scope.
91//!
92//! <!-- References -->
93#![cfg_attr(
94 any(feature = "write-floats", feature = "write-integers"),
95 doc = "
96[`FormattedSize`]: FormattedSize
97[`T::FORMATTED_SIZE_DECIMAL`]: FormattedSize::FORMATTED_SIZE_DECIMAL
98"
99)]
100#![cfg_attr(
101 not(any(feature = "write-floats", feature = "write-integers")),
102 doc = "
103[`FormattedSize`]: https://docs.rs/lexical-core/latest/lexical_core/trait.FormattedSize.html
104[`T::FORMATTED_SIZE_DECIMAL`]: https://docs.rs/lexical-core/latest/lexical_core/trait.FormattedSize.html#associatedconstant.FORMATTED_SIZE_DECIMAL
105"
106)]
107//!
108//! ```rust
109//! # #[cfg(feature = "write-integers")] {
110//! use lexical_core::FormattedSize;
111//!
112//! let mut buf = [b'0'; f64::FORMATTED_SIZE];
113//! let slc = lexical_core::write::<f64>(15.1, &mut buf);
114//! assert_eq!(slc, b"15.1");
115//! # }
116//! ```
117//!
118//! # Conversion API
119//!
120//! This writes and parses numbers to and from a format identical to
121//! Rust's [`parse`][`core-parse`] and [`write`][`core-write`].
122//!
123//! [`core-parse`]: core::str::FromStr::from_str
124//! [`core-write`]: core::fmt::Display::fmt
125//!
126//! <!-- Spacer for rustfmt -->
127#![cfg_attr(
128 any(feature = "write-floats", feature = "write-integers"),
129 doc = "- [`write`]: Write a number to string."
130)]
131#![cfg_attr(
132 any(feature = "parse-floats", feature = "parse-integers"),
133 doc = "
134- [`parse`]: Parse a number from string validating the complete string is a number.
135- [`parse_partial`]: Parse a number from string returning the number and the number
136 of digits it was able to parse.
137"
138)]
139//!
140//! ```rust
141//! # #[cfg(all(feature = "parse-floats", feature = "write-floats"))] {
142//! # use core::str;
143//! use lexical_core::FormattedSize;
144//!
145//! // parse
146//! let f: f64 = lexical_core::parse(b"3.5").unwrap();
147//! assert_eq!(f, 3.5);
148//!
149//! let (f, count): (f64, usize) = lexical_core::parse_partial(b"3.5").unwrap();
150//! assert_eq!(f, 3.5);
151//! assert_eq!(count, 3);
152//!
153//! // write
154//! let mut buffer = [0u8; f64::FORMATTED_SIZE_DECIMAL];
155//! let digits = lexical_core::write(f, &mut buffer);
156//! assert_eq!(str::from_utf8(digits), Ok("3.5"));
157//! # }
158//! ```
159//!
160//! # Options/Formatting API
161//!
162//! Each number parser and writer contains extensive formatting control
163//! through options and [`mod@format`] specifications, including digit
164//! [`separator`] support (that is, numbers such as `1_2__3.4_5`), if
165//! integral, fractional, or any significant digits are required, if to
166//! disable parsing or writing of non-finite values, if `+` signs are
167//! invalid or required, and much more.
168//!
169//! [`separator`]: NumberFormat::digit_separator
170//!
171//! <!-- Spacer for rustfmt -->
172#![cfg_attr(
173 feature = "write-floats",
174 doc = "[`nan_string`]: WriteFloatOptionsBuilder::nan_string"
175)]
176#![cfg_attr(
177 all(not(feature = "write-floats"), feature = "parse-floats"),
178 doc = "[`nan_string`]: ParseFloatOptionsBuilder::nan_string"
179)]
180#![cfg_attr(
181 all(not(feature = "write-floats"), not(feature = "parse-floats")),
182 doc = "[`nan_string`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.nan_string"
183)]
184//!
185//! <!-- Spacer for rustfmt -->
186#![cfg_attr(
187 any(feature = "write-floats", feature = "write-integers"),
188 doc = "- [`write_with_options`]: Write a number to string using custom formatting options."
189)]
190#![cfg_attr(
191 any(feature = "parse-floats", feature = "parse-integers"),
192 doc = "
193- [`parse_with_options`]: Parse a number from string using custom formatting options,
194 validating the complete string is a number.
195- [`parse_partial_with_options`]: Parse a number from string using custom formatting
196 options, returning the number and the number of digits it was able to parse.
197"
198)]
199//!
200//! Some options, such as custom string representations of non-finite
201//! floats (such as [`NaN`][`nan_string`]), are available without the
202//! [`format`](crate#format) feature. For more comprehensive examples, see the
203//! [`format`](#format) and [Comprehensive Configuration] sections
204//! below.
205//!
206//! ```rust
207//! # #[cfg(all(feature = "parse-floats", feature = "write-floats", feature = "format"))] {
208//! # use core::str;
209//! use lexical_core::{format, parse_float_options, write_float_options, FormattedSize};
210//!
211//! // parse
212//! let f: f64 = lexical_core::parse_with_options::<_, { format::JSON }>(
213//! b"3.5",
214//! &parse_float_options::JSON
215//! ).unwrap();
216//!
217//! // write
218//! const BUFFER_SIZE: usize = write_float_options::
219//! JSON.buffer_size_const::<f64, { format::JSON }>();
220//! let mut buffer = [0u8; BUFFER_SIZE];
221//! let digits = lexical_core::write_with_options::<_, { format::JSON }>(
222//! f,
223//! &mut buffer,
224//! &write_float_options::JSON
225//! );
226//! assert_eq!(str::from_utf8(digits), Ok("3.5"));
227//! # }
228//! ```
229//!
230//! [Comprehensive Configuration]: #comprehensive-configuration
231//!
232//! # Features
233//!
234//! In accordance with the Rust ethos, all features are additive: the crate
235//! may be build with `--all-features` without issue. The following features
236//! are enabled by default:
237//!
238//! * `write-integers` (Default) - Enable writing of integers.
239//! * `write-floats` (Default) - Enable writing of floats.
240//! * `parse-integers` (Default) - Enable parsing of integers.
241//! * `parse-floats` (Default) - Enable parsing of floats.
242//! * `power-of-two` - Add support for writing power-of-two number strings.
243//! * `radix` - Add support for strings of any radix.
244//! * `compact` - Reduce code size at the cost of performance.
245//! * `format` - Add support for custom number formatting.
246//! * `f16` - Enable support for half-precision [`f16`][`ieee-f16`] and
247//! [`bf16`][`brain-float`] floats.
248//! * `std` (Default) - Disable to allow use in a [`no_std`] environment.
249//!
250//! [`ieee-f16`]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
251//! [`brain-float`]: https://en.wikipedia.org/wiki/Bfloat16_floating-point_format
252//!
253//! A complete description of supported features includes:
254//!
255//! #### write-integers
256//!
257//! Enable support for writing integers to string.
258//!
259//! ```rust
260//! # #[cfg(feature = "write-integers")] {
261//! # use core::str;
262//! use lexical_core::FormattedSize;
263//!
264//! let mut buffer = [0u8; i64::FORMATTED_SIZE_DECIMAL];
265//! let digits = lexical_core::write(1234, &mut buffer);
266//! assert_eq!(str::from_utf8(digits), Ok("1234"));
267//! # }
268//! ```
269//!
270//! #### write-floats
271//!
272//! Enable support for writing floating-point numbers to string.
273//!
274//! ```rust
275//! # #[cfg(feature = "write-floats")] {
276//! # use core::str;
277//! use lexical_core::FormattedSize;
278//!
279//! let mut buffer = [0u8; f64::FORMATTED_SIZE_DECIMAL];
280//! let digits = lexical_core::write(1.234, &mut buffer);
281//! assert_eq!(str::from_utf8(digits), Ok("1.234"));
282//! # }
283//! ```
284//!
285//! #### parse-integers
286//!
287//! Enable support for parsing integers from string.
288//!
289//! ```rust
290//! # #[cfg(feature = "parse-integers")] {
291//! let f: i64 = lexical_core::parse(b"1234").unwrap();
292//! assert_eq!(f, 1234);
293//! # }
294//! ```
295//!
296//! #### parsing-floats
297//!
298//! Enable support for parsing floating-point numbers from string.
299//!
300//! ```rust
301//! # #[cfg(feature = "parse-integers")] {
302//! let f: f64 = lexical_core::parse(b"1.234").unwrap();
303//! assert_eq!(f, 1.234);
304//! # }
305//! ```
306//!
307//! #### format
308//!
309//! Adds support for the entire format [API][NumberFormatBuilder]. This
310//! allows extensive configurability for parsing and writing numbers
311//! in custom formats, with different valid syntax requirements.
312//!
313//! ##### JSON
314//!
315//! For example, in JSON, the following floats are valid or invalid:
316//!
317//! ```text
318//! -1 // valid
319//! +1 // invalid
320//! 1 // valid
321//! 1. // invalid
322//! .1 // invalid
323//! 0.1 // valid
324//! nan // invalid
325//! inf // invalid
326//! Infinity // invalid
327//! ```
328//!
329//! All of the finite numbers are valid in Rust, and Rust supports non-finite
330//! floats. In order to parse standard-conforming JSON floats using
331//! `lexical-core`, you may use the following approach:
332//!
333//! ```rust
334//! # #[cfg(all(feature = "parse-floats", feature = "format"))] {
335//! use lexical_core::{format, parse_float_options, parse_with_options, Result};
336//!
337//! fn parse_json_float<Bytes: AsRef<[u8]>>(bytes: Bytes) -> Result<f64> {
338//! parse_with_options::<_, { format::JSON }>(bytes.as_ref(), &parse_float_options::JSON)
339//! }
340//! # }
341//! ```
342//!
343//! Enabling the [`format`](crate#format) API significantly increases compile
344//! times, however, it enables a large amount of customization in how floats are
345//! written.
346//!
347//! #### power-of-two
348//!
349//! Enable doing numeric conversions to and from strings radixes that are powers
350//! of two, that is, `2`, `4`, `8`, `16`, and `32`. This avoids most of the
351//! overhead and binary bloat of the [`radix`](#radix) feature, while enabling
352//! support for the most commonly-used radixes.
353//!
354//! ```rust
355//! # #[cfg(all(feature = "parse-floats", feature = "write-floats", feature = "power-of-two"))] {
356//! # use core::str;
357//! use lexical_core::{
358//! ParseFloatOptions,
359//! WriteFloatOptions,
360//! FormattedSize,
361//! NumberFormatBuilder
362//! };
363//!
364//! // parse
365//! const BINARY: u128 = NumberFormatBuilder::binary();
366//! let value = "1.0011101111100111011011001000101101000011100101011";
367//! let f: f64 = lexical_core::parse_with_options::<_, { BINARY }>(
368//! value.as_bytes(),
369//! &ParseFloatOptions::new()
370//! ).unwrap();
371//!
372//! // write
373//! let mut buffer = [0u8; f64::FORMATTED_SIZE];
374//! let digits = lexical_core::write_with_options::<_, { BINARY }>(
375//! f,
376//! &mut buffer,
377//! &WriteFloatOptions::new()
378//! );
379//! assert_eq!(str::from_utf8(digits), Ok(value));
380//! # }
381//! ```
382//!
383//! #### radix
384//!
385//! Enable doing numeric conversions to and from strings for all radixes.
386//! This requires more static storage than [`power-of-two`](#power-of-two),
387//! and increases compile times, but can be quite useful
388//! for esoteric programming languages which use duodecimal floats, for
389//! example.
390//!
391//! ```rust
392//! # #[cfg(all(feature = "parse-floats", feature = "write-floats", feature = "radix"))] {
393//! # use core::str;
394//! use lexical_core::{
395//! ParseFloatOptions,
396//! WriteFloatOptions,
397//! FormattedSize,
398//! NumberFormatBuilder
399//! };
400//!
401//! // parse
402//! const FORMAT: u128 = NumberFormatBuilder::from_radix(12);
403//! let value = "1.29842830A44BAA2";
404//! let f: f64 = lexical_core::parse_with_options::<_, { FORMAT }>(
405//! value.as_bytes(),
406//! &ParseFloatOptions::new()
407//! ).unwrap();
408//!
409//! // write
410//! let mut buffer = [0u8; f64::FORMATTED_SIZE];
411//! let digits = lexical_core::write_with_options::<_, { FORMAT }>(
412//! f,
413//! &mut buffer,
414//! &WriteFloatOptions::new()
415//! );
416//! assert_eq!(str::from_utf8(digits), Ok(value));
417//! # }
418//! ```
419//!
420//! #### compact
421//!
422//! Reduce the generated code size at the cost of performance. This minimizes
423//! the number of static tables, inlining, and generics used, drastically
424//! reducing the size of the generated binaries.
425//!
426//! #### std
427//!
428//! Enable use of the standard library. Currently, the standard library
429//! is not used, and may be disabled without any change in functionality
430//! on stable.
431//!
432//! # Comprehensive Configuration
433//!
434//! `lexical-core` provides two main levels of configuration:
435//! - The [`NumberFormatBuilder`], creating a packed struct with custom
436//! formatting options.
437//! - The Options API.
438//!
439//! ## Number Format
440//!
441//! The number format class provides numerous flags to specify number parsing or
442//! writing. When the [`power-of-two`](#power-of-two) feature is
443//! enabled, additional flags are added:
444//! - The radix for the significant digits (default `10`).
445//! - The radix for the exponent base (default `10`).
446//! - The radix for the exponent digits (default `10`).
447//!
448//! When the [`format`](#format) feature is enabled, numerous other syntax and
449//! digit separator flags are enabled, including:
450//! - A digit separator character, to group digits for increased legibility.
451//! - Whether leading, trailing, internal, and consecutive digit separators are
452//! allowed.
453//! - Toggling required float components, such as digits before the decimal
454//! point.
455//! - Toggling whether special floats are allowed or are case-sensitive.
456//!
457//! Many pre-defined constants therefore exist to simplify common use-cases,
458//! including:
459//! - [`JSON`], [`XML`], [`TOML`], [`YAML`], [`SQLite`], and many more.
460//! - [`Rust`], [`Python`], [`C#`], [`FORTRAN`], [`COBOL`] literals and strings,
461//! and many more.
462//!
463//! For a list of all supported fields, see
464//! [Fields][NumberFormatBuilder#fields-1].
465//!
466//! <!-- Spacer for rustfmt -->
467#![cfg_attr(
468 feature = "format",
469 doc = "
470[`JSON`]: format::JSON
471[`XML`]: format::XML
472[`TOML`]: format::TOML
473[`YAML`]: format::YAML
474[`SQLite`]: format::SQLITE
475[`Rust`]: format::RUST_LITERAL
476[`Python`]: format::PYTHON_LITERAL
477[`C#`]: format::CSHARP_LITERAL
478[`FORTRAN`]: format::FORTRAN_LITERAL
479[`COBOL`]: format::COBOL_LITERAL
480"
481)]
482#![cfg_attr(
483 not(feature = "format"),
484 doc = "
485[`JSON`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.JSON.html
486[`XML`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.XML.html
487[`TOML`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.TOML.html
488[`YAML`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.YAML.html
489[`SQLite`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.SQLITE.html
490[`Rust`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.RUST_LITERAL.html
491[`Python`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.PYTHON_LITERAL.html
492[`C#`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.CSHARP_LITERAL.html
493[`FORTRAN`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.FORTRAN_LITERAL.html
494[`COBOL`]: https://docs.rs/lexical-core/latest/lexical_core/format/constant.COBOL_LITERAL.html
495"
496)]
497//!
498//! ## Options API
499//!
500//! The Options API provides high-level options to specify number parsing
501//! or writing, options not intrinsically tied to a number format.
502//! For example, the Options API provides:
503//!
504//! - The [`exponent`][`write-float-exponent`] character (defaults to `b'e'` or `b'^'`, depending on the radix).
505//! - The [`decimal point`][`write-float-decimal_point`] character (defaults to `b'.'`).
506//! - Custom [`NaN`][f64::NAN] and [`Infinity`][f64::INFINITY] string
507//! [`representations`][`write-float-nan_string`].
508//! - Whether to [`trim`][`write-float-trim_floats`] the fraction component from integral floats.
509//! - The exponent [`break-point`][`write-float-positive_exponent_break`] for scientific notation.
510//! - The [`maximum`][`write-float-max_significant_digits`] and [`minimum`][`write-float-min_significant_digits`] number of significant digits to write.
511//! - The rounding [`mode`][`write-float-round_mode`] when truncating significant digits while writing.
512//!
513//! <!-- Spacer for Rustfmt -->
514#![cfg_attr(
515 feature = "write-floats",
516 doc = "
517[`write-float-exponent`]: WriteFloatOptionsBuilder::exponent
518[`write-float-decimal_point`]: WriteFloatOptionsBuilder::decimal_point
519[`write-float-nan_string`]: WriteFloatOptionsBuilder::nan_string
520[`write-float-trim_floats`]: WriteFloatOptionsBuilder::trim_floats
521[`write-float-positive_exponent_break`]: WriteFloatOptionsBuilder::positive_exponent_break
522[`write-float-max_significant_digits`]: WriteFloatOptionsBuilder::max_significant_digits
523[`write-float-min_significant_digits`]: WriteFloatOptionsBuilder::min_significant_digits
524[`write-float-round_mode`]: WriteFloatOptionsBuilder::round_mode
525"
526)]
527#![cfg_attr(
528 not(feature = "write-floats"),
529 doc = "
530[`write-float-exponent`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.exponent
531[`write-float-decimal_point`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.decimal_point
532[`write-float-nan_string`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.nan_string
533[`write-float-trim_floats`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.trim_floats
534[`write-float-positive_exponent_break`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.positive_exponent_break
535[`write-float-max_significant_digits`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.max_significant_digits
536[`write-float-min_significant_digits`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.min_significant_digits
537[`write-float-round_mode`]: https://docs.rs/lexical-core/latest/lexical_core/struct.WriteFloatOptionsBuilder.html#method.round_mode
538"
539)]
540//!
541//! The available options are:
542#![cfg_attr(feature = "parse-floats", doc = " - [`ParseFloatOptions`]")]
543#![cfg_attr(feature = "parse-integers", doc = " - [`ParseIntegerOptions`]")]
544#![cfg_attr(feature = "write-floats", doc = " - [`WriteFloatOptions`]")]
545#![cfg_attr(feature = "write-integers", doc = " - [`WriteIntegerOptions`]")]
546//!
547//! In addition, pre-defined constants for each category of options may
548//! be found in their respective modules, for example, [`JSON`][`JSON-OPTS`].
549//!
550//! <!-- Spacer for Rustfmt -->
551#![cfg_attr(feature = "parse-floats", doc = "[`JSON-OPTS`]: parse_float_options::JSON")]
552#![cfg_attr(
553 not(feature = "parse-floats"),
554 doc = "[`JSON-OPTS`]: https://docs.rs/lexical-core/latest/lexical_core/parse_float_options/constant.JSON.html"
555)]
556//!
557//! ## Examples
558//!
559//! An example of creating your own options to parse European-style
560//! numbers (which use commas as decimal points, and periods as digit
561//! separators) is as follows:
562//!
563//! ```
564//! # #[cfg(all(feature = "parse-floats", feature = "format"))] {
565//! # use core::num;
566//! // This creates a format to parse a European-style float number.
567//! // The decimal point is a comma, and the digit separators (optional)
568//! // are periods.
569//! const EUROPEAN: u128 = lexical_core::NumberFormatBuilder::new()
570//! .digit_separator(num::NonZeroU8::new(b'.'))
571//! .build_strict();
572//! const COMMA_OPTIONS: lexical_core::ParseFloatOptions = lexical_core::ParseFloatOptions::builder()
573//! .decimal_point(b',')
574//! .build_strict();
575//! assert_eq!(
576//! lexical_core::parse_with_options::<f32, EUROPEAN>(b"300,10", &COMMA_OPTIONS),
577//! Ok(300.10)
578//! );
579//!
580//! // Another example, using a pre-defined constant for JSON.
581//! const JSON: u128 = lexical_core::format::JSON;
582//! const JSON_OPTIONS: lexical_core::ParseFloatOptions = lexical_core::ParseFloatOptions::new();
583//! assert_eq!(
584//! lexical_core::parse_with_options::<f32, JSON>(b"0e1", &JSON_OPTIONS),
585//! Ok(0.0)
586//! );
587//! assert_eq!(
588//! lexical_core::parse_with_options::<f32, JSON>(b"1E+2", &JSON_OPTIONS),
589//! Ok(100.0)
590//! );
591//! # }
592//! ```
593//!
594//! # Version Support
595//!
596//! The minimum, standard, required version is [`1.63.0`][`rust-1.63.0`], for
597//! const generic support. Older versions of lexical support older Rust
598//! versions.
599//!
600//! # Algorithms
601//!
602//! - [Parsing Floats](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-float/docs/Algorithm.md)
603//! - [Parsing Integers](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-integer/docs/Algorithm.md)
604//! - [Writing Floats](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-write-float/docs/Algorithm.md)
605//! - [Writing Integers](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-write-integer/docs/Algorithm.md)
606//!
607//! # Benchmarks
608//!
609//! - [Parsing Floats](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-float/docs/Benchmarks.md)
610//! - [Parsing Integers](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-integer/docs/Benchmarks.md)
611//! - [Writing Floats](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-write-float/docs/Benchmarks.md)
612//! - [Writing Integers](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-write-integer/docs/Benchmarks.md)
613//! - [Comprehensive Benchmarks](https://github.com/Alexhuszagh/lexical-benchmarks)
614//!
615//! A comprehensive analysis of lexical commits and their performance can be
616//! found in [benchmarks].
617//!
618//! # Design
619//!
620//! - [Binary Size](https://github.com/Alexhuszagh/rust-lexical/blob/main/docs/BinarySize.md)
621//! - [Build Timings](https://github.com/Alexhuszagh/rust-lexical/blob/main/docs/BuildTimings.md)
622//! - [Digit Separators](https://github.com/Alexhuszagh/rust-lexical/blob/main/docs/DigitSeparators.md)
623//!
624//! # Safety Guarantees
625//!
626//! There is no non-trivial unsafe behavior in `lexical-core` itself,
627//! however, any incorrect safety invariants in our parsers and writers
628//! ([`lexical-parse-float`], [`lexical-parse-integer`],
629//! [`lexical-write-float`], and [`lexical-write-integer`]) could cause those
630//! safety invariants to be broken.
631//!
632//! [`lexical-parse-float`]: https://crates.io/crates/lexical-parse-float
633//! [`lexical-parse-integer`]: https://crates.io/crates/lexical-parse-integer
634//! [`lexical-write-float`]: https://crates.io/crates/lexical-write-float
635//! [`lexical-write-integer`]: https://crates.io/crates/lexical-write-integer
636//!
637//! <!-- Spacer for Rustfmt -->
638#![cfg_attr(
639 any(feature = "write-floats", feature = "write-integers"),
640 doc = "
641[`write`]: crate::write
642[`write_with_options`]: crate::write_with_options
643"
644)]
645#![cfg_attr(
646 not(any(feature = "write-floats", feature = "write-integers")),
647 doc = "
648[`write`]: https://docs.rs/lexical-core/latest/lexical_core/fn.write.html
649[`write_with_options`]: https://docs.rs/lexical-core/latest/lexical_core/fn.write_with_options.html
650"
651)]
652#![cfg_attr(
653 any(feature = "parse-floats", feature = "parse-integers"),
654 doc = "
655[`parse`]: crate::parse
656[`parse_partial`]: crate::parse_partial
657[`parse_with_options`]: crate::parse_with_options
658[`parse_partial_with_options`]: crate::parse_partial_with_options
659"
660)]
661#![cfg_attr(
662 not(any(feature = "parse-floats", feature = "parse-integers")),
663 doc = "
664[`parse`]: https://docs.rs/lexical-core/latest/lexical_core/fn.parse.html
665[`parse_partial`]: https://docs.rs/lexical-core/latest/lexical_core/fn.parse_partial.html
666[`parse_with_options`]: https://docs.rs/lexical-core/latest/lexical_core/fn.parse_with_options.html
667[`parse_partial_with_options`]: https://docs.rs/lexical-core/latest/lexical_core/fn.parse_partial_with_options.html
668"
669)]
670//!
671//! <!-- Space for Rustfmt -->
672#![cfg_attr(feature = "parse-floats", doc = "[`ParseFloatOptions`]: crate::ParseFloatOptions")]
673#![cfg_attr(feature = "parse-integers", doc = "[`ParseIntegerOptions`]: crate::ParseIntegerOptions")]
674#![cfg_attr(feature = "write-floats", doc = "[`WriteFloatOptions`]: crate::WriteFloatOptions")]
675#![cfg_attr(feature = "write-integers", doc = "[`WriteIntegerOptions`]: crate::WriteIntegerOptions")]
676//!
677//! [`String`]: https://doc.rust-lang.org/alloc/string/struct.String.html
678//! [`NumberFormatBuilder`]: crate::NumberFormatBuilder
679//! [benchmarks]: https://github.com/Alexhuszagh/lexical-benchmarks
680//! [`rust-1.63.0`]: https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html
681
682// We want to have the same safety guarantees as Rust core,
683// so we allow unused unsafe to clearly document safety guarantees.
684#![allow(unused_unsafe)]
685#![cfg_attr(feature = "lint", warn(unsafe_op_in_unsafe_fn))]
686#![cfg_attr(not(feature = "std"), no_std)]
687#![cfg_attr(docsrs, feature(doc_cfg))]
688#![cfg_attr(docsrs, feature(doc_auto_cfg))]
689#![deny(
690 clippy::doc_markdown,
691 clippy::unnecessary_safety_comment,
692 clippy::semicolon_if_nothing_returned,
693 clippy::unwrap_used,
694 clippy::as_underscore
695)]
696#![allow(
697 // used when concepts are logically separate
698 clippy::match_same_arms,
699 // loss of precision is intentional
700 clippy::integer_division,
701 // mathematical names use 1-character identifiers
702 clippy::min_ident_chars,
703 // these are not cryptographically secure contexts
704 clippy::integer_division_remainder_used,
705 // this can be intentional
706 clippy::module_name_repetitions,
707 // this is intentional: already passing a pointer and need performance
708 clippy::needless_pass_by_value,
709 // we use this for inline formatting for unsafe blocks
710 clippy::semicolon_inside_block,
711)]
712#![cfg_attr(rustfmt, rustfmt_skip)] // reason = "this simplifies our imports"
713
714// Re-exports
715pub use lexical_util::Error;
716pub use lexical_util::result::Result;
717
718pub use lexical_util::format::{
719 self,
720 // FIXME: Do not export in the next breaking release.
721 format_error,
722 // FIXME: Do not export in the next breaking release.
723 format_is_valid,
724 NumberFormat,
725 NumberFormatBuilder,
726};
727
728#[cfg(feature = "f16")]
729pub use lexical_util::bf16::bf16;
730
731#[cfg(feature = "f16")]
732pub use lexical_util::f16::f16;
733
734// PARSE
735
736#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
737pub use lexical_util::options::ParseOptions;
738
739#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
740use lexical_util::{from_lexical, from_lexical_with_options};
741
742#[cfg(feature = "parse-floats")]
743pub use lexical_parse_float::{
744 options as parse_float_options,
745 Options as ParseFloatOptions,
746 OptionsBuilder as ParseFloatOptionsBuilder,
747};
748
749#[cfg(feature = "parse-floats")]
750use lexical_parse_float::{
751 FromLexical as FromFloat,
752 FromLexicalWithOptions as FromFloatWithOptions,
753};
754#[cfg(feature = "parse-integers")]
755pub use lexical_parse_integer::{
756 options as parse_integer_options,
757 Options as ParseIntegerOptions,
758 OptionsBuilder as ParseIntegerOptionsBuilder,
759};
760#[cfg(feature = "parse-integers")]
761use lexical_parse_integer::{
762 FromLexical as FromInteger,
763 FromLexicalWithOptions as FromIntegerWithOptions,
764};
765
766// WRITE
767
768#[cfg(any(feature = "write-floats", feature = "write-integers"))]
769pub use lexical_util::options::WriteOptions;
770
771#[cfg(any(feature = "write-floats", feature = "write-integers"))]
772use lexical_util::{to_lexical, to_lexical_with_options};
773
774#[cfg(any(feature = "write-floats", feature = "write-integers"))]
775pub use lexical_util::constants::{FormattedSize, BUFFER_SIZE};
776
777#[cfg(feature = "write-floats")]
778pub use lexical_write_float::{
779 options as write_float_options,
780 Options as WriteFloatOptions,
781 OptionsBuilder as WriteFloatOptionsBuilder,
782};
783#[cfg(feature = "write-floats")]
784use lexical_write_float::{ToLexical as ToFloat, ToLexicalWithOptions as ToFloatWithOptions};
785
786#[cfg(feature = "write-integers")]
787pub use lexical_write_integer::{
788 options as write_integer_options,
789 Options as WriteIntegerOptions,
790 OptionsBuilder as WriteIntegerOptionsBuilder,
791};
792
793#[cfg(feature = "write-integers")]
794use lexical_write_integer::{ToLexical as ToInteger, ToLexicalWithOptions as ToIntegerWithOptions};
795
796// API
797// ---
798
799#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
800from_lexical!(
801 "lexical_core",
802 1234,
803 u64,
804 4,
805 #[cfg_attr(docsrs, doc(cfg(any(feature = "parse-floats", feature = "parse-integers"))))]
806);
807
808#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
809from_lexical_with_options!(
810 "lexical_core",
811 1234,
812 u64,
813 4,
814 ParseIntegerOptions,
815 #[cfg_attr(docsrs, doc(cfg(any(feature = "parse-floats", feature = "parse-integers"))))]
816);
817
818#[cfg(any(feature = "write-floats", feature = "write-integers"))]
819to_lexical!(
820 "lexical_core",
821 1234,
822 u64,
823 #[cfg_attr(docsrs, doc(cfg(any(feature = "write-floats", feature = "write-integers"))))]
824);
825
826#[cfg(any(feature = "write-floats", feature = "write-integers"))]
827to_lexical_with_options!(
828 "lexical_core",
829 1234,
830 u64,
831 WriteIntegerOptions,
832 #[cfg_attr(docsrs, doc(cfg(any(feature = "write-floats", feature = "write-integers"))))]
833);
834
835/// Implement `FromLexical` and `FromLexicalWithOptions` for numeric types.
836///
837/// * `t` - The numerical type.
838/// * `from` - The internal trait that implements
839/// `from_lexical`.
840/// * `from_lexical_with_options` - The internal trait that implements
841/// `from_lexical`.
842/// * `options` - The options type to configure settings.
843#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
844macro_rules! from_lexical_impl {
845 ($t:ident, $from:ident, $from_options:ident, $options:ident) => {
846 impl FromLexical for $t {
847 #[cfg_attr(not(feature = "compact"), inline)]
848 fn from_lexical(bytes: &[u8]) -> Result<Self> {
849 <Self as $from>::from_lexical(bytes)
850 }
851
852 #[cfg_attr(not(feature = "compact"), inline)]
853 fn from_lexical_partial(bytes: &[u8]) -> Result<(Self, usize)> {
854 <Self as $from>::from_lexical_partial(bytes)
855 }
856 }
857
858 impl FromLexicalWithOptions for $t {
859 type Options = $options;
860
861 #[cfg_attr(not(feature = "compact"), inline)]
862 fn from_lexical_with_options<const FORMAT: u128>(
863 bytes: &[u8],
864 options: &Self::Options,
865 ) -> Result<Self> {
866 <Self as $from_options>::from_lexical_with_options::<FORMAT>(bytes, options)
867 }
868
869 #[cfg_attr(not(feature = "compact"), inline)]
870 fn from_lexical_partial_with_options<const FORMAT: u128>(
871 bytes: &[u8],
872 options: &Self::Options,
873 ) -> Result<(Self, usize)> {
874 <Self as $from_options>::from_lexical_partial_with_options::<FORMAT>(bytes, options)
875 }
876 }
877 };
878}
879
880/// Implement `FromLexical` and `FromLexicalWithOptions` for integers.
881#[cfg(feature = "parse-integers")]
882macro_rules! integer_from_lexical {
883 ($($t:ident)*) => ($(
884 from_lexical_impl!($t, FromInteger, FromIntegerWithOptions, ParseIntegerOptions);
885 )*);
886}
887
888#[cfg(feature = "parse-integers")]
889integer_from_lexical! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
890
891/// Implement `FromLexical` and `FromLexicalWithOptions` for floats.
892#[cfg(feature = "parse-floats")]
893macro_rules! float_from_lexical {
894 ($($t:ident)*) => ($(
895 from_lexical_impl!($t, FromFloat, FromFloatWithOptions, ParseFloatOptions);
896 )*);
897}
898
899#[cfg(feature = "parse-floats")]
900float_from_lexical! { f32 f64 }
901
902/// Implement `ToLexical` and `ToLexicalWithOptions` for numeric types.
903///
904/// * `t` - The numerical type.
905/// * `to` - The internal trait that implements
906/// `to_lexical`.
907/// * `to_lexical_with_options` - The internal trait that implements
908/// `to_lexical`.
909/// * `options` - The options type to configure settings.
910#[cfg(any(feature = "write-floats", feature = "write-integers"))]
911macro_rules! to_lexical_impl {
912 ($t:ident, $to:ident, $to_options:ident, $options:ident) => {
913 impl ToLexical for $t {
914 #[cfg_attr(not(feature = "compact"), inline)]
915 fn to_lexical(self, bytes: &mut [u8]) -> &mut [u8] {
916 <Self as $to>::to_lexical(self, bytes)
917 }
918 }
919
920 impl ToLexicalWithOptions for $t {
921 type Options = $options;
922 #[cfg_attr(not(feature = "compact"), inline(always))]
923 fn to_lexical_with_options<'a, const FORMAT: u128>(
924 self,
925 bytes: &'a mut [u8],
926 options: &Self::Options,
927 ) -> &'a mut [u8] {
928 <Self as $to_options>::to_lexical_with_options::<FORMAT>(self, bytes, options)
929 }
930 }
931 };
932}
933
934/// Implement `ToLexical` and `ToLexicalWithOptions` for integers.
935#[cfg(feature = "write-integers")]
936macro_rules! integer_to_lexical {
937 ($($t:ident)*) => ($(
938 to_lexical_impl!($t, ToInteger, ToIntegerWithOptions, WriteIntegerOptions);
939 )*);
940}
941
942#[cfg(feature = "write-integers")]
943integer_to_lexical! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
944
945/// Implement `ToLexical` and `ToLexicalWithOptions` for floats.
946#[cfg(feature = "write-floats")]
947macro_rules! float_to_lexical {
948 ($($t:ident)*) => ($(
949 to_lexical_impl!($t, ToFloat, ToFloatWithOptions, WriteFloatOptions);
950 )*);
951}
952
953#[cfg(feature = "write-floats")]
954float_to_lexical! { f32 f64 }
955
956/// Write number to string.
957///
958/// Returns a subslice of the input buffer containing the written bytes,
959/// starting from the same address in memory as the input slice.
960///
961/// * `value` - Number to serialize.
962/// * `bytes` - Buffer to write number to.
963///
964/// # Panics
965///
966/// Panics if the buffer may not be large enough to hold the serialized
967/// number. In order to ensure the function will not panic, provide a
968/// buffer with at least `{integer}::FORMATTED_SIZE` elements.
969///
970/// # Examples
971///
972/// ```
973/// # #[cfg(feature = "write-floats")] {
974/// // import `BUFFER_SIZE` to get the maximum bytes written by the number.
975/// use lexical_core::BUFFER_SIZE;
976///
977/// let mut buffer = [0u8; BUFFER_SIZE];
978/// let float = 3.14159265359_f32;
979///
980/// lexical_core::write(float, &mut buffer);
981///
982/// assert_eq!(&buffer[0..9], b"3.1415927");
983/// # }
984/// ```
985///
986/// This will panic, because the buffer is not large enough:
987///
988/// ```should_panic
989/// # #[cfg(feature = "write-floats")] {
990/// // note: the buffer is only one byte large
991/// let mut buffer = [0u8; 1];
992/// let float = 3.14159265359_f32;
993///
994/// lexical_core::write(float, &mut buffer);
995/// # }
996/// # #[cfg(not(feature = "write-floats"))] {
997/// # panic!("");
998/// # }
999/// ```
1000#[inline]
1001#[cfg(any(feature = "write-floats", feature = "write-integers"))]
1002pub fn write<N: ToLexical>(n: N, bytes: &mut [u8]) -> &mut [u8] {
1003 n.to_lexical(bytes)
1004}
1005
1006/// Write number to string with custom options.
1007///
1008/// Returns a subslice of the input buffer containing the written bytes,
1009/// starting from the same address in memory as the input slice.
1010///
1011/// * `FORMAT` - Packed struct containing the number format.
1012/// * `value` - Number to serialize.
1013/// * `bytes` - Buffer to write number to.
1014/// * `options` - Options to customize number parsing.
1015///
1016/// # Panics
1017///
1018/// Panics if the buffer may not be large enough to hold the serialized
1019/// number. In order to ensure the function will not panic, provide a
1020/// buffer with at least `{integer}::FORMATTED_SIZE` elements. If you
1021/// are using custom digit precision control or exponent break points
1022/// for writing floats, these constants may be insufficient to store
1023/// the serialized number, and up to 1200 bytes may be required with
1024/// radix support.
1025///
1026/// If the provided `FORMAT` is not valid, the function may panic. Please
1027/// ensure `is_valid()` is called prior to using the format, or checking
1028/// its validity using a static assertion.
1029///
1030/// # Examples
1031///
1032/// ```
1033/// # #[cfg(feature = "write-floats")] {
1034/// // import `BUFFER_SIZE` to get the maximum bytes written by the number.
1035/// use lexical_core::BUFFER_SIZE;
1036///
1037/// let mut buffer = [0u8; BUFFER_SIZE];
1038/// let float = 3.14159265359_f32;
1039///
1040/// const FORMAT: u128 = lexical_core::format::STANDARD;
1041/// const OPTIONS: lexical_core::WriteFloatOptions = lexical_core::WriteFloatOptions::new();
1042/// lexical_core::write_with_options::<_, FORMAT>(float, &mut buffer, &OPTIONS);
1043///
1044/// assert_eq!(&buffer[0..9], b"3.1415927");
1045/// # }
1046/// ```
1047///
1048/// This will panic, because the buffer is not large enough:
1049///
1050/// ```should_panic
1051/// # #[cfg(feature = "write-floats")] {
1052/// // note: the buffer is only one byte large
1053/// let mut buffer = [0u8; 1];
1054/// let float = 3.14159265359_f32;
1055///
1056/// const FORMAT: u128 = lexical_core::format::STANDARD;
1057/// const OPTIONS: lexical_core::WriteFloatOptions = lexical_core::WriteFloatOptions::new();
1058/// lexical_core::write_with_options::<_, FORMAT>(float, &mut buffer, &OPTIONS);
1059/// # }
1060/// # #[cfg(not(feature = "write-floats"))] {
1061/// # panic!("");
1062/// # }
1063/// ```
1064#[inline]
1065#[cfg(any(feature = "write-floats", feature = "write-integers"))]
1066pub fn write_with_options<'a, N: ToLexicalWithOptions, const FORMAT: u128>(
1067 n: N,
1068 bytes: &'a mut [u8],
1069 options: &N::Options,
1070) -> &'a mut [u8] {
1071 n.to_lexical_with_options::<FORMAT>(bytes, options)
1072}
1073
1074/// Parse complete number from string.
1075///
1076/// This method parses the entire string, returning an error if
1077/// any invalid digits are found during parsing.
1078///
1079/// * `bytes` - Byte slice containing a numeric string.
1080///
1081/// # Examples
1082///
1083/// ```
1084/// # #[cfg(feature = "parse-floats")] {
1085/// let string = "3.14159265359";
1086/// let result = lexical_core::parse::<f32>(string.as_bytes());
1087/// assert_eq!(result, Ok(3.14159265359_f32));
1088/// # }
1089/// ```
1090#[inline]
1091#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
1092pub fn parse<N: FromLexical>(bytes: &[u8]) -> Result<N> {
1093 N::from_lexical(bytes)
1094}
1095
1096/// Parse partial number from string.
1097///
1098/// This method parses until an invalid digit is found (or the end
1099/// of the string), returning the number of processed digits
1100/// and the parsed value until that point.
1101///
1102/// * `bytes` - Byte slice containing a numeric string.
1103///
1104/// # Examples
1105///
1106/// ```
1107/// # #[cfg(feature = "parse-floats")] {
1108/// let string = "3.14159265359 hello";
1109/// let result = lexical_core::parse_partial::<f32>(string.as_bytes());
1110/// assert_eq!(result, Ok((3.14159265359_f32, 13)));
1111/// # }
1112/// ```
1113#[inline]
1114#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
1115pub fn parse_partial<N: FromLexical>(bytes: &[u8]) -> Result<(N, usize)> {
1116 N::from_lexical_partial(bytes)
1117}
1118
1119/// Parse complete number from string with custom parsing options.
1120///
1121/// This method parses the entire string, returning an error if
1122/// any invalid digits are found during parsing.
1123///
1124/// * `FORMAT` - Packed struct containing the number format.
1125/// * `bytes` - Byte slice containing a numeric string.
1126/// * `options` - Options to customize number parsing.
1127///
1128/// # Examples
1129///
1130/// ```
1131/// # #[cfg(all(feature = "parse-floats", feature = "format"))] {
1132/// const JSON: u128 = lexical_core::format::JSON;
1133/// const OPTIONS: lexical_core::ParseFloatOptions = lexical_core::ParseFloatOptions::new();
1134/// let string = "3.14159265359";
1135/// let result = lexical_core::parse_with_options::<f32, JSON>(string.as_bytes(), &OPTIONS);
1136/// assert_eq!(result, Ok(3.14159265359_f32));
1137/// # }
1138/// ```
1139#[inline]
1140#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
1141pub fn parse_with_options<N: FromLexicalWithOptions, const FORMAT: u128>(
1142 bytes: &[u8],
1143 options: &N::Options,
1144) -> Result<N> {
1145 N::from_lexical_with_options::<FORMAT>(bytes, options)
1146}
1147
1148/// Parse partial number from string with custom parsing options.
1149///
1150/// This method parses until an invalid digit is found (or the end
1151/// of the string), returning the number of processed digits
1152/// and the parsed value until that point.
1153///
1154/// * `FORMAT` - Packed struct containing the number format.
1155/// * `bytes` - Byte slice containing a numeric string.
1156/// * `options` - Options to customize number parsing.
1157///
1158/// # Examples
1159///
1160/// ```
1161/// # #[cfg(all(feature = "parse-floats", feature = "format"))] {
1162/// const JSON: u128 = lexical_core::format::JSON;
1163/// const OPTIONS: lexical_core::ParseFloatOptions = lexical_core::ParseFloatOptions::new();
1164/// let string = "3.14159265359 hello";
1165/// let result = lexical_core::parse_partial_with_options::<f32, JSON>(string.as_bytes(), &OPTIONS);
1166/// assert_eq!(result, Ok((3.14159265359_f32, 13)));
1167/// # }
1168/// ```
1169#[inline]
1170#[cfg(any(feature = "parse-floats", feature = "parse-integers"))]
1171pub fn parse_partial_with_options<N: FromLexicalWithOptions, const FORMAT: u128>(
1172 bytes: &[u8],
1173 options: &N::Options,
1174) -> Result<(N, usize)> {
1175 N::from_lexical_partial_with_options::<FORMAT>(bytes, options)
1176}