facet_core/impls_core/
tuple.rs1use core::{fmt, mem};
2
3use crate::{
4 Characteristic, Facet, MarkerTraits, Repr, Shape, StructKind, StructType, Type, TypeNameOpts,
5 UserType, VTableView, ValueVTable, types::field_in_type,
6};
7
8#[inline(always)]
9pub fn write_type_name_list(
10 f: &mut fmt::Formatter<'_>,
11 opts: TypeNameOpts,
12 open: &'static str,
13 delimiter: &'static str,
14 close: &'static str,
15 shapes: &'static [&'static Shape],
16) -> fmt::Result {
17 f.pad(open)?;
18 if let Some(opts) = opts.for_children() {
19 for (index, shape) in shapes.iter().enumerate() {
20 if index > 0 {
21 f.pad(delimiter)?;
22 }
23 shape.write_type_name(f, opts)?;
24 }
25 } else {
26 write!(f, "⋯")?;
27 }
28 f.pad(close)?;
29 Ok(())
30}
31
32macro_rules! impl_facet_for_tuple {
33 {
36 continue from ($($elems:ident.$idx:tt,)+),
37 remaining ()
38 } => {};
39 {
40 continue from ($($elems:ident.$idx:tt,)+),
41 remaining ($next:ident.$nextidx:tt, $($remaining:ident.$remainingidx:tt,)*)
42 } => {
43 impl_facet_for_tuple! {
44 impl ($($elems.$idx,)+ $next.$nextidx,),
45 remaining ($($remaining.$remainingidx,)*)
46 }
47 };
48 { debug on $f:ident { $first:stmt; } } => {
50 write!($f, "(")?;
51 $first
52 write!($f, ",)")
53 };
54 {
56 impl ($($elems:ident.$idx:tt,)+),
57 remaining ($($remaining:ident.$remainingidx:tt,)*)
58 } => {
59 unsafe impl<'a $(, $elems)+> Facet<'a> for ($($elems,)+)
60 where
61 $($elems: Facet<'a>,)+
62 {
63 const VTABLE: &'static ValueVTable = &const {
64 ValueVTable::builder::<Self>()
65 .type_name(|f, opts| {
66 write_type_name_list(f, opts, "(", ", ", ")", &[$($elems::SHAPE),+])
67 })
68 .drop_in_place(|| Some(|data| unsafe { data.drop_in_place::<Self>() }))
69 .marker_traits(||
70 MarkerTraits::all()
71 $(.intersection($elems::SHAPE.vtable.marker_traits()))+
72 )
73 .default_in_place(|| {
74 let elem_shapes = const { &[$($elems::SHAPE),+] };
75 if Characteristic::all_default(elem_shapes) {
76 Some(|mut dst| {
77 $(
78 unsafe {
79 (<VTableView<$elems>>::of().default_in_place().unwrap())(
80 dst.field_uninit_at(mem::offset_of!(Self, $idx))
81 );
82 }
83 )+
84
85 unsafe { dst.assume_init() }
86 })
87 } else {
88 None
89 }
90 })
91 .build()
92 };
93
94 const SHAPE: &'static Shape = &const {
95 Shape::builder_for_sized::<Self>()
96 .type_identifier(const {
97 let fields = [
98 $(field_in_type!(Self, $idx),)+
99 ];
100 if fields.len() == 1 {
101 "(_)"
102 } else {
103 "(⋯)"
104 }
105 })
106 .ty(Type::User(UserType::Struct(StructType {
107 repr: Repr::default(),
108 kind: StructKind::Tuple,
109 fields: &const {[
110 $(field_in_type!(Self, $idx),)+
111 ]}
112 })))
113 .build()
114 };
115 }
116
117 impl_facet_for_tuple! {
118 continue from ($($elems.$idx,)+),
119 remaining ($($remaining.$remainingidx,)*)
120 }
121 };
122 { ($first:ident.$firstidx:tt $(, $remaining:ident.$remainingidx:tt)* $(,)?) } => {
124 impl_facet_for_tuple! {
125 impl ($first.$firstidx,),
126 remaining ($($remaining.$remainingidx,)*)
127 }
128 };
129}
130
131#[cfg(feature = "tuples-12")]
132impl_facet_for_tuple! {
133 (T0.0, T1.1, T2.2, T3.3, T4.4, T5.5, T6.6, T7.7, T8.8, T9.9, T10.10, T11.11)
134}
135
136#[cfg(not(feature = "tuples-12"))]
137impl_facet_for_tuple! {
138 (T0.0, T1.1, T2.2, T3.3)
139}