• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

facet-rs / facet / 14651557860

24 Apr 2025 08:58PM UTC coverage: 57.927% (+8.6%) from 49.28%
14651557860

Pull #386

github

web-flow
Merge 49455a66b into 9e2670ec4
Pull Request #386: Use declarative macros for tuple implementations of Facet

4 of 43 new or added lines in 3 files covered. (9.3%)

14 existing lines in 2 files now uncovered.

6299 of 10874 relevant lines covered (57.93%)

72.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.75
/facet-core/src/impls_core/tuple.rs
1
use core::{alloc::Layout, fmt, mem};
2

3
use crate::{
4
    Characteristic, ConstTypeId, Def, Facet, Field, FieldFlags, MarkerTraits, PtrConst, Shape,
5
    Struct, TypeNameOpts, ValueVTable, shape_of,
6
};
7

8
#[inline(always)]
9
pub 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

32
macro_rules! impl_facet_for_tuple {
33
    {
34
        continue from ($($elems:ident.$idx:tt,)+),
35
        remaining ()
36
    } => {};
37
    {
38
        continue from ($($elems:ident.$idx:tt,)+),
39
        remaining ($next:ident.$nextidx:tt, $($remaining:ident.$remainingidx:tt,)*)
40
    } => {
41
        impl_facet_for_tuple! {
42
            impl ($($elems.$idx,)+ $next.$nextidx,),
43
            remaining ($($remaining.$remainingidx,)*)
44
        }
45
    };
46
    { debug on $f:ident { $first:stmt; } } => {
47
        write!($f, "(")?;
48
        $first
49
        write!($f, ",)")
50
    };
51
    { debug on $f:ident { $first:stmt; $($stmt:stmt;)+ } } => {
52
        write!($f, "(")?;
53
        $first
54
        $(
55
            write!($f, ", ")?;
56
            $stmt
57
        )+
58
        write!($f, ")")
59
    };
60
    {
61
        impl ($($elems:ident.$idx:tt,)+),
62
        remaining ($($remaining:ident.$remainingidx:tt,)*)
63
    } => {
64
        unsafe impl<'a $(, $elems)+> Facet<'a> for ($($elems,)+)
65
        where
66
            $($elems: Facet<'a>,)+
67
        {
68
            const SHAPE: &'static Shape = &const {
NEW
69
                fn type_name<'a $(, $elems)+>(f: &mut fmt::Formatter, opts: TypeNameOpts) -> fmt::Result
×
NEW
70
                where
×
NEW
71
                    $($elems: Facet<'a>,)+
×
NEW
72
                {
×
NEW
73
                    write_type_name_list(f, opts, "(", ", ", ")", &[$($elems::SHAPE),+])
×
NEW
74
                }
×
75

76
                Shape::builder()
77
                    .id(ConstTypeId::of::<Self>())
78
                    .layout(Layout::new::<Self>())
79
                    .vtable(&const {
80
                        let mut builder = ValueVTable::builder()
81
                            .type_name(type_name::<$($elems),+>)
82
                            .marker_traits(
83
                                MarkerTraits::all()
84
                                    $(.intersection($elems::SHAPE.vtable.marker_traits))+
85
                            );
86

87
                        let elem_shapes = const { &[$($elems::SHAPE),+] };
88
                        if Characteristic::Eq.all(elem_shapes) {
NEW
89
                            builder = builder.debug(|value, f| {
×
NEW
90
                                let value = unsafe { value.get::<Self>() };
×
NEW
91

×
92
                                impl_facet_for_tuple! {
×
93
                                    debug on f {
94
                                        $(
95
                                            unsafe {
NEW
96
                                                let ptr = &value.$idx as *const $elems;
×
NEW
97
                                                ($elems::SHAPE.vtable.debug.unwrap_unchecked())(
×
NEW
98
                                                    PtrConst::new(ptr),
×
NEW
99
                                                    f,
×
NEW
100
                                                )
×
NEW
101
                                            }?;
×
102
                                        )+
103
                                    }
104
                                }
NEW
105
                            });
×
106

NEW
107
                            builder = builder.eq(|a, b| {
×
NEW
108
                                let a = unsafe { a.get::<Self>() };
×
NEW
109
                                let b = unsafe { b.get::<Self>() };
×
NEW
110

×
NEW
111
                                $(
×
NEW
112
                                    unsafe {
×
NEW
113
                                        let a_ptr = &a.$idx as *const $elems;
×
NEW
114
                                        let b_ptr = &b.$idx as *const $elems;
×
NEW
115

×
NEW
116
                                        if !($elems::SHAPE.vtable.eq.unwrap_unchecked())(
×
NEW
117
                                            PtrConst::new(a_ptr),
×
NEW
118
                                            PtrConst::new(b_ptr),
×
NEW
119
                                        ) {
×
NEW
120
                                            return false;
×
NEW
121
                                        }
×
NEW
122
                                    }
×
NEW
123
                                )+
×
NEW
124

×
NEW
125
                                true
×
NEW
126
                            });
×
127
                        }
128

129
                        builder.build()
130
                    })
131
                    .def(Def::Struct({
132
                        Struct::builder()
133
                            .tuple()
134
                            .fields(
135
                                &const {[
136
                                    $(
137
                                        Field::builder()
138
                                            .name(stringify!($idx))
139
                                            .shape(|| shape_of(&|t: &Self| &t.$idx))
11✔
140
                                            .offset(mem::offset_of!(Self, $idx))
141
                                            .flags(FieldFlags::EMPTY)
142
                                            .build(),
143
                                    )+
144
                                ]}
145
                            )
146
                            .build()
147
                    }))
148
                    .build()
149
            };
150
        }
151

152
        impl_facet_for_tuple! {
153
            continue from ($($elems.$idx,)+),
154
            remaining ($($remaining.$remainingidx,)*)
155
        }
156
    };
157
    { ($first:ident.$firstidx:tt $(, $remaining:ident.$remainingidx:tt)* $(,)?) } => {
158
        impl_facet_for_tuple! {
159
            impl ($first.$firstidx,),
160
            remaining ($($remaining.$remainingidx,)*)
161
        }
162
    };
163
}
164

165
impl_facet_for_tuple! {
166
    (T0.0, T1.1, T2.2, T3.3, T4.4, T5.5, T6.6, T7.7, T8.8, T9.9, T10.10, T11.11)
167
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc