1#[cfg(feature = "alloc")]
4pub extern crate alloc;
5pub extern crate core;
6#[cfg(feature = "std")]
7pub extern crate std;
8
9use core::cell::Cell;
10use core::fmt;
11use core::iter::{Enumerate, Peekable};
12use core::ops::Deref;
13use core::pin::Pin;
14
15pub use crate::error::{ErrorMarker, ResultConverter};
16pub use crate::values::get_value;
17use crate::{FastWritable, Values};
18
19pub struct TemplateLoop<I>
20where
21 I: Iterator,
22{
23 iter: Peekable<Enumerate<I>>,
24}
25
26impl<I> TemplateLoop<I>
27where
28 I: Iterator,
29{
30 #[inline]
31 pub fn new(iter: I) -> Self {
32 TemplateLoop {
33 iter: iter.enumerate().peekable(),
34 }
35 }
36}
37
38impl<I> Iterator for TemplateLoop<I>
39where
40 I: Iterator,
41{
42 type Item = (<I as Iterator>::Item, LoopItem);
43
44 #[inline]
45 fn next(&mut self) -> Option<(<I as Iterator>::Item, LoopItem)> {
46 self.iter.next().map(|(index0, item)| {
47 (
48 item,
49 LoopItem {
50 index0,
51 last: self.iter.peek().is_none(),
52 },
53 )
54 })
55 }
56}
57
58#[derive(Copy, Clone)]
59pub struct LoopItem {
60 pub index0: usize,
61 pub last: bool,
62}
63
64pub struct FmtCell<F> {
65 func: Cell<Option<F>>,
66 err: Cell<Option<crate::Error>>,
67}
68
69impl<F> FmtCell<F>
70where
71 F: for<'a, 'b> FnOnce(&'a mut fmt::Formatter<'b>) -> crate::Result<()>,
72{
73 #[inline]
74 pub fn new(f: F) -> Self {
75 Self {
76 func: Cell::new(Some(f)),
77 err: Cell::new(None),
78 }
79 }
80
81 #[inline]
82 pub fn take_err(&self) -> crate::Result<()> {
83 Err(self.err.take().unwrap_or(crate::Error::Fmt))
84 }
85}
86
87impl<F> fmt::Display for FmtCell<F>
88where
89 F: for<'a, 'b> FnOnce(&'a mut fmt::Formatter<'b>) -> crate::Result<()>,
90{
91 #[inline]
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 if let Some(func) = self.func.take()
94 && let Err(err) = func(f)
95 {
96 self.err.set(Some(err));
97 return Err(fmt::Error);
98 }
99 Ok(())
100 }
101}
102
103#[inline]
104pub fn get_primitive_value<T: PrimitiveType>(value: T) -> T::Value {
105 value.get()
106}
107
108pub trait PrimitiveType {
110 type Value: Copy + Send + Sync + 'static;
111
112 fn get(&self) -> Self::Value;
113}
114
115macro_rules! primitive_type {
116 ($($ty:ty),* $(,)?) => {$(
117 impl PrimitiveType for $ty {
118 type Value = $ty;
119
120 #[inline]
121 fn get(&self) -> Self::Value {
122 *self
123 }
124 }
125 )*};
126}
127
128primitive_type! {
129 bool,
130 f32, f64,
131 i8, i16, i32, i64, i128, isize,
132 u8, u16, u32, u64, u128, usize,
133}
134
135crate::impl_for_ref! {
136 impl PrimitiveType for T {
137 type Value = T::Value;
138
139 #[inline]
140 fn get(&self) -> Self::Value {
141 <T>::get(self)
142 }
143 }
144}
145
146impl<T> PrimitiveType for Pin<T>
147where
148 T: Deref,
149 <T as Deref>::Target: PrimitiveType,
150{
151 type Value = <<T as Deref>::Target as PrimitiveType>::Value;
152
153 #[inline]
154 fn get(&self) -> Self::Value {
155 self.as_ref().get_ref().get()
156 }
157}
158
159impl<T: PrimitiveType + Copy> PrimitiveType for Cell<T> {
179 type Value = T::Value;
180
181 #[inline]
182 fn get(&self) -> Self::Value {
183 self.get().get()
184 }
185}
186
187impl<T: PrimitiveType> PrimitiveType for core::num::Wrapping<T> {
188 type Value = T::Value;
189
190 #[inline]
191 fn get(&self) -> Self::Value {
192 self.0.get()
193 }
194}
195
196impl<T: PrimitiveType> PrimitiveType for core::num::Saturating<T> {
197 type Value = T::Value;
198
199 #[inline]
200 fn get(&self) -> Self::Value {
201 self.0.get()
202 }
203}
204
205macro_rules! primitize_nz {
206 ($($nz:ty => $bare:ident,)+) => { $(
207 impl PrimitiveType for $nz {
208 type Value = $bare;
209
210 #[inline]
211 fn get(&self) -> Self::Value {
212 <$nz>::get(*self).get()
213 }
214 }
215 )+ };
216}
217
218primitize_nz! {
219 core::num::NonZeroI8 => i8,
220 core::num::NonZeroI16 => i16,
221 core::num::NonZeroI32 => i32,
222 core::num::NonZeroI64 => i64,
223 core::num::NonZeroI128 => i128,
224 core::num::NonZeroIsize => isize,
225 core::num::NonZeroU8 => u8,
226 core::num::NonZeroU16 => u16,
227 core::num::NonZeroU32 => u32,
228 core::num::NonZeroU64 => u64,
229 core::num::NonZeroU128 => u128,
230 core::num::NonZeroUsize => usize,
231}
232
233#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
235pub struct Empty;
236
237impl fmt::Display for Empty {
238 #[inline]
239 fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
240 Ok(())
241 }
242}
243
244impl FastWritable for Empty {
245 #[inline]
246 fn write_into(&self, _: &mut dyn fmt::Write, _: &dyn Values) -> crate::Result<()> {
247 Ok(())
248 }
249}
250
251impl fmt::Write for Empty {
252 #[inline]
253 fn write_str(&mut self, _: &str) -> fmt::Result {
254 Ok(())
255 }
256
257 #[inline]
258 fn write_char(&mut self, _: char) -> fmt::Result {
259 Ok(())
260 }
261}
262
263#[inline]
264pub fn as_bool<T: PrimitiveType<Value = bool>>(value: T) -> bool {
265 value.get()
266}
267
268pub struct Concat<L, R>(pub L, pub R);
269
270impl<L: fmt::Display, R: fmt::Display> fmt::Display for Concat<L, R> {
271 #[inline]
272 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
273 self.0.fmt(f)?;
274 self.1.fmt(f)
275 }
276}
277
278impl<L: FastWritable, R: FastWritable> FastWritable for Concat<L, R> {
279 #[inline]
280 fn write_into(&self, dest: &mut dyn fmt::Write, values: &dyn Values) -> crate::Result<()> {
281 self.0.write_into(dest, values)?;
282 self.1.write_into(dest, values)
283 }
284}
285
286pub trait EnumVariantTemplate {
287 fn render_into_with_values(
288 &self,
289 writer: &mut dyn fmt::Write,
290 values: &dyn crate::Values,
291 ) -> crate::Result<()>;
292}