lexical_write_integer/
write.rs

1//! Shared trait and methods for writing integers.
2
3#![doc(hidden)]
4
5use lexical_util::format;
6
7/// Select the back-end.
8#[cfg(feature = "compact")]
9use crate::compact::Compact;
10#[cfg(not(feature = "compact"))]
11use crate::decimal::Decimal;
12#[cfg(all(not(feature = "compact"), feature = "power-of-two"))]
13use crate::radix::Radix;
14
15/// Define the implementation to write significant digits.
16macro_rules! write_mantissa {
17    ($($t:tt)+) => {
18        /// Internal implementation to write significant digits for float writers.
19        #[doc(hidden)]
20        #[inline(always)]
21        fn write_mantissa<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize {
22            self.write_integer::<FORMAT, { format::RADIX }, { format::RADIX_SHIFT }>(buffer)
23        }
24
25        /// Internal implementation to write significant digits for float writers.
26        #[doc(hidden)]
27        #[inline(always)]
28        fn write_mantissa_signed<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize {
29            self.write_integer_signed::<FORMAT, { format::RADIX }, { format::RADIX_SHIFT }>(buffer)
30        }
31    };
32}
33
34/// Define the implementation to write exponent digits.
35macro_rules! write_exponent {
36    ($($t:tt)+) => (
37        // NOTE: This should always be signed, but for backwards compatibility as
38        // a precaution we keep the original just in case someone uses the private API.
39
40        /// Internal implementation to write exponent digits for float writers.
41        // NOTE: This is not part of the public API.
42        #[doc(hidden)]
43        #[inline(always)]
44        #[deprecated = "use `write_exponent_signed`, since exponents are always signed."]
45        fn write_exponent<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize
46        {
47            self.write_integer::<FORMAT, { format::EXPONENT_RADIX }, { format::EXPONENT_RADIX_SHIFT }>(buffer)
48        }
49
50        /// Internal implementation to write exponent digits for float writers.
51        #[doc(hidden)]
52        #[inline(always)]
53        fn write_exponent_signed<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize
54        {
55            self.write_integer_signed::<FORMAT, { format::EXPONENT_RADIX }, { format::EXPONENT_RADIX_SHIFT }>(buffer)
56        }
57    )
58}
59
60/// Write integer trait, implemented in terms of the compact back-end.
61#[cfg(feature = "compact")]
62pub trait WriteInteger: Compact {
63    /// Forward write integer parameters to an unoptimized backend.
64    ///
65    /// # Preconditions
66    ///
67    /// `self` must be non-negative and unsigned.
68    ///
69    /// [`FORMATTED_SIZE`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE
70    /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
71    fn write_integer<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
72        self,
73        buffer: &mut [u8],
74    ) -> usize {
75        let radix = format::radix_from_flags(FORMAT, MASK, SHIFT);
76        self.compact(radix, buffer)
77    }
78
79    /// Forward write integer parameters to an optimized backend.
80    ///
81    /// This requires a type that was previously signed.
82    ///
83    /// # Preconditions
84    ///
85    /// `self` must be non-negative but is `>= 0` and `<= Signed::MAX`.
86    ///
87    /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
88    #[inline(always)]
89    fn write_integer_signed<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
90        self,
91        buffer: &mut [u8],
92    ) -> usize {
93        self.write_integer::<FORMAT, MASK, SHIFT>(buffer)
94    }
95
96    write_mantissa!(Compact);
97    write_exponent!(Compact);
98}
99
100/// Write integer trait, implemented in terms of the optimized, decimal
101/// back-end.
102#[cfg(all(not(feature = "compact"), not(feature = "power-of-two")))]
103pub trait WriteInteger: Decimal {
104    /// Forward write integer parameters to an optimized backend.
105    ///
106    /// # Preconditions
107    ///
108    /// `self` must be non-negative and unsigned.
109    ///
110    /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
111    #[inline(always)]
112    fn write_integer<const __: u128, const ___: u128, const ____: i32>(
113        self,
114        buffer: &mut [u8],
115    ) -> usize {
116        self.decimal(buffer)
117    }
118
119    /// Forward write integer parameters to an optimized backend.
120    ///
121    /// This requires a type that was previously signed.
122    ///
123    /// # Preconditions
124    ///
125    /// `self` must be non-negative but is `>= 0` and `<= Signed::MAX`.
126    ///
127    /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
128    #[inline(always)]
129    fn write_integer_signed<const __: u128, const ___: u128, const ____: i32>(
130        self,
131        buffer: &mut [u8],
132    ) -> usize {
133        self.decimal_signed(buffer)
134    }
135
136    write_mantissa!(Decimal);
137    write_exponent!(Decimal);
138}
139
140/// Write integer trait, implemented in terms of the optimized, decimal or radix
141/// back-end.
142#[cfg(all(not(feature = "compact"), feature = "power-of-two"))]
143pub trait WriteInteger: Decimal + Radix {
144    /// Forward write integer parameters to an optimized backend.
145    ///
146    /// # Preconditions
147    ///
148    /// `self` must be non-negative and unsigned.
149    ///
150    /// [`FORMATTED_SIZE`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE
151    /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
152    #[inline(always)]
153    fn write_integer<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
154        self,
155        buffer: &mut [u8],
156    ) -> usize {
157        if format::radix_from_flags(FORMAT, MASK, SHIFT) == 10 {
158            self.decimal(buffer)
159        } else {
160            self.radix::<FORMAT, MASK, SHIFT>(buffer)
161        }
162    }
163
164    /// Forward write integer parameters to an optimized backend.
165    ///
166    /// This requires a type that was previously signed.
167    ///
168    /// # Preconditions
169    ///
170    /// `self` must be non-negative but is `>= 0` and `<= Signed::MAX`.
171    ///
172    /// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
173    #[inline(always)]
174    fn write_integer_signed<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
175        self,
176        buffer: &mut [u8],
177    ) -> usize {
178        if format::radix_from_flags(FORMAT, MASK, SHIFT) == 10 {
179            self.decimal_signed(buffer)
180        } else {
181            self.radix::<FORMAT, MASK, SHIFT>(buffer)
182        }
183    }
184
185    write_mantissa!(Decimal + Radix);
186    write_exponent!(Decimal + Radix);
187}
188
189macro_rules! write_integer_impl {
190    ($($t:ty)*) => ($(
191        impl WriteInteger for $t {}
192    )*)
193}
194
195write_integer_impl! { u8 u16 u32 u64 u128 usize }