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

facet-rs / facet / 14604214242

22 Apr 2025 08:40PM UTC coverage: 45.467%. First build
14604214242

Pull #372

github

web-flow
Merge 9f54ba190 into 6e87adc96
Pull Request #372: Draft: Invariance

55 of 239 new or added lines in 25 files covered. (23.01%)

5778 of 12708 relevant lines covered (45.47%)

56.16 hits per line

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

0.0
/facet-dev/src/fn_ptr.rs
1
use std::iter;
2

3
// Generate implementations for function pointers up to the following arity
4
const MAX_ARITY: i32 = 6;
5
// Generate implementations for the following calling conventions
6
// (abi-string, abi-enum-variant-name)
7
#[rustfmt::skip]
8
const ABIS: &[(&str, &str)] = &[
9
    ("Rust", "Rust"),
10
    ("C", "C"),
11
];
12

13
/// Generate implementations for function pointers. It's highly repetitive and hard to get done with only
14
/// declarative macros. So that's why it's generated.
15
pub fn generate() -> String {
×
16
    use std::fmt::Write;
17
    let mut s = String::with_capacity(65536);
×
18

19
    macro_rules! w {
20
        ($($t:tt)*) => {
21
            write!(s, $($t)*).unwrap()
22
        };
23
    }
24

25
    // Header
26
    w!("//! GENERATED: DO NOT EDIT — this file is generated by the `facet-dev` crate.\n");
×
27
    w!("//! Run `just gen` to regenerate.\n\n");
×
28

×
29
    w!("use core::{{alloc::Layout, fmt}};\n\n");
×
30
    w!("use crate::{{\n");
×
31
    w!("    value_vtable, ConstTypeId, Def, Facet, FunctionAbi,\n");
×
32
    w!("    FunctionPointerDef, Shape, TypeNameOpts, TypeParam\n");
×
33
    w!("}};
×
34
\n");
×
35

×
36
    // Helper functions
×
37
    w!("#[inline(always)]\n");
×
38
    w!("pub fn write_type_name_list(\n");
×
39
    w!("    f: &mut fmt::Formatter<'_>,\n");
×
40
    w!("    opts: TypeNameOpts,\n");
×
41
    w!("    abi: FunctionAbi,\n");
×
42
    w!("    params: &'static [&'static Shape],\n");
×
43
    w!("    ret_type: &'static Shape,\n");
×
44
    w!(") -> fmt::Result {{\n");
×
45
    w!("    if abi != FunctionAbi::Rust {{\n");
×
46
    w!("        f.pad(\"extern \\\"\")?;\n");
×
47
    w!("        if let Some(abi) = abi.as_abi_str() {{\n");
×
48
    w!("            f.pad(abi)?;\n");
×
49
    w!("        }}\n");
×
50
    w!("        f.pad(\"\\\" \")?;\n");
×
51
    w!("    }}\n");
×
52
    w!("    f.pad(\"fn\")?;\n");
×
53
    w!("    f.pad(\"(\")?;\n");
×
54
    w!("    if let Some(opts) = opts.for_children() {{\n");
×
55
    w!("        for (index, shape) in params.iter().enumerate() {{\n");
×
56
    w!("            if index > 0 {{\n");
×
57
    w!("                f.pad(\", \")?;\n");
×
58
    w!("            }}\n");
×
59
    w!("            shape.write_type_name(f, opts)?;\n");
×
60
    w!("        }}\n");
×
61
    w!("    }} else {{\n");
×
62
    w!("        write!(f, \"⋯\")?;\n");
×
63
    w!("    }}\n");
×
64
    w!("    f.pad(\") -> \")?;\n");
×
65
    w!("    ret_type.write_type_name(f, opts)?;\n");
×
66
    w!("    Ok(())\n");
×
67
    w!("}}\n\n");
×
68

69
    for &(abi_string, abi_name) in ABIS {
×
70
        for n in 0..=MAX_ARITY {
×
71
            let return_param = String::from("R");
×
72
            // Generate type parameters and where clauses
×
73
            let type_params = (0..n)
×
74
                .map(|i| format!("T{}", i))
×
75
                .collect::<Vec<_>>()
×
76
                .join(", ");
×
77
            let where_predicates = (0..n)
×
NEW
78
                .map(|i| format!("T{}: Facet<'facet>", i))
×
NEW
79
                .chain(iter::once("R: Facet<'facet>".to_owned()))
×
80
                .collect::<Vec<_>>()
×
81
                .join(",\n    ");
×
82
            let param_shape_list = (0..n)
×
83
                .map(|i| format!("T{}::SHAPE", i))
×
84
                .collect::<Vec<_>>()
×
85
                .join(", ");
×
86
            let param_shape_ctor = (0..n)
×
87
                .map(|i| format!("|| T{}::SHAPE", i))
×
88
                .collect::<Vec<_>>()
×
89
                .join(", ");
×
90

×
91
            let type_param_build = (0..n)
×
92
                .map(|i| format!("TypeParam {{ name: \"T{i}\", shape: || T{i}::SHAPE }}"))
×
93
                .collect::<Vec<_>>()
×
94
                .join(", ");
×
95

96
            let extern_abi = if abi_string == "Rust" {
×
97
                String::new()
×
98
            } else {
99
                format!("extern \"{abi_string}\" ")
×
100
            };
101

102
            // Start impl block
103
            w!(
×
NEW
104
                "unsafe impl<'facet, {return_param}, {type_params}> Facet<'facet> for {extern_abi}fn({type_params}) -> {return_param}\n",
×
105
            );
×
106
            w!("where\n");
×
107
            w!("    {}\n", where_predicates);
×
108
            w!("{{\n");
×
109
            w!("    const SHAPE: &'static Shape = &const {{\n");
×
110

×
111
            // type_name function
×
112
            w!(
×
NEW
113
                "        fn type_name<'facet, {return_param}, {type_params}>(f: &mut fmt::Formatter, opts: TypeNameOpts) -> fmt::Result\n",
×
114
            );
×
115
            w!("        where\n");
×
116
            w!("            {}\n", where_predicates);
×
117
            w!("        {{\n");
×
118
            w!("            write_type_name_list(\n");
×
119
            w!("                f,\n");
×
120
            w!("                opts,\n");
×
121
            w!("                FunctionAbi::{abi_name},\n");
×
122
            w!("                &[\n");
×
123
            w!("                    {}\n", param_shape_list);
×
124
            w!("                ],\n");
×
125
            w!("                {return_param}::SHAPE,\n");
×
126
            w!("            )\n");
×
127
            w!("        }}\n\n");
×
128

×
129
            // Shape builder start
×
130
            w!("        Shape::builder()\n");
×
131
            w!("            .id(ConstTypeId::of::<Self>())\n");
×
132
            w!("            .layout(Layout::new::<Self>())\n");
×
133
            // FIXME: Dont use the macro here we can generate this
×
134
            // FIXME: type name
×
135
            w!(
×
136
                "            .vtable(value_vtable!(Self, type_name::<{return_param}, {type_params}>))\n"
×
137
            );
×
138
            w!("            .type_params(&[{type_param_build}])\n");
×
139
            w!("            .def(Def::FunctionPointer({{\n");
×
140
            w!("                FunctionPointerDef::builder()\n");
×
141
            w!("                    .parameter_types(&const {{ [{param_shape_ctor}] }})\n");
×
142
            w!("                    .return_type(|| R::SHAPE)\n");
×
143
            w!("                    .abi(FunctionAbi::{})\n", abi_name);
×
144
            w!("                    .build()\n");
×
145
            w!("            }}))\n");
×
146

×
147
            // Finish implementation
×
148
            w!("            .build()\n");
×
149
            w!("    }};\n");
×
150
            w!("}}\n");
×
151
        }
152
    }
153
    s
×
154
}
×
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