devela/build/generate/
tuple.rs

1// devela build::generate::tuple
2//
3//! Code generator for the [`Tuple`] trait, `TupleElement*` enums and `TupleIter*` structs.
4//
5// TOC
6// - Tuple trait definition
7// - manual Tuple impls for arities < 2
8// - automatic Tuple impls for arities >= 2
9// - enums definitions
10// - iterators definitions and implementations
11//
12
13use super::super::utils::*;
14use std::{
15    fs::{create_dir_all, File},
16    io::{BufWriter, Error, Write},
17    write as w0, writeln as w,
18};
19
20#[rustfmt::skip] const MAX_ARITY: usize = {
21    if cfg!(not(feature = "_tuple_24")) { 12
22    } else if cfg!(all(feature = "_tuple_24", not(feature = "_tuple_36"))) { 24
23    } else if cfg!(all(feature = "_tuple_36", not(feature = "_tuple_48"))) { 36
24    } else if cfg!(all(feature = "_tuple_48", not(feature = "_tuple_72"))) { 48
25    } else { 72 }
26};
27
28#[rustfmt::skip]
29pub(crate) fn generate() -> Result<(), Error> {
30    let build_out_dir = out_dir().join("build/");
31    create_dir_all(&build_out_dir)?;
32    let path = build_out_dir.join("tuple.rs");
33
34    // the generated file will be imported from /src/data/collections/tuple/mod.rs
35    #[cfg(feature = "__dbg")]
36    println(&format!("generated: {}", path.display()));
37
38    let file = File::create(path)?;
39    let mut f = BufWriter::new(file);
40    // let mut f = BufWriter::with_capacity(100 * 1024, file);
41
42    /* Tuple trait definition */
43    // --------------------------------------------------------------------------
44
45    w!(f, r#"
46#[doc = crate::TAG_DATA_STRUCTURE!()]
47/// Extension trait providing convenience methods for [tuples][tuple].
48///
49/// This trait is sealed and cannot be implemented for any other type.
50///
51/// Tuples are random-access, sequentially allocated, statically sized,
52/// heterogeneous data structures.
53///
54/// They enable structured grouping and access to a sequence of different types.
55///
56/// # Features
57/// By default it's implemented for tuples of arity of 12 or less.
58/// It supports increased arities of 24, 36, 48 and 72 by enabling the
59/// corresponding capability feature: `_tuple_[24|36|48|72]`.
60///
61/// # Vendored
62/// This is adapted work from [tupl][crate::_info::vendored#tupl]"#)?;
63// In sync with code::utils::_doc::doc_!(vendor:)
64
65    w!(f, "{TAB1}#[cfg_attr(feature = \"nightly_doc\", doc(notable_trait))]
66    #[cfg_attr(feature = \"nightly_doc\", doc(notable_trait))]
67    #[allow(private_bounds)]
68    pub trait Tuple: Sealed {{
69
70    /* constants */
71
72    /// The arity of this tuple (the number of contained elements)
73    const ARITY: usize;
74
75    /* name fields */
76    /// The first element of the tuple, at index 0.
77    type Head;
78    /// The last element of the tuple, at index `ARITY-1`.
79    type Tail;
80
81    /// This tuple without its head.
82    type NoHead;
83    /// This tuple without its tail.
84    type NoTail;
85    /// This tuple with an extra element `T` appended to it.
86    type Append<T>;
87    /// This tuple with an extra element `T` prepended to it.
88    type Prepend<T>;
89    ")?;
90
91    // index fields
92    for i in 0..MAX_ARITY {
93        w!(f, "{TAB1}/// The type of the element at index {}.", i)?;
94        w!(f, "{TAB1}type _{};", i)?;
95    }
96
97    w!(f, r#"
98    /// The maximum arity supported by the current compilation options.
99    ///
100    /// See the available [features](#features) to increase this number."#)?;
101    w!(f, "{TAB1}const MAX_ARITY: usize = {MAX_ARITY};")?;
102
103    /* Tuple methods */
104
105    w!(f, "{TAB1}/// Returns a shared reference to the head of this tuple.
106    #[must_use]
107    fn head(&self) -> &Self::Head;")?;
108    w!(f, "{TAB1}/// Returns a shared reference to the tail of this tuple.
109    #[must_use]
110    fn tail(&self) -> &Self::Tail;")?;
111
112    w!(f, "{TAB1}/// Returns an exclusive reference to the head of this tuple.
113    #[must_use]
114    fn head_mut(&mut self) -> &mut Self::Head;")?;
115    w!(f, "{TAB1}/// Returns an exclusive reference to the tail of this tuple.
116    #[must_use]
117    fn tail_mut(&mut self) -> &mut Self::Tail;")?;
118
119    w!(f, "{TAB1}/// Returns this tuple with the head element splitted from the rest.
120    #[must_use]
121    fn split_head(self) -> (Self::Head, Self::NoHead);")?;
122    w!(f, "{TAB1}/// Returns this tuple with the tail element splitted from the rest.
123    #[must_use]
124    fn split_tail(self) -> (Self::NoTail, Self::Tail);")?;
125
126    w!(f, "{TAB1}/// Returns this tuple without the head.
127    #[must_use]
128    fn no_head(self) -> Self::NoHead;")?;
129    w!(f, "{TAB1}/// Returns this tuple without the tail.
130    #[must_use]
131    fn no_tail(self) -> Self::NoTail;")?;
132
133    w!(f, "{TAB1}/// Appends the given `value` to this tuple.
134    #[must_use]
135    fn append<T>(self, value: T) -> Self::Append<T>;")?;
136    w!(f, "{TAB1}/// Prepends the given `value` to this tuple.
137    #[must_use]
138    fn prepend<T>(self, value: T) -> Self::Prepend<T>;")?;
139
140    // nth
141    w!(f, "{TAB1}/// Returns the `nth` element, or `None` if `nth >= ARITY`.
142    #[allow(clippy::type_complexity)]
143    fn nth(self, nth: usize) -> Option<TupleElement<")?;
144        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
145        w!(f, ">>;")?;
146
147    w!(f, "{TAB1}/// Returns the `nth` element cloned, or `None` if `nth >= ARITY`.
148    #[allow(clippy::type_complexity)]
149    fn nth_cloned(&self, nth: usize) -> Option<TupleElement<")?;
150        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
151        w!(f, ">> where ")?;
152        for i in 0..MAX_ARITY {
153            w0!(f, "Self::_{i}: Clone")?;
154            if i == MAX_ARITY-1 { w!(f, ";")?; } else { w0!(f, ",")?; }
155        }
156
157    w!(f, "{TAB1}/// Returns a shared reference to the `nth` element,
158    /// or `None` if `nth >= ARITY`.
159    #[allow(clippy::type_complexity)]
160    fn nth_ref(&self, nth: usize) -> Option<TupleElementRef<")?;
161        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
162        w!(f, ">>;")?;
163
164    w!(f, "{TAB1}/// Returns an exclusive reference to the `nth` element,
165    /// or `None` if `nth >= ARITY`.
166    #[allow(clippy::type_complexity)]
167    fn nth_mut(&mut self, nth: usize) -> Option<TupleElementMut<")?;
168        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
169        w!(f, ">>;")?;
170
171    // iter
172    w0!(f, "{TAB1}/// Returns an iterator over elements of the tuple.
173    #[allow(clippy::type_complexity)]
174    fn into_iter(self) -> TupleIter<")?;
175        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
176        w!(f, ">;")?;
177    w0!(f, "{TAB1}/// Returns an iterator over shared references to elements of the tuple.
178    #[allow(clippy::type_complexity)]
179    fn iter_ref(&self) -> TupleIterRef<")?;
180        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
181        w!(f, ">;")?;
182    w!(f, "{TAB1}/// Returns an iterator over exclusive reference to elements of the tuple.
183    #[allow(clippy::type_complexity)]
184    fn iter_mut(&mut self) -> TupleIterMut<")?;
185        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
186        w!(f, ">;")?;
187
188    /* Tuple auto-implemented methods */
189
190    w!(f, "{TAB1}/// Returns the arity (number of elements) of this tuple.
191    #[must_use]
192    fn arity(&self) -> usize {{ Self::ARITY }}")?;
193
194    w!(f, "{TAB1}/// Wraps the tuple in a [`TupleFmt`] for formatting purposes.
195    fn fmt(&self) -> TupleFmt<Self> where Self: Sized {{ TupleFmt(self) }}")?;
196
197    w!(f, "}}")?; // end define Tuple
198
199
200    /* manual implementations of Tuple for arities of 0 and 1 */
201    // --------------------------------------------------------------------------
202
203    /* arity 0 */
204
205    w!(f, "impl Sealed for () {{}}")?;
206
207    w!(f, r#"impl Tuple for () {{
208    const ARITY: usize = 0;
209
210    type Head = ();
211    type Tail = ();
212    type NoHead = ();
213    type NoTail = ();
214    type Append<T> = (T,);
215    type Prepend<T> = (T,);
216
217    // methods
218    fn head(&self) -> &Self::Head {{ self }}
219    fn tail(&self) -> &Self::Tail {{ self }}
220    fn head_mut(&mut self) -> &mut Self::Head {{ self }}
221    fn tail_mut(&mut self) -> &mut Self::Tail {{ self }}
222    fn split_head(self) -> (Self::Head, Self::NoHead) {{ ((), ()) }}
223    fn split_tail(self) -> (Self::NoTail, Self::Tail) {{ ((), ()) }}
224    fn no_head(self) -> Self::NoHead {{}}
225    fn no_tail(self) -> Self::NoTail {{}}
226    fn append<T>(self, value: T) -> Self::Append<T> {{ (value,) }}
227    fn prepend<T>(self, value: T) -> Self::Prepend<T> {{ (value,) }}
228    "#)?;
229
230        // index types
231        for i in 0..MAX_ARITY { w!(f, "{TAB1}type _{i} = ();")?; }
232
233        /* methods */
234
235        // nth
236        w!(f, "\n{TAB1}fn nth(self, _nth: usize) -> Option<TupleElement<")?;
237        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> {{")?;
238            w!(f, "{TAB2}None")?;
239        w!(f, "{TAB1}}}")?;
240        w!(f, "{TAB1}fn nth_cloned(&self, _nth: usize) -> Option<TupleElement<")?;
241        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> where ")?;
242            for i in 0..MAX_ARITY { w0!(f, "Self::_{i}: Clone,")?; }
243            w!(f, "{{")?;
244                w!(f, "{TAB2}None")?;
245        w!(f, "{TAB1}}}")?;
246        w!(f, "{TAB1}fn nth_ref(&self, _nth: usize) -> Option<TupleElementRef<")?;
247        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> {{")?;
248            w!(f, "{TAB2}None")?;
249        w!(f, "{TAB1}}}")?;
250        w!(f, "{TAB1}fn nth_mut(&mut self, _nth: usize) -> Option<TupleElementMut<")?;
251        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> {{")?;
252            w!(f, "{TAB2}None")?;
253            w!(f, "{TAB1}}}")?;
254
255        // iter
256        w0!(f, "{TAB1}fn into_iter(self) -> TupleIter<")?;
257        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
258        w0!(f, "> {{
259        TupleIter {{
260            tuple: (")?; for _ in 0..MAX_ARITY { w0!(f, "None, ")?; } w!(f, "),
261            front_index: 0,
262            back_index: 0,
263        }}
264    }}")?;
265        w0!(f, "{TAB1}fn iter_ref(&self) -> TupleIterRef<")?;
266        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
267        w0!(f, "> {{
268        TupleIterRef {{
269            tuple: (")?; for _ in 0..MAX_ARITY { w0!(f, "&(), ")?; } w!(f, "),
270            front_index: 0,
271            back_index: 0,
272        }}
273    }}")?;
274        w0!(f, "{TAB1}fn iter_mut(&mut self) -> TupleIterMut<")?;
275        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
276        w0!(f, "> {{
277        TupleIterMut {{
278            tuple: (")?; for _ in 0..MAX_ARITY { w0!(f, "None, ")?; } w!(f, "),
279            front_index: 0,
280            back_index: 0,
281        }}
282    }}")?;
283
284    w!(f, "}}")?;
285
286    w!(f, r#"
287impl TupleDebug for () {{
288    fn fmt_debug(&self, f: &mut Formatter) -> FmtResult<()> {{
289        f.debug_tuple("").finish()
290    }}
291}}
292impl TupleDisplay for () {{
293    fn fmt_display(&self, f: &mut Formatter) -> FmtResult<()> {{
294        write!(f, "()")
295    }}
296}}"#)?;
297
298    /* arity 1 */
299
300    w!(f, "impl<_0> Sealed for (_0,) {{}}")?;
301
302    w!(f, r#"impl<_0> Tuple for (_0,) {{
303    const ARITY: usize = 1;
304
305    type Head = _0;
306    type Tail = _0;
307    type NoHead = ();
308    type NoTail = ();
309    type Append<T> = (_0, T);
310    type Prepend<T> = (T, _0);
311
312    // methods
313    fn head(&self) -> &Self::Head {{ &self.0 }}
314    fn tail(&self) -> &Self::Tail {{ &self.0 }}
315    fn head_mut(&mut self) -> &mut Self::Head {{ &mut self.0 }}
316    fn tail_mut(&mut self) -> &mut Self::Tail {{ &mut self.0 }}
317    fn split_head(self) -> (Self::Head, Self::NoHead) {{ (self.0, ()) }}
318    fn split_tail(self) -> (Self::NoTail, Self::Tail) {{ ((), self.0) }}
319    fn no_head(self) -> Self::NoHead {{}}
320    fn no_tail(self) -> Self::NoTail {{}}
321    fn append<T>(self, value: T) -> Self::Append<T> {{ (self.0, value) }}
322    fn prepend<T>(self, value: T) -> Self::Prepend<T> {{ (value, self.0) }}
323    "#)?;
324
325        // index types
326        w!(f, "type _0 = _0;")?;
327        for i in 1..MAX_ARITY { w!(f, "type _{i} = ();")?; }
328
329        /* methods */
330
331        // nth
332        w0!(f, "{TAB1}fn nth(self, nth: usize) -> Option<TupleElement<")?;
333        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> {{")?;
334            w!(f, "{TAB2}match nth {{")?;
335                w!(f, "{TAB3}0 => Some(TupleElement::_0(self.0)),")?;
336                w!(f, "{TAB3}_ => None,")?;
337            w!(f, "{TAB2}}}")?;
338        w!(f, "{TAB1}}}")?;
339        w0!(f, "{TAB1}fn nth_cloned(&self, nth: usize) -> Option<TupleElement<")?;
340        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> where ")?;
341            for i in 0..MAX_ARITY { w0!(f, "Self::_{i}: Clone,")?; }
342            w!(f, "{{")?;
343            w!(f, "{TAB2}match nth {{")?;
344                w!(f, "{TAB3}0 => Some(TupleElement::_0(self.0.clone())),")?;
345                w!(f, "{TAB3}_ => None,")?;
346            w!(f, "{TAB2}}}")?;
347        w!(f, "{TAB1}}}")?;
348        w0!(f, "{TAB1}fn nth_ref(&self, nth: usize) -> Option<TupleElementRef<")?;
349        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> {{")?;
350            w!(f, "{TAB2}match nth {{")?;
351                w!(f, "{TAB3}0 => Some(TupleElementRef::_0(&self.0)),")?;
352                w!(f, "{TAB3}_ => None,")?;
353            w!(f, "{TAB2}}}")?;
354        w!(f, "{TAB1}}}")?;
355        w0!(f, "{TAB1}fn nth_mut(&mut self, nth: usize) -> Option<TupleElementMut<")?;
356        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> {{")?;
357            w!(f, "{TAB2}match nth {{")?;
358                w!(f, "{TAB3}0 => Some(TupleElementMut::_0(&mut self.0)),")?;
359                w!(f, "{TAB3}_ => None,")?;
360            w!(f, "{TAB2}}}")?;
361        w!(f, "{TAB1}}}")?;
362
363        // iter
364        w0!(f, "{TAB1}fn into_iter(self) -> TupleIter<")?;
365        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
366        w0!(f, "> {{
367        TupleIter {{
368            tuple: (Some(self.0), ")?;
369                for _ in 1..MAX_ARITY { w0!(f, "None, ")?; }
370                w!(f, "),
371            front_index: 0,
372            back_index: 0,
373        }}
374    }}")?;
375        w0!(f, "{TAB1}fn iter_ref(&self) -> TupleIterRef<")?;
376        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
377        w0!(f, "> {{
378        TupleIterRef {{
379            tuple: (&self.0, ")?;
380                for _ in 1..MAX_ARITY { w0!(f, "&(), ")?; }
381                w!(f, "),
382            front_index: 0,
383            back_index: 0,
384        }}
385    }}")?;
386        w0!(f, "{TAB1}fn iter_mut(&mut self) -> TupleIterMut<")?;
387        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
388        w0!(f, "> {{
389        TupleIterMut {{
390            tuple: (Some(&mut self.0), ")?;
391                for _ in 1..MAX_ARITY { w0!(f, "None, ")?; }
392                w!(f, "),
393            front_index: 0,
394            back_index: 0,
395        }}
396    }}")?;
397
398    w!(f, "}}")?;
399
400    w!(f, r#"
401impl<_0: Debug> TupleDebug for (_0,) {{
402    fn fmt_debug(&self, f: &mut Formatter) -> FmtResult<()> {{
403        f.debug_tuple("").field(&self.0).finish()
404    }}
405}}
406impl<_0: Display> TupleDisplay for (_0,) {{
407    fn fmt_display(&self, f: &mut Formatter) -> FmtResult<()> {{
408        write!(f, "({{}},)", &self.0)
409    }}
410}}"#)?;
411
412
413    /* auto implementations of Tuple for arities >= 2 */
414    // --------------------------------------------------------------------------
415
416    for arity in 2..=MAX_ARITY {
417        w0!(f, "impl<")?; for i in 0..arity { w0!(f, "_{i},")?; }
418        w0!(f, "> Sealed for (")?; for i in 0..arity { w0!(f, "_{i},")?; }
419        w!(f, ") {{}}")?;
420
421        w0!(f, "impl<")?; for i in 0..arity { w0!(f, "_{i},")?; }
422        w0!(f, "> Tuple for (")?; for i in 0..arity { w0!(f, "_{i},")?; }
423        w!(f, ") {{")?;
424
425        // constants
426        w!(f, "{TAB1}const ARITY: usize = {arity};")?;
427
428        // name fields
429        w!(f, "{TAB1}/// The first element of the tuple, at index 0.")?;
430        w!(f, "{TAB1}type Head = _0;")?;
431        w!(f, "{TAB1}/// The last element of the tuple, at index `ARITY-1`.")?;
432        w!(f, "{TAB1}type Tail = _{};", arity-1)?;
433
434        w!(f, "{TAB1}///.")?;
435        w0!(f, "{TAB1}type NoHead = (")?; for i in 1..arity { w0!(f, "_{i},")?; } w!(f, ");")?;
436        w0!(f, "{TAB1}type NoTail = (")?; for i in 0..arity-1 { w0!(f, "_{i},")?; } w!(f, ");")?;
437        w0!(f, "{TAB1}type Append<T> = (")?; for i in 0..arity { w0!(f, "_{i},")?; } w!(f, "T);")?;
438        w0!(f, "{TAB1}type Prepend<T> = (T, ")?; for i in 0..arity { w0!(f, "_{i},")?; } w!(f, ");")?;
439
440        // index fields
441        w!(f, "{TAB1}/// The type of the element at index 0 (the first field).")?;
442        w!(f, "{TAB1}type _0 = _0;")?;
443        for i in 1..arity-1 {
444            w!(f, "{TAB1}/// The type of the element at index {i}.")?;
445            w!(f, "{TAB1}type _{i} = _{i};")?;
446        }
447        if arity > 1 {
448            w!(f, "{TAB1}/// The type of the element at index {} (the last field).", arity-1)?;
449            w!(f, "{TAB1}type _{0} = _{0};", arity-1)?;
450        }
451        for i in arity..MAX_ARITY {
452            w!(f, "{TAB1}/// Non-existing element with current arity.")?;
453            w!(f, "{TAB1}type _{i} = ();")?;
454        }
455
456        /* Tuple methods */
457
458        w!(f, "{TAB1}fn head(&self) -> &Self::Head {{ &self.0 }}")?;
459        w!(f, "{TAB1}fn tail(&self) -> &Self::Tail {{ &self.{} }}", arity-1)?;
460        w!(f, "{TAB1}fn head_mut(&mut self) -> &mut Self::Head {{ &mut self.0 }}")?;
461        w!(f, "{TAB1}fn tail_mut(&mut self) -> &mut Self::Tail {{ &mut self.{} }}", arity-1)?;
462
463        w0!(f, "{TAB1}fn split_head(self) -> (Self::Head, Self::NoHead) {{ (self.0, (")?;
464            for i in 1..arity { w0!(f, "self.{i},")?; }
465        w!(f, ")) }}")?;
466
467        w0!(f, "{TAB1}fn split_tail(self) -> (Self::NoTail, Self::Tail) {{ ((")?;
468            for i in 0..arity-1 { w0!(f, "self.{i},")?; }
469        w!(f, "), self.{}) }}", arity-1)?;
470
471        w0!(f, "{TAB1}fn no_head(self) -> Self::NoHead {{ (")?;
472            for i in 1..arity { w0!(f, "self.{i},")?; }
473        w!(f, ") }}")?;
474        w0!(f, "{TAB1}fn no_tail(self) -> Self::NoTail {{ (")?;
475            for i in 0..arity-1 { w0!(f, "self.{i},")?; }
476        w!(f, ") }}")?;
477
478        w0!(f, "{TAB1}fn append<T>(self, value: T) -> Self::Append<T> {{ (")?;
479            for i in 0..arity { w0!(f, "self.{i},")?; }
480        w!(f, "value) }}")?;
481        w0!(f, "{TAB1}fn prepend<T>(self, value: T) -> Self::Prepend<T> {{ (value, ")?;
482            for i in 0..arity { w0!(f, "self.{i},")?; }
483        w!(f, ") }}")?;
484
485        // nth
486        w0!(f, "{TAB1}fn nth(self, nth: usize) -> Option<TupleElement<")?;
487        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
488        w!(f, ">> {{")?;
489            w!(f, "{TAB2}match nth {{")?;
490                for i in 0..arity {
491                    w!(f, "{TAB3}{i} => Some(TupleElement::_{i}(self.{i})),")?; }
492                w!(f, "{TAB3}_ => None")?;
493            w!(f, "{TAB2}}}")?;
494        w!(f, "{TAB1}}}")?;
495
496        w0!(f, "{TAB1}fn nth_cloned(&self, nth: usize) -> Option<TupleElement<")?;
497        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; } w!(f, ">> where ")?;
498            for i in 0..MAX_ARITY { w0!(f, "Self::_{i}: Clone,")?; }
499            w!(f, "{{")?;
500            w!(f, "{TAB2}match nth {{")?;
501                for i in 0..arity {
502                    w!(f, "{TAB3}{i} => Some(TupleElement::_{i}(self.{i}.clone())),")?; }
503                w!(f, "{TAB3}_ => None")?;
504            w!(f, "{TAB2}}}")?;
505        w!(f, "{TAB1}}}")?;
506        w0!(f, "{TAB1}fn nth_ref(&self, nth: usize) -> Option<TupleElementRef<")?;
507        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
508        w!(f, ">> {{")?;
509            w!(f, "{TAB2}match nth {{")?;
510                for i in 0..arity {
511                    w!(f, "{TAB3}{i} => Some(TupleElementRef::_{i}(&self.{i})),")?; }
512                w!(f, "{TAB3}_ => None")?;
513            w!(f, "{TAB2}}}")?;
514        w!(f, "{TAB1}}}")?;
515        w0!(f, "{TAB1}fn nth_mut(&mut self, nth: usize) -> Option<TupleElementMut<")?;
516        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
517        w!(f, ">> {{")?;
518            w!(f, "{TAB2}match nth {{")?;
519                for i in 0..arity {
520                    w!(f, "{TAB3}{i} => Some(TupleElementMut::_{i}(&mut self.{i})),")?; }
521                w!(f, "{TAB3}_ => None")?;
522            w!(f, "{TAB2}}}")?;
523        w!(f, "{TAB1}}}")?;
524
525        // iter
526        w0!(f, "{TAB1}fn into_iter(self) -> TupleIter<")?;
527        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
528        w0!(f, "> {{
529        let back_index = self.arity() - 1;
530        TupleIter {{
531            tuple: (Some(self.0), Some(self.1), ")?;
532                for i in 2..arity { w0!(f, "Some(self.{i}), ")?; }
533                for _ in arity..MAX_ARITY { w0!(f, "None, ")?; }
534                w!(f, "),
535            front_index: 0,
536            back_index,
537        }}
538    }}")?;
539        w0!(f, "{TAB1}fn iter_ref(&self) -> TupleIterRef<")?;
540        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
541        w0!(f, "> {{
542        let back_index = self.arity() - 1;
543        TupleIterRef {{
544            tuple: (&self.0, &self.1, ")?;
545                for i in 2..arity { w0!(f, "&self.{i}, ")?; }
546                for _ in arity..MAX_ARITY { w0!(f, "&(), ")?; }
547                w!(f, "),
548            front_index: 0,
549            back_index,
550        }}
551    }}")?;
552        w0!(f, "{TAB1}fn iter_mut(&mut self) -> TupleIterMut<")?;
553        for i in 0..MAX_ARITY { w0!(f, "Self::_{i},")?; }
554        w0!(f, "> {{
555        let back_index = self.arity() - 1;
556        TupleIterMut {{
557            tuple: (Some(&mut self.0), Some(&mut self.1), ")?;
558                for i in 2..arity { w0!(f, "Some(&mut self.{i}), ")?; }
559                for _ in arity..MAX_ARITY { w0!(f, "None, ")?; }
560                w!(f, "),
561            front_index: 0,
562            back_index,
563        }}
564    }}")?;
565
566        w!(f, "}}")?; // end impl Tuple
567
568        /* impl other traits */
569
570        w!(f, "#[rustfmt::skip]")?;
571        w0!(f, "impl<")?; for i in 0..arity { w0!(f, "_{i}: Debug, ")?; }
572        w0!(f, "> TupleDebug for (")?; for i in 0..arity { w0!(f, "_{i},")?; }
573        w!(f, ") {{\n{TAB1}fn fmt_debug(&self, f: &mut Formatter) -> FmtResult<()> {{")?;
574            w0!(f, "{TAB2}f.debug_tuple(\"\")")?;
575                for i in 0..arity { w0!(f, ".field(&self.{i})")?; }
576                w!(f, ".finish()")?;
577        w!(f, "{TAB1}}}\n}}")?;
578
579        w!(f, "#[rustfmt::skip]")?;
580        w0!(f, "impl<")?; for i in 0..arity { w0!(f, "_{i}: Display, ")?; }
581        w0!(f, "> TupleDisplay for (")?; for i in 0..arity { w0!(f, "_{i},")?; }
582        w!(f, ") {{\n{TAB1}fn fmt_display(&self, f: &mut Formatter) -> FmtResult<()> {{")?;
583            w!(f, "{TAB2}write!(f, \"({{}}\", &self.0)?;")?;
584                for i in 1..arity { w!(f, "{TAB2}write!(f, \", {{}}\", &self.{i})?;")?; }
585            w!(f, "{TAB2}write!(f, \")\")")?;
586        w!(f, "{TAB1}}}\n}}")?;
587    }
588
589
590    /* enums definitions */
591    // --------------------------------------------------------------------------
592
593    w!(f, "/// An element of a [`Tuple`].")?;
594    w!(f, "#[non_exhaustive]")?;
595    w!(f, "#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]")?;
596    w0!(f, "pub enum TupleElement<")?;
597        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
598        // variants
599        for i in 0..MAX_ARITY {
600            w!(f, "{TAB1}/// The tuple element at index {i}.")?;
601            w!(f, "{TAB1}_{i}(_{i}),")?;
602        }
603    w!(f, "}}")?;
604
605    w!(f, "/// A shared reference to an element of a [`Tuple`].")?;
606    w!(f, "#[non_exhaustive]")?;
607    w!(f, "#[derive(Debug, PartialEq, Eq, Hash)]")?;
608    w0!(f, "pub enum TupleElementRef<'a, ")?;
609        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
610        // variants
611        for i in 0..MAX_ARITY {
612            w!(f, "{TAB1}/// A shared reference to the tuple element at index {i}.")?;
613            w!(f, "{TAB1}_{i}(&'a _{i}),")?;
614        }
615    w!(f, "}}")?;
616
617    w!(f, "/// An exclusive reference to an element of a [`Tuple`].")?;
618    w!(f, "#[non_exhaustive]")?;
619    w!(f, "#[derive(Debug, PartialEq, Eq, Hash)]")?;
620    w0!(f, "pub enum TupleElementMut<'a, ")?;
621        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
622        // variants
623        for i in 0..MAX_ARITY {
624            w!(f, "{TAB1}/// An exclusive reference to the tuple element at index {i}.")?;
625            w!(f, "{TAB1}_{i}(&'a mut _{i}),")?;
626        }
627    w!(f, "}}")?;
628
629
630    /* iterators definitions */
631    // --------------------------------------------------------------------------
632
633    // into
634    w!(f, r"#[doc = crate::TAG_ITERATOR!()]")?;
635    w!(f, "/// An iterator over elements of a [`Tuple`].")?;
636    w!(f, "#[derive(Clone)]")?;
637    w0!(f, "pub struct TupleIter<")?;
638        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
639        // fields
640        w!(f, "#[allow(clippy::type_complexity)]")?;
641        w!(f, "tuple: (")?;
642            for i in 0..MAX_ARITY { w0!(f, "Option<_{i}>,")?; } w!(f, "),")?;
643        w!(f, "front_index: usize,")?;
644        w!(f, "back_index: usize,")?;
645    w!(f, "}}")?;
646    // methods
647    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w0!(f, "> TupleIter<")?;
648        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
649        w!(f, "{TAB1}/// Returns the remaining elements in the iterator.
650    pub const fn remaining(&self) -> usize {{ self.back_index + 1 - self.front_index }}
651}}")?;
652
653    // ref
654    w!(f, r"#[doc = crate::TAG_ITERATOR!()]")?;
655    w!(f, "/// An iterator over shared references to elements of a [`Tuple`].")?;
656    w!(f, "#[derive(Clone)]")?;
657    w!(f, "pub struct TupleIterRef<'a, ")?;
658        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
659        // fields
660        w!(f, "#[allow(clippy::type_complexity)]")?;
661        w!(f, "tuple: (")?;
662            for i in 0..MAX_ARITY { w0!(f, "&'a _{i},")?; } w!(f, "),")?;
663        w!(f, "front_index: usize,")?;
664        w!(f, "back_index: usize,")?;
665    w!(f, "}}")?;
666    // methods
667    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w0!(f, "> TupleIterRef<'_, ")?;
668        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
669        w!(f, "/// Returns the remaining elements in the iterator.
670        pub const fn remaining(&self) -> usize {{ self.back_index + 1 - self.front_index }}
671    }}")?;
672
673    // mut
674    w!(f, r"#[doc = crate::TAG_ITERATOR!()]")?;
675    w!(f, "/// An iterator over exclusive references to elements of a [`Tuple`].")?;
676    w!(f, "pub struct TupleIterMut<'a, ")?;
677        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
678        // fields
679        w!(f, "#[allow(clippy::type_complexity)]")?;
680        w!(f, "tuple: (")?;
681            for i in 0..MAX_ARITY { w0!(f, "Option<&'a mut _{i}>,")?; } w!(f, "),")?;
682        w!(f, "front_index: usize,")?;
683        w!(f, "back_index: usize,")?;
684    w!(f, "}}")?;
685    // methods
686    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> TupleIterMut<'_, ")?;
687        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
688        w!(f, "/// Returns the remaining elements in the iterator.
689        pub const fn remaining(&self) -> usize {{ self.back_index + 1 - self.front_index }}
690    }}")?;
691
692    /* iterators traits implementations */
693    // --------------------------------------------------------------------------
694
695    // Into
696    w!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
697    w!(f, "> Iterator for TupleIter<")?;
698        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
699        w0!(f, "{TAB1}type Item = TupleElement<")?;
700        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w0!(f, ">;")?;
701        //
702        w!(f, "{TAB1}fn next(&mut self) -> Option<Self::Item> {{
703            #[allow(clippy::never_loop)]
704            if self.front_index > self.back_index {{
705                None
706            }} else {{
707                let result = match self.front_index {{")?;
708                    for i in 0..MAX_ARITY {
709                        w!(f, "{TAB5}{i} => self.tuple.{i}.take().map(TupleElement::_{i}),")?;
710                    }
711                    w!(f, "{TAB5}_ => None,
712                }};
713                self.front_index += 1;
714                result
715            }}
716        }}
717        fn size_hint(&self) -> (usize, Option<usize>) {{
718            (self.remaining(), Some(self.remaining()))
719        }}
720        fn count(self) -> usize {{ self.remaining() }}
721    }}")?;
722    //
723    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
724    w0!(f, "> DoubleEndedIterator for TupleIter<")?;
725        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
726        w!(f, "{TAB1}fn next_back(&mut self) -> Option<Self::Item> {{
727            #[allow(clippy::never_loop)]
728            if self.front_index > self.back_index {{
729                None
730            }} else {{
731                let result = match self.back_index {{")?;
732                    for i in 0..MAX_ARITY {
733                        w!(f, "{TAB5}{i} => self.tuple.{i}.take().map(TupleElement::_{i}),")?;
734                    }
735                    w!(f, "{TAB5}_ => None,
736                }};
737                if self.back_index == 0 {{
738                    self.front_index = self.back_index + 1; // Ensure iteration stops
739                }} else {{
740                    self.back_index -= 1;
741                }}
742                result
743            }}
744        }}
745    }}")?;
746    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
747    w0!(f, "> ExactSizeIterator for TupleIter<")?;
748        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
749        w!(f, "{TAB1}fn len(&self) -> usize {{ self.remaining() }}
750    }}")?;
751    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
752    w0!(f, "> core::iter::FusedIterator for TupleIter<")?;
753        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{}}")?;
754
755    // Ref
756    w0!(f, "impl<'a, ")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
757    w0!(f, "> Iterator for TupleIterRef<'a, ")?;
758        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
759        w!(f, "type Item = TupleElementRef<'a, ")?;
760        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, ">;")?;
761        //
762        w!(f, "{TAB1}fn next(&mut self) -> Option<Self::Item> {{
763            #[allow(clippy::never_loop)]
764            if self.front_index > self.back_index {{
765                None
766            }} else {{
767                let result = match self.front_index {{")?;
768                    for i in 0..MAX_ARITY {
769                        w!(f, "{TAB5}{i} => Some(TupleElementRef::_{i}(self.tuple.{i})),")?;
770                    }
771                    w!(f, "{TAB5}_ => None,
772                }};
773                self.front_index += 1;
774                result
775            }}
776        }}
777        fn size_hint(&self) -> (usize, Option<usize>) {{
778            (self.remaining(), Some(self.remaining()))
779        }}
780        fn count(self) -> usize {{ self.remaining() }}
781    }}")?;
782    //
783    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
784    w0!(f, "> DoubleEndedIterator for TupleIterRef<'_, ")?;
785        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
786        w!(f, "{TAB1}fn next_back(&mut self) -> Option<Self::Item> {{
787            #[allow(clippy::never_loop)]
788            if self.front_index > self.back_index {{
789                None
790            }} else {{
791                let result = match self.back_index {{")?;
792                    for i in 0..MAX_ARITY {
793                        w!(f, "{TAB5}{i} => Some(TupleElementRef::_{i}(self.tuple.{i})),")?;
794                    }
795                    w!(f, "{TAB5}_ => None,
796                }};
797                if self.back_index == 0 {{
798                    self.front_index = self.back_index + 1; // Ensure iteration stops
799                }} else {{
800                    self.back_index -= 1;
801                }}
802                result
803            }}
804        }}
805    }}")?;
806    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
807    w0!(f, "> ExactSizeIterator for TupleIterRef<'_, ")?;
808        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
809        w!(f, "{TAB1}fn len(&self) -> usize {{ self.remaining() }}
810    }}")?;
811    // NOTE: better not to implement FusedIterator
812    // w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
813    // w0!(f, "> core::iter::FusedIterator for TupleIterRef<'_, ")?;
814    //     for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{}}")?;
815
816    // Mut
817    w0!(f, "impl<'a, ")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
818    w0!(f, "> Iterator for TupleIterMut<'a, ")?;
819        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
820        w0!(f, "type Item = TupleElementMut<'a, ")?;
821        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, ">;")?;
822        //
823        w!(f, "{TAB1}fn next(&mut self) -> Option<Self::Item> {{
824            #[allow(clippy::never_loop)]
825            if self.front_index > self.back_index {{
826                None
827            }} else {{
828                let result = match self.front_index {{")?;
829                    for i in 0..MAX_ARITY {
830                        w!(f, "{TAB5}{i} => self.tuple.{i}.take().map(TupleElementMut::_{i}),")?;
831                    }
832                    w!(f, "{TAB5}_ => None,
833                }};
834                self.front_index += 1;
835                result
836            }}
837        }}
838        fn size_hint(&self) -> (usize, Option<usize>) {{
839            (self.remaining(), Some(self.remaining()))
840        }}
841        fn count(self) -> usize {{ self.remaining() }}
842    }}")?;
843    //
844    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
845    w0!(f, "> DoubleEndedIterator for TupleIterMut<'_, ")?;
846        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
847        w!(f, "{TAB1}fn next_back(&mut self) -> Option<Self::Item> {{
848            #[allow(clippy::never_loop)]
849            if self.front_index > self.back_index {{
850                None
851            }} else {{
852                let result = match self.back_index {{")?;
853                    for i in 0..MAX_ARITY {
854                        w!(f, "{TAB5}{i} => self.tuple.{i}.take().map(TupleElementMut::_{i}),")?;
855                    }
856                    w!(f, "{TAB5}_ => None,
857                }};
858                if self.back_index == 0 {{
859                    self.front_index = self.back_index + 1; // Ensure iteration stops
860                }} else {{
861                    self.back_index -= 1;
862                }}
863                result
864            }}
865        }}
866    }}")?;
867    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
868    w0!(f, "> ExactSizeIterator for TupleIterMut<'_, ")?;
869        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w!(f, "> {{")?;
870        w!(f, "{TAB1}fn len(&self) -> usize {{ self.remaining() }}
871    }}")?;
872    w0!(f, "impl<")?; for i in 0..MAX_ARITY { w0!(f, "_{i},")?; }
873    w0!(f, "> core::iter::FusedIterator for TupleIterMut<'_, ")?;
874        for i in 0..MAX_ARITY { w0!(f, "_{i},")?; } w0!(f, "> {{}}")?;
875
876    // --------------------------------------------------------------------------
877
878    if let Err(e) = f.flush() {
879        eprintln!("Failed to write to file: {}", e);
880        std::process::exit(1);
881    }
882
883    // #[cfg(doc)] // format the source if we're building the docs
884    // super::super::rustfmt_file(path);
885    Ok(())
886}