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

facet-rs / facet / 14459841398

15 Apr 2025 02:20AM UTC coverage: 30.835% (+0.7%) from 30.122%
14459841398

push

github

web-flow
Rename opaque to ptr, closes #221 (#222)

47 of 344 new or added lines in 20 files covered. (13.66%)

1 existing line in 1 file now uncovered.

2032 of 6590 relevant lines covered (30.83%)

25.82 hits per line

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

0.0
/facet-codegen/src/gen_tuple_impl.rs
1
pub(super) fn generate_tuples_impls() -> String {
×
2
    use std::fmt::Write;
3
    let mut s = String::with_capacity(65536);
×
4

5
    macro_rules! w {
6
        ($($t:tt)*) => {
7
            write!(s, $($t)*).unwrap()
8
        };
9
    }
10

11
    // Header
12
    w!("//! GENERATED: DO NOT EDIT — this file is generated by the `facet-codegen` crate.\n");
×
13
    w!("//! Run `just codegen` to regenerate.\n\n");
×
14

15
    w!("use core::{{alloc::Layout, fmt}};\n\n");
×
16
    w!("use crate::{{\n");
×
NEW
17
    w!("    Characteristic, ConstTypeId, Def, Facet, Field, FieldFlags, PtrConst, Shape,\n");
×
18
    w!("    Struct, TypeNameOpts, ValueVTable,\n");
×
19
    w!("}};
×
20
\n");
×
21

22
    // Helper functions
23
    w!("#[inline(always)]\n");
×
24
    w!("pub fn write_type_name_list(\n");
×
25
    w!("    f: &mut fmt::Formatter<'_>,\n");
×
26
    w!("    opts: TypeNameOpts,\n");
×
27
    w!("    open: &'static str,\n");
×
28
    w!("    delimiter: &'static str,\n");
×
29
    w!("    close: &'static str,\n");
×
30
    w!("    shapes: &'static [&'static Shape],\n");
×
31
    w!(") -> fmt::Result {{\n");
×
32
    w!("    f.pad(open)?;\n");
×
33
    w!("    if let Some(opts) = opts.for_children() {{\n");
×
34
    w!("        for (index, shape) in shapes.iter().enumerate() {{\n");
×
35
    w!("            if index > 0 {{\n");
×
36
    w!("                f.pad(delimiter)?;\n");
×
37
    w!("            }}\n");
×
38
    w!("            shape.write_type_name(f, opts)?;\n");
×
39
    w!("        }}\n");
×
40
    w!("    }} else {{\n");
×
41
    w!("        write!(f, \"⋯\")?;\n");
×
42
    w!("    }}\n");
×
43
    w!("    f.pad(close)?;\n");
×
44
    w!("    Ok(())\n");
×
45
    w!("}}\n\n");
×
46

47
    w!("macro_rules! field {{\n");
×
48
    w!("    ($idx:tt, $ty:ty,) => {{\n");
×
49
    w!("        Field::builder()\n");
×
50
    w!("            .name(stringify!($idx))\n");
×
51
    w!("            .shape(|| $crate::shape_of(&|t: &$ty| &t.$idx))\n");
×
52
    w!("            .offset(core::mem::offset_of!($ty, $idx))\n");
×
53
    w!("            .flags(FieldFlags::EMPTY)\n");
×
54
    w!("            .build()\n");
×
55
    w!("    }};\n");
×
56
    w!("}}\n\n");
×
57

58
    // Generate implementations for tuples of different sizes
59
    let max_tuple_size = 12;
×
60

61
    for n in 1..=max_tuple_size {
×
62
        // Generate type parameters and where clauses
63
        let type_params = (0..n)
×
64
            .map(|i| format!("T{}", i))
×
65
            .collect::<Vec<_>>()
66
            .join(", ");
67
        let where_predicates = (0..n)
×
68
            .map(|i| format!("T{}: Facet", i))
×
69
            .collect::<Vec<_>>()
70
            .join(",\n    ");
71
        let shape_list = (0..n)
×
72
            .map(|i| format!("T{}::SHAPE", i))
×
73
            .collect::<Vec<_>>()
74
            .join(", ");
75

76
        // Start impl block
77
        w!(
×
78
            "unsafe impl<{}> Facet for {}
×
79
",
×
80
            type_params,
×
81
            // Handle formatting of tuple types correctly
82
            if n == 1 {
×
83
                "(T0,)".to_string()
×
84
            } else {
85
                format!("({})", type_params)
×
86
            },
87
        );
88
        w!("where\n");
×
89
        w!("    {}\n", where_predicates);
×
90
        w!("{{\n");
×
91
        w!("    const SHAPE: &'static Shape = &const {{\n");
×
92

93
        // type_name function
94
        w!(
×
95
            "        fn type_name<{}>(f: &mut fmt::Formatter, opts: TypeNameOpts) -> fmt::Result\n",
×
96
            type_params
×
97
        );
98
        w!("        where\n");
×
99
        w!("            {}\n", where_predicates);
×
100
        w!("        {{\n");
×
101
        if n <= 3 {
×
102
            w!(
×
103
                "            write_type_name_list(f, opts, \"(\", \", \", \")\", &[{}])\n",
×
104
                shape_list
×
105
            );
106
        } else {
107
            w!("            write_type_name_list(\n");
×
108
            w!("                f,\n");
×
109
            w!("                opts,\n");
×
110
            w!("                \"(\",\n");
×
111
            w!("                \", \",\n");
×
112
            w!("                \")\",\n");
×
113
            w!("                &[\n");
×
114
            w!("                    {},\n", shape_list);
×
115
            w!("                ],\n");
×
116
            w!("            )\n");
×
117
        }
118
        w!("        }}\n\n");
×
119

120
        // Shape builder start
121
        w!("        Shape::builder()\n");
×
122
        w!("            .id(ConstTypeId::of::<");
×
123
        if n == 1 {
×
124
            w!("(T0,)")
×
125
        } else {
126
            w!("({})", type_params)
×
127
        }
128
        w!(">())\n");
×
129
        w!("            .layout(Layout::new::<");
×
130
        if n == 1 {
×
131
            w!("(T0,)")
×
132
        } else {
133
            w!("({})", type_params)
×
134
        }
135
        w!(">())\n");
×
136
        w!("            .vtable(\n");
×
137
        w!("                &const {{\n");
×
138
        w!("                    let mut builder = ValueVTable::builder()\n");
×
139
        w!(
×
140
            "                        .type_name(type_name::<{}>)\n",
×
141
            type_params
×
142
        );
143
        w!("                        .marker_traits(");
×
144
        if n == 1 {
×
145
            w!("T0::SHAPE.vtable.marker_traits);\n\n")
×
146
        } else {
147
            w!("                        {{\n");
×
148
            w!("                            T0::SHAPE.vtable.marker_traits\n");
×
149
            for i in 1..n {
×
150
                w!(
×
151
                    "                                .intersection(T{i}::SHAPE.vtable.marker_traits)\n"
×
152
                );
153
            }
154
            w!("                    }});\n\n");
×
155
        }
156

157
        // Conditional debug and eq implementations
158
        w!("                    if Characteristic::Eq.all(&[");
×
159
        if n <= 5 {
×
160
            w!("{}", shape_list);
×
161
        } else {
162
            w!("\n");
×
163
            w!("                        {},\n", shape_list);
×
164
            w!("                    ");
×
165
        }
166
        w!("]) {{\n");
×
167

168
        // debug implementation
169
        w!("                        builder = builder.debug(|value, f| {{\n");
×
170
        if n == 1 {
×
171
            w!("                            let value = unsafe {{ value.get::<(T0,)>() }};\n");
×
172
        } else {
173
            w!(
×
174
                "                            let value = unsafe {{ value.get::<({})>() }};\n",
×
175
                type_params
×
176
            );
177
        }
178
        w!("                            write!(f, \"(\")?;\n");
×
179

180
        for i in 0..n {
×
181
            if i > 0 {
×
182
                w!("                            write!(f, \", \")?;\n");
×
183
            }
184
            w!("                            unsafe {{\n");
×
185
            w!(
×
186
                "                                let ptr = &value.{0} as *const T{0};\n",
×
187
                i
×
188
            );
189
            w!(
×
190
                "                                (T{0}::SHAPE.vtable.debug.unwrap_unchecked())(\n",
×
191
                i
×
192
            );
NEW
193
            w!("                                    PtrConst::new(ptr),\n");
×
194
            w!("                                    f,\n");
×
195
            w!("                                )\n");
×
196
            w!("                            }}?;\n");
×
197
        }
198

199
        w!("                            write!(f, \")\")\n");
×
200
        w!("                        }});\n\n");
×
201

202
        // eq implementation
203
        w!("                        builder = builder.eq(|a, b| {{\n");
×
204
        if n == 1 {
×
205
            w!("                            let a = unsafe {{ a.get::<(T0,)>() }};\n");
×
206
            w!("                            let b = unsafe {{ b.get::<(T0,)>() }};\n\n");
×
207
        } else {
208
            w!(
×
209
                "                            let a = unsafe {{ a.get::<({})>() }};\n",
×
210
                type_params
×
211
            );
212
            w!(
×
213
                "                            let b = unsafe {{ b.get::<({})>() }};\n\n",
×
214
                type_params
×
215
            );
216
        }
217

218
        // Compare elements except the last one
219
        for i in 0..n - 1 {
×
220
            w!("                            // Compare element {}\n", i);
×
221
            w!("                            unsafe {{\n");
×
222
            w!(
×
223
                "                                let a_ptr = &a.{0} as *const T{0};\n",
×
224
                i
×
225
            );
226
            w!(
×
227
                "                                let b_ptr = &b.{0} as *const T{0};\n",
×
228
                i
×
229
            );
230
            w!(
×
231
                "                                if !(T{0}::SHAPE.vtable.eq.unwrap_unchecked())(\n",
×
232
                i
×
233
            );
NEW
234
            w!("                                    PtrConst::new(a_ptr),\n");
×
NEW
235
            w!("                                    PtrConst::new(b_ptr),\n");
×
236
            w!("                                ) {{\n");
×
237
            w!("                                    return false;\n");
×
238
            w!("                                }}\n");
×
239
            w!("                            }}\n\n");
×
240
        }
241

242
        // Special case for the last element
243
        let last = n - 1;
×
244
        w!("                            // Compare last element\n");
×
245
        w!("                            unsafe {{\n");
×
246
        w!(
×
247
            "                                (T{0}::SHAPE.vtable.eq.unwrap_unchecked())(\n",
×
248
            last
×
249
        );
250
        w!(
×
NEW
251
            "                                    PtrConst::new(&a.{0} as *const T{0}),\n",
×
252
            last
×
253
        );
254
        w!(
×
NEW
255
            "                                    PtrConst::new(&b.{0} as *const T{0}),\n",
×
256
            last
×
257
        );
258
        w!("                                )\n");
×
259
        w!("                            }}\n");
×
260
        w!("                        }});\n");
×
261
        w!("                    }}\n\n");
×
262

263
        // Finish vtable builder
264
        w!("                    builder.build()\n");
×
265
        w!("                }},\n");
×
266
        w!("            )\n");
×
267
        w!("            .def(Def::Struct({{\n");
×
268
        w!("                Struct::builder()\n");
×
269
        w!("                    .tuple()\n");
×
270
        w!("                    .fields(\n");
×
271

272
        // Generate field array
273
        if n <= 3 {
×
274
            w!("                        &const {{ [");
×
275
            for i in 0..n {
×
276
                if i > 0 {
×
277
                    w!(",\n                        ");
×
278
                }
279
                if n == 1 {
×
280
                    w!("field!({}, (T0,),)", i);
×
281
                } else {
282
                    let field_tuple = format!("({},)", type_params);
×
283
                    w!("field!({}, {},)", i, field_tuple);
×
284
                }
285
            }
286
            w!("] }}\n");
×
287
        } else {
288
            w!("                        &const {{\n");
×
289
            w!("                            [\n");
×
290
            for i in 0..n {
×
291
                if n == 1 {
×
292
                    w!("                                field!({}, (T0,),)", i);
×
293
                } else {
294
                    let field_tuple = format!("({},)", type_params);
×
295
                    w!(
×
296
                        "                                field!({}, {},)",
×
297
                        i,
×
298
                        field_tuple
×
299
                    );
300
                }
301
                if i < n - 1 {
×
302
                    w!(",\n");
×
303
                } else {
304
                    w!("\n");
×
305
                }
306
            }
307
            w!("                            ]\n");
×
308
            w!("                        }},\n");
×
309
        }
310

311
        // Finish implementation
312
        w!("                    )\n");
×
313
        w!("                    .build()\n");
×
314
        w!("            }}))\n");
×
315
        w!("            .build()\n");
×
316
        w!("    }};\n");
×
317
        w!("}}\n");
×
318
    }
319

320
    s
×
321
}
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

© 2025 Coveralls, Inc