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

facet-rs / facet / 20071389342

09 Dec 2025 04:48PM UTC coverage: 58.627% (-0.1%) from 58.736%
20071389342

push

github

fasterthanlime
feat: add try_from for &str to Utf8PathBuf, Url, Uuid, Ulid

Enable default values from string literals for these common CLI types.
Previously they only supported String as source, now they also accept &str.

4 of 44 new or added lines in 3 files covered. (9.09%)

275 existing lines in 13 files now uncovered.

26243 of 44763 relevant lines covered (58.63%)

633.18 hits per line

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

72.09
/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
// TypeOps lifted out - shared static
7
static STRING_TYPE_OPS: TypeOpsDirect = type_ops_direct!(alloc::string::String => Default, Clone);
8

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

25
    // Check if source is String (clone it)
UNCOV
26
    if src_shape.id == <alloc::string::String as crate::Facet>::SHAPE.id {
×
UNCOV
27
        let src_string: &alloc::string::String =
×
UNCOV
28
            unsafe { &*(src.as_byte_ptr() as *const alloc::string::String) };
×
UNCOV
29
        unsafe { dst.write(src_string.clone()) };
×
UNCOV
30
        return Ok(());
×
UNCOV
31
    }
×
32

UNCOV
33
    Err(alloc::format!(
×
UNCOV
34
        "cannot convert {} to String",
×
UNCOV
35
        src_shape.type_identifier
×
UNCOV
36
    ))
×
37
}
2✔
38

39
unsafe impl Facet<'_> for alloc::string::String {
40
    // String implements: Display, Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, FromStr
41
    const SHAPE: &'static Shape = &const {
42
        const VTABLE: VTableDirect = vtable_direct!(alloc::string::String =>
43
            FromStr,
44
            Display,
45
            Debug,
46
            Hash,
47
            PartialEq,
48
            PartialOrd,
49
            Ord,
50
            [try_from = string_try_from],
51
        );
52

53
        ShapeBuilder::for_sized::<alloc::string::String>("String")
54
            .ty(Type::User(UserType::Opaque))
55
            .def(Def::Scalar)
56
            .vtable_direct(&VTABLE)
57
            .type_ops_direct(&STRING_TYPE_OPS)
58
            .eq()
59
            .send()
60
            .sync()
61
            .build()
62
    };
63
}
64

65
#[cfg(test)]
66
mod tests {
67
    use core::ptr::NonNull;
68

69
    use crate::Facet;
70
    use alloc::string::String;
71

72
    #[test]
73
    fn test_string_has_parse() {
1✔
74
        // Check that String has a parse function in its vtable
75
        let shape = String::SHAPE;
1✔
76
        assert!(
1✔
77
            shape.vtable.has_parse(),
1✔
78
            "String should have parse function"
79
        );
80
    }
1✔
81

82
    #[test]
83
    fn test_string_parse() {
1✔
84
        // Test that we can parse a string into a String
85
        let shape = String::SHAPE;
1✔
86

87
        // Allocate memory for the String
88
        let layout = shape.layout.sized_layout().unwrap();
1✔
89
        let ptr = unsafe { alloc::alloc::alloc(layout) };
1✔
90
        let Some(ptr) = NonNull::new(ptr) else {
1✔
UNCOV
91
            alloc::alloc::handle_alloc_error(layout)
×
92
        };
93
        let ptr_mut = crate::PtrMut::new(ptr.as_ptr());
1✔
94

95
        // Parse the string using the new API
96
        let result = unsafe { shape.call_parse("hello world", ptr_mut) };
1✔
97
        assert!(result.is_some(), "String should have parse function");
1✔
98
        assert!(result.unwrap().is_ok());
1✔
99

100
        // Get the parsed value
101
        let parsed = unsafe { ptr_mut.get::<String>() };
1✔
102
        assert_eq!(parsed, &String::from("hello world"));
1✔
103

104
        // Clean up
105
        unsafe {
1✔
106
            shape.call_drop_in_place(ptr_mut).unwrap();
1✔
107
            alloc::alloc::dealloc(ptr.as_ptr(), layout);
1✔
108
        }
1✔
109
    }
1✔
110
}
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