Skip to main content

facet_core/impls/std/
path.rs

1use crate::{
2    Def, Facet, PtrConst, Shape, ShapeBuilder, TryFromOutcome, Type, UserType, VTableDirect,
3    VTableIndirect, vtable_direct, vtable_indirect,
4};
5
6/// Try to convert from &str or String to PathBuf
7///
8/// # Safety
9/// `dst` must be valid for writes, `src` must point to valid data of type described by `src_shape`
10unsafe fn pathbuf_try_from(
11    dst: *mut std::path::PathBuf,
12    src_shape: &'static Shape,
13    src: PtrConst,
14) -> TryFromOutcome {
15    // Check if source is &str (Copy type, use get)
16    if src_shape.id == <&str as Facet>::SHAPE.id {
17        let str_ref: &str = unsafe { src.get::<&str>() };
18        unsafe { dst.write(std::path::PathBuf::from(str_ref)) };
19        return TryFromOutcome::Converted;
20    }
21
22    // Check if source is String (consume via read)
23    if src_shape.id == <alloc::string::String as Facet>::SHAPE.id {
24        let string: alloc::string::String = unsafe { src.read::<alloc::string::String>() };
25        unsafe { dst.write(std::path::PathBuf::from(string)) };
26        return TryFromOutcome::Converted;
27    }
28
29    TryFromOutcome::Unsupported
30}
31
32/// Parse a PathBuf from a string
33///
34/// # Safety
35/// `target` must be valid for writes
36unsafe fn pathbuf_parse(s: &str, target: *mut std::path::PathBuf) -> Result<(), crate::ParseError> {
37    // PathBuf::from never fails - any string is a valid path
38    unsafe { target.write(std::path::PathBuf::from(s)) };
39    Ok(())
40}
41
42unsafe impl Facet<'_> for std::path::PathBuf {
43    const SHAPE: &'static Shape = &const {
44        const VTABLE: VTableDirect = vtable_direct!(std::path::PathBuf =>
45            Debug,
46            Hash,
47            PartialEq,
48            PartialOrd,
49            Ord,
50            [parse = pathbuf_parse],
51            [try_from = pathbuf_try_from],
52        );
53
54        ShapeBuilder::for_sized::<std::path::PathBuf>("PathBuf")
55            .module_path("std::path")
56            .ty(Type::User(UserType::Opaque))
57            .def(Def::Scalar)
58            .vtable_direct(&VTABLE)
59            .eq()
60            .send()
61            .sync()
62            .build()
63    };
64}
65
66unsafe impl Facet<'_> for std::path::Path {
67    const SHAPE: &'static Shape = &const {
68        const VTABLE: VTableIndirect = vtable_indirect!(std::path::Path =>
69            Debug,
70            Hash,
71            PartialEq,
72            PartialOrd,
73            Ord,
74        );
75
76        ShapeBuilder::for_unsized::<std::path::Path>("Path")
77            .module_path("std::path")
78            .ty(Type::User(UserType::Opaque))
79            .def(Def::Scalar)
80            .vtable_indirect(&VTABLE)
81            .eq()
82            .send()
83            .sync()
84            .build()
85    };
86}