lexical_write_integer/options.rs
1//! Configuration options for writing integers.
2//!
3//! This currently has no functionality, since we do not
4//! support any features for writing integers at this time.
5//!
6//! # Examples
7//!
8//! ```rust
9//! # use core::str;
10//! use lexical_write_integer::{Options, ToLexicalWithOptions};
11//! use lexical_write_integer::format::STANDARD;
12//!
13//! const OPTIONS: Options = Options::builder()
14//! .build_strict();
15//!
16//! const BUFFER_SIZE: usize = OPTIONS.buffer_size_const::<u64, STANDARD>();
17//! let mut buffer = [0u8; BUFFER_SIZE];
18//! let value = 1234u64;
19//! let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &OPTIONS);
20//! assert_eq!(str::from_utf8(digits), Ok("1234"));
21//! ```
22
23use lexical_util::constants::FormattedSize;
24use lexical_util::format::NumberFormat;
25use lexical_util::options::WriteOptions;
26use lexical_util::result::Result;
27
28/// Builder for [`Options`].
29///
30/// # Examples
31///
32/// ```rust
33/// use core::str;
34///
35/// use lexical_write_integer::{Options, ToLexicalWithOptions};
36/// use lexical_write_integer::format::STANDARD;
37///
38/// const OPTIONS: Options = Options::builder()
39/// .build_strict();
40///
41/// const BUFFER_SIZE: usize = OPTIONS.buffer_size_const::<u64, STANDARD>();
42/// let mut buffer = [0u8; BUFFER_SIZE];
43/// let value = 1234u64;
44/// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &OPTIONS);
45/// assert_eq!(str::from_utf8(digits), Ok("1234"));
46/// ```
47#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
48pub struct OptionsBuilder {}
49
50impl OptionsBuilder {
51 /// Create new options builder with default options.
52 #[inline(always)]
53 pub const fn new() -> Self {
54 Self {}
55 }
56
57 // BUILDERS
58
59 /// Check if the builder state is valid.
60 #[inline(always)]
61 pub const fn is_valid(&self) -> bool {
62 true
63 }
64
65 /// Build the [`Options`] struct without validation.
66 ///
67 /// <div class="warning">
68 ///
69 /// This is completely safe, however, misusing this could cause panics at
70 /// runtime. Always check if [`is_valid`] prior to using the built
71 /// options.
72 ///
73 /// </div>
74 ///
75 /// [`is_valid`]: Self::is_valid
76 #[inline(always)]
77 pub const fn build_unchecked(&self) -> Options {
78 Options {}
79 }
80
81 /// Build the [`Options`] struct.
82 ///
83 /// This can never panic.
84 ///
85 /// <!-- # Panics
86 ///
87 /// If the built options are not valid. This should always
88 /// be used within a const context to avoid panics at runtime.
89 /// -->
90 #[inline(always)]
91 pub const fn build_strict(&self) -> Options {
92 match self.build() {
93 Ok(value) => value,
94 Err(error) => core::panic!("{}", error.description()),
95 }
96 }
97
98 /// Build the [`Options`] struct.
99 #[inline(always)]
100 pub const fn build(&self) -> Result<Options> {
101 Ok(self.build_unchecked())
102 }
103}
104
105impl Default for OptionsBuilder {
106 #[inline(always)]
107 fn default() -> Self {
108 Self::new()
109 }
110}
111
112/// Immutable options to customize writing integers.
113///
114/// # Examples
115///
116/// ```rust
117/// use core::str;
118///
119/// use lexical_write_integer::{Options, ToLexicalWithOptions};
120/// use lexical_write_integer::format::STANDARD;
121///
122/// const OPTIONS: Options = Options::builder()
123/// .build_strict();
124///
125/// const BUFFER_SIZE: usize = OPTIONS.buffer_size_const::<u64, STANDARD>();
126/// let mut buffer = [0u8; BUFFER_SIZE];
127/// let value = 1234u64;
128/// let digits = value.to_lexical_with_options::<STANDARD>(&mut buffer, &OPTIONS);
129/// assert_eq!(str::from_utf8(digits), Ok("1234"));
130/// ```
131// FIXME: Add phantom data for private fields.
132// This is a BREAKING change so requires a major API release.
133#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
134pub struct Options {}
135
136impl Options {
137 /// Create options with default values.
138 #[inline(always)]
139 pub const fn new() -> Self {
140 Self {}
141 }
142
143 /// Create the default options for a given radix.
144 #[inline(always)]
145 #[cfg(feature = "power-of-two")]
146 pub const fn from_radix(_: u8) -> Self {
147 Self::new()
148 }
149
150 /// Check if the options state is valid.
151 #[inline(always)]
152 pub const fn is_valid(&self) -> bool {
153 true
154 }
155
156 /// Get an upper bound on the required buffer size.
157 ///
158 /// This is always [`FORMATTED_SIZE`][FormattedSize::FORMATTED_SIZE]
159 /// or [`FORMATTED_SIZE_DECIMAL`][FormattedSize::FORMATTED_SIZE_DECIMAL],
160 /// depending on the radix.
161 #[inline(always)]
162 pub const fn buffer_size_const<T: FormattedSize, const FORMAT: u128>(&self) -> usize {
163 if (NumberFormat::<FORMAT> {}.radix()) == 10 {
164 T::FORMATTED_SIZE_DECIMAL
165 } else {
166 T::FORMATTED_SIZE
167 }
168 }
169
170 // BUILDERS
171
172 /// Get [`OptionsBuilder`] as a static function.
173 #[inline(always)]
174 pub const fn builder() -> OptionsBuilder {
175 OptionsBuilder::new()
176 }
177
178 /// Create [`OptionsBuilder`] using existing values.
179 #[inline(always)]
180 pub const fn rebuild(&self) -> OptionsBuilder {
181 OptionsBuilder {}
182 }
183}
184
185impl Default for Options {
186 #[inline(always)]
187 fn default() -> Self {
188 Self::new()
189 }
190}
191
192impl WriteOptions for Options {
193 #[inline(always)]
194 fn is_valid(&self) -> bool {
195 Self::is_valid(self)
196 }
197
198 #[doc = lexical_util::write_options_doc!()]
199 #[inline(always)]
200 fn buffer_size<T: FormattedSize, const FORMAT: u128>(&self) -> usize {
201 self.buffer_size_const::<T, FORMAT>()
202 }
203}
204
205// PRE-DEFINED CONSTANTS
206// ---------------------
207
208/// Standard number format.
209#[rustfmt::skip]
210pub const STANDARD: Options = Options::new();