facet_core/impls/std/
path.rs

1use crate::{
2    Def, Facet, PtrConst, Shape, ShapeBuilder, Type, UserType, VTableDirect, VTableIndirect,
3    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) -> Result<(), alloc::string::String> {
15    // Check if source is &str
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 Ok(());
20    }
21
22    // Check if source is String
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 Ok(());
27    }
28
29    Err(alloc::format!(
30        "cannot convert {} to PathBuf",
31        src_shape.type_identifier
32    ))
33}
34
35/// Parse a PathBuf from a string
36///
37/// # Safety
38/// `target` must be valid for writes
39unsafe fn pathbuf_parse(s: &str, target: *mut std::path::PathBuf) -> Result<(), crate::ParseError> {
40    // PathBuf::from never fails - any string is a valid path
41    unsafe { target.write(std::path::PathBuf::from(s)) };
42    Ok(())
43}
44
45unsafe impl Facet<'_> for std::path::PathBuf {
46    const SHAPE: &'static Shape = &const {
47        const VTABLE: VTableDirect = vtable_direct!(std::path::PathBuf =>
48            Debug,
49            Hash,
50            PartialEq,
51            PartialOrd,
52            Ord,
53            [parse = pathbuf_parse],
54            [try_from = pathbuf_try_from],
55        );
56
57        ShapeBuilder::for_sized::<std::path::PathBuf>("PathBuf")
58            .ty(Type::User(UserType::Opaque))
59            .def(Def::Scalar)
60            .vtable_direct(&VTABLE)
61            .eq()
62            .send()
63            .sync()
64            .build()
65    };
66}
67
68unsafe impl Facet<'_> for std::path::Path {
69    const SHAPE: &'static Shape = &const {
70        const VTABLE: VTableIndirect = vtable_indirect!(std::path::Path =>
71            Debug,
72            Hash,
73            PartialEq,
74            PartialOrd,
75            Ord,
76        );
77
78        ShapeBuilder::for_unsized::<std::path::Path>("Path")
79            .ty(Type::User(UserType::Opaque))
80            .def(Def::Scalar)
81            .vtable_indirect(&VTABLE)
82            .eq()
83            .send()
84            .sync()
85            .build()
86    };
87}