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

facet-rs / facet / 20134750802

11 Dec 2025 01:29PM UTC coverage: 57.796% (-0.1%) from 57.906%
20134750802

push

github

fasterthanlime
feat: Add concept of truthiness

The easiest way to tell if something should be serialized or not!

61 of 197 new or added lines in 14 files covered. (30.96%)

1 existing line in 1 file now uncovered.

28969 of 50123 relevant lines covered (57.8%)

6281.89 hits per line

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

67.39
/facet-core/src/impls/alloc/string.rs
1
use crate::{
2
    Def, Facet, PtrConst, Shape, ShapeBuilder, Type, TypeOpsDirect, UserType, VTableDirect,
3
    type_ops_direct, vtable_direct,
4
};
5

6
#[inline(always)]
NEW
7
unsafe fn string_truthy(value: PtrConst) -> bool {
×
NEW
8
    !unsafe { value.get::<alloc::string::String>() }.is_empty()
×
NEW
9
}
×
10

11
// TypeOps lifted out - shared static
12
static STRING_TYPE_OPS: TypeOpsDirect = TypeOpsDirect {
13
    is_truthy: Some(string_truthy),
14
    ..type_ops_direct!(alloc::string::String => Default, Clone)
15
};
16

17
/// Try to convert from &str or String to String
18
///
19
/// # Safety
20
/// `dst` must be valid for writes, `src` must point to valid data of type described by `src_shape`
21
unsafe fn string_try_from(
2✔
22
    dst: *mut alloc::string::String,
2✔
23
    src_shape: &'static Shape,
2✔
24
    src: PtrConst,
2✔
25
) -> Result<(), alloc::string::String> {
2✔
26
    // Check if source is &str
27
    if src_shape.id == <&str as crate::Facet>::SHAPE.id {
2✔
28
        let str_ref: &str = unsafe { src.get::<&str>() };
2✔
29
        unsafe { dst.write(alloc::string::String::from(str_ref)) };
2✔
30
        return Ok(());
2✔
31
    }
×
32

33
    // Check if source is String (clone it)
34
    if src_shape.id == <alloc::string::String as crate::Facet>::SHAPE.id {
×
35
        let src_string: &alloc::string::String =
×
36
            unsafe { &*(src.as_byte_ptr() as *const alloc::string::String) };
×
37
        unsafe { dst.write(src_string.clone()) };
×
38
        return Ok(());
×
39
    }
×
40

41
    Err(alloc::format!(
×
42
        "cannot convert {} to String",
×
43
        src_shape.type_identifier
×
44
    ))
×
45
}
2✔
46

47
unsafe impl Facet<'_> for alloc::string::String {
48
    // String implements: Display, Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, FromStr
49
    const SHAPE: &'static Shape = &const {
50
        const VTABLE: VTableDirect = vtable_direct!(alloc::string::String =>
51
            FromStr,
52
            Display,
53
            Debug,
54
            Hash,
55
            PartialEq,
56
            PartialOrd,
57
            Ord,
58
            [try_from = string_try_from],
59
        );
60

61
        ShapeBuilder::for_sized::<alloc::string::String>("String")
62
            .ty(Type::User(UserType::Opaque))
63
            .def(Def::Scalar)
64
            .vtable_direct(&VTABLE)
65
            .type_ops_direct(&STRING_TYPE_OPS)
66
            .eq()
67
            .send()
68
            .sync()
69
            .build()
70
    };
71
}
72

73
#[cfg(test)]
74
mod tests {
75
    use core::ptr::NonNull;
76

77
    use crate::Facet;
78
    use alloc::string::String;
79

80
    #[test]
81
    fn test_string_has_parse() {
1✔
82
        // Check that String has a parse function in its vtable
83
        let shape = String::SHAPE;
1✔
84
        assert!(
1✔
85
            shape.vtable.has_parse(),
1✔
86
            "String should have parse function"
87
        );
88
    }
1✔
89

90
    #[test]
91
    fn test_string_parse() {
1✔
92
        // Test that we can parse a string into a String
93
        let shape = String::SHAPE;
1✔
94

95
        // Allocate memory for the String
96
        let layout = shape.layout.sized_layout().unwrap();
1✔
97
        let ptr = unsafe { alloc::alloc::alloc(layout) };
1✔
98
        let Some(ptr) = NonNull::new(ptr) else {
1✔
99
            alloc::alloc::handle_alloc_error(layout)
×
100
        };
101
        let ptr_mut = crate::PtrMut::new(ptr.as_ptr());
1✔
102

103
        // Parse the string using the new API
104
        let result = unsafe { shape.call_parse("hello world", ptr_mut) };
1✔
105
        assert!(result.is_some(), "String should have parse function");
1✔
106
        assert!(result.unwrap().is_ok());
1✔
107

108
        // Get the parsed value
109
        let parsed = unsafe { ptr_mut.get::<String>() };
1✔
110
        assert_eq!(parsed, &String::from("hello world"));
1✔
111

112
        // Clean up
113
        unsafe {
1✔
114
            shape.call_drop_in_place(ptr_mut).unwrap();
1✔
115
            alloc::alloc::dealloc(ptr.as_ptr(), layout);
1✔
116
        }
1✔
117
    }
1✔
118
}
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