Skip to main content

facet_core/impls/core/
duration.rs

1use alloc::string::String;
2use core::time::Duration;
3
4use crate::{
5    Def, Facet, OxPtrConst, ProxyDef, PtrConst, PtrMut, PtrUninit, Shape, ShapeBuilder, Type,
6    UserType, VTableIndirect,
7};
8
9unsafe fn duration_proxy_convert_out(
10    target_ptr: PtrConst,
11    proxy_ptr: PtrUninit,
12) -> Result<PtrMut, String> {
13    unsafe {
14        let duration = target_ptr.get::<Duration>();
15        let secs = duration.as_secs();
16        let nanos = duration.subsec_nanos();
17        let proxy_mut = proxy_ptr.as_mut_byte_ptr() as *mut (u64, u32);
18        proxy_mut.write((secs, nanos));
19        Ok(PtrMut::new(proxy_mut as *mut u8))
20    }
21}
22
23unsafe fn duration_proxy_convert_in(
24    proxy_ptr: PtrConst,
25    target_ptr: PtrUninit,
26) -> Result<PtrMut, String> {
27    unsafe {
28        let (secs, nanos): (u64, u32) = proxy_ptr.read::<(u64, u32)>();
29        let duration = Duration::new(secs, nanos);
30        let target_mut = target_ptr.as_mut_byte_ptr() as *mut Duration;
31        target_mut.write(duration);
32        Ok(PtrMut::new(target_mut as *mut u8))
33    }
34}
35
36const DURATION_PROXY: ProxyDef = ProxyDef {
37    shape: <(u64, u32) as Facet>::SHAPE,
38    convert_in: duration_proxy_convert_in,
39    convert_out: duration_proxy_convert_out,
40};
41
42unsafe fn display_duration(
43    source: OxPtrConst,
44    f: &mut core::fmt::Formatter<'_>,
45) -> Option<core::fmt::Result> {
46    unsafe {
47        let d = source.get::<Duration>();
48        Some(write!(f, "{}s {}ns", d.as_secs(), d.subsec_nanos()))
49    }
50}
51
52unsafe fn partial_eq_duration(a: OxPtrConst, b: OxPtrConst) -> Option<bool> {
53    unsafe { Some(a.get::<Duration>() == b.get::<Duration>()) }
54}
55
56const DURATION_VTABLE: VTableIndirect = VTableIndirect {
57    display: Some(display_duration),
58    partial_eq: Some(partial_eq_duration),
59    ..VTableIndirect::EMPTY
60};
61
62unsafe impl Facet<'_> for Duration {
63    const SHAPE: &'static Shape = &const {
64        ShapeBuilder::for_sized::<Duration>("Duration")
65            .module_path("core::time")
66            .ty(Type::User(UserType::Opaque))
67            .def(Def::Scalar)
68            .vtable_indirect(&DURATION_VTABLE)
69            .proxy(&DURATION_PROXY)
70            .build()
71    };
72}