lexical_util/
api.rs

1//! Implement string conversion routines in a single trait.
2
3// NOTE:
4//  We use macros to define the traits, rather than implement here
5//  since we can't define traits for types when both are defined outside
6//  the current crate, including in workspaces.
7
8// FROM LEXICAL
9
10/// Define `FromLexical` trait.
11#[macro_export]
12#[cfg(feature = "parse")]
13macro_rules! from_lexical {
14    () => {
15        /// Trait for numerical types that can be parsed from bytes.
16        pub trait FromLexical: lexical_util::num::Number {
17            /// Checked parser for a string-to-number conversion.
18            ///
19            /// This method parses the entire string, returning an error if
20            /// any invalid digits are found during parsing. Returns a `Result`
21            /// containing either the parsed value, or an error containing
22            /// any errors that occurred during parsing.
23            ///
24            /// * `bytes`   - Slice containing a numeric string.
25            fn from_lexical(bytes: &[u8]) -> lexical_util::result::Result<Self>;
26
27            /// Checked parser for a string-to-number conversion.
28            ///
29            /// This method parses until an invalid digit is found (or the end
30            /// of the string), returning the number of processed digits
31            /// and the parsed value until that point. Returns a `Result`
32            /// containing either the parsed value and the number of processed
33            /// digits, or an error containing any errors that occurred during
34            /// parsing.
35            ///
36            /// * `bytes`   - Slice containing a numeric string.
37            fn from_lexical_partial(bytes: &[u8]) -> lexical_util::result::Result<(Self, usize)>;
38        }
39    };
40}
41
42/// Define `FromLexicalWithOptions` trait.
43#[macro_export]
44#[cfg(feature = "parse")]
45macro_rules! from_lexical_with_options {
46    () => {
47        /// Trait for numerical types that can be parsed from bytes with custom options.
48        ///
49        /// The `Options` type specifies the configurable options to provide.
50        pub trait FromLexicalWithOptions: lexical_util::num::Number {
51            /// Custom formatting options for parsing a number.
52            type Options: lexical_util::options::ParseOptions;
53
54            /// Checked parser for a string-to-number conversion.
55            ///
56            /// This method parses the entire string, returning an error if
57            /// any invalid digits are found during parsing. The parsing
58            /// is dictated by the options, which specifies special
59            /// float strings, required float components, digit separators,
60            /// exponent characters, and more. Returns a `Result` containing
61            /// either the parsed value, or an error containing any errors
62            /// that occurred during parsing.
63            ///
64            /// * `FORMAT`  - Flags and characters designating the number grammar.
65            /// * `bytes`   - Slice containing a numeric string.
66            /// * `options` - Options to dictate number parsing.
67            ///
68            /// The `FORMAT` packed struct is built using [`NumberFormatBuilder`].
69            /// Any invalid number format will prevent parsing, returning
70            /// the appropriate format error. If you are unsure which format
71            /// to use, use [`STANDARD`].
72            ///
73            /// [`NumberFormatBuilder`]: lexical_util::format::NumberFormatBuilder
74            /// [`STANDARD`]: lexical_util::format::STANDARD
75            fn from_lexical_with_options<const FORMAT: u128>(
76                bytes: &[u8],
77                options: &Self::Options,
78            ) -> lexical_util::result::Result<Self>;
79
80            /// Checked parser for a string-to-number conversion.
81            ///
82            /// This method parses until an invalid digit is found (or the end
83            /// of the string), returning the number of processed digits
84            /// and the parsed value until that point. Returns a `Result`
85            /// containing either the parsed value and the number of
86            /// processed digits, or an error containing any errors that
87            /// occurred during parsing.
88            ///
89            /// * `FORMAT`  - Flags and characters designating the number grammar.
90            /// * `bytes`   - Slice containing a numeric string.
91            /// * `options` - Options to dictate number parsing.
92            ///
93            /// The `FORMAT` packed struct is built using [`NumberFormatBuilder`].
94            /// Any invalid number format will prevent parsing, returning
95            /// the appropriate format error. If you are unsure which format
96            /// to use, use [`STANDARD`].
97            ///
98            /// [`NumberFormatBuilder`]: lexical_util::format::NumberFormatBuilder
99            /// [`STANDARD`]: lexical_util::format::STANDARD
100            fn from_lexical_partial_with_options<const FORMAT: u128>(
101                bytes: &[u8],
102                options: &Self::Options,
103            ) -> lexical_util::result::Result<(Self, usize)>;
104        }
105    };
106}
107
108// TO LEXICAL
109
110/// Define `ToLexical` trait.
111#[macro_export]
112#[cfg(feature = "write")]
113macro_rules! to_lexical {
114    () => {
115        /// Trait for numerical types that can be serialized to bytes.
116        ///
117        /// To determine the number of bytes required to serialize a value to
118        /// string, check the associated constants from a required trait:
119        /// - [`FORMATTED_SIZE`]
120        /// - [`FORMATTED_SIZE_DECIMAL`]
121        ///
122        /// [`FORMATTED_SIZE`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE
123        /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
124        pub trait ToLexical:
125            lexical_util::constants::FormattedSize + lexical_util::num::Number
126        {
127            /// Serializer for a number-to-string conversion.
128            ///
129            /// Returns a subslice of the input buffer containing the written bytes,
130            /// starting from the same address in memory as the input slice.
131            ///
132            /// * `value`   - Number to serialize.
133            /// * `bytes`   - Buffer to write number to.
134            ///
135            /// # Panics
136            ///
137            /// Panics if the buffer is not of sufficient size. The caller
138            /// must provide a slice of sufficient size. In order to ensure
139            /// the function will not panic, ensure the buffer has at least
140            /// [`FORMATTED_SIZE_DECIMAL`] elements.
141            ///
142            /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
143            fn to_lexical<'a>(self, bytes: &'a mut [u8]) -> &'a mut [u8];
144        }
145    };
146}
147
148/// Define `ToLexicalWithOptions` trait.
149#[macro_export]
150#[cfg(feature = "write")]
151macro_rules! to_lexical_with_options {
152    () => {
153        /// Trait for numerical types that can be serialized to bytes with custom
154        /// options.
155        ///
156        /// To determine the number of bytes required to serialize a value to
157        /// string, check the associated constants from a required trait:
158        /// - [`FORMATTED_SIZE`]
159        /// - [`FORMATTED_SIZE_DECIMAL`]
160        ///
161        /// The `Options` type specifies the configurable options to provide.
162        ///
163        /// [`FORMATTED_SIZE`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE
164        /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
165        pub trait ToLexicalWithOptions:
166            lexical_util::constants::FormattedSize + lexical_util::num::Number
167        {
168            /// Custom formatting options for writing a number.
169            type Options: lexical_util::options::WriteOptions;
170
171            /// Serializer for a number-to-string conversion.
172            ///
173            /// Returns a subslice of the input buffer containing the written bytes,
174            /// starting from the same address in memory as the input slice.
175            ///
176            /// * `FORMAT`  - Flags and characters designating the number grammar.
177            /// * `value`   - Number to serialize.
178            /// * `bytes`   - Buffer to write number to.
179            /// * `options` - Options for number formatting.
180            ///
181            /// # Panics
182            ///
183            /// Panics if the buffer is not of sufficient size. The caller
184            /// must provide a slice of sufficient size. In order to ensure
185            /// the function will not panic, ensure the buffer has at least
186            /// [`FORMATTED_SIZE`] elements. If you are changing the
187            /// number significant digits written, the exponent break points,
188            /// or disabling scientific notation, you will need a larger buffer
189            /// than the one provided. An upper limit on the buffer size can
190            /// then be determined using [`WriteOptions::buffer_size`]. If you
191            /// are not using `min_significant_digits`, 1200 bytes is always
192            /// enough to hold the the output for a custom radix, and `400`
193            /// is always enough for decimal strings.
194            ///
195            /// **Floats Only**
196            ///
197            /// These panics are only when using uncommon features for float
198            /// writing, represent configuration errors, so runtime error
199            /// handling is not provided.
200            ///
201            /// Also panics if the provided number format is invalid, or
202            /// if the mantissa radix is not equal to the exponent base
203            /// and the mantissa radix/exponent base combinations are
204            /// not in the following list:
205            ///
206            /// - `4, 2`
207            /// - `8, 2`
208            /// - `16, 2`
209            /// - `32, 2`
210            /// - `16, 4`
211            ///
212            /// Panics as well if the NaN or Inf string provided to the writer
213            /// is disabled, but the value provided is NaN or Inf, respectively.
214            ///
215            /// [`WriteOptions::buffer_size`]: lexical_util::options::WriteOptions::buffer_size
216            /// [`FORMATTED_SIZE`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE
217            fn to_lexical_with_options<'a, const FORMAT: u128>(
218                self,
219                bytes: &'a mut [u8],
220                options: &Self::Options,
221            ) -> &'a mut [u8];
222        }
223    };
224}