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

facet-rs / facet / 19993677870

06 Dec 2025 08:12PM UTC coverage: 58.752% (+0.05%) from 58.705%
19993677870

push

github

fasterthanlime
Reduce/cordon bloat in facet, introduce bloatbench

Looks into codegen size, compile times etc. - again :) after adding a buuuunch of features.

- [x] Disable miette's default features (derive, which depends on syn) (`b.miette`)
- [x] Don't enable miette fancy by default in facet-json (`b.miette-fancy`)
- [x] Flatten closures in facet-json to avoid generic instantiations (`b.flatten-closures`)
- [x] Get rid of shape_of in Shape derive, use `#field_type` directly (`b.shape-of`)
- [x] Detect known derives in facet-macros, eschew impls! for them (`b.detect-derives`)
- [x] Gate nonzero impls, net impls (`b.gate-impls`)
- [x] Gate doc-comments, vtable-fmt, vtable-cmp, vtable-hash (`b.gate-vtable`)
- [x] Make 'auto trait detection' opt-in (`b.auto-traits-optin`)
- [x] Detect traits from `derive` and from `#[facet(default)]` (`b.derive-traits`)
- [x] Allow manual trait specification via `#[facet(traits(...))]` (`b.manual-traits`)
- [x] Go back to builders (they expand to less code) (`b.builders`)
- [x] VTable restructured with sub-vtables (`format`, `cmp`, `hash`, `markers`) (`b.vtable-substruct`)
- [x] Convert manual impls to ShapeBuilder (`scalar.rs`, `fn_ptr.rs`, `impls_num_complex.rs`) (`b.shapebuilder`)
- [x] **Confirmed**: `#![allow(uncommon_codepoints, nonstandard_style)]` in library = no warnings in consumers (`b.unicode-test`)
- [x] Add `FieldBuilder::new(name, shape_fn, offset)` builder (`b.field-builder`)
- [x] Add `StructTypeBuilder::new(kind, fields)` builder (`b.structtype-builder`)
- [x] Add `VariantBuilder::new(name, data)` builder (`b.variant-builder`)
- [x] Add `EnumTypeBuilder::new(enum_repr, variants)` builder (`b.enumtype-builder`)
- [x] Create `::facet::𝟋` module with type aliases and builder exports (`b.prelude-mod`)
- [x] Update derive macro to use builder pattern for Field, StructType, Variant, EnumType (`b.derive-builders`)

Based on analysis in `facet-bloatbench/MACRO-OPTIMIZATION-ANALYSIS.md`:

- [x] Remove `let mut vtable = const... (continued)

1199 of 3227 new or added lines in 72 files covered. (37.16%)

145 existing lines in 29 files now uncovered.

24253 of 41280 relevant lines covered (58.75%)

504.69 hits per line

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

89.8
/facet-core/src/impls_alloc/string.rs
1
use crate::{Facet, MarkerTraits, Shape, ShapeBuilder, ValueVTable};
2
use alloc::string::ToString;
3

4
#[cfg(feature = "alloc")]
5
unsafe impl Facet<'_> for alloc::string::String {
6
    // String implements: Display, Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash
7
    const SHAPE: &'static Shape = &const {
8
        ShapeBuilder::for_sized::<alloc::string::String>(|f, _opts| write!(f, "String"), "String")
1,566✔
9
            .drop_in_place(ValueVTable::drop_in_place_for::<alloc::string::String>())
10
            .default_in_place(|target| unsafe { target.put(alloc::string::String::new()) })
16✔
11
            .clone_into(|src, dst| unsafe { dst.put(src.get::<alloc::string::String>().clone()) })
1✔
12
            .parse(|s, target| {
279✔
13
                // For String, parsing from a string is just copying the string
14
                Ok(unsafe { target.put(s.to_string()) })
279✔
15
            })
279✔
16
            .display(|data, f| {
11✔
17
                let data = unsafe { data.get::<alloc::string::String>() };
11✔
18
                core::fmt::Display::fmt(data, f)
11✔
19
            })
11✔
20
            .debug(|data, f| {
8✔
21
                let data = unsafe { data.get::<alloc::string::String>() };
8✔
22
                core::fmt::Debug::fmt(data, f)
8✔
23
            })
8✔
24
            .partial_eq(|left, right| unsafe {
25
                *left.get::<alloc::string::String>() == *right.get::<alloc::string::String>()
67✔
26
            })
67✔
27
            .partial_ord(|left, right| unsafe {
28
                left.get::<alloc::string::String>()
1✔
29
                    .partial_cmp(right.get::<alloc::string::String>())
1✔
30
            })
1✔
31
            .ord(|left, right| unsafe {
32
                left.get::<alloc::string::String>()
1✔
33
                    .cmp(right.get::<alloc::string::String>())
1✔
34
            })
1✔
NEW
35
            .hash(|value, hasher| {
×
36
                use core::hash::Hash;
NEW
37
                let value = unsafe { value.get::<alloc::string::String>() };
×
NEW
38
                value.hash(&mut { hasher })
×
UNCOV
39
            })
×
40
            .markers(MarkerTraits::EMPTY.with_eq())
41
            .build()
42
    };
43
}
44

45
#[cfg(test)]
46
mod tests {
47
    use core::ptr::NonNull;
48

49
    use crate::Facet;
50
    use crate::ptr::PtrUninit;
51
    use alloc::string::String;
52

53
    #[test]
54
    fn test_string_has_parse() {
1✔
55
        // Check that String has a parse function in its vtable
56
        let shape = String::SHAPE;
1✔
57
        assert!(
1✔
58
            shape.vtable.has_parse(),
1✔
59
            "String should have parse function"
60
        );
61
    }
1✔
62

63
    #[test]
64
    fn test_string_parse() {
1✔
65
        // Test that we can parse a string into a String
66
        let shape = String::SHAPE;
1✔
67
        let parse_fn = shape.vtable.parse.unwrap();
1✔
68

69
        // Allocate memory for the String
70
        let layout = shape.layout.sized_layout().unwrap();
1✔
71
        let ptr = unsafe { alloc::alloc::alloc(layout) };
1✔
72
        let Some(ptr) = NonNull::new(ptr) else {
1✔
73
            alloc::alloc::handle_alloc_error(layout)
×
74
        };
75
        let uninit = PtrUninit::new(ptr);
1✔
76

77
        // Parse the string
78
        let result = unsafe { parse_fn("hello world", uninit) };
1✔
79
        assert!(result.is_ok());
1✔
80

81
        // Get the parsed value
82
        let ptr_mut = result.unwrap();
1✔
83
        let parsed = unsafe { ptr_mut.get::<String>() };
1✔
84
        assert_eq!(parsed, &String::from("hello world"));
1✔
85

86
        // Clean up
87
        unsafe {
1✔
88
            ptr_mut.drop_in_place::<String>();
1✔
89
            alloc::alloc::dealloc(ptr.as_ptr(), layout);
1✔
90
        }
1✔
91
    }
1✔
92
}
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